nr_ra_procedures.c 34.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 22 23 24 25 26 27 28 29 30 31 32 33
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file ra_procedures.c
 * \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15)
 * \author R. Knopp, Navid Nikaein, Guido Casati
 * \date 2019
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
 * \note
 * \warning
 */

/* RRC */
rmagueta's avatar
rmagueta committed
34
#include "RRC/NR_UE/rrc_proto.h"
35 36 37 38 39 40

/* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"

41
#include <executables/softmodem-common.h>
42
#include "openair2/LAYER2/RLC/rlc.h"
43

44 45
int16_t get_prach_tx_power(NR_UE_MAC_INST_t *mac)
{
46
  RA_config_t *ra = &mac->ra;
47
  int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
48
  int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
49
  return min(ra->prach_resources.RA_PCMAX, ra_preamble_rx_power);
50
}
51

52 53 54 55
// Random Access procedure initialization as per 5.1.1 and initialization of variables specific
// to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16)
// todo:
// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX (currently hardcoded to 0)
56
void init_RA(NR_UE_MAC_INST_t *mac,
cig's avatar
cig committed
57
             NR_PRACH_RESOURCES_t *prach_resources,
58 59
             NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon,
             NR_RACH_ConfigGeneric_t *rach_ConfigGeneric,
60 61
             NR_RACH_ConfigDedicated_t *rach_ConfigDedicated)
{
francescomani's avatar
francescomani committed
62
  mac->state = UE_PERFORMING_RA;
63 64
  RA_config_t *ra = &mac->ra;
  ra->RA_active = 1;
65 66 67
  ra->ra_PreambleIndex = -1;
  ra->RA_usedGroupA = 1;
  ra->RA_RAPID_found = 0;
68
  ra->preambleTransMax = 0;
69
  ra->first_Msg3 = true;
70
  ra->starting_preamble_nb = 0;
71
  ra->RA_backoff_cnt = 0;
72
  ra->RA_window_cnt = -1;
73

74 75
  fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;

76
  prach_resources->RA_PREAMBLE_BACKOFF = 0;
77
  NR_SubcarrierSpacing_t prach_scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
78
  int n_prbs = get_N_RA_RB(prach_scs, mac->current_UL_BWP->scs);
79
  int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP->BWPStart;
80
  // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1)
81
  prach_resources->RA_PCMAX = nr_get_Pcmax(mac, 2, false, prach_scs, cfg->carrier_config.dl_grid_size[prach_scs], true, n_prbs, start_prb);
82 83 84 85 86 87 88
  prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
  prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
  prach_resources->POWER_OFFSET_2STEP_RA = 0;
  prach_resources->RA_SCALING_FACTOR_BI = 1;

  if (rach_ConfigDedicated) {
    if (rach_ConfigDedicated->cfra){
89 90
      LOG_I(MAC, "Initialization of 2-step contention-free random access procedure\n");
      prach_resources->RA_TYPE = RA_2STEP;
91
      ra->cfra = 1;
Thomas Schlichter's avatar
Thomas Schlichter committed
92 93
    } else if (rach_ConfigDedicated->ext1){
      if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){
94
        LOG_I(MAC, "Setting RA type to 2-step...\n");
Thomas Schlichter's avatar
Thomas Schlichter committed
95 96 97
        prach_resources->RA_TYPE = RA_2STEP;
        ra->cfra = 1;
      } else {
98
        LOG_E(MAC, "Config not handled\n");
Thomas Schlichter's avatar
Thomas Schlichter committed
99 100
      }
    } else {
101
      LOG_E(MAC, "Config not handled\n");
102
    }
103 104 105 106
  } else if (nr_rach_ConfigCommon){
    LOG_I(MAC, "Initialization of 4-step contention-based random access procedure\n");
    prach_resources->RA_TYPE = RA_4STEP;
    ra->cfra = 0;
Thomas Schlichter's avatar
Thomas Schlichter committed
107
  } else {
108
    LOG_E(MAC, "Config not handled\n");
109 110
  }

111 112
  switch (rach_ConfigGeneric->powerRampingStep){ // in dB
    case 0:
113 114
      prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
      break;
115
    case 1:
116 117
      prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
      break;
118
    case 2:
119 120
      prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
      break;
121
    case 3:
122 123
      prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
      break;
124
  }
125

126 127
  switch (rach_ConfigGeneric->preambleTransMax) {
    case 0:
128
      ra->preambleTransMax = 3;
129
      break;
130
    case 1:
131
      ra->preambleTransMax = 4;
132
      break;
133
    case 2:
134
      ra->preambleTransMax = 5;
135
      break;
136
    case 3:
137
      ra->preambleTransMax = 6;
138
      break;
139
    case 4:
140
      ra->preambleTransMax = 7;
141
      break;
142
    case 5:
143
      ra->preambleTransMax = 8;
144
      break;
145
    case 6:
146
      ra->preambleTransMax = 10;
147
      break;
148
    case 7:
149
      ra->preambleTransMax = 20;
150
      break;
151
    case 8:
152
      ra->preambleTransMax = 50;
153
      break;
154
    case 9:
155
      ra->preambleTransMax = 100;
156
      break;
157
    case 10:
158
      ra->preambleTransMax = 200;
159 160 161
      break;
  }

162
  if (nr_rach_ConfigCommon->ext1) {
163
    if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity_r16){
164
      LOG_D(MAC, "Missing implementation for Access Identity initialization procedures\n");
165 166
    }
  }
167 168
}

francescomani's avatar
francescomani committed
169
/* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */
170
static int8_t nr_get_DELTA_PREAMBLE(NR_UE_MAC_INST_t *mac, int CC_id, uint16_t prach_format)
171
{
172
  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
francescomani's avatar
francescomani committed
173
  NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
174
  int prach_sequence_length = nr_rach_ConfigCommon->prach_RootSequenceIndex.present - 1;
francescomani's avatar
francescomani committed
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
  uint8_t prachConfigIndex, mu;

  AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");

  // SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211

  switch (scs){
    case NR_SubcarrierSpacing_kHz15:
    mu = 0;
    break;

    case NR_SubcarrierSpacing_kHz30:
    mu = 1;
    break;

    case NR_SubcarrierSpacing_kHz60:
    mu = 2;
    break;

    case NR_SubcarrierSpacing_kHz120:
    mu = 3;
    break;

    case NR_SubcarrierSpacing_kHz240:
    mu = 4;
    break;

202
    case NR_SubcarrierSpacing_kHz480_v1700:
francescomani's avatar
francescomani committed
203 204 205
    mu = 5;
    break;

206
    case NR_SubcarrierSpacing_kHz960_v1700:
francescomani's avatar
francescomani committed
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
    mu = 6;
    break;

    case NR_SubcarrierSpacing_spare1:
    mu = 7;
    break;

    default:
    AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %lu\n", scs);
  }

  // Preamble formats given by prach_ConfigurationIndex and tables 6.3.3.2-2 and 6.3.3.2-2 in TS 38.211

  prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;

  if (prach_sequence_length == 0) {
    AssertFatal(prach_format < 4, "Illegal PRACH format %d for sequence length 839\n", prach_format);
    switch (prach_format) {

      // long preamble formats
      case 0:
      case 3:
      return  0;

      case 1:
      return -3;

      case 2:
      return -6;
    }
  } else {
    switch (prach_format) { // short preamble formats
      case 0:
      case 3:
      return 8 + 3*mu;

      case 1:
      case 4:
      case 8:
      return 5 + 3*mu;

      case 2:
      case 5:
      return 3 + 3*mu;

      case 6:
      return 3*mu;

      case 7:
      return 5 + 3*mu;

      default:
259 260 261 262
      AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n",
                  mac->ue_id,
                  prach_format,
                  prachConfigIndex);
francescomani's avatar
francescomani committed
263 264 265 266 267 268 269 270 271 272 273 274
    }
  }
  return 0;
}

// TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration
// Measurement units:
// - preambleReceivedTargetPower      dBm (-202..-60, 2 dBm granularity)
// - delta_preamble                   dB
// - RA_PREAMBLE_POWER_RAMPING_STEP   dB
// - POWER_OFFSET_2STEP_RA            dB
// returns receivedTargerPower in dBm
275
static int nr_get_Po_NOMINAL_PUSCH(NR_UE_MAC_INST_t *mac, NR_PRACH_RESOURCES_t *prach_resources, uint8_t CC_id)
276
{
francescomani's avatar
francescomani committed
277 278 279
  int8_t receivedTargerPower;
  int8_t delta_preamble;

280
  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
francescomani's avatar
francescomani committed
281
  long preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower;
282
  delta_preamble = nr_get_DELTA_PREAMBLE(mac, CC_id, prach_resources->prach_format);
francescomani's avatar
francescomani committed
283

284 285 286 287
  receivedTargerPower = preambleReceivedTargetPower +
                        delta_preamble +
                        (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP +
                        prach_resources->POWER_OFFSET_2STEP_RA;
francescomani's avatar
francescomani committed
288

289
  LOG_D(MAC, "ReceivedTargerPower is %d dBm \n", receivedTargerPower);
francescomani's avatar
francescomani committed
290 291 292
  return receivedTargerPower;
}

293 294
void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon)
{
cig's avatar
cig committed
295 296
  // Determine the SSB to RACH mapping ratio
  // =======================================
Mario Hudon's avatar
Mario Hudon committed
297

298
  NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
299
  bool multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB
300 301 302 303
  uint8_t ssb_rach_ratio; // Nb of SSBs per RACH or RACHs per SSB
  int total_preambles_per_ssb;
  uint8_t ssb_nb_in_ro;
  int numberOfRA_Preambles = 64;
Mario Hudon's avatar
Mario Hudon committed
304

305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
  switch (ssb_perRACH_config){
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneEighth:
      multiple_ssb_per_ro = false;
      ssb_rach_ratio = 8;
      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneEighth + 1);
      break;
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneFourth:
      multiple_ssb_per_ro = false;
      ssb_rach_ratio = 4;
      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneFourth + 1);
      break;
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_oneHalf:
      multiple_ssb_per_ro = false;
      ssb_rach_ratio = 2;
      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.oneHalf + 1);
      break;
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_one:
      multiple_ssb_per_ro = true;
      ssb_rach_ratio = 1;
      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.one + 1);
      break;
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_two:
      multiple_ssb_per_ro = true;
      ssb_rach_ratio = 2;
      ra->cb_preambles_per_ssb = 4 * (nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.two + 1);
      break;
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_four:
      multiple_ssb_per_ro = true;
      ssb_rach_ratio = 4;
      ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.four;
      break;
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_eight:
      multiple_ssb_per_ro = true;
      ssb_rach_ratio = 8;
      ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.eight;
      break;
    case NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR_sixteen:
      multiple_ssb_per_ro = true;
      ssb_rach_ratio = 16;
      ra->cb_preambles_per_ssb = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->choice.sixteen;
      break;
    default:
      AssertFatal(1 == 0, "Unsupported ssb_perRACH_config %d\n", ssb_perRACH_config);
  }
cig's avatar
cig committed
349

350 351
  if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles)
    numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
Mario Hudon's avatar
Mario Hudon committed
352

353 354 355 356
  // Compute the proper Preamble selection params according to the selected SSB and the ssb_perRACH_OccasionAndCB_PreamblesPerSSB configuration
  if ((true == multiple_ssb_per_ro) && (ssb_rach_ratio > 1)) {
    total_preambles_per_ssb = numberOfRA_Preambles / ssb_rach_ratio;

357
    ssb_nb_in_ro = ra->ssb_nb_in_ro;
358
    ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
cig's avatar
cig committed
359
  } else {
360 361
    total_preambles_per_ssb = numberOfRA_Preambles;
    ra->starting_preamble_nb = 0;
cig's avatar
cig committed
362 363 364
  }
}

365
// This routine implements RA preamble configuration according to
cig's avatar
cig committed
366 367 368 369 370 371
// section 5.1 (Random Access procedure) of 3GPP TS 38.321 version 16.2.1 Release 16
void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t *mac, int16_t dl_pathloss){

  int messageSizeGroupA = 0;
  int sizeOfRA_PreamblesGroupA = 0;
  int messagePowerOffsetGroupB = 0;
372
  int PLThreshold = 0;
373
  long deltaPreamble_Msg3 = 0;
cig's avatar
cig committed
374
  uint8_t noGroupB = 0;
375
  // Random seed generation
376 377 378 379 380 381
  unsigned int seed;

  if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
    // Overwrite seed with non-random seed for IQ player/recorder
    seed = 1;
  } else {
382 383
    // & to truncate the int64_t and keep only the LSB bits, up to sizeof(int)
    seed = (unsigned int) (rdtsc_oai() & ~0);
384
  }
385

386
  RA_config_t *ra = &mac->ra;
387
  NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
388
  NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
389

390 391
  if (mac->current_UL_BWP->msg3_DeltaPreamble) {
    deltaPreamble_Msg3 = (*mac->current_UL_BWP->msg3_DeltaPreamble) * 2; // dB
392 393
    LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
  }
394

395
  if (!setup->groupBconfigured) {
396 397 398 399 400 401 402
    noGroupB = 1;
    LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
  } else {
    // RA preambles group B is configured
    // - Random Access Preambles group B is configured for 4-step RA type
    // - Defining the number of RA preambles in RA Preamble Group A for each SSB
    LOG_D(MAC, "In %s:%d: preambles group B is configured...\n", __FUNCTION__, __LINE__);
403 404
    sizeOfRA_PreamblesGroupA = setup->groupBconfigured->numberOfRA_PreamblesGroupA;
    switch (setup->groupBconfigured->ra_Msg3SizeGroupA){
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
      /* - Threshold to determine the groups of RA preambles */
      case 0:
      messageSizeGroupA = 56;
      break;
      case 1:
      messageSizeGroupA = 144;
      break;
      case 2:
      messageSizeGroupA = 208;
      break;
      case 3:
      messageSizeGroupA = 256;
      break;
      case 4:
      messageSizeGroupA = 282;
      break;
      case 5:
      messageSizeGroupA = 480;
      break;
      case 6:
      messageSizeGroupA = 640;
      break;
      case 7:
      messageSizeGroupA = 800;
      break;
      case 8:
      messageSizeGroupA = 1000;
      break;
      case 9:
      messageSizeGroupA = 72;
      break;
      default:
437
      AssertFatal(1 == 0, "Unknown ra_Msg3SizeGroupA %lu\n", setup->groupBconfigured->ra_Msg3SizeGroupA);
438 439
      /* todo cases 10 -15*/
      }
cig's avatar
cig committed
440

441 442
      /* Power offset for preamble selection in dB */
      messagePowerOffsetGroupB = -9999;
443
      switch (setup->groupBconfigured->messagePowerOffsetGroupB){
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468
      case 0:
      messagePowerOffsetGroupB = -9999;
      break;
      case 1:
      messagePowerOffsetGroupB = 0;
      break;
      case 2:
      messagePowerOffsetGroupB = 5;
      break;
      case 3:
      messagePowerOffsetGroupB = 8;
      break;
      case 4:
      messagePowerOffsetGroupB = 10;
      break;
      case 5:
      messagePowerOffsetGroupB = 12;
      break;
      case 6:
      messagePowerOffsetGroupB = 15;
      break;
      case 7:
      messagePowerOffsetGroupB = 18;
      break;
      default:
469
      AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", setup->groupBconfigured->messagePowerOffsetGroupB);
470
    }
471

472
    PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
cig's avatar
cig committed
473 474

  }
475

cig's avatar
cig committed
476
  /* Msg3 has not been transmitted yet */
477
  if (ra->first_Msg3) {
478 479 480
    if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) {
      if (noGroupB) {
        // use Group A preamble
481
        ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % ra->cb_preambles_per_ssb);
482 483 484 485
        ra->RA_usedGroupA = 1;
      } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) {
        // Group B is configured and RA preamble Group A is used
        // - todo add condition on CCCH_sdu_size for initiation by CCCH
486
        ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % sizeOfRA_PreamblesGroupA);
487 488 489 490 491
        ra->RA_usedGroupA = 1;
      } else {
        // Group B preamble is configured and used
        // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
        // the remaining belong to RA Preambles Group B
492
        ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r(&seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
493 494
        ra->RA_usedGroupA = 0;
      }
cig's avatar
cig committed
495 496
    }
  } else { // Msg3 is being retransmitted
497
    if (ra->RA_usedGroupA && noGroupB) {
498
      ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % ra->cb_preambles_per_ssb);
499
    } else if (ra->RA_usedGroupA && !noGroupB){
500
      ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % sizeOfRA_PreamblesGroupA);
cig's avatar
cig committed
501
    } else {
502
      ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r(&seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
503
    }
cig's avatar
cig committed
504 505
  }
}
506

cig's avatar
cig committed
507 508
// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
cig's avatar
cig committed
509 510 511 512 513 514 515 516
// - currently the PRACH preamble is set through RRC configuration for 4-step CFRA mode
// todo:
// - determine next available PRACH occasion
// -- if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
// -- else if SSB is selected above
// -- else if CSI-RS is selected above
// - switch initialisation cases
// -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
517
// --- SSB selection, set ra_PreambleIndex
cig's avatar
cig committed
518 519 520 521
// -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000
// --- set PREAMBLE_INDEX to ra_preamble_index
// --- select the SSB signalled by PDCCH
// -- RA initiated for SI request:
522
// --- SSB selection, set ra_PreambleIndex
cig's avatar
cig committed
523 524 525 526
// - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
// - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
// - Contention-based RA preamble selection:
// -- selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB
527
void nr_get_prach_resources(NR_UE_MAC_INST_t *mac,
cig's avatar
cig committed
528 529 530
                            int CC_id,
                            uint8_t gNB_id,
                            NR_PRACH_RESOURCES_t *prach_resources,
531 532
                            NR_RACH_ConfigDedicated_t *rach_ConfigDedicated)
{
533
  RA_config_t *ra = &mac->ra;
534

535
  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
cig's avatar
cig committed
536

537
  LOG_D(MAC, "Getting PRACH resources frame (first_Msg3 %d)\n", ra->first_Msg3);
cig's avatar
cig committed
538 539 540 541

  if (rach_ConfigDedicated) {
    if (rach_ConfigDedicated->cfra){
      uint8_t cfra_ssb_resource_idx = 0;
francescomani's avatar
francescomani committed
542
      ra->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex;
543 544 545
      LOG_D(MAC, "Selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", 
            ra->ra_PreambleIndex,
            cfra_ssb_resource_idx);
cig's avatar
cig committed
546 547
    }
  } else {
548 549
    /* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we
             can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */
550
    int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm) : 0;
551
    ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon);
cig's avatar
cig committed
552
    ra_preambles_config(prach_resources, mac, dl_pathloss);
553
    LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex);
cig's avatar
cig committed
554
  }
555

556 557
  if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
    prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER++;
558
  prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mac, prach_resources, CC_id);
cig's avatar
cig committed
559

560 561
}

cig's avatar
cig committed
562
// TbD: RA_attempt_number not used
563 564
void nr_Msg1_transmitted(NR_UE_MAC_INST_t *mac)
{
565 566 567
  RA_config_t *ra = &mac->ra;
  ra->ra_state = WAIT_RAR;
  ra->RA_attempt_number++;
cig's avatar
cig committed
568
}
569

570 571
void nr_Msg3_transmitted(NR_UE_MAC_INST_t *mac, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id)
{
572
  RA_config_t *ra = &mac->ra;
573 574
  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = mac->current_UL_BWP->rach_ConfigCommon;
  long mu = mac->current_UL_BWP->scs;
575
  int subframes_per_slot = nr_slots_per_frame[mu] / 10;
576

577 578 579 580 581
  // start contention resolution timer
  int RA_contention_resolution_timer_subframes = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) << 3;
  // timer step 1 slot and timer target given by ra_ContentionResolutionTimer
  nr_timer_setup(&ra->contention_resolution_timer, RA_contention_resolution_timer_subframes * subframes_per_slot, 1);
  nr_timer_start(&ra->contention_resolution_timer);
582

583
  ra->ra_state = WAIT_CONTENTION_RESOLUTION;
francescomani's avatar
francescomani committed
584
}
585

586
void nr_get_msg3_payload(NR_UE_MAC_INST_t *mac, uint8_t *buf, int TBS_max)
francescomani's avatar
francescomani committed
587 588
{
  RA_config_t *ra = &mac->ra;
589 590 591 592 593 594 595

  // we already stored MSG3 in the buffer, we can use that
  if (ra->Msg3_buffer) {
    buf = ra->Msg3_buffer;
    return;
  }

596 597 598
  uint8_t *pdu = buf;
  *(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_CCCH};
  pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
599
  tbs_size_t len = mac_rlc_data_req(mac->ue_id,
600
                                    mac->ue_id,
francescomani's avatar
francescomani committed
601 602 603 604
                                    0,
                                    0,
                                    ENB_FLAG_NO,
                                    MBMS_FLAG_NO,
605 606
                                    0, // SRB0 for messages sent in MSG3
                                    TBS_max - sizeof(NR_MAC_SUBHEADER_FIXED), /* size of mac_ce above */
francescomani's avatar
francescomani committed
607 608 609 610 611 612 613
                                    (char *)pdu,
                                    0,
                                    0);
  AssertFatal(len > 0, "no data for Msg.3\n");
  // UE Contention Resolution Identity
  // Store the first 48 bits belonging to the uplink CCCH SDU within Msg3 to determine whether or not the
  // Random Access Procedure has been successful after reception of Msg4
614
  // We copy from persisted memory to another persisted memory
francescomani's avatar
francescomani committed
615 616
  memcpy(ra->cont_res_id, pdu, sizeof(uint8_t) * 6);
  pdu += len;
617
  AssertFatal(TBS_max >= pdu - buf, "Allocated resources are not enough for Msg3!\n");
francescomani's avatar
francescomani committed
618
  // Padding: fill remainder with 0
619 620 621
  LOG_D(NR_MAC, "Remaining %ld bytes, filling with padding\n", pdu - buf);
  while (pdu < buf + TBS_max - sizeof(NR_MAC_SUBHEADER_FIXED)) {
    *(NR_MAC_SUBHEADER_FIXED *)pdu = (NR_MAC_SUBHEADER_FIXED){.LCID = UL_SCH_LCID_PADDING};
francescomani's avatar
francescomani committed
622 623
    pdu += sizeof(NR_MAC_SUBHEADER_FIXED);
  }
624 625
  ra->Msg3_buffer = calloc(TBS_max, sizeof(uint8_t));
  memcpy(ra->Msg3_buffer, buf, sizeof(uint8_t) * TBS_max);
626 627
}

cig's avatar
cig committed
628 629 630
/**
 * Function:            handles Random Access Preamble Initialization (5.1.1 TS 38.321)
 *                      handles Random Access Response reception (5.1.4 TS 38.321)
cig's avatar
cig committed
631
 * Note:                In SA mode the Msg3 contains a CCCH SDU, therefore no C-RNTI MAC CE is transmitted.
cig's avatar
cig committed
632 633 634 635 636 637 638 639 640
 *
 * @prach_resources     pointer to PRACH resources
 * @prach_pdu           pointer to FAPI UL PRACH PDU
 * @mod_id              module ID
 * @CC_id               CC ID
 * @frame               current UL TX frame
 * @gNB_id              gNB ID
 * @nr_slot_tx          current UL TX slot
 */
641
void nr_ue_get_rach(NR_UE_MAC_INST_t *mac, int CC_id, frame_t frame, uint8_t gNB_id, int nr_slot_tx)
francescomani's avatar
francescomani committed
642
{
643 644
  RA_config_t *ra = &mac->ra;
  NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated;
645
  NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources;
646

cig's avatar
cig committed
647
  // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
648 649 650 651
  if (ra->ra_state == RA_UE_IDLE) {
    if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) &&
       ((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) {
      ra->ra_state = GENERATE_PREAMBLE;
cig's avatar
cig committed
652
    } else {
653
      LOG_D(NR_MAC,"PRACH Condition not met: ra state %d, frame %d, sync_frame %d\n", ra->ra_state, frame, mac->first_sync_frame);
francescomani's avatar
francescomani committed
654
      return;
cig's avatar
cig committed
655 656 657
    }
  }

658
  LOG_D(NR_MAC, "[UE %d][%d.%d]: ra_state %d, RA_active %d\n", mac->ue_id, frame, nr_slot_tx, ra->ra_state, ra->RA_active);
659

660
  if (ra->ra_state > RA_UE_IDLE && ra->ra_state < RA_SUCCEEDED) {
661

662
    if (ra->RA_active == 0) {
663
      NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
664
      NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
665
      init_RA(mac, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated);
666

francescomani's avatar
francescomani committed
667 668
      // TODO this piece of code is required to compute MSG3_size that is used by ra_preambles_config function
      // Not a good implementation, it needs improvements
francescomani's avatar
francescomani committed
669
      int size_sdu = 0;
cig's avatar
cig committed
670

671 672
      // Concerning the C-RNTI MAC CE, it has to be included if the UL transmission (Msg3) is not being made for the CCCH logical channel.
      // Therefore it has been assumed that this event only occurs only when RA is done and it is not SA mode.
francescomani's avatar
francescomani committed
673
      if (get_softmodem_params()->nsa) {
674

675
        uint8_t mac_sdus[34*1056];
676 677 678
        uint16_t sdu_lengths[NB_RB_MAX] = {0};
        int TBS_bytes = 848;
        int mac_ce_len = 0;
679
        unsigned short post_padding = 1;
680 681 682

        // fill ulsch_buffer with random data
        for (int i = 0; i < TBS_bytes; i++){
683
          mac_sdus[i] = (unsigned char) (rand()&0xff);
684 685 686 687 688 689 690 691 692 693 694
        }
        //Sending SDUs with size 1
        //Initialize elements of sdu_lengths
        sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
        size_sdu += sdu_lengths[0];

        if (size_sdu > 0) {
          memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6);
          ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
        }

francescomani's avatar
francescomani committed
695
      } else if (!get_softmodem_params()->sa) {
francescomani's avatar
francescomani committed
696 697
        uint8_t temp_pdu[16] = {0};
        size_sdu = nr_write_ce_ulsch_pdu(temp_pdu, mac, 0,  &(mac->crnti), NULL, NULL, NULL);
698
        ra->Msg3_size = size_sdu;
cig's avatar
cig committed
699
      }
700
    } else if (ra->RA_window_cnt != -1) { // RACH is active
701

francescomani's avatar
francescomani committed
702
      LOG_D(MAC, "[%d.%d] RA is active: RA window count %d, RA backoff count %d\n", frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt);
703

704 705
      if (ra->RA_BI_found){
        prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * ra->RA_backoff_indicator;
cig's avatar
cig committed
706 707 708
      } else {
        prach_resources->RA_PREAMBLE_BACKOFF = 0;
      }
709

710
      if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) {
cig's avatar
cig committed
711

712 713
        if(ra->cfra) {
          // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
714
          nr_ra_succeeded(mac, gNB_id, frame, nr_slot_tx);
715
        }
cig's avatar
cig committed
716

717
      } else if (ra->RA_window_cnt == 0 && !ra->RA_RAPID_found) {
cig's avatar
cig committed
718

719
        LOG_W(MAC, "[UE %d][%d:%d] RAR reception failed \n", mac->ue_id, frame, nr_slot_tx);
720

721
        nr_ra_failed(mac, CC_id, prach_resources, frame, nr_slot_tx);
cig's avatar
cig committed
722

723
      } else if (ra->RA_window_cnt > 0) {
724

725
        LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA window count %d) \n", mac->ue_id, frame, nr_slot_tx, ra->RA_window_cnt);
726

727
        // Fill in preamble and PRACH resources
728
        ra->RA_window_cnt--;
francescomani's avatar
francescomani committed
729
        if (ra->ra_state == GENERATE_PREAMBLE) {
730
          nr_get_prach_resources(mac, CC_id, gNB_id, prach_resources, rach_ConfigDedicated);
luis_pereira87's avatar
luis_pereira87 committed
731
        }
732
      } else if (ra->RA_backoff_cnt > 0) {
cig's avatar
cig committed
733

734
        LOG_D(MAC, "[UE %d][%d.%d]: RAR not received yet (RA backoff count %d) \n", mac->ue_id, frame, nr_slot_tx, ra->RA_backoff_cnt);
cig's avatar
cig committed
735

736
        ra->RA_backoff_cnt--;
cig's avatar
cig committed
737

francescomani's avatar
francescomani committed
738
        if ((ra->RA_backoff_cnt > 0 && ra->ra_state == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) {
739
          nr_get_prach_resources(mac, CC_id, gNB_id, prach_resources, rach_ConfigDedicated);
cig's avatar
cig committed
740
        }
741 742
      }
    }
743
  }
cig's avatar
cig committed
744

745
  if (is_nr_timer_active(ra->contention_resolution_timer)) {
746
    nr_ue_contention_resolution(mac, CC_id, frame, nr_slot_tx, prach_resources);
747
  }
748
}
cig's avatar
cig committed
749

750 751
void nr_get_RA_window(NR_UE_MAC_INST_t *mac)
{
752
  RA_config_t *ra = &mac->ra;
753
  NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP->rach_ConfigCommon;
754
  AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
cig's avatar
cig committed
755
  NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
756
 
757
  int ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
758
  int mu = mac->current_DL_BWP->scs;
cig's avatar
cig committed
759

760
  ra->RA_window_cnt = ra->RA_offset * nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB
cig's avatar
cig committed
761 762

  switch (ra_ResponseWindow) {
cig's avatar
cig committed
763
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
764
      ra->RA_window_cnt += 1;
cig's avatar
cig committed
765
      break;
cig's avatar
cig committed
766
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
767
      ra->RA_window_cnt += 2;
cig's avatar
cig committed
768
      break;
cig's avatar
cig committed
769
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
770
      ra->RA_window_cnt += 4;
cig's avatar
cig committed
771
      break;
cig's avatar
cig committed
772
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
773
      ra->RA_window_cnt += 8;
cig's avatar
cig committed
774
      break;
cig's avatar
cig committed
775
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
776
      ra->RA_window_cnt += 10;
cig's avatar
cig committed
777
      break;
cig's avatar
cig committed
778
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
779
      ra->RA_window_cnt += 20;
cig's avatar
cig committed
780
      break;
cig's avatar
cig committed
781
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
782
      ra->RA_window_cnt += 40;
cig's avatar
cig committed
783
      break;
cig's avatar
cig committed
784
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
785
      ra->RA_window_cnt += 80;
cig's avatar
cig committed
786 787
      break;
  }
788
}
789 790 791 792 793 794 795 796

////////////////////////////////////////////////////////////////////////////
/////////* Random Access Contention Resolution (5.1.35 TS 38.321) */////////
////////////////////////////////////////////////////////////////////////////
// Handling contention resolution timer
// WIP todo:
// - beam failure recovery
// - RA completed
797 798
void nr_ue_contention_resolution(NR_UE_MAC_INST_t *mac, int cc_id, frame_t frame, int slot, NR_PRACH_RESOURCES_t *prach_resources)
{
799
  RA_config_t *ra = &mac->ra;
800

801 802 803 804 805 806
  if (nr_timer_expired(ra->contention_resolution_timer)) {
    ra->t_crnti = 0;
    nr_timer_stop(&ra->contention_resolution_timer);
    // Signal PHY to quit RA procedure
    LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", mac->ue_id);
    nr_ra_failed(mac, cc_id, prach_resources, frame, slot);
807 808 809 810 811 812 813
  }
}

// Handlig successful RA completion @ MAC layer
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
// todo:
// - complete handling of received contention-based RA preamble
814
void nr_ra_succeeded(NR_UE_MAC_INST_t *mac, const uint8_t gNB_index, const frame_t frame, const int slot)
815
{
816
  RA_config_t *ra = &mac->ra;
817

818
  if (ra->cfra) {
819
    LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mac->ue_id, frame, slot);
820
    ra->RA_window_cnt = -1;
821
  } else {
822
    LOG_A(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mac->ue_id, frame, slot);
823
    nr_timer_stop(&ra->contention_resolution_timer);
824
    mac->crnti = ra->t_crnti;
825
    ra->t_crnti = 0;
826
    LOG_D(MAC, "[UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", mac->ue_id, frame, slot);
827 828
  }

829
  LOG_D(MAC, "[UE %d] clearing RA_active flag...\n", mac->ue_id);
830 831
  ra->RA_active = 0;
  ra->ra_state = RA_SUCCEEDED;
832
  mac->state = UE_CONNECTED;
833
  free_and_zero(ra->Msg3_buffer);
834
  nr_mac_rrc_ra_ind(mac->ue_id, frame, true);
835 836
}

837
// Handling failure of RA procedure @ MAC layer
838 839 840
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
// todo:
// - complete handling of received contention-based RA preamble
841
void nr_ra_failed(NR_UE_MAC_INST_t *mac, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot)
842
{
843
  RA_config_t *ra = &mac->ra;
844
  // Random seed generation
845
  unsigned int seed;
846

847 848
  if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
    // Overwrite seed with non-random seed for IQ player/recorder
849 850
    seed = 1;
  } else {
851 852
    // & to truncate the int64_t and keep only the LSB bits, up to sizeof(int)
    seed = (unsigned int) (rdtsc_oai() & ~0);
853 854
  }
  
855
  ra->first_Msg3 = true;
856
  ra->ra_PreambleIndex = -1;
857
  ra->ra_state = RA_UE_IDLE;
858 859 860

  prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;

861
  if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1){
862

863 864 865 866 867
    LOG_D(MAC, "[UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n",
          mac->ue_id,
          frame,
          slot,
          ra->preambleTransMax);
868

869
    ra->RA_backoff_cnt = rand_r(&seed) % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
870 871
    prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
    prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
872
    prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mac, prach_resources, CC_id);
873

874 875 876
  } else {
    // Resetting RA window
    nr_get_RA_window(mac);
877
  }
878
}
879

francescomani's avatar
francescomani committed
880
void prepare_msg4_feedback(NR_UE_MAC_INST_t *mac, int pid, int ack_nack)
881
{
francescomani's avatar
francescomani committed
882
  NR_UE_HARQ_STATUS_t *current_harq = &mac->dl_harq_info[pid];
883 884 885
  int sched_slot = current_harq->ul_slot;
  int sched_frame = current_harq->ul_frame;
  mac->nr_ue_emul_l1.num_harqs = 1;
886 887 888 889 890
  PUCCH_sched_t pucch = {.n_CCE = current_harq->n_CCE,
                         .N_CCE = current_harq->N_CCE,
                         .delta_pucch = current_harq->delta_pucch,
                         .ack_payload = ack_nack,
                         .n_harq = 1};
891 892
  current_harq->active = false;
  current_harq->ack_received = false;
francescomani's avatar
francescomani committed
893 894 895 896 897
  if (get_softmodem_params()->emulate_l1) {
    mac->nr_ue_emul_l1.harq[pid].active = true;
    mac->nr_ue_emul_l1.harq[pid].active_dl_harq_sfn = sched_frame;
    mac->nr_ue_emul_l1.harq[pid].active_dl_harq_slot = sched_slot;
  }
898 899 900 901 902 903 904
  fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_PUCCH);
  if (!pdu)
    return;
  int ret = nr_ue_configure_pucch(mac, sched_slot, mac->ra.t_crnti, &pucch, &pdu->pucch_config_pdu);
  if (ret != 0)
    remove_ul_config_last_item(pdu);
  release_ul_config(pdu, false);
905
}