config_ue.c 96.2 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 34
#define _GNU_SOURCE

35
//#include "mac_defs.h"
36
#include <NR_MAC_gNB/mac_proto.h>
37
#include "NR_MAC_UE/mac_proto.h"
38
#include "NR_MAC-CellGroupConfig.h"
39
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
40 41
#include "common/utils/nr/nr_common.h"
#include "executables/softmodem-common.h"
42
#include "SCHED_NR/phy_frame_config_nr.h"
43
#include "oai_asn1.h"
44

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
const long logicalChannelGroup0_NR = 0;
typedef struct NR_LogicalChannelConfig__ul_SpecificParameters LcConfig_UlParamas_t;

const LcConfig_UlParamas_t NR_LCSRB1 = {
    .priority = 1,
    .prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
    .logicalChannelGroup = (long *)&logicalChannelGroup0_NR};

const LcConfig_UlParamas_t NR_LCSRB2 = {
    .priority = 3,
    .prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
    .logicalChannelGroup = (long *)&logicalChannelGroup0_NR};

const LcConfig_UlParamas_t NR_LCSRB3 = {
    .priority = 1,
    .prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity,
    .logicalChannelGroup = (long *)&logicalChannelGroup0_NR};

// these are the default values for SRB configurations(SRB1 and SRB2) as mentioned in 36.331 pg 258-259
const NR_LogicalChannelConfig_t NR_SRB1_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
                                                                                 (LcConfig_UlParamas_t *)&NR_LCSRB1};
const NR_LogicalChannelConfig_t NR_SRB2_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
                                                                                 (LcConfig_UlParamas_t *)&NR_LCSRB2};
const NR_LogicalChannelConfig_t NR_SRB3_logicalChannelConfig_defaultValue = {.ul_SpecificParameters =
                                                                                 (LcConfig_UlParamas_t *)&NR_LCSRB3};

francescomani's avatar
francescomani committed
71
void set_tdd_config_nr_ue(fapi_nr_tdd_table_t *tdd_table,
72
                          int mu,
francescomani's avatar
francescomani committed
73 74 75 76 77 78 79 80 81 82 83
                          NR_TDD_UL_DL_Pattern_t *pattern)
{
  const int nrofDownlinkSlots = pattern->nrofDownlinkSlots;
  const int nrofDownlinkSymbols = pattern->nrofDownlinkSymbols;
  const int nrofUplinkSlots = pattern->nrofUplinkSlots;
  const int nrofUplinkSymbols = pattern->nrofUplinkSymbols;
  const int nb_periods_per_frame = get_nb_periods_per_frame(pattern->dl_UL_TransmissionPeriodicity);
  const int nb_slots_per_period = ((1 << mu) * NR_NUMBER_OF_SUBFRAMES_PER_FRAME) / nb_periods_per_frame;
  tdd_table->tdd_period_in_slots = nb_slots_per_period;

  if ((nrofDownlinkSymbols + nrofUplinkSymbols) == 0)
84 85 86 87 88 89 90 91 92
    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
93

francescomani's avatar
francescomani committed
94
  tdd_table->max_tdd_periodicity_list = (fapi_nr_max_tdd_periodicity_t *) malloc(nb_slots_per_period * sizeof(fapi_nr_max_tdd_periodicity_t));
Raymond Knopp's avatar
Raymond Knopp committed
95

francescomani's avatar
francescomani committed
96 97 98
  for(int memory_alloc = 0 ; memory_alloc < nb_slots_per_period; memory_alloc++)
    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
99

francescomani's avatar
francescomani committed
100 101
  int slot_number = 0;
  while(slot_number != nb_slots_per_period) {
102
    if(nrofDownlinkSlots != 0) {
francescomani's avatar
francescomani committed
103 104 105
      for (int number_of_symbol = 0; number_of_symbol < nrofDownlinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
        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;
        if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
106 107 108
          slot_number++;
      }
    }
Raymond Knopp's avatar
Raymond Knopp committed
109

110
    if (nrofDownlinkSymbols != 0 || nrofUplinkSymbols != 0) {
francescomani's avatar
francescomani committed
111 112
      for(int number_of_symbol = 0; number_of_symbol < nrofDownlinkSymbols; number_of_symbol++) {
        tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 0;
113
      }
francescomani's avatar
francescomani committed
114 115
      for(int number_of_symbol = nrofDownlinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol++) {
        tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 2;
116
      }
francescomani's avatar
francescomani committed
117 118
      for(int number_of_symbol = NR_NUMBER_OF_SYMBOLS_PER_SLOT - nrofUplinkSymbols; number_of_symbol < NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
        tdd_table->max_tdd_periodicity_list[slot_number].max_num_of_symbol_per_slot_list[number_of_symbol].slot_config = 1;
119 120 121
      }
      slot_number++;
    }
Raymond Knopp's avatar
Raymond Knopp committed
122

123
    if(nrofUplinkSlots != 0) {
francescomani's avatar
francescomani committed
124 125 126
      for (int number_of_symbol = 0; number_of_symbol < nrofUplinkSlots * NR_NUMBER_OF_SYMBOLS_PER_SLOT; number_of_symbol++) {
        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;
        if((number_of_symbol + 1) % NR_NUMBER_OF_SYMBOLS_PER_SLOT == 0)
127 128 129 130 131
          slot_number++;
      }
    }
  }
}
Raymond Knopp's avatar
Raymond Knopp committed
132

133 134 135 136
static void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
                                NR_ServingCellConfigCommonSIB_t *scc,
                                module_id_t module_id,
                                int cc_idP)
137
{
138 139 140 141 142 143 144
  fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
  mac->phy_config.Mod_id = module_id;
  mac->phy_config.CC_id = cc_idP;

  LOG_D(MAC, "Entering SA UE Config Common\n");

  // carrier config
145
  NR_FrequencyInfoDL_SIB_t *frequencyInfoDL = &scc->downlinkConfigCommon.frequencyInfoDL;
146
  AssertFatal(frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR, "Field mandatory present for DL in SIB1\n");
147
  mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0]->freqBandIndicatorNR;
148
  int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
149
                                          mac->nr_band,
150
                                          frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
151
  cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
152 153 154

  uint64_t dl_bw_khz = (12 * frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth) *
                       (15 << frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing);
155 156
  cfg->carrier_config.dl_frequency = (downlink_frequency[cc_idP][0]/1000) - (dl_bw_khz>>1);

157
  for (int i = 0; i < 5; i++) {
158 159 160
    if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
      cfg->carrier_config.dl_grid_size[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
      cfg->carrier_config.dl_k0[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
161 162 163 164 165 166 167
    }
    else {
      cfg->carrier_config.dl_grid_size[i] = 0;
      cfg->carrier_config.dl_k0[i] = 0;
    }
  }

168
  NR_FrequencyInfoUL_SIB_t *frequencyInfoUL = &scc->uplinkConfigCommon->frequencyInfoUL;
169
  mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
170
  bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
171
                                      mac->nr_band,
172
                                      frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
173
  cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
174

175
  if (frequencyInfoUL->absoluteFrequencyPointA == NULL)
176 177 178 179 180
    cfg->carrier_config.uplink_frequency = cfg->carrier_config.dl_frequency;
  else
    // TODO check if corresponds to what reported in SIB1
    cfg->carrier_config.uplink_frequency = (downlink_frequency[cc_idP][0]/1000) + uplink_frequency_offset[cc_idP][0];

181 182 183 184
  for (int i = 0; i < 5; i++) {
    if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
      cfg->carrier_config.ul_grid_size[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
      cfg->carrier_config.ul_k0[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
    }
    else {
      cfg->carrier_config.ul_grid_size[i] = 0;
      cfg->carrier_config.ul_k0[i] = 0;
    }
  }

  mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
  // cell config
  cfg->cell_config.phy_cell_id = mac->physCellId;
  cfg->cell_config.frame_duplex_type = mac->frame_type;

  // SSB config
  cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
  cfg->ssb_config.scs_common = get_softmodem_params()->numerology;

  // SSB Table config
202
  cfg->ssb_table.ssb_offset_point_a = frequencyInfoDL->offsetToPointA;
203 204 205 206
  cfg->ssb_table.ssb_period = scc->ssb_PeriodicityServingCell;
  cfg->ssb_table.ssb_subcarrier_offset = mac->ssb_subcarrier_offset;

  if (mac->frequency_range == FR1){
laurent's avatar
laurent committed
207
    cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) scc->ssb_PositionsInBurst.inOneGroup.buf[0]) << 24;
208 209 210 211 212 213 214 215 216 217
    cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
  }
  else{
    for (int i=0; i<8; i++){
      if ((scc->ssb_PositionsInBurst.groupPresence->buf[0]>>(7-i))&0x01)
        cfg->ssb_table.ssb_mask_list[i>>2].ssb_mask |= scc->ssb_PositionsInBurst.inOneGroup.buf[0]<<(24-8*(i%4));
    }
  }

  // TDD Table Configuration
218
  if (cfg->cell_config.frame_duplex_type == TDD){
219
    set_tdd_config_nr_ue(&cfg->tdd_table_1, cfg->ssb_config.scs_common, &mac->tdd_UL_DL_ConfigurationCommon->pattern1);
francescomani's avatar
francescomani committed
220 221
    if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) {
      cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t));
222
      set_tdd_config_nr_ue(cfg->tdd_table_2, cfg->ssb_config.scs_common, mac->tdd_UL_DL_ConfigurationCommon->pattern2);
francescomani's avatar
francescomani committed
223
    }
224 225 226 227 228
  }

  // PRACH configuration

  uint8_t nb_preambles = 64;
229 230 231
  NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
  if(rach_ConfigCommon->totalNumberOfRA_Preambles != NULL)
     nb_preambles = *rach_ConfigCommon->totalNumberOfRA_Preambles;
232

233
  cfg->prach_config.prach_sequence_length = rach_ConfigCommon->prach_RootSequenceIndex.present-1;
234

235 236
  if (rach_ConfigCommon->msg1_SubcarrierSpacing)
    cfg->prach_config.prach_sub_c_spacing = *rach_ConfigCommon->msg1_SubcarrierSpacing;
237 238 239 240 241 242 243
  else {
    // If absent, the UE applies the SCS as derived from the prach-ConfigurationIndex (for 839)
    int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
    const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, mac->frame_type);
    int format = prach_config_info_p[0];
    cfg->prach_config.prach_sub_c_spacing = format == 3 ? 5 : 4;
  }
244

245
  cfg->prach_config.restricted_set_config = rach_ConfigCommon->restrictedSetConfig;
246

247 248 249 250
  AssertFatal(rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM < 4,
              "msg1 FDM identifier %ld undefined (0,1,2,3)\n", rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM);
  cfg->prach_config.num_prach_fd_occasions = 1 << rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM;

251 252 253

  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 (int i=0; i<cfg->prach_config.num_prach_fd_occasions; i++) {
254 255
    fapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &cfg->prach_config.num_prach_fd_occasions_list[i];
    prach_fd_occasion->num_prach_fd_occasions = i;
256
    if (cfg->prach_config.prach_sequence_length)
257
      prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l139;
258
    else
259 260 261 262 263 264 265 266
      prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l839;
    prach_fd_occasion->k1 = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP.genericParameters.locationAndBandwidth, MAX_BWP_SIZE) +
                                            rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart +
                                            (get_N_RA_RB(cfg->prach_config.prach_sub_c_spacing, frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing ) * i);
    prach_fd_occasion->prach_zero_corr_conf = rach_ConfigCommon->rach_ConfigGeneric.zeroCorrelationZoneConfig;
    prach_fd_occasion->num_root_sequences = compute_nr_root_seq(rach_ConfigCommon,
                                                                nb_preambles, mac->frame_type, mac->frequency_range);
    //prach_fd_occasion->num_unused_root_sequences = ???
267
  }
268
  cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1;
269 270 271

}

272 273 274 275
static void config_common_ue(NR_UE_MAC_INST_t *mac,
                             NR_ServingCellConfigCommon_t *scc,
                             module_id_t module_id,
                             int cc_idP)
276
{
277
  fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
Raymond Knopp's avatar
Raymond Knopp committed
278

cig's avatar
cig committed
279 280
  mac->phy_config.Mod_id = module_id;
  mac->phy_config.CC_id = cc_idP;
281
  
282
  // carrier config
cig's avatar
cig committed
283
  LOG_D(MAC, "Entering UE Config Common\n");
284

285
  AssertFatal(scc->downlinkConfigCommon, "Not expecting downlinkConfigCommon to be NULL here\n");
286

287 288 289 290 291 292 293 294 295 296
  NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
  if (frequencyInfoDL) { // NeedM for inter-freq handover
    mac->nr_band = *frequencyInfoDL->frequencyBandList.list.array[0];
    mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
    mac->frequency_range = mac->nr_band < 256 ? FR1 : FR2;

    int bw_index = get_supported_band_index(frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                                            mac->nr_band,
                                            frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
    cfg->carrier_config.dl_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);
297

298 299
    cfg->carrier_config.dl_frequency = from_nrarfcn(mac->nr_band,
                                                    *scc->ssbSubcarrierSpacing,
300 301 302
                                                    frequencyInfoDL->absoluteFrequencyPointA)
                                       / 1000; // freq in kHz

303 304 305 306
    for (int i = 0; i < 5; i++) {
      if (i == frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
        cfg->carrier_config.dl_grid_size[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
        cfg->carrier_config.dl_k0[i] = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
307
      } else {
308 309 310
        cfg->carrier_config.dl_grid_size[i] = 0;
        cfg->carrier_config.dl_k0[i] = 0;
      }
311
    }
312 313
  }

314 315
  if (scc->uplinkConfigCommon && scc->uplinkConfigCommon->frequencyInfoUL) {
    NR_FrequencyInfoUL_t *frequencyInfoUL = scc->uplinkConfigCommon->frequencyInfoUL;
316
    mac->p_Max = frequencyInfoUL->p_Max ? *frequencyInfoUL->p_Max : INT_MIN;
317

318 319 320 321 322 323 324 325 326 327 328
    int bw_index = get_supported_band_index(frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing,
                                            *frequencyInfoUL->frequencyBandList->list.array[0],
                                            frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth);
    cfg->carrier_config.uplink_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index);

    long *UL_pointA = NULL;
    if (frequencyInfoUL->absoluteFrequencyPointA)
      UL_pointA = frequencyInfoUL->absoluteFrequencyPointA;
    else if (frequencyInfoDL)
      UL_pointA = &frequencyInfoDL->absoluteFrequencyPointA;

329
    if (UL_pointA)
330 331
      cfg->carrier_config.uplink_frequency = from_nrarfcn(*frequencyInfoUL->frequencyBandList->list.array[0],
                                                          *scc->ssbSubcarrierSpacing,
332 333
                                                          *UL_pointA)
                                             / 1000; // freq in kHz
334 335 336 337 338

    for (int i = 0; i < 5; i++) {
      if (i == frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing) {
        cfg->carrier_config.ul_grid_size[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
        cfg->carrier_config.ul_k0[i] = frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->offsetToCarrier;
339
      } else {
340 341 342
        cfg->carrier_config.ul_grid_size[i] = 0;
        cfg->carrier_config.ul_k0[i] = 0;
      }
343
    }
344
  }
345

346 347
  // cell config
  cfg->cell_config.phy_cell_id = *scc->physCellId;
348
  cfg->cell_config.frame_duplex_type = mac->frame_type;
349 350 351 352 353 354

  // SSB config
  cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower;
  cfg->ssb_config.scs_common = *scc->ssbSubcarrierSpacing;

  // SSB Table config
355
  if (frequencyInfoDL && frequencyInfoDL->absoluteFrequencySSB) {
356
    int scs_scaling = 1 << (cfg->ssb_config.scs_common);
357
    if (frequencyInfoDL->absoluteFrequencyPointA < 600000)
358
      scs_scaling = scs_scaling * 3;
359
    if (frequencyInfoDL->absoluteFrequencyPointA > 2016666)
360
      scs_scaling = scs_scaling >> 2;
361
    uint32_t absolute_diff = (*frequencyInfoDL->absoluteFrequencySSB - frequencyInfoDL->absoluteFrequencyPointA);
362
    cfg->ssb_table.ssb_offset_point_a = absolute_diff / (12 * scs_scaling) - 10;
363 364
    cfg->ssb_table.ssb_period = *scc->ssb_periodicityServingCell;
    // NSA -> take ssb offset from SCS
365
    cfg->ssb_table.ssb_subcarrier_offset = absolute_diff % (12 * scs_scaling);
366
  }
367 368 369

  switch (scc->ssb_PositionsInBurst->present) {
  case 1 :
370
    cfg->ssb_table.ssb_mask_list[0].ssb_mask = scc->ssb_PositionsInBurst->choice.shortBitmap.buf[0] << 24;
371 372 373 374 375 376 377 378 379 380
    cfg->ssb_table.ssb_mask_list[1].ssb_mask = 0;
    break;
  case 2 :
    cfg->ssb_table.ssb_mask_list[0].ssb_mask = ((uint32_t) 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 (int i = 0; i < 4; i++) {
Laurent THOMAS's avatar
Laurent THOMAS committed
381 382
      cfg->ssb_table.ssb_mask_list[0].ssb_mask += (uint32_t) scc->ssb_PositionsInBurst->choice.longBitmap.buf[3 - i] << i * 8;
      cfg->ssb_table.ssb_mask_list[1].ssb_mask += (uint32_t) scc->ssb_PositionsInBurst->choice.longBitmap.buf[7 - i] << i * 8;
383 384 385 386 387 388 389 390
    }
    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 (cfg->cell_config.frame_duplex_type == TDD){
391
    set_tdd_config_nr_ue(&cfg->tdd_table_1, cfg->ssb_config.scs_common, &mac->tdd_UL_DL_ConfigurationCommon->pattern1);
francescomani's avatar
francescomani committed
392 393
    if (mac->tdd_UL_DL_ConfigurationCommon->pattern2) {
      cfg->tdd_table_2 = (fapi_nr_tdd_table_t *) malloc(sizeof(fapi_nr_tdd_table_t));
394
      set_tdd_config_nr_ue(cfg->tdd_table_2, cfg->ssb_config.scs_common, mac->tdd_UL_DL_ConfigurationCommon->pattern2);
francescomani's avatar
francescomani committed
395
    }
396 397 398 399
  }

  // PRACH configuration
  uint8_t nb_preambles = 64;
400 401
  if (scc->uplinkConfigCommon && scc->uplinkConfigCommon->initialUplinkBWP
      && scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon) { // all NeedM
402

403
    NR_RACH_ConfigCommon_t *rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
404
    if (rach_ConfigCommon->totalNumberOfRA_Preambles != NULL)
405
      nb_preambles = *rach_ConfigCommon->totalNumberOfRA_Preambles;
406

407
    cfg->prach_config.prach_sequence_length = rach_ConfigCommon->prach_RootSequenceIndex.present - 1;
408

409 410 411 412 413 414 415 416 417
    if (rach_ConfigCommon->msg1_SubcarrierSpacing)
      cfg->prach_config.prach_sub_c_spacing = *rach_ConfigCommon->msg1_SubcarrierSpacing;
    else {
      // If absent, the UE applies the SCS as derived from the prach-ConfigurationIndex (for 839)
      int config_index = rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
      const int64_t *prach_config_info_p = get_prach_config_info(mac->frequency_range, config_index, mac->frame_type);
      int format = prach_config_info_p[0];
      cfg->prach_config.prach_sub_c_spacing = format == 3 ? 5 : 4;
    }
418

419 420
    cfg->prach_config.restricted_set_config = rach_ConfigCommon->restrictedSetConfig;

421 422 423
    AssertFatal(rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM < 4,
                "msg1 FDM identifier %ld undefined (0,1,2,3)\n", rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM);
    cfg->prach_config.num_prach_fd_occasions = 1 << rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM;
424

425 426
    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));
427 428 429 430 431 432 433 434 435 436
    for (int i = 0; i < cfg->prach_config.num_prach_fd_occasions; i++) {
      fapi_nr_num_prach_fd_occasions_t *prach_fd_occasion = &cfg->prach_config.num_prach_fd_occasions_list[i];
      prach_fd_occasion->num_prach_fd_occasions = i;
      if (cfg->prach_config.prach_sequence_length)
        prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l139;
      else
        prach_fd_occasion->prach_root_sequence_index = rach_ConfigCommon->prach_RootSequenceIndex.choice.l839;

      prach_fd_occasion->k1 = rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
      prach_fd_occasion->prach_zero_corr_conf = rach_ConfigCommon->rach_ConfigGeneric.zeroCorrelationZoneConfig;
437 438
      prach_fd_occasion->num_root_sequences =
          compute_nr_root_seq(rach_ConfigCommon, nb_preambles, mac->frame_type, mac->frequency_range);
439

440 441
      cfg->prach_config.ssb_per_rach = rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present - 1;
      // prach_fd_occasion->num_unused_root_sequences = ???
442
    }
443
  }
Raymond Knopp's avatar
Raymond Knopp committed
444 445
}

446 447
void release_common_ss_cset(NR_BWP_PDCCH_t *pdcch)
{
448 449 450 451 452 453
  asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS);
  asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->ra_SS);
  asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->paging_SS);
  asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->search_space_zero);
  asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, pdcch->commonControlResourceSet);
  asn1cFreeStruc(asn_DEF_NR_ControlResourceSet, pdcch->coreset0);
454 455
}

456
static void modlist_ss(NR_SearchSpace_t *source, NR_SearchSpace_t *target)
457 458 459
{
  target->searchSpaceId = source->searchSpaceId;
  if (source->controlResourceSetId)
460
    UPDATE_MAC_IE(target->controlResourceSetId, source->controlResourceSetId, NR_ControlResourceSetId_t);
461
  if (source->monitoringSlotPeriodicityAndOffset)
462
    UPDATE_MAC_IE(target->monitoringSlotPeriodicityAndOffset,
463 464
                source->monitoringSlotPeriodicityAndOffset,
                struct NR_SearchSpace__monitoringSlotPeriodicityAndOffset);
465
  UPDATE_MAC_IE(target->duration, source->duration, long);
466
  if (source->monitoringSymbolsWithinSlot)
467
    UPDATE_MAC_IE(target->monitoringSymbolsWithinSlot, source->monitoringSymbolsWithinSlot, BIT_STRING_t);
468
  if (source->nrofCandidates)
469
    UPDATE_MAC_IE(target->nrofCandidates, source->nrofCandidates, struct NR_SearchSpace__nrofCandidates);
470
  if (source->searchSpaceType)
471
    UPDATE_MAC_IE(target->searchSpaceType, source->searchSpaceType, struct NR_SearchSpace__searchSpaceType);
472
}
473

474 475 476
static NR_SearchSpace_t *get_common_search_space(const struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList,
                                                 const NR_BWP_PDCCH_t *pdcch,
                                                 const NR_SearchSpaceId_t ss_id)
477 478
{
  if (ss_id == 0)
479
    return pdcch->search_space_zero;
480 481 482 483

  NR_SearchSpace_t *css = NULL;
  for (int i = 0; i < commonSearchSpaceList->list.count; i++) {
    if (commonSearchSpaceList->list.array[i]->searchSpaceId == ss_id) {
484 485
      css = calloc(1, sizeof(*css));
      modlist_ss(commonSearchSpaceList->list.array[i], css);
486 487 488 489 490 491 492
      break;
    }
  }
  AssertFatal(css, "Couldn't find CSS with Id %ld\n", ss_id);
  return css;
}

493
static void configure_common_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_ConfigCommon_t *pdcch_ConfigCommon)
494 495
{
  if (pdcch_ConfigCommon) {
496
    asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->otherSI_SS);
497 498 499 500 501
    if (pdcch_ConfigCommon->searchSpaceOtherSystemInformation)
      pdcch->otherSI_SS = get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList,
                                                  pdcch,
                                                  *pdcch_ConfigCommon->searchSpaceOtherSystemInformation);

502
    asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->ra_SS);
503
    if (pdcch_ConfigCommon->ra_SearchSpace) {
504
      if (pdcch->otherSI_SS && *pdcch_ConfigCommon->ra_SearchSpace == pdcch->otherSI_SS->searchSpaceId)
505 506
        pdcch->ra_SS = pdcch->otherSI_SS;
      else
507 508
        pdcch->ra_SS =
            get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->ra_SearchSpace);
509 510
    }

511
    asn1cFreeStruc(asn_DEF_NR_SearchSpace, pdcch->paging_SS);
512
    if (pdcch_ConfigCommon->pagingSearchSpace) {
513
      if (pdcch->otherSI_SS && *pdcch_ConfigCommon->pagingSearchSpace == pdcch->otherSI_SS->searchSpaceId)
514
        pdcch->paging_SS = pdcch->otherSI_SS;
515
      else if (pdcch->ra_SS && *pdcch_ConfigCommon->pagingSearchSpace == pdcch->ra_SS->searchSpaceId)
516 517
        pdcch->paging_SS = pdcch->ra_SS;
      if (!pdcch->paging_SS)
518 519
        pdcch->paging_SS =
            get_common_search_space(pdcch_ConfigCommon->commonSearchSpaceList, pdcch, *pdcch_ConfigCommon->pagingSearchSpace);
520 521
    }

522
    UPDATE_MAC_IE(pdcch->commonControlResourceSet, pdcch_ConfigCommon->commonControlResourceSet, NR_ControlResourceSet_t);
523 524 525
  }
}

526
static void modlist_coreset(NR_ControlResourceSet_t *source, NR_ControlResourceSet_t *target)
527 528 529
{
  target->controlResourceSetId = source->controlResourceSetId;
  target->frequencyDomainResources.size = source->frequencyDomainResources.size;
francescomani's avatar
francescomani committed
530
  if (!target->frequencyDomainResources.buf)
531 532
    target->frequencyDomainResources.buf =
        calloc(target->frequencyDomainResources.size, sizeof(*target->frequencyDomainResources.buf));
533 534 535 536 537 538 539 540 541 542
  for (int i = 0; i < source->frequencyDomainResources.size; i++)
    target->frequencyDomainResources.buf[i] = source->frequencyDomainResources.buf[i];
  target->duration = source->duration;
  target->precoderGranularity = source->precoderGranularity;
  long *shiftIndex = NULL;
  if (target->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved)
    shiftIndex = target->cce_REG_MappingType.choice.interleaved->shiftIndex;
  if (source->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved) {
    target->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved;
    target->cce_REG_MappingType.choice.interleaved->reg_BundleSize = source->cce_REG_MappingType.choice.interleaved->reg_BundleSize;
543 544 545 546 547 548 549
    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);
  } else {
    free(shiftIndex);
550 551
    target->cce_REG_MappingType = source->cce_REG_MappingType;
  }
552 553
  UPDATE_MAC_IE(target->tci_PresentInDCI, source->tci_PresentInDCI, long);
  UPDATE_MAC_IE(target->pdcch_DMRS_ScramblingID, source->pdcch_DMRS_ScramblingID, long);
554 555 556 557 558 559
  // TCI States
  if (source->tci_StatesPDCCH_ToReleaseList) {
    for (int i = 0; i < source->tci_StatesPDCCH_ToReleaseList->list.count; i++) {
      long id = *source->tci_StatesPDCCH_ToReleaseList->list.array[i];
      int j;
      for (j = 0; j < target->tci_StatesPDCCH_ToAddList->list.count; j++) {
560
        if (id == *target->tci_StatesPDCCH_ToAddList->list.array[j])
561 562 563 564 565 566 567 568 569
          break;
      }
      if (j < target->tci_StatesPDCCH_ToAddList->list.count)
        asn_sequence_del(&target->tci_StatesPDCCH_ToAddList->list, j, 1);
      else
        LOG_E(NR_MAC, "Element not present in the list, impossible to release\n");
    }
  }
  if (source->tci_StatesPDCCH_ToAddList) {
francescomani's avatar
francescomani committed
570 571 572 573 574
    if (target->tci_StatesPDCCH_ToAddList) {
      for (int i = 0; i < source->tci_StatesPDCCH_ToAddList->list.count; i++) {
        long id = *source->tci_StatesPDCCH_ToAddList->list.array[i];
        int j;
        for (j = 0; j < target->tci_StatesPDCCH_ToAddList->list.count; j++) {
575
          if (id == *target->tci_StatesPDCCH_ToAddList->list.array[j])
francescomani's avatar
francescomani committed
576 577 578
            break;
        }
        if (j == target->tci_StatesPDCCH_ToAddList->list.count)
579
          ASN_SEQUENCE_ADD(&target->tci_StatesPDCCH_ToAddList->list, source->tci_StatesPDCCH_ToAddList->list.array[i]);
francescomani's avatar
francescomani committed
580
      }
581 582 583 584
    } else
      UPDATE_MAC_IE(target->tci_StatesPDCCH_ToAddList,
                    source->tci_StatesPDCCH_ToAddList,
                    struct NR_ControlResourceSet__tci_StatesPDCCH_ToAddList);
585 586 587 588
  }
  // end TCI States
}

589
static void configure_ss_coreset(NR_BWP_PDCCH_t *pdcch, NR_PDCCH_Config_t *pdcch_Config)
590
{
591
  if (!pdcch_Config)
592
    return;
593
  if (pdcch_Config->controlResourceSetToAddModList) {
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609
    for (int i = 0; i < pdcch_Config->controlResourceSetToAddModList->list.count; i++) {
      NR_ControlResourceSet_t *source_coreset = pdcch_Config->controlResourceSetToAddModList->list.array[i];
      NR_ControlResourceSet_t *target_coreset = NULL;
      for (int j = 0; j < pdcch->list_Coreset.count; j++) {
        if (pdcch->list_Coreset.array[j]->controlResourceSetId == source_coreset->controlResourceSetId) {
          target_coreset = pdcch->list_Coreset.array[j];
          break;
        }
      }
      if (!target_coreset) {
        target_coreset = calloc(1, sizeof(*target_coreset));
        ASN_SEQUENCE_ADD(&pdcch->list_Coreset, target_coreset);
      }
      modlist_coreset(source_coreset, target_coreset);
    }
  }
610
  if (pdcch_Config->controlResourceSetToReleaseList) {
611 612 613 614 615 616 617 618 619 620
    for (int i = 0; i < pdcch_Config->controlResourceSetToReleaseList->list.count; i++) {
      NR_ControlResourceSetId_t id = *pdcch_Config->controlResourceSetToReleaseList->list.array[i];
      for (int j = 0; j < pdcch->list_Coreset.count; j++) {
        if (id == pdcch->list_Coreset.array[j]->controlResourceSetId) {
          asn_sequence_del(&pdcch->list_Coreset, j, 1);
          break;
        }
      }
    }
  }
621
  if (pdcch_Config->searchSpacesToAddModList) {
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
    for (int i = 0; i < pdcch_Config->searchSpacesToAddModList->list.count; i++) {
      NR_SearchSpace_t *source_ss = pdcch_Config->searchSpacesToAddModList->list.array[i];
      NR_SearchSpace_t *target_ss = NULL;
      for (int j = 0; j < pdcch->list_SS.count; j++) {
        if (pdcch->list_SS.array[j]->searchSpaceId == source_ss->searchSpaceId) {
          target_ss = pdcch->list_SS.array[j];
          break;
        }
      }
      if (!target_ss) {
        target_ss = calloc(1, sizeof(*target_ss));
        ASN_SEQUENCE_ADD(&pdcch->list_SS, target_ss);
      }
      modlist_ss(source_ss, target_ss);
    }
  }
638
  if (pdcch_Config->searchSpacesToReleaseList) {
639 640 641 642 643 644 645
    for (int i = 0; i < pdcch_Config->searchSpacesToReleaseList->list.count; i++) {
      NR_ControlResourceSetId_t id = *pdcch_Config->searchSpacesToReleaseList->list.array[i];
      for (int j = 0; j < pdcch->list_SS.count; j++) {
        if (id == pdcch->list_SS.array[j]->searchSpaceId) {
          asn_sequence_del(&pdcch->list_SS, j, 1);
          break;
        }
646 647
      }
    }
648 649 650
  }
}

651
static int lcid_cmp(const void *a, const void *b)
652
{
653 654 655 656 657 658 659 660
  long pa, pb;
  memcpy(&pa, &((nr_lcordered_info_t*)a)->logicalChannelConfig->ul_SpecificParameters->priority, sizeof(pa));
  memcpy(&pb, &((nr_lcordered_info_t*)b)->logicalChannelConfig->ul_SpecificParameters->priority, sizeof(pb));
  if (pa < pb)
    return -1;
  else if (pa > pb)
    return 1;
  return 0;
661 662
}

663
static int nr_get_ms_bucketsizeduration(long bucketsizeduration)
Sriharsha Korada's avatar
Sriharsha Korada committed
664 665
{
  switch (bucketsizeduration) {
666 667 668 669 670 671
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5:
      return 5;
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms10:
      return 10;
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms20:
      return 20;
Sriharsha Korada's avatar
Sriharsha Korada committed
672 673 674 675 676 677 678 679 680 681 682 683 684
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50:
      return 50;
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100:
      return 100;
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms150:
      return 150;
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300:
      return 300;
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms500:
      return 500;
    case NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000:
      return 1000;
    default:
685
      AssertFatal(false, "Invalid bucketSizeDuration %ld\n", bucketsizeduration);
Sriharsha Korada's avatar
Sriharsha Korada committed
686 687 688
  }
}

689
void nr_configure_sched_info(NR_UE_MAC_INST_t *mac, long channel_identity, NR_LogicalChannelConfig_t *lc_config)
690
{
691
  LOG_D(NR_MAC, "Applying RRC Logical Channel Config to lcid %li\n", channel_identity);
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712

  // initialize the variable Bj for every LCID
  mac->scheduling_info.lc_sched_info[channel_identity - 1].Bj = 0;

  // store the bucket size
  int pbr = nr_get_pbr(lc_config->ul_SpecificParameters->prioritisedBitRate);
  int bsd = nr_get_ms_bucketsizeduration(lc_config->ul_SpecificParameters->bucketSizeDuration);

  // in infinite pbr, the bucket is saturated by pbr
  if (lc_config->ul_SpecificParameters->prioritisedBitRate
      == NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity) {
    bsd = 1;
  }
  mac->scheduling_info.lc_sched_info[channel_identity - 1].bucket_size = pbr * bsd;

  if (lc_config->ul_SpecificParameters->logicalChannelGroup != NULL)
    mac->scheduling_info.lc_sched_info[channel_identity - 1].LCGID = *lc_config->ul_SpecificParameters->logicalChannelGroup;
  else
    mac->scheduling_info.lc_sched_info[channel_identity - 1].LCGID = 0;
}

713 714 715
static void configure_logicalChannelBearer(module_id_t module_id,
                                           struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_toadd_list,
                                           struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_torelease_list)
716 717
{
  NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
718

719 720
  if (rlc_torelease_list) {
    for (int i = 0; i < rlc_torelease_list->list.count; i++) {
721 722 723 724 725 726 727 728 729 730 731
      long id = *rlc_torelease_list->list.array[i];
      int j;
      for (j = 0; j < mac->lc_ordered_list.count; j++) {
        if (id == mac->lc_ordered_list.array[j]->lcid)
          break;
      }
      if (j < mac->lc_ordered_list.count) {
        nr_lcordered_info_t *lc_info = mac->lc_ordered_list.array[j];
        free(lc_info->logicalChannelConfig);
        asn_sequence_del(&mac->lc_ordered_list, j, 0);
        free(lc_info);
732
      }
733 734
      else
        LOG_E(NR_MAC, "Element not present in the list, impossible to release\n");
735 736
    }
  }
737

738 739 740 741
  if (rlc_toadd_list) {
    for (int i = 0; i < rlc_toadd_list->list.count; i++) {
      NR_RLC_BearerConfig_t *rlc_bearer = rlc_toadd_list->list.array[i];
      int lc_identity = rlc_bearer->logicalChannelIdentity;
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
      NR_LogicalChannelConfig_t *mac_lc_config = rlc_bearer->mac_LogicalChannelConfig;
      int j;
      for (j = 0; j < mac->lc_ordered_list.count; j++) {
        if (lc_identity == mac->lc_ordered_list.array[j]->lcid)
          break;
      }
      if (j < mac->lc_ordered_list.count) {
        LOG_D(NR_MAC, "Logical channel %d is already established, Reconfiguring now\n", lc_identity);
        if (mac_lc_config != NULL) {
          nr_configure_sched_info(mac, lc_identity, mac_lc_config);
          UPDATE_MAC_IE(mac->lc_ordered_list.array[j]->logicalChannelConfig,
                        rlc_bearer->mac_LogicalChannelConfig,
                        NR_LogicalChannelConfig_t);
        }
      }
      else {
758
        /* setup of new LCID*/
759 760
        nr_lcordered_info_t *lc_info = calloc(1, sizeof(*lc_info));
        lc_info->lcid = lc_identity;
761 762 763 764
        LOG_D(NR_MAC, "Establishing the logical channel %d\n", lc_identity);
        AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer should be present for LCID establishment\n");
        if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) { /* SRB */
          NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
765 766
          if (mac_lc_config != NULL) {
            UPDATE_MAC_IE(lc_info->logicalChannelConfig, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t);
767
          } else {
768 769 770 771 772 773 774 775 776 777 778 779 780 781
            LOG_D(NR_RRC, "Applying the default logicalChannelConfig for SRB\n");
            switch (srb_id) {
              case 1 :
                lc_info->logicalChannelConfig = (NR_LogicalChannelConfig_t *)&NR_SRB1_logicalChannelConfig_defaultValue;
                break;
              case 2 :
                lc_info->logicalChannelConfig = (NR_LogicalChannelConfig_t *)&NR_SRB2_logicalChannelConfig_defaultValue;
                break;
              case 3 :
                lc_info->logicalChannelConfig = (NR_LogicalChannelConfig_t *)&NR_SRB3_logicalChannelConfig_defaultValue;
                break;
              default :
                AssertFatal(false, "The logical id %d is not a valid SRB id %li\n", lc_identity, srb_id);
            }
782 783
          }
        } else { /* DRB */
784 785
          AssertFatal(mac_lc_config, "When establishing a DRB, LogicalChannelConfig should be mandatorily present\n");
          UPDATE_MAC_IE(lc_info->logicalChannelConfig, rlc_bearer->mac_LogicalChannelConfig, NR_LogicalChannelConfig_t);
786
        }
787 788
        nr_configure_sched_info(mac, lc_identity, lc_info->logicalChannelConfig);
        ASN_SEQUENCE_ADD(&mac->lc_ordered_list, lc_info);
francescomani's avatar
francescomani committed
789
      }
790
    }
791 792

    // reorder the logical channels as per its priority
793
    qsort(mac->lc_ordered_list.array, mac->lc_ordered_list.count, sizeof(nr_lcordered_info_t*), lcid_cmp);
794
  }
795 796
}

francescomani's avatar
francescomani committed
797
void ue_init_config_request(NR_UE_MAC_INST_t *mac, int scs)
francescomani's avatar
francescomani committed
798
{
francescomani's avatar
francescomani committed
799 800 801 802 803 804
  int slots_per_frame = nr_slots_per_frame[scs];
  LOG_I(NR_MAC, "Initializing dl and ul config_request. num_slots = %d\n", slots_per_frame);
  mac->dl_config_request = calloc(slots_per_frame, sizeof(*mac->dl_config_request));
  mac->ul_config_request = calloc(slots_per_frame, sizeof(*mac->ul_config_request));
  for (int i = 0; i < slots_per_frame; i++)
    pthread_mutex_init(&(mac->ul_config_request[i].mutex_ul_config), NULL);
805
}
francescomani's avatar
francescomani committed
806

807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
static void update_mib_conf(NR_MIB_t *target, NR_MIB_t *source)
{
  target->systemFrameNumber.size = source->systemFrameNumber.size;
  target->systemFrameNumber.bits_unused = source->systemFrameNumber.bits_unused;
  if (!target->systemFrameNumber.buf)
    target->systemFrameNumber.buf = calloc(target->systemFrameNumber.size, sizeof(*target->systemFrameNumber.buf));
  for (int i = 0; i < target->systemFrameNumber.size; i++)
    target->systemFrameNumber.buf[i] = source->systemFrameNumber.buf[i];
  target->subCarrierSpacingCommon = source->subCarrierSpacingCommon;
  target->ssb_SubcarrierOffset = source->ssb_SubcarrierOffset;
  target->dmrs_TypeA_Position = source->dmrs_TypeA_Position;
  target->pdcch_ConfigSIB1 = source->pdcch_ConfigSIB1;
  target->cellBarred = source->cellBarred;
  target->intraFreqReselection = source->intraFreqReselection;
}

823 824 825
void nr_rrc_mac_config_req_mib(module_id_t module_id,
                               int cc_idP,
                               NR_MIB_t *mib,
826
                               int sched_sib)
francescomani's avatar
francescomani committed
827 828
{
  NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
829
  AssertFatal(mib, "MIB should not be NULL\n");
830 831 832
  if (!mac->mib)
    mac->mib = calloc(1, sizeof(*mac->mib));
  update_mib_conf(mac->mib, mib);
833 834
  mac->phy_config.Mod_id = module_id;
  mac->phy_config.CC_id = cc_idP;
835 836 837 838
  if (sched_sib == 1)
    mac->get_sib1 = true;
  else if (sched_sib == 2)
    mac->get_otherSI = true;
839
  nr_ue_decode_mib(module_id, cc_idP);
840
}
841

842
static void setup_puschpowercontrol(NR_PUSCH_PowerControl_t *source, NR_PUSCH_PowerControl_t *target)
843
{
844 845
  UPDATE_MAC_IE(target->tpc_Accumulation, source->tpc_Accumulation, long);
  UPDATE_MAC_IE(target->msg3_Alpha, source->msg3_Alpha, NR_Alpha_t);
846
  if (source->p0_NominalWithoutGrant)
847
    UPDATE_MAC_IE(target->p0_NominalWithoutGrant, source->p0_NominalWithoutGrant, long);
848
  if (source->p0_AlphaSets)
849 850 851
    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);
852
  if (source->pathlossReferenceRSToReleaseList) {
853 854 855
    RELEASE_IE_FROMLIST(source->pathlossReferenceRSToReleaseList,
                        target->pathlossReferenceRSToAddModList,
                        pusch_PathlossReferenceRS_Id);
856 857 858 859
  }
  if (source->pathlossReferenceRSToAddModList) {
    if (!target->pathlossReferenceRSToAddModList)
      target->pathlossReferenceRSToAddModList = calloc(1, sizeof(*target->pathlossReferenceRSToAddModList));
860 861 862 863
    ADDMOD_IE_FROMLIST(source->pathlossReferenceRSToAddModList,
                       target->pathlossReferenceRSToAddModList,
                       pusch_PathlossReferenceRS_Id,
                       NR_PUSCH_PathlossReferenceRS_t);
864 865
  }
  if (source->sri_PUSCH_MappingToReleaseList) {
866 867 868
    RELEASE_IE_FROMLIST(source->sri_PUSCH_MappingToReleaseList,
                        target->sri_PUSCH_MappingToAddModList,
                        sri_PUSCH_PowerControlId);
869 870 871 872
  }
  if (source->sri_PUSCH_MappingToAddModList) {
    if (!target->sri_PUSCH_MappingToAddModList)
      target->sri_PUSCH_MappingToAddModList = calloc(1, sizeof(*target->sri_PUSCH_MappingToAddModList));
873 874 875 876
    ADDMOD_IE_FROMLIST(source->sri_PUSCH_MappingToAddModList,
                       target->sri_PUSCH_MappingToAddModList,
                       sri_PUSCH_PowerControlId,
                       NR_SRI_PUSCH_PowerControl_t);
877 878 879
  }
}

880
static void setup_puschconfig(NR_PUSCH_Config_t *source, NR_PUSCH_Config_t *target)
881
{
882 883
  UPDATE_MAC_IE(target->dataScramblingIdentityPUSCH, source->dataScramblingIdentityPUSCH, long);
  UPDATE_MAC_IE(target->txConfig, source->txConfig, long);
884
  if (source->dmrs_UplinkForPUSCH_MappingTypeA)
885 886 887 888
    HANDLE_SETUPRELEASE_IE(target->dmrs_UplinkForPUSCH_MappingTypeA,
                           source->dmrs_UplinkForPUSCH_MappingTypeA,
                           NR_DMRS_UplinkConfig_t,
                           asn_DEF_NR_SetupRelease_DMRS_UplinkConfig);
889
  if (source->dmrs_UplinkForPUSCH_MappingTypeB)
890 891 892 893
    HANDLE_SETUPRELEASE_IE(target->dmrs_UplinkForPUSCH_MappingTypeB,
                           source->dmrs_UplinkForPUSCH_MappingTypeB,
                           NR_DMRS_UplinkConfig_t,
                           asn_DEF_NR_SetupRelease_DMRS_UplinkConfig);
894 895 896 897 898
  if (source->pusch_PowerControl) {
    if (!target->pusch_PowerControl)
      target->pusch_PowerControl = calloc(1, sizeof(*target->pusch_PowerControl));
    setup_puschpowercontrol(source->pusch_PowerControl, target->pusch_PowerControl);
  }
899
  UPDATE_MAC_IE(target->frequencyHopping, source->frequencyHopping, long);
900
  if (source->frequencyHoppingOffsetLists)
901 902 903
    UPDATE_MAC_IE(target->frequencyHoppingOffsetLists,
                  source->frequencyHoppingOffsetLists,
                  struct NR_PUSCH_Config__frequencyHoppingOffsetLists);
904
  target->resourceAllocation = source->resourceAllocation;
905 906 907 908 909 910 911 912 913 914 915 916 917
  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);
918
  if (source->uci_OnPUSCH) {
919 920
    if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_release)
      asn1cFreeStruc(asn_DEF_NR_UCI_OnPUSCH, target->uci_OnPUSCH);
921
    if (source->uci_OnPUSCH->present == NR_SetupRelease_UCI_OnPUSCH_PR_setup) {
922 923 924
      if (target->uci_OnPUSCH) {
        target->uci_OnPUSCH->choice.setup->scaling = source->uci_OnPUSCH->choice.setup->scaling;
        if (source->uci_OnPUSCH->choice.setup->betaOffsets)
925 926 927
          UPDATE_MAC_IE(target->uci_OnPUSCH->choice.setup->betaOffsets,
                        source->uci_OnPUSCH->choice.setup->betaOffsets,
                        struct NR_UCI_OnPUSCH__betaOffsets);
928 929 930 931 932
      }
    }
  }
}

933
static void setup_pdschconfig(NR_PDSCH_Config_t *source, NR_PDSCH_Config_t *target)
934
{
935
  UPDATE_MAC_IE(target->dataScramblingIdentityPDSCH, source->dataScramblingIdentityPDSCH, long);
936
  if (source->dmrs_DownlinkForPDSCH_MappingTypeA)
937 938 939 940
    HANDLE_SETUPRELEASE_IE(target->dmrs_DownlinkForPDSCH_MappingTypeA,
                           source->dmrs_DownlinkForPDSCH_MappingTypeA,
                           NR_DMRS_DownlinkConfig_t,
                           asn_DEF_NR_SetupRelease_DMRS_DownlinkConfig);
941
  if (source->dmrs_DownlinkForPDSCH_MappingTypeB)
942 943 944 945
    HANDLE_SETUPRELEASE_IE(target->dmrs_DownlinkForPDSCH_MappingTypeB,
                           source->dmrs_DownlinkForPDSCH_MappingTypeB,
                           NR_DMRS_DownlinkConfig_t,
                           asn_DEF_NR_SetupRelease_DMRS_DownlinkConfig);
946 947
  // TCI States
  if (source->tci_StatesToReleaseList) {
948 949 950
    RELEASE_IE_FROMLIST(source->tci_StatesToReleaseList,
                        target->tci_StatesToAddModList,
                        tci_StateId);
951 952 953 954
  }
  if (source->tci_StatesToAddModList) {
    if (!target->tci_StatesToAddModList)
      target->tci_StatesToAddModList = calloc(1, sizeof(*target->tci_StatesToAddModList));
955 956 957 958
    ADDMOD_IE_FROMLIST(source->tci_StatesToAddModList,
                       target->tci_StatesToAddModList,
                       tci_StateId,
                       NR_TCI_State_t);
959 960
  }
  // end TCI States
961
  UPDATE_MAC_IE(target->vrb_ToPRB_Interleaver, source->vrb_ToPRB_Interleaver, long);
962 963
  target->resourceAllocation = source->resourceAllocation;
  if (source->pdsch_TimeDomainAllocationList)
964 965 966 967 968
    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);
969 970
  // rateMatchPattern
  if (source->rateMatchPatternToReleaseList) {
971 972 973
    RELEASE_IE_FROMLIST(source->rateMatchPatternToReleaseList,
                        target->rateMatchPatternToAddModList,
                        rateMatchPatternId);
974 975 976 977
  }
  if (source->rateMatchPatternToAddModList) {
    if (!target->rateMatchPatternToAddModList)
      target->rateMatchPatternToAddModList = calloc(1, sizeof(*target->rateMatchPatternToAddModList));
978 979 980 981
    ADDMOD_IE_FROMLIST(source->rateMatchPatternToAddModList,
                       target->rateMatchPatternToAddModList,
                       rateMatchPatternId,
                       NR_RateMatchPattern_t);
982 983
  }
  // end rateMatchPattern
984 985
  UPDATE_MAC_IE(target->rateMatchPatternGroup1, source->rateMatchPatternGroup1, NR_RateMatchPatternGroup_t);
  UPDATE_MAC_IE(target->rateMatchPatternGroup2, source->rateMatchPatternGroup2, NR_RateMatchPatternGroup_t);
986
  target->rbg_Size = source->rbg_Size;
987 988
  UPDATE_MAC_IE(target->mcs_Table, source->mcs_Table, long);
  UPDATE_MAC_IE(target->maxNrofCodeWordsScheduledByDCI, source->maxNrofCodeWordsScheduledByDCI, long);
989
  UPDATE_MAC_NP_IE(target->prb_BundlingType, source->prb_BundlingType, struct NR_PDSCH_Config__prb_BundlingType);
990 991 992
  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");
993 994
}

995
static void setup_sr_resource(NR_SchedulingRequestResourceConfig_t *target, NR_SchedulingRequestResourceConfig_t *source)
996 997 998 999
{
  target->schedulingRequestResourceId = source->schedulingRequestResourceId;
  target->schedulingRequestID = source->schedulingRequestID;
  if (source->periodicityAndOffset)
1000 1001 1002
    UPDATE_MAC_IE(target->periodicityAndOffset,
                  source->periodicityAndOffset,
                  struct NR_SchedulingRequestResourceConfig__periodicityAndOffset);
1003
  if (source->resource)
1004
    UPDATE_MAC_IE(target->resource, source->resource, NR_PUCCH_ResourceId_t);
1005 1006
}

1007
static void setup_pucchconfig(NR_PUCCH_Config_t *source, NR_PUCCH_Config_t *target)
1008 1009 1010 1011 1012
{
  // PUCCH-ResourceSet
  if (source->resourceSetToAddModList) {
    if (!target->resourceSetToAddModList)
      target->resourceSetToAddModList = calloc(1, sizeof(*target->resourceSetToAddModList));
1013 1014 1015 1016
    ADDMOD_IE_FROMLIST(source->resourceSetToAddModList,
                       target->resourceSetToAddModList,
                       pucch_ResourceSetId,
                       NR_PUCCH_ResourceSet_t);
1017 1018
  }
  if (source->resourceSetToReleaseList) {
1019 1020 1021
    RELEASE_IE_FROMLIST(source->resourceSetToReleaseList,
                        target->resourceSetToAddModList,
                        pucch_ResourceSetId);
1022 1023 1024 1025 1026
  }
  // PUCCH-Resource
  if (source->resourceToAddModList) {
    if (!target->resourceToAddModList)
      target->resourceToAddModList = calloc(1, sizeof(*target->resourceToAddModList));
1027 1028 1029 1030
    ADDMOD_IE_FROMLIST(source->resourceToAddModList,
                       target->resourceToAddModList,
                       pucch_ResourceId,
                       NR_PUCCH_Resource_t);
1031 1032
  }
  if (source->resourceToReleaseList) {
1033 1034 1035
    RELEASE_IE_FROMLIST(source->resourceToReleaseList,
                        target->resourceToAddModList,
                        pucch_ResourceId);
1036 1037 1038
  }
  // PUCCH-FormatConfig
  if (source->format1)
1039 1040 1041 1042
    HANDLE_SETUPRELEASE_IE(target->format1,
                           source->format1,
                           NR_PUCCH_FormatConfig_t,
                           asn_DEF_NR_SetupRelease_PUCCH_FormatConfig);
1043
  if (source->format2)
1044 1045 1046 1047
    HANDLE_SETUPRELEASE_IE(target->format2,
                           source->format2,
                           NR_PUCCH_FormatConfig_t,
                           asn_DEF_NR_SetupRelease_PUCCH_FormatConfig);
1048
  if (source->format3)
1049 1050 1051 1052
    HANDLE_SETUPRELEASE_IE(target->format3,
                           source->format3,
                           NR_PUCCH_FormatConfig_t,
                           asn_DEF_NR_SetupRelease_PUCCH_FormatConfig);
1053
  if (source->format4)
1054 1055 1056 1057
    HANDLE_SETUPRELEASE_IE(target->format4,
                           source->format4,
                           NR_PUCCH_FormatConfig_t,
                           asn_DEF_NR_SetupRelease_PUCCH_FormatConfig);
1058 1059 1060 1061
  // SchedulingRequestResourceConfig
  if (source->schedulingRequestResourceToAddModList) {
    if (!target->schedulingRequestResourceToAddModList)
      target->schedulingRequestResourceToAddModList = calloc(1, sizeof(*target->schedulingRequestResourceToAddModList));
1062 1063 1064 1065 1066
    ADDMOD_IE_FROMLIST_WFUNCTION(source->schedulingRequestResourceToAddModList,
                                 target->schedulingRequestResourceToAddModList,
                                 schedulingRequestResourceId,
                                 NR_SchedulingRequestResourceConfig_t,
                                 setup_sr_resource);
1067 1068
  }
  if (source->schedulingRequestResourceToReleaseList) {
1069 1070 1071
    RELEASE_IE_FROMLIST(source->schedulingRequestResourceToReleaseList,
                        target->schedulingRequestResourceToAddModList,
                        schedulingRequestResourceId);
1072 1073
  }

1074 1075 1076 1077 1078 1079
  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);
  if (source->dl_DataToUL_ACK)
    UPDATE_MAC_IE(target->dl_DataToUL_ACK, source->dl_DataToUL_ACK, struct NR_PUCCH_Config__dl_DataToUL_ACK);
1080 1081 1082 1083
  // PUCCH-SpatialRelationInfo
  if (source->spatialRelationInfoToAddModList) {
    if (!target->spatialRelationInfoToAddModList)
      target->spatialRelationInfoToAddModList = calloc(1, sizeof(*target->spatialRelationInfoToAddModList));
1084 1085 1086 1087
    ADDMOD_IE_FROMLIST(source->spatialRelationInfoToAddModList,
                       target->spatialRelationInfoToAddModList,
                       pucch_SpatialRelationInfoId,
                       NR_PUCCH_SpatialRelationInfo_t);
1088 1089
  }
  if (source->spatialRelationInfoToReleaseList) {
1090 1091 1092
    RELEASE_IE_FROMLIST(source->spatialRelationInfoToReleaseList,
                        target->spatialRelationInfoToAddModList,
                        pucch_SpatialRelationInfoId);
1093 1094 1095 1096 1097
  }

  if (source->pucch_PowerControl) {
    if (!target->pucch_PowerControl)
      target->pucch_PowerControl = calloc(1, sizeof(*target->pucch_PowerControl));
1098 1099 1100 1101 1102
    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);
1103
    if (source->pucch_PowerControl->p0_Set)
1104
      UPDATE_MAC_IE(target->pucch_PowerControl->p0_Set, source->pucch_PowerControl->p0_Set, struct NR_PUCCH_PowerControl__p0_Set);
1105
    if (source->pucch_PowerControl->pathlossReferenceRSs)
1106 1107 1108 1109 1110 1111
      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);
1112 1113 1114
  }
}

1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
static void handle_aperiodic_srs_type(struct NR_SRS_ResourceSet__resourceType__aperiodic *source,
                                      struct NR_SRS_ResourceSet__resourceType__aperiodic *target)
{
  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);
  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);
}

1128
static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSet_t *source)
1129 1130 1131
{
  target->srs_ResourceSetId = source->srs_ResourceSetId;
  if (source->srs_ResourceIdList)
1132
    UPDATE_MAC_IE(target->srs_ResourceIdList, source->srs_ResourceIdList, struct NR_SRS_ResourceSet__srs_ResourceIdList);
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156

  if (target->resourceType.present != source->resourceType.present) {
    UPDATE_MAC_NP_IE(target->resourceType, source->resourceType, struct NR_SRS_ResourceSet__resourceType);
  }
  else {
    switch (source->resourceType.present) {
      case NR_SRS_ResourceSet__resourceType_PR_aperiodic:
        handle_aperiodic_srs_type(source->resourceType.choice.aperiodic, target->resourceType.choice.aperiodic);
        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);
        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);
        break;
      default:
        break;
    }
1157
  }
1158
  target->usage = source->usage;
1159
  UPDATE_MAC_IE(target->alpha, source->alpha, NR_Alpha_t);
1160
  if (source->p0)
1161
    UPDATE_MAC_IE(target->p0, source->p0, long);
1162
  if (source->pathlossReferenceRS)
1163 1164
    UPDATE_MAC_IE(target->pathlossReferenceRS, source->pathlossReferenceRS, struct NR_PathlossReferenceRS_Config);
  UPDATE_MAC_IE(target->srs_PowerControlAdjustmentStates, source->srs_PowerControlAdjustmentStates, long);
1165 1166
}

1167
static void setup_srsconfig(NR_SRS_Config_t *source, NR_SRS_Config_t *target)
1168
{
1169
  UPDATE_MAC_IE(target->tpc_Accumulation, source->tpc_Accumulation, long);
1170 1171 1172 1173
  // SRS-Resource
  if (source->srs_ResourceToAddModList) {
    if (!target->srs_ResourceToAddModList)
      target->srs_ResourceToAddModList = calloc(1, sizeof(*target->srs_ResourceToAddModList));
1174 1175 1176 1177
    ADDMOD_IE_FROMLIST(source->srs_ResourceToAddModList,
                       target->srs_ResourceToAddModList,
                       srs_ResourceId,
                       NR_SRS_Resource_t);
1178 1179
  }
  if (source->srs_ResourceToReleaseList) {
1180 1181 1182
    RELEASE_IE_FROMLIST(source->srs_ResourceToReleaseList,
                        target->srs_ResourceToAddModList,
                        srs_ResourceId);
1183 1184 1185 1186 1187
  }
  // SRS-ResourceSet
  if (source->srs_ResourceSetToAddModList) {
    if (!target->srs_ResourceSetToAddModList)
      target->srs_ResourceSetToAddModList = calloc(1, sizeof(*target->srs_ResourceSetToAddModList));
1188 1189 1190 1191 1192
    ADDMOD_IE_FROMLIST_WFUNCTION(source->srs_ResourceSetToAddModList,
                                 target->srs_ResourceSetToAddModList,
                                 srs_ResourceSetId,
                                 NR_SRS_ResourceSet_t,
                                 setup_srsresourceset);
1193 1194
  }
  if (source->srs_ResourceSetToReleaseList) {
1195 1196 1197
    RELEASE_IE_FROMLIST(source->srs_ResourceSetToReleaseList,
                        target->srs_ResourceSetToAddModList,
                        srs_ResourceSetId);
1198 1199 1200
  }
}

1201
static NR_UE_DL_BWP_t *get_dl_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup)
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
{
  NR_UE_DL_BWP_t *bwp = NULL;
  for (int i = 0; i < mac->dl_BWPs.count; i++) {
    if (bwp_id == mac->dl_BWPs.array[i]->bwp_id) {
      bwp = mac->dl_BWPs.array[i];
      break;
    }
  }
  if (!bwp && setup) {
    bwp = calloc(1, sizeof(*bwp));
    ASN_SEQUENCE_ADD(&mac->dl_BWPs, bwp);
  }
  if (!setup) {
1215 1216
    mac->sc_info.n_dl_bwp = mac->dl_BWPs.count - 1;
    mac->sc_info.dl_bw_tbslbrm = 0;
1217
    for (int i = 0; i < mac->dl_BWPs.count; i++) {
1218 1219
      if (mac->dl_BWPs.array[i]->BWPSize > mac->sc_info.dl_bw_tbslbrm)
        mac->sc_info.dl_bw_tbslbrm = mac->dl_BWPs.array[i]->BWPSize;
1220 1221 1222 1223 1224
    }
  }
  return bwp;
}

1225
static NR_UE_UL_BWP_t *get_ul_bwp_structure(NR_UE_MAC_INST_t *mac, int bwp_id, bool setup)
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
{
  NR_UE_UL_BWP_t *bwp = NULL;
  for (int i = 0; i < mac->ul_BWPs.count; i++) {
    if (bwp_id == mac->ul_BWPs.array[i]->bwp_id) {
      bwp = mac->ul_BWPs.array[i];
      break;
    }
  }
  if (!bwp && setup) {
    bwp = calloc(1, sizeof(*bwp));
    ASN_SEQUENCE_ADD(&mac->ul_BWPs, bwp);
  }
  if (!setup) {
1239 1240
    mac->sc_info.n_ul_bwp = mac->ul_BWPs.count - 1;
    mac->sc_info.ul_bw_tbslbrm = 0;
1241
    for (int i = 0; i < mac->ul_BWPs.count; i++) {
1242 1243
      if (mac->ul_BWPs.array[i]->BWPSize > mac->sc_info.ul_bw_tbslbrm)
        mac->sc_info.ul_bw_tbslbrm = mac->ul_BWPs.array[i]->BWPSize;
1244 1245 1246 1247 1248
    }
  }
  return bwp;
}

1249
static void configure_dedicated_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_DownlinkDedicated_t *dl_dedicated)
1250
{
1251
  if (dl_dedicated) {
1252 1253 1254
    NR_UE_DL_BWP_t *bwp = get_dl_bwp_structure(mac, bwp_id, true);
    bwp->bwp_id = bwp_id;
    NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id];
1255 1256 1257
    if(dl_dedicated->pdsch_Config) {
      if (dl_dedicated->pdsch_Config->present == NR_SetupRelease_PDSCH_Config_PR_release)
        asn1cFreeStruc(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config);
1258
      if (dl_dedicated->pdsch_Config->present == NR_SetupRelease_PDSCH_Config_PR_setup) {
1259 1260 1261 1262 1263
        if (!bwp->pdsch_Config)
          bwp->pdsch_Config = calloc(1, sizeof(*bwp->pdsch_Config));
        setup_pdschconfig(dl_dedicated->pdsch_Config->choice.setup, bwp->pdsch_Config);
      }
    }
1264 1265
    if (dl_dedicated->pdcch_Config) {
      if (dl_dedicated->pdcch_Config->present == NR_SetupRelease_PDCCH_Config_PR_release) {
1266 1267 1268 1269 1270
        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);
      }
1271 1272
      if (dl_dedicated->pdcch_Config->present == NR_SetupRelease_PDCCH_Config_PR_setup)
        configure_ss_coreset(pdcch, dl_dedicated->pdcch_Config->choice.setup);
1273 1274 1275 1276
    }
  }
}

1277
static void configure_dedicated_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_UplinkDedicated_t *ul_dedicated)
1278
{
1279
  if (ul_dedicated) {
1280 1281
    NR_UE_UL_BWP_t *bwp = get_ul_bwp_structure(mac, bwp_id, true);
    bwp->bwp_id = bwp_id;
1282 1283 1284
    if(ul_dedicated->pucch_Config) {
      if (ul_dedicated->pucch_Config->present == NR_SetupRelease_PUCCH_Config_PR_release)
        asn1cFreeStruc(asn_DEF_NR_PUCCH_Config, bwp->pucch_Config);
1285
      if (ul_dedicated->pucch_Config->present == NR_SetupRelease_PUCCH_Config_PR_setup) {
1286 1287 1288 1289 1290
        if (!bwp->pucch_Config)
          bwp->pucch_Config = calloc(1, sizeof(*bwp->pucch_Config));
        setup_pucchconfig(ul_dedicated->pucch_Config->choice.setup, bwp->pucch_Config);
      }
    }
1291 1292 1293
    if(ul_dedicated->pusch_Config) {
      if (ul_dedicated->pusch_Config->present == NR_SetupRelease_PUSCH_Config_PR_release)
        asn1cFreeStruc(asn_DEF_NR_PUSCH_Config, bwp->pusch_Config);
1294
      if (ul_dedicated->pusch_Config->present == NR_SetupRelease_PUSCH_Config_PR_setup) {
1295 1296 1297 1298 1299
        if (!bwp->pusch_Config)
          bwp->pusch_Config = calloc(1, sizeof(*bwp->pusch_Config));
        setup_puschconfig(ul_dedicated->pusch_Config->choice.setup, bwp->pusch_Config);
      }
    }
1300 1301 1302
    if(ul_dedicated->srs_Config) {
      if (ul_dedicated->srs_Config->present == NR_SetupRelease_SRS_Config_PR_release)
        asn1cFreeStruc(asn_DEF_NR_SRS_Config, bwp->srs_Config);
1303
      if (ul_dedicated->srs_Config->present == NR_SetupRelease_SRS_Config_PR_setup) {
1304 1305 1306 1307 1308 1309 1310 1311 1312
        if (!bwp->srs_Config)
          bwp->srs_Config = calloc(1, sizeof(*bwp->srs_Config));
        setup_srsconfig(ul_dedicated->srs_Config->choice.setup, bwp->srs_Config);
      }
    }
    AssertFatal(!ul_dedicated->configuredGrantConfig, "configuredGrantConfig not supported\n");
  }
}

1313
static void configure_common_BWP_dl(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_DownlinkCommon_t *dl_common)
1314
{
1315
  if (dl_common) {
1316 1317 1318 1319 1320 1321 1322 1323
    NR_UE_DL_BWP_t *bwp = get_dl_bwp_structure(mac, bwp_id, true);
    bwp->bwp_id = bwp_id;
    NR_BWP_t *dl_genericParameters = &dl_common->genericParameters;
    bwp->scs = dl_genericParameters->subcarrierSpacing;
    bwp->cyclicprefix = dl_genericParameters->cyclicPrefix;
    bwp->BWPSize = NRRIV2BW(dl_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
    bwp->BWPStart = NRRIV2PRBOFFSET(dl_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
    if (bwp_id == 0) {
1324 1325
      mac->sc_info.initial_dl_BWPSize = bwp->BWPSize;
      mac->sc_info.initial_dl_BWPStart = bwp->BWPStart;
1326 1327
    }
    if (dl_common->pdsch_ConfigCommon) {
1328 1329 1330 1331
      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);
1332 1333
      if (dl_common->pdsch_ConfigCommon->present == NR_SetupRelease_PDSCH_ConfigCommon_PR_release)
        asn1cFreeStruc(asn_DEF_NR_PDSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common);
1334 1335 1336
    }
    NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id];
    if (dl_common->pdcch_ConfigCommon) {
1337 1338 1339
      if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_setup)
        configure_common_ss_coreset(pdcch, dl_common->pdcch_ConfigCommon->choice.setup);
      if (dl_common->pdcch_ConfigCommon->present == NR_SetupRelease_PDCCH_ConfigCommon_PR_release)
1340 1341 1342 1343 1344
        release_common_ss_cset(pdcch);
    }
  }
}

1345
static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_UplinkCommon_t *ul_common)
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
{
  if (ul_common) {
    NR_UE_UL_BWP_t *bwp = get_ul_bwp_structure(mac, bwp_id, true);
    bwp->bwp_id = bwp_id;
    NR_BWP_t *ul_genericParameters = &ul_common->genericParameters;
    bwp->scs = ul_genericParameters->subcarrierSpacing;
    bwp->cyclicprefix = ul_genericParameters->cyclicPrefix;
    bwp->BWPSize = NRRIV2BW(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
    bwp->BWPStart = NRRIV2PRBOFFSET(ul_genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
    if (bwp_id == 0) {
1356 1357
      mac->sc_info.initial_ul_BWPSize = bwp->BWPSize;
      mac->sc_info.initial_ul_BWPStart = bwp->BWPStart;
1358 1359
    }
    if (ul_common->rach_ConfigCommon) {
1360 1361 1362 1363
      HANDLE_SETUPRELEASE_DIRECT(bwp->rach_ConfigCommon,
                                 ul_common->rach_ConfigCommon,
                                 NR_RACH_ConfigCommon_t,
                                 asn_DEF_NR_RACH_ConfigCommon);
1364 1365
    }
    if (ul_common->pucch_ConfigCommon)
1366 1367 1368 1369
      HANDLE_SETUPRELEASE_DIRECT(bwp->pucch_ConfigCommon,
                                 ul_common->pucch_ConfigCommon,
                                 NR_PUCCH_ConfigCommon_t,
                                 asn_DEF_NR_PUCCH_ConfigCommon);
1370
    if (ul_common->pusch_ConfigCommon) {
1371 1372 1373 1374 1375 1376 1377
      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);
      }
      if (ul_common->pusch_ConfigCommon->present == NR_SetupRelease_PUSCH_ConfigCommon_PR_release) {
1378
        asn1cFreeStruc(asn_DEF_NR_PUSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common);
1379 1380 1381 1382 1383 1384 1385
        free(bwp->msg3_DeltaPreamble);
        bwp->msg3_DeltaPreamble = NULL;
      }
    }
  }
}

1386 1387
void nr_rrc_mac_config_req_reset(module_id_t module_id,
                                 NR_UE_MAC_reset_cause_t reset_cause)
francescomani's avatar
francescomani committed
1388 1389 1390 1391 1392
{
  NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
  reset_mac_inst(mac);
  reset_ra(&mac->ra);
  release_mac_configuration(mac);
1393
  nr_ue_init_mac(module_id);
francescomani's avatar
francescomani committed
1394 1395 1396

  // Sending to PHY a request to resync
  // with no target cell ID
1397 1398 1399 1400 1401 1402
  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);
  }
francescomani's avatar
francescomani committed
1403 1404
}

1405 1406
void nr_rrc_mac_config_req_sib1(module_id_t module_id,
                                int cc_idP,
1407
                                NR_SI_SchedulingInfo_t *si_SchedulingInfo,
1408 1409 1410 1411
                                NR_ServingCellConfigCommonSIB_t *scc)
{
  NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
  AssertFatal(scc, "SIB1 SCC should not be NULL\n");
1412

1413 1414
  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);
1415

1416
  config_common_ue_sa(mac, scc, module_id, cc_idP);
1417 1418 1419 1420 1421 1422 1423 1424 1425
  configure_common_BWP_dl(mac,
                          0, // bwp-id
                          &scc->downlinkConfigCommon.initialDownlinkBWP);
  if (scc->uplinkConfigCommon)
    configure_common_BWP_ul(mac,
                            0, // bwp-id
                            &scc->uplinkConfigCommon->initialUplinkBWP);
  // set current BWP only if coming from non-connected state
  // otherwise it is just a periodically update of the SIB1 content
1426
  if (mac->state < UE_CONNECTED) {
1427 1428 1429 1430 1431 1432 1433 1434
    mac->current_DL_BWP = get_dl_bwp_structure(mac, 0, false);
    AssertFatal(mac->current_DL_BWP, "Couldn't find DL-BWP0\n");
    mac->current_UL_BWP = get_ul_bwp_structure(mac, 0, false);
    AssertFatal(mac->current_UL_BWP, "Couldn't find DL-BWP0\n");
  }

  // Setup the SSB to Rach Occasions mapping according to the config
  build_ssb_to_ro_map(mac);
francescomani's avatar
francescomani committed
1435

1436 1437 1438 1439
  if (!get_softmodem_params()->emulate_l1)
    mac->if_module->phy_config_request(&mac->phy_config);
  mac->phy_config_request_sent = true;
}
francescomani's avatar
francescomani committed
1440

1441 1442 1443 1444
static void handle_reconfiguration_with_sync(NR_UE_MAC_INST_t *mac,
                                             module_id_t module_id,
                                             int cc_idP,
                                             const NR_ReconfigurationWithSync_t *reconfigurationWithSync)
1445
{
1446 1447 1448
  mac->crnti = reconfigurationWithSync->newUE_Identity;
  LOG_I(NR_MAC, "Configuring CRNTI %x\n", mac->crnti);

1449 1450
  RA_config_t *ra = &mac->ra;
  if (reconfigurationWithSync->rach_ConfigDedicated) {
1451 1452 1453 1454
    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);
1455
  }
1456

1457 1458
  if (reconfigurationWithSync->spCellConfigCommon) {
    NR_ServingCellConfigCommon_t *scc = reconfigurationWithSync->spCellConfigCommon;
1459 1460 1461
    if (scc->physCellId)
      mac->physCellId = *scc->physCellId;
    mac->dmrs_TypeA_Position = scc->dmrs_TypeA_Position;
1462
    UPDATE_MAC_IE(mac->tdd_UL_DL_ConfigurationCommon, scc->tdd_UL_DL_ConfigurationCommon, NR_TDD_UL_DL_ConfigCommon_t);
1463
    config_common_ue(mac, scc, module_id, cc_idP);
1464 1465 1466 1467 1468 1469 1470 1471
    if (scc->downlinkConfigCommon)
      configure_common_BWP_dl(mac,
                              0, // bwp-id
                              scc->downlinkConfigCommon->initialDownlinkBWP);
    if (scc->uplinkConfigCommon)
      configure_common_BWP_ul(mac,
                              0, // bwp-id
                              scc->uplinkConfigCommon->initialUplinkBWP);
1472
  }
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485

  mac->state = UE_NOT_SYNC;
  ra->ra_state = RA_UE_IDLE;
  nr_ue_mac_default_configs(mac);

  if (!get_softmodem_params()->emulate_l1) {
    mac->synch_request.Mod_id = module_id;
    mac->synch_request.CC_id = cc_idP;
    mac->synch_request.synch_req.target_Nid_cell = mac->physCellId;
    mac->if_module->synch_request(&mac->synch_request);
    mac->if_module->phy_config_request(&mac->phy_config);
    mac->phy_config_request_sent = true;
  }
1486 1487
}

1488 1489
static void configure_physicalcellgroup(NR_UE_MAC_INST_t *mac,
                                        const NR_PhysicalCellGroupConfig_t *phyConfig)
1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506
{
  mac->pdsch_HARQ_ACK_Codebook = phyConfig->pdsch_HARQ_ACK_Codebook;
  mac->harq_ACK_SpatialBundlingPUCCH = phyConfig->harq_ACK_SpatialBundlingPUCCH ? true : false;
  mac->harq_ACK_SpatialBundlingPUSCH = phyConfig->harq_ACK_SpatialBundlingPUSCH ? true : false;

  NR_P_Max_t *p_NR_FR1 = phyConfig->p_NR_FR1;
  NR_P_Max_t *p_UE_FR1 = phyConfig->ext1 ?
                         phyConfig->ext1->p_UE_FR1 :
                         NULL;
  if (p_NR_FR1 == NULL)
    mac->p_Max_alt = p_UE_FR1 == NULL ? INT_MIN : *p_UE_FR1;
  else
    mac->p_Max_alt = p_UE_FR1 == NULL ? *p_NR_FR1 :
                                        (*p_UE_FR1 < *p_NR_FR1 ?
                                        *p_UE_FR1 : *p_NR_FR1);
}

1507
static void configure_maccellgroup(NR_UE_MAC_INST_t *mac, const NR_MAC_CellGroupConfig_t *mcg)
1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559
{
  NR_UE_SCHEDULING_INFO *si = &mac->scheduling_info;
  if (mcg->drx_Config)
    LOG_E(NR_MAC, "DRX not implemented! Configuration not handled!\n");
  if (mcg->schedulingRequestConfig) {
    const NR_SchedulingRequestConfig_t *src = mcg->schedulingRequestConfig;
    if (src->schedulingRequestToReleaseList) {
      for (int i = 0; i < src->schedulingRequestToReleaseList->list.count; i++) {
        if (*src->schedulingRequestToReleaseList->list.array[i] == si->sr_id) {
          si->SR_COUNTER = 0;
          si->sr_ProhibitTimer = 0;
          si->sr_ProhibitTimer_Running = 0;
          si->sr_id = -1; // invalid init value
        }
        else
          LOG_E(NR_MAC, "Cannot release SchedulingRequestConfig. Not configured.\n");
      }
    }
    if (src->schedulingRequestToAddModList) {
      for (int i = 0; i < src->schedulingRequestToAddModList->list.count; i++) {
        NR_SchedulingRequestToAddMod_t *sr = src->schedulingRequestToAddModList->list.array[i];
        AssertFatal(si->sr_id == -1 ||
                    si->sr_id == sr->schedulingRequestId,
                    "Current implementation cannot handle more than 1 SR configuration\n");
        si->sr_id = sr->schedulingRequestId;
        si->sr_TransMax = sr->sr_TransMax;
        if (sr->sr_ProhibitTimer)
          LOG_E(NR_MAC, "SR prohibit timer not properly implemented\n");
      }
    }
  }
  if (mcg->bsr_Config) {
    si->periodicBSR_Timer = mcg->bsr_Config->periodicBSR_Timer;
    si->retxBSR_Timer = mcg->bsr_Config->retxBSR_Timer;
    if (mcg->bsr_Config->logicalChannelSR_DelayTimer)
      LOG_E(NR_MAC, "Handling of logicalChannelSR_DelayTimer not implemented\n");
  }
  if (mcg->tag_Config) {
    // TODO TAG not handled
    if(mcg->tag_Config->tag_ToAddModList) {
      for (int i = 0; i < mcg->tag_Config->tag_ToAddModList->list.count; i++) {
        if (mcg->tag_Config->tag_ToAddModList->list.array[i]->timeAlignmentTimer !=
            NR_TimeAlignmentTimer_infinity)
          LOG_E(NR_MAC, "TimeAlignmentTimer not handled\n");
      }
    }
  }
  if (mcg->phr_Config) {
    // TODO configuration when PHR is implemented
  }
}

1560
static void configure_csi_resourcemapping(NR_CSI_RS_ResourceMapping_t *target, NR_CSI_RS_ResourceMapping_t *source)
francescomani's avatar
francescomani committed
1561
{
1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
  if (target->frequencyDomainAllocation.present != source->frequencyDomainAllocation.present) {
    UPDATE_MAC_NP_IE(target->frequencyDomainAllocation,
                     source->frequencyDomainAllocation,
                     struct NR_CSI_RS_ResourceMapping__frequencyDomainAllocation);
  }
  else {
    switch (source->frequencyDomainAllocation.present) {
      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1:
        target->frequencyDomainAllocation.choice.row1.size = source->frequencyDomainAllocation.choice.row1.size;
        target->frequencyDomainAllocation.choice.row1.bits_unused = source->frequencyDomainAllocation.choice.row1.bits_unused;
        if (!target->frequencyDomainAllocation.choice.row1.buf)
          target->frequencyDomainAllocation.choice.row1.buf =
              calloc(target->frequencyDomainAllocation.choice.row1.size, sizeof(uint8_t));
        for (int i = 0; i < target->frequencyDomainAllocation.choice.row1.size; i++)
          target->frequencyDomainAllocation.choice.row1.buf[i] = source->frequencyDomainAllocation.choice.row1.buf[i];
        break;
      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
        target->frequencyDomainAllocation.choice.row2.size = source->frequencyDomainAllocation.choice.row2.size;
        target->frequencyDomainAllocation.choice.row2.bits_unused = source->frequencyDomainAllocation.choice.row2.bits_unused;
        if (!target->frequencyDomainAllocation.choice.row2.buf)
          target->frequencyDomainAllocation.choice.row2.buf =
              calloc(target->frequencyDomainAllocation.choice.row2.size, sizeof(uint8_t));
        for (int i = 0; i < target->frequencyDomainAllocation.choice.row2.size; i++)
          target->frequencyDomainAllocation.choice.row2.buf[i] = source->frequencyDomainAllocation.choice.row2.buf[i];
        break;
      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
        target->frequencyDomainAllocation.choice.row4.size = source->frequencyDomainAllocation.choice.row4.size;
        target->frequencyDomainAllocation.choice.row4.bits_unused = source->frequencyDomainAllocation.choice.row4.bits_unused;
        if (!target->frequencyDomainAllocation.choice.row4.buf)
          target->frequencyDomainAllocation.choice.row4.buf =
              calloc(target->frequencyDomainAllocation.choice.row4.size, sizeof(uint8_t));
        for (int i = 0; i < target->frequencyDomainAllocation.choice.row4.size; i++)
          target->frequencyDomainAllocation.choice.row4.buf[i] = source->frequencyDomainAllocation.choice.row4.buf[i];
        break;
      case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
        target->frequencyDomainAllocation.choice.other.size = source->frequencyDomainAllocation.choice.other.size;
        target->frequencyDomainAllocation.choice.other.bits_unused = source->frequencyDomainAllocation.choice.other.bits_unused;
        if (!target->frequencyDomainAllocation.choice.other.buf)
          target->frequencyDomainAllocation.choice.other.buf =
              calloc(target->frequencyDomainAllocation.choice.other.size, sizeof(uint8_t));
        for (int i = 0; i < target->frequencyDomainAllocation.choice.other.size; i++)
          target->frequencyDomainAllocation.choice.other.buf[i] = source->frequencyDomainAllocation.choice.other.buf[i];
        break;
      default:
        AssertFatal(false, "Invalid entry\n");
    }
francescomani's avatar
francescomani committed
1608 1609 1610
  }
  target->nrofPorts = source->nrofPorts;
  target->firstOFDMSymbolInTimeDomain = source->firstOFDMSymbolInTimeDomain;
1611
  UPDATE_MAC_IE(target->firstOFDMSymbolInTimeDomain2, source->firstOFDMSymbolInTimeDomain2, long);
francescomani's avatar
francescomani committed
1612 1613 1614 1615 1616
  target->cdm_Type = source->cdm_Type;
  target->density = source->density;
  target->freqBand = source->freqBand;
}

1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641
static void configure_csirs_resource(NR_NZP_CSI_RS_Resource_t *target, NR_NZP_CSI_RS_Resource_t *source)
{
  configure_csi_resourcemapping(&target->resourceMapping, &source->resourceMapping);
  target->powerControlOffset = source->powerControlOffset;
  UPDATE_MAC_IE(target->powerControlOffsetSS, source->powerControlOffsetSS, long);
  target->scramblingID = source->scramblingID;
  if (source->periodicityAndOffset)
    UPDATE_MAC_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);
}

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);
  if (source->freqBand)
    UPDATE_MAC_IE(target->freqBand, source->freqBand, NR_CSI_FrequencyOccupation_t);
  if (source->periodicityAndOffset)
    UPDATE_MAC_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)
1642 1643
{
  switch (csi_MeasConfig_sr->present) {
1644
    case NR_SetupRelease_CSI_MeasConfig_PR_NOTHING:
1645
      break;
1646 1647
    case NR_SetupRelease_CSI_MeasConfig_PR_release :
      asn1cFreeStruc(asn_DEF_NR_CSI_MeasConfig, sc_info->csi_MeasConfig);
1648
      break;
1649 1650 1651 1652
    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);
      } else { // modification
1653
        NR_CSI_MeasConfig_t *target = sc_info->csi_MeasConfig;
1654 1655
        NR_CSI_MeasConfig_t *csi_MeasConfig = csi_MeasConfig_sr->choice.setup;
        if (csi_MeasConfig->reportTriggerSize)
1656
          UPDATE_MAC_IE(target->reportTriggerSize, csi_MeasConfig->reportTriggerSize, long);
1657
        if (csi_MeasConfig->aperiodicTriggerStateList)
1658 1659 1660 1661
          HANDLE_SETUPRELEASE_DIRECT(sc_info->aperiodicTriggerStateList,
                                     csi_MeasConfig->aperiodicTriggerStateList,
                                     NR_CSI_AperiodicTriggerStateList_t,
                                     asn_DEF_NR_CSI_AperiodicTriggerStateList);
1662
        if (csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList)
1663 1664 1665 1666
          HANDLE_SETUPRELEASE_IE(target->semiPersistentOnPUSCH_TriggerStateList,
                                 csi_MeasConfig->semiPersistentOnPUSCH_TriggerStateList,
                                 NR_CSI_SemiPersistentOnPUSCH_TriggerStateList_t,
                                 asn_DEF_NR_SetupRelease_CSI_SemiPersistentOnPUSCH_TriggerStateList);
1667 1668
        // NZP-CSI-RS-Resources
        if (csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList) {
1669 1670 1671
          RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList,
                              target->nzp_CSI_RS_ResourceToAddModList,
                              nzp_CSI_RS_ResourceId);
1672 1673
        }
        if (csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList) {
1674 1675 1676 1677 1678 1679 1680
          if (!target->nzp_CSI_RS_ResourceToAddModList)
            target->nzp_CSI_RS_ResourceToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceToAddModList));
          ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList,
                                       target->nzp_CSI_RS_ResourceToAddModList,
                                       nzp_CSI_RS_ResourceId,
                                       NR_NZP_CSI_RS_Resource_t,
                                       configure_csirs_resource);
1681 1682 1683
        }
        // NZP-CSI-RS-ResourceSets
        if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList) {
1684 1685 1686
          RELEASE_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToReleaseList,
                              target->nzp_CSI_RS_ResourceSetToAddModList,
                              nzp_CSI_ResourceSetId);
1687 1688
        }
        if (csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList) {
1689 1690 1691 1692 1693 1694
          if (!target->nzp_CSI_RS_ResourceSetToAddModList)
            target->nzp_CSI_RS_ResourceSetToAddModList = calloc(1, sizeof(*target->nzp_CSI_RS_ResourceSetToAddModList));
          ADDMOD_IE_FROMLIST(csi_MeasConfig->nzp_CSI_RS_ResourceSetToAddModList,
                             target->nzp_CSI_RS_ResourceSetToAddModList,
                             nzp_CSI_ResourceSetId,
                             NR_NZP_CSI_RS_ResourceSet_t);
1695 1696 1697
        }
        // CSI-IM-Resource
        if (csi_MeasConfig->csi_IM_ResourceToReleaseList) {
1698 1699 1700
          RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceToReleaseList,
                              target->csi_IM_ResourceToAddModList,
                              csi_IM_ResourceId);
1701 1702
        }
        if (csi_MeasConfig->csi_IM_ResourceToAddModList) {
1703 1704 1705 1706 1707 1708 1709
          if (!target->csi_IM_ResourceToAddModList)
            target->csi_IM_ResourceToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceToAddModList));
          ADDMOD_IE_FROMLIST_WFUNCTION(csi_MeasConfig->csi_IM_ResourceToAddModList,
                                       target->csi_IM_ResourceToAddModList,
                                       csi_IM_ResourceId,
                                       NR_CSI_IM_Resource_t,
                                       configure_csiim_resource);
1710 1711 1712
        }
        // CSI-IM-ResourceSets
        if (csi_MeasConfig->csi_IM_ResourceSetToReleaseList) {
1713 1714 1715
          RELEASE_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToReleaseList,
                              target->csi_IM_ResourceSetToAddModList,
                              csi_IM_ResourceSetId);
1716 1717
        }
        if (csi_MeasConfig->csi_IM_ResourceSetToAddModList) {
1718 1719 1720 1721 1722 1723
          if (!target->csi_IM_ResourceSetToAddModList)
            target->csi_IM_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_IM_ResourceSetToAddModList));
          ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_IM_ResourceSetToAddModList,
                             target->csi_IM_ResourceSetToAddModList,
                             csi_IM_ResourceSetId,
                             NR_CSI_IM_ResourceSet_t);
1724 1725 1726
        }
        // CSI-SSB-ResourceSets
        if (csi_MeasConfig->csi_SSB_ResourceSetToReleaseList) {
1727 1728 1729
          RELEASE_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToReleaseList,
                              target->csi_SSB_ResourceSetToAddModList,
                              csi_SSB_ResourceSetId);
1730 1731
        }
        if (csi_MeasConfig->csi_SSB_ResourceSetToAddModList) {
1732 1733 1734 1735 1736 1737
          if (!target->csi_SSB_ResourceSetToAddModList)
            target->csi_SSB_ResourceSetToAddModList = calloc(1, sizeof(*target->csi_SSB_ResourceSetToAddModList));
          ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_SSB_ResourceSetToAddModList,
                             target->csi_SSB_ResourceSetToAddModList,
                             csi_SSB_ResourceSetId,
                             NR_CSI_SSB_ResourceSet_t);
1738 1739 1740
        }
        // CSI-ResourceConfigs
        if (csi_MeasConfig->csi_ResourceConfigToReleaseList) {
1741 1742 1743
          RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToReleaseList,
                              target->csi_ResourceConfigToAddModList,
                              csi_ResourceConfigId);
1744 1745
        }
        if (csi_MeasConfig->csi_ResourceConfigToAddModList) {
1746 1747 1748 1749 1750 1751
          if (!target->csi_ResourceConfigToAddModList)
            target->csi_ResourceConfigToAddModList = calloc(1, sizeof(*target->csi_ResourceConfigToAddModList));
          ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ResourceConfigToAddModList,
                             target->csi_ResourceConfigToAddModList,
                             csi_ResourceConfigId,
                             NR_CSI_ResourceConfig_t);
1752 1753 1754
        }
        // CSI-ReportConfigs
        if (csi_MeasConfig->csi_ReportConfigToReleaseList) {
1755 1756 1757
          RELEASE_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToReleaseList,
                              target->csi_ReportConfigToAddModList,
                              reportConfigId);
1758 1759
        }
        if (csi_MeasConfig->csi_ReportConfigToAddModList) {
1760 1761 1762 1763 1764 1765
          if (!target->csi_ReportConfigToAddModList)
            target->csi_ReportConfigToAddModList = calloc(1, sizeof(*target->csi_ReportConfigToAddModList));
          ADDMOD_IE_FROMLIST(csi_MeasConfig->csi_ReportConfigToAddModList,
                             target->csi_ReportConfigToAddModList,
                             reportConfigId,
                             NR_CSI_ReportConfig_t);
1766 1767 1768
        }
      }
      break;
1769
    default:
1770 1771 1772 1773
      AssertFatal(false, "Invalid case\n");
  }
}

1774
static void configure_servingcell_info(NR_UE_ServingCell_Info_t *sc_info, NR_ServingCellConfig_t *scd)
1775
{
1776 1777 1778
  if (scd->csi_MeasConfig)
    configure_csiconfig(sc_info, scd->csi_MeasConfig);

1779
  if (scd->supplementaryUplink)
1780
    UPDATE_MAC_IE(sc_info->supplementaryUplink, scd->supplementaryUplink, NR_UplinkConfig_t);
1781
  if (scd->crossCarrierSchedulingConfig)
1782
    UPDATE_MAC_IE(sc_info->crossCarrierSchedulingConfig, scd->crossCarrierSchedulingConfig, NR_CrossCarrierSchedulingConfig_t);
1783 1784
  if (scd->pdsch_ServingCellConfig) {
    switch (scd->pdsch_ServingCellConfig->present) {
1785
      case NR_SetupRelease_PDSCH_ServingCellConfig_PR_NOTHING:
1786
        break;
1787
      case NR_SetupRelease_PDSCH_ServingCellConfig_PR_release:
1788
        // release all configurations
1789 1790
        if (sc_info->pdsch_CGB_Transmission)
          asn1cFreeStruc(asn_DEF_NR_PDSCH_CodeBlockGroupTransmission, sc_info->pdsch_CGB_Transmission);
1791 1792 1793 1794 1795 1796 1797 1798 1799
        if (sc_info->xOverhead_PDSCH) {
          free(sc_info->xOverhead_PDSCH);
          sc_info->xOverhead_PDSCH = NULL;
        }
        if (sc_info->maxMIMO_Layers_PDSCH) {
          free(sc_info->maxMIMO_Layers_PDSCH);
          sc_info->maxMIMO_Layers_PDSCH = NULL;
        }
        break;
1800
      case NR_SetupRelease_PDSCH_ServingCellConfig_PR_setup: {
1801 1802
        NR_PDSCH_ServingCellConfig_t *pdsch_servingcellconfig = scd->pdsch_ServingCellConfig->choice.setup;
        if (pdsch_servingcellconfig->codeBlockGroupTransmission)
1803 1804 1805 1806 1807 1808 1809
          HANDLE_SETUPRELEASE_DIRECT(sc_info->pdsch_CGB_Transmission,
                                     pdsch_servingcellconfig->codeBlockGroupTransmission,
                                     NR_PDSCH_CodeBlockGroupTransmission_t,
                                     asn_DEF_NR_PDSCH_CodeBlockGroupTransmission);
        UPDATE_MAC_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);
1810 1811
        break;
      }
1812
      default:
1813 1814 1815
        AssertFatal(false, "Invalid case\n");
    }
  }
1816
  if (scd->uplinkConfig && scd->uplinkConfig->pusch_ServingCellConfig) {
1817
    switch (scd->uplinkConfig->pusch_ServingCellConfig->present) {
1818
      case NR_SetupRelease_PUSCH_ServingCellConfig_PR_NOTHING:
1819
        break;
1820
      case NR_SetupRelease_PUSCH_ServingCellConfig_PR_release:
1821
        // release all configurations
1822 1823
        if (sc_info->pusch_CGB_Transmission)
          asn1cFreeStruc(asn_DEF_NR_PUSCH_CodeBlockGroupTransmission, sc_info->pusch_CGB_Transmission);
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836
        if (sc_info->rateMatching_PUSCH) {
          free(sc_info->rateMatching_PUSCH);
          sc_info->rateMatching_PUSCH = NULL;
        }
        if (sc_info->xOverhead_PUSCH) {
          free(sc_info->xOverhead_PUSCH);
          sc_info->xOverhead_PUSCH = NULL;
        }
        if (sc_info->maxMIMO_Layers_PUSCH) {
          free(sc_info->maxMIMO_Layers_PUSCH);
          sc_info->maxMIMO_Layers_PUSCH = NULL;
        }
        break;
1837
      case NR_SetupRelease_PUSCH_ServingCellConfig_PR_setup: {
1838
        NR_PUSCH_ServingCellConfig_t *pusch_servingcellconfig = scd->uplinkConfig->pusch_ServingCellConfig->choice.setup;
1839 1840 1841 1842
        UPDATE_MAC_IE(sc_info->rateMatching_PUSCH, pusch_servingcellconfig->rateMatching, long);
        UPDATE_MAC_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);
1843
        if (pusch_servingcellconfig->codeBlockGroupTransmission)
1844 1845 1846 1847
          HANDLE_SETUPRELEASE_DIRECT(sc_info->pusch_CGB_Transmission,
                                     pusch_servingcellconfig->codeBlockGroupTransmission,
                                     NR_PUSCH_CodeBlockGroupTransmission_t,
                                     asn_DEF_NR_PUSCH_CodeBlockGroupTransmission);
1848 1849
        break;
      }
1850
      default:
1851 1852 1853 1854 1855
        AssertFatal(false, "Invalid case\n");
    }
  }
}

1856
void release_dl_BWP(NR_UE_MAC_INST_t *mac, int index)
1857
{
1858 1859 1860 1861
  NR_UE_DL_BWP_t *bwp = mac->dl_BWPs.array[index];
  int bwp_id = bwp->bwp_id;
  asn_sequence_del(&mac->dl_BWPs, index, 0);

1862
  free(bwp->cyclicprefix);
1863 1864
  asn1cFreeStruc(asn_DEF_NR_PDSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common);
  asn1cFreeStruc(asn_DEF_NR_PDSCH_Config, bwp->pdsch_Config);
1865 1866 1867 1868 1869 1870 1871 1872 1873 1874
  free(bwp);

  NR_BWP_PDCCH_t *pdcch = &mac->config_BWP_PDCCH[bwp_id];
  release_common_ss_cset(pdcch);
  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);
}

1875
void release_ul_BWP(NR_UE_MAC_INST_t *mac, int index)
1876
{
1877 1878 1879
  NR_UE_UL_BWP_t *bwp = mac->ul_BWPs.array[index];
  asn_sequence_del(&mac->ul_BWPs, index, 0);

1880
  free(bwp->cyclicprefix);
1881 1882 1883 1884 1885 1886 1887
  asn1cFreeStruc(asn_DEF_NR_RACH_ConfigCommon, bwp->rach_ConfigCommon);
  asn1cFreeStruc(asn_DEF_NR_PUSCH_TimeDomainResourceAllocationList, bwp->tdaList_Common);
  asn1cFreeStruc(asn_DEF_NR_ConfiguredGrantConfig, bwp->configuredGrantConfig);
  asn1cFreeStruc(asn_DEF_NR_PUSCH_Config, bwp->pusch_Config);
  asn1cFreeStruc(asn_DEF_NR_PUCCH_Config, bwp->pucch_Config);
  asn1cFreeStruc(asn_DEF_NR_PUCCH_ConfigCommon, bwp->pucch_ConfigCommon);
  asn1cFreeStruc(asn_DEF_NR_SRS_Config, bwp->srs_Config);
1888
  free(bwp->msg3_DeltaPreamble);
1889
  bwp->msg3_DeltaPreamble = NULL;
1890 1891 1892
  free(bwp);
}

1893
static void configure_BWPs(NR_UE_MAC_INST_t *mac, NR_ServingCellConfig_t *scd)
1894
{
1895
  configure_dedicated_BWP_dl(mac, 0, scd->initialDownlinkBWP);
1896
  if (scd->downlinkBWP_ToReleaseList) {
1897 1898 1899 1900 1901 1902
    for (int i = 0; i < scd->downlinkBWP_ToReleaseList->list.count; i++) {
      for (int j = 0; j < mac->dl_BWPs.count; j++) {
        if (*scd->downlinkBWP_ToReleaseList->list.array[i] == mac->dl_BWPs.array[i]->bwp_id)
          release_dl_BWP(mac, i);
      }
    }
1903 1904 1905 1906
  }
  if (scd->downlinkBWP_ToAddModList) {
    for (int i = 0; i < scd->downlinkBWP_ToAddModList->list.count; i++) {
      NR_BWP_Downlink_t *bwp = scd->downlinkBWP_ToAddModList->list.array[i];
1907 1908
      configure_common_BWP_dl(mac, bwp->bwp_Id, bwp->bwp_Common);
      configure_dedicated_BWP_dl(mac, bwp->bwp_Id, bwp->bwp_Dedicated);
1909 1910 1911 1912 1913 1914 1915 1916
    }
  }
  if (scd->firstActiveDownlinkBWP_Id) {
    mac->current_DL_BWP = get_dl_bwp_structure(mac, *scd->firstActiveDownlinkBWP_Id, false);
    AssertFatal(mac->current_DL_BWP, "Couldn't find DL-BWP %ld\n", *scd->firstActiveDownlinkBWP_Id);
  }

  if (scd->uplinkConfig) {
1917
    configure_dedicated_BWP_ul(mac, 0, scd->uplinkConfig->initialUplinkBWP);
1918
    if (scd->uplinkConfig->uplinkBWP_ToReleaseList) {
1919 1920 1921 1922 1923 1924
      for (int i = 0; i < scd->uplinkConfig->uplinkBWP_ToReleaseList->list.count; i++) {
        for (int j = 0; j < mac->ul_BWPs.count; j++) {
          if (*scd->uplinkConfig->uplinkBWP_ToReleaseList->list.array[i] == mac->ul_BWPs.array[i]->bwp_id)
            release_ul_BWP(mac, i);
        }
      }
1925 1926 1927 1928
    }
    if (scd->uplinkConfig->uplinkBWP_ToAddModList) {
      for (int i = 0; i < scd->uplinkConfig->uplinkBWP_ToAddModList->list.count; i++) {
        NR_BWP_Uplink_t *bwp = scd->uplinkConfig->uplinkBWP_ToAddModList->list.array[i];
1929 1930
        configure_common_BWP_ul(mac, bwp->bwp_Id, bwp->bwp_Common);
        configure_dedicated_BWP_ul(mac, bwp->bwp_Id, bwp->bwp_Dedicated);
1931 1932 1933 1934
      }
    }
    if (scd->uplinkConfig->firstActiveUplinkBWP_Id) {
      mac->current_UL_BWP = get_ul_bwp_structure(mac, *scd->uplinkConfig->firstActiveUplinkBWP_Id, false);
1935
      AssertFatal(mac->current_UL_BWP, "Couldn't find UL-BWP %ld\n", *scd->uplinkConfig->firstActiveUplinkBWP_Id);
1936 1937 1938 1939
    }
  }
}

1940 1941 1942
void nr_rrc_mac_config_req_cg(module_id_t module_id,
                              int cc_idP,
                              NR_CellGroupConfig_t *cell_group_config)
1943 1944 1945 1946
{
  LOG_I(MAC,"Applying CellGroupConfig from gNodeB\n");
  AssertFatal(cell_group_config, "CellGroupConfig should not be NULL\n");
  NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
1947

1948 1949
  if (cell_group_config->mac_CellGroupConfig)
    configure_maccellgroup(mac, cell_group_config->mac_CellGroupConfig);
francescomani's avatar
francescomani committed
1950

1951 1952 1953 1954 1955
  if (cell_group_config->physicalCellGroupConfig)
    configure_physicalcellgroup(mac, cell_group_config->physicalCellGroupConfig);

  if (cell_group_config->spCellConfig) {
    NR_SpCellConfig_t *spCellConfig = cell_group_config->spCellConfig;
1956
    NR_ServingCellConfig_t *scd = spCellConfig->spCellConfigDedicated;
1957 1958 1959 1960 1961
    mac->servCellIndex = spCellConfig->servCellIndex ? *spCellConfig->servCellIndex : 0;
    if (spCellConfig->reconfigurationWithSync) {
      LOG_A(NR_MAC, "Received reconfigurationWithSync\n");
      handle_reconfiguration_with_sync(mac, module_id, cc_idP, spCellConfig->reconfigurationWithSync);
    }
1962 1963
    if (scd) {
      configure_servingcell_info(&mac->sc_info, scd);
1964
      configure_BWPs(mac, scd);
1965
    }
1966
  }
1967

1968 1969 1970 1971
  configure_logicalChannelBearer(module_id,
                                 cell_group_config->rlc_BearerToAddModList,
                                 cell_group_config->rlc_BearerToReleaseList);

1972
  // Setup the SSB to Rach Occasions mapping according to the config
1973 1974 1975
  // Only if RACH is configured for current BWP
  if (mac->current_UL_BWP->rach_ConfigCommon)
    build_ssb_to_ro_map(mac);
1976

1977
  if (!mac->dl_config_request || !mac->ul_config_request)
1978
    ue_init_config_request(mac, mac->current_DL_BWP->scs);
1979
}