nr_ra_procedures.c 32.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
/*
 * 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
 */

/* Tools */
#include "SIMULATION/TOOLS/sim.h"	// for taus

/* RRC */
#include "NR_RACH-ConfigCommon.h"
rmagueta's avatar
rmagueta committed
38
#include "RRC/NR_UE/rrc_proto.h"
39 40 41 42 43

/* PHY */
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/defs_common.h"
#include "PHY/defs_nr_common.h"
cig's avatar
cig committed
44
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
45 46 47 48 49 50

/* 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"

51 52
#include <executables/softmodem-common.h>

53 54
void nr_get_RA_window(NR_UE_MAC_INST_t *mac);

55 56 57 58
// 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)
cig's avatar
cig committed
59 60
void init_RA(module_id_t mod_id,
             NR_PRACH_RESOURCES_t *prach_resources,
61 62 63
             NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon,
             NR_RACH_ConfigGeneric_t *rach_ConfigGeneric,
             NR_RACH_ConfigDedicated_t *rach_ConfigDedicated) {
64

cig's avatar
cig committed
65
  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
66

67 68
  RA_config_t *ra          = &mac->ra;
  ra->RA_active            = 1;
69 70
  ra->ra_PreambleIndex     = -1;
  ra->RA_usedGroupA        = 1;
71
  ra->RA_RAPID_found       = 0;
cig's avatar
cig committed
72 73
  ra->preambleTransMax     = 0;
  ra->first_Msg3           = 1;
74
  ra->starting_preamble_nb = 0;
cig's avatar
cig committed
75
  ra->RA_backoff_cnt       = 0;
76

77
  prach_resources->RA_PREAMBLE_BACKOFF = 0;
cig's avatar
cig committed
78
  prach_resources->RA_PCMAX = nr_get_Pcmax(mod_id);
79 80 81 82
  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;
83

84 85
  if (rach_ConfigDedicated) {
    if (rach_ConfigDedicated->cfra){
86 87
      LOG_I(MAC, "Initialization of 2-step contention-free random access procedure\n");
      prach_resources->RA_TYPE = RA_2STEP;
88
      ra->cfra = 1;
Thomas Schlichter's avatar
Thomas Schlichter committed
89 90 91 92 93 94 95 96 97 98
    } else if (rach_ConfigDedicated->ext1){
      if (rach_ConfigDedicated->ext1->cfra_TwoStep_r16){
        LOG_I(MAC, "In %s: setting RA type to 2-step...\n", __FUNCTION__);
        prach_resources->RA_TYPE = RA_2STEP;
        ra->cfra = 1;
      } else {
        LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__);
      }
    } else {
      LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__);
99
    }
100 101 102 103
  } 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
104 105
  } else {
    LOG_E(MAC, "In %s: config not handled\n", __FUNCTION__);
106
  }
107

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

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

159 160 161 162 163
  if (nr_rach_ConfigCommon->ext1) {
    if (nr_rach_ConfigCommon->ext1->ra_PrioritizationForAccessIdentity){
      LOG_D(MAC, "In %s:%d: Missing implementation for Access Identity initialization procedures\n", __FUNCTION__, __LINE__);
    }
  }
164
}
cig's avatar
cig committed
165

166
void ssb_rach_config(RA_config_t *ra, NR_PRACH_RESOURCES_t *prach_resources, NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon, fapi_nr_ul_config_prach_pdu *prach_pdu){
cig's avatar
cig committed
167

cig's avatar
cig committed
168 169
  // Determine the SSB to RACH mapping ratio
  // =======================================
Mario Hudon's avatar
Mario Hudon committed
170

171 172 173 174 175 176
  NR_RACH_ConfigCommon__ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR ssb_perRACH_config = nr_rach_ConfigCommon->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present;
  boolean_t multiple_ssb_per_ro; // true if more than one or exactly one SSB per RACH occasion, false if more than one RO per SSB
  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
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 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
  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
222

223 224
  if (nr_rach_ConfigCommon->totalNumberOfRA_Preambles)
    numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
Mario Hudon's avatar
Mario Hudon committed
225

226 227 228 229 230 231
  // 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;

    ssb_nb_in_ro = prach_pdu->ssb_nb_in_ro;
    ra->starting_preamble_nb = total_preambles_per_ssb * ssb_nb_in_ro;
cig's avatar
cig committed
232
  } else {
233 234
    total_preambles_per_ssb = numberOfRA_Preambles;
    ra->starting_preamble_nb = 0;
cig's avatar
cig committed
235 236 237
  }
}

238
// This routine implements RA preamble configuration according to
cig's avatar
cig committed
239 240 241 242 243 244
// 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;
245
  int PLThreshold = 0;
246
  long deltaPreamble_Msg3 = 0;
cig's avatar
cig committed
247
  uint8_t noGroupB = 0;
248
  RA_config_t *ra = &mac->ra;
249 250 251 252
  NR_RACH_ConfigCommon_t *setup;
  if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
  else          setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
  NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
Mario Hudon's avatar
Mario Hudon committed
253

254 255 256
  NR_BWP_UplinkCommon_t *initialUplinkBWP = (mac->scc) ? mac->scc->uplinkConfigCommon->initialUplinkBWP : &mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP;
  if (initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble){
    deltaPreamble_Msg3 = (*initialUplinkBWP->pusch_ConfigCommon->choice.setup->msg3_DeltaPreamble) * 2; // dB
257 258
    LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
  }
Mario Hudon's avatar
Mario Hudon committed
259

260
  if (!setup->groupBconfigured) {
261 262 263 264 265 266 267
    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__);
268 269
    sizeOfRA_PreamblesGroupA = setup->groupBconfigured->numberOfRA_PreamblesGroupA;
    switch (setup->groupBconfigured->ra_Msg3SizeGroupA){
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
      /* - 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:
302
      AssertFatal(1 == 0, "Unknown ra_Msg3SizeGroupA %lu\n", setup->groupBconfigured->ra_Msg3SizeGroupA);
303 304
      /* todo cases 10 -15*/
      }
cig's avatar
cig committed
305

306 307
      /* Power offset for preamble selection in dB */
      messagePowerOffsetGroupB = -9999;
308
      switch (setup->groupBconfigured->messagePowerOffsetGroupB){
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
      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:
334
      AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", setup->groupBconfigured->messagePowerOffsetGroupB);
335
    }
336

337
    PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
338

cig's avatar
cig committed
339
  }
340

cig's avatar
cig committed
341
  /* Msg3 has not been transmitted yet */
342
  if (ra->first_Msg3) {
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
    if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) {
      if (noGroupB) {
        // use Group A preamble
        ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
        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
        ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
        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
        ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
        ra->RA_usedGroupA = 0;
      }
cig's avatar
cig committed
360 361
    }
  } else { // Msg3 is being retransmitted
362
    if (ra->RA_usedGroupA && noGroupB) {
363
      ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % ra->cb_preambles_per_ssb);
364
    } else if (ra->RA_usedGroupA && !noGroupB){
365
      ra->ra_PreambleIndex = ra->starting_preamble_nb + ((taus()) % sizeOfRA_PreamblesGroupA);
cig's avatar
cig committed
366
    } else {
367
      ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + ((taus()) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
368
    }
cig's avatar
cig committed
369
  }
370
  prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex;
cig's avatar
cig committed
371
}
372

373 374 375 376 377 378 379 380
// RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
// - this does not apply to contention-free RA Preamble for beam failure recovery request
// - getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
// - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier
// - f_id: index of the PRACH occasion in the frequency domain
// - s_id is starting symbol of the PRACH occasion [0...14]
// - t_id is the first slot of the PRACH occasion in a system frame [0...80]
uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu){
381

382
  RA_config_t *ra = &mac->ra;
383 384 385 386
  uint8_t ul_carrier_id = 0; // NUL
  uint8_t f_id = prach_pdu->num_ra;
  uint8_t t_id = prach_pdu->prach_slot;
  uint8_t s_id = prach_pdu->prach_start_symbol;
387

388
  ra->ra_rnti = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
389

390
  LOG_D(MAC, "Computed ra_RNTI is %x \n", ra->ra_rnti);
391

392
  return ra->ra_rnti;
393

394
}
Mario Hudon's avatar
Mario Hudon committed
395

cig's avatar
cig committed
396 397
// 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
398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
// - 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)
// --- SSB selection, set prach_resources->ra_PreambleIndex
// -- 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:
// --- SSB selection, set prach_resources->ra_PreambleIndex
// - 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
cig's avatar
cig committed
416 417 418 419 420 421 422 423
void nr_get_prach_resources(module_id_t mod_id,
                            int CC_id,
                            uint8_t gNB_id,
                            NR_PRACH_RESOURCES_t *prach_resources,
                            fapi_nr_ul_config_prach_pdu *prach_pdu,
                            NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){

  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
424
  RA_config_t *ra = &mac->ra;
425 426 427 428

  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc)?
    mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup : 
    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
cig's avatar
cig committed
429

430
  LOG_D(PHY, "In %s: getting PRACH resources frame (first_Msg3 %d)\n", __FUNCTION__, ra->first_Msg3);
cig's avatar
cig committed
431 432 433 434 435

  if (rach_ConfigDedicated) {
    if (rach_ConfigDedicated->cfra){
      uint8_t cfra_ssb_resource_idx = 0;
      prach_resources->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex;
cig's avatar
cig committed
436
      LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, prach_resources->ra_PreambleIndex, cfra_ssb_resource_idx);
cig's avatar
cig committed
437 438 439
    }
  } else {
    int16_t dl_pathloss = get_nr_PL(mod_id, CC_id, gNB_id);
440
    ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu);
cig's avatar
cig committed
441
    ra_preambles_config(prach_resources, mac, dl_pathloss);
442
    LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex);
cig's avatar
cig committed
443
  }
444

445 446
  if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
    prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER++;
447
  prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
448
  prach_resources->ra_RNTI = set_ra_rnti(mac, prach_pdu);
cig's avatar
cig committed
449

450 451
}

cig's avatar
cig committed
452
// TbD: RA_attempt_number not used
453
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
cig's avatar
cig committed
454
  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
455 456 457
  RA_config_t *ra = &mac->ra;
  ra->ra_state = WAIT_RAR;
  ra->RA_attempt_number++;
cig's avatar
cig committed
458
}
459 460

void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
461

462
  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
463 464 465
  NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (mac->scc) ? 
    mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup:
    mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
466
  RA_config_t *ra = &mac->ra;
467 468 469

  LOG_D(MAC,"In %s: [UE %d] Frame %d, CB-RA: starting contention resolution timer\n", __FUNCTION__, mod_id, frameP);

470
  // start contention resolution timer
471 472
  ra->RA_contention_resolution_cnt = (nr_rach_ConfigCommon->ra_ContentionResolutionTimer + 1) * 8;
  ra->RA_contention_resolution_timer_active = 1;
473
  ra->ra_state = WAIT_CONTENTION_RESOLUTION;
474

475 476 477
}

/////////////////////////////////////////////////////////////////////////
cig's avatar
cig committed
478 479 480 481
// This function handles:
// - Random Access Preamble Initialization (5.1.1 TS 38.321)
// - Random Access Response reception (5.1.4 TS 38.321)
/// In the current implementation, RA is 4-step contention free only
482
/////////////////////////////////////////////////////////////////////////
cig's avatar
cig committed
483 484
// todo TS 38.321:
// - BWP operation (subclause 5.15 TS 38.321)
cig's avatar
cig committed
485
// - beam failure recovery
cig's avatar
cig committed
486
// - handle initialization by handover
cig's avatar
cig committed
487 488
// - handle DL assignment on PDCCH for RA-RNTI
// - transmission on DCCH using PRACH (during handover, or sending SR for example)
cig's avatar
cig committed
489 490 491 492
// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader)
// - fix rrc data req logic
// - retrieve TBS
// - add mac_rrc_nr_data_req_ue, etc ...
cig's avatar
cig committed
493
// - Msg3 Retransmissions to be scheduled by DCI 0_0
cig's avatar
cig committed
494
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
495
                       fapi_nr_ul_config_prach_pdu *prach_pdu,
cig's avatar
cig committed
496 497 498 499
                       module_id_t mod_id,
                       int CC_id,
                       frame_t frame,
                       uint8_t gNB_id,
500
                       int nr_slot_tx){
501

cig's avatar
cig committed
502
  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
503
  RA_config_t *ra = &mac->ra;
504
  uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
505 506
  uint8_t lcid = UL_SCH_LCID_CCCH;
  uint8_t *payload;
cig's avatar
cig committed
507 508
  uint16_t size_sdu = 0;
  unsigned short post_padding;
509 510 511
  NR_RACH_ConfigCommon_t *setup;
  if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
  else          setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
cig's avatar
cig committed
512
  AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
cig's avatar
cig committed
513
  NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
514
  NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated;
515

cig's avatar
cig committed
516 517
  uint8_t sdu_lcids[NB_RB_MAX] = {0};
  uint16_t sdu_lengths[NB_RB_MAX] = {0};
rmagueta's avatar
rmagueta committed
518 519
  int num_sdus = 0;
  int offset = 0;
520

cig's avatar
cig committed
521 522
  // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
  if (!prach_resources->init_msg1) {
rmagueta's avatar
rmagueta committed
523
    if ( (mac->common_configuration_complete>0 || get_softmodem_params()->do_ra==1) && ((MAX_FRAME_NUMBER+frame-prach_resources->sync_frame)%MAX_FRAME_NUMBER)>150 ){
cig's avatar
cig committed
524 525
      prach_resources->init_msg1 = 1;
    } else {
luis_pereira87's avatar
luis_pereira87 committed
526
      LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame);
cig's avatar
cig committed
527 528 529
      return 0;
    }
  }
530

luis_pereira87's avatar
luis_pereira87 committed
531
  LOG_D(NR_MAC,"frame %d prach_resources->init_msg1 %d, ra->ra_state %d, ra->RA_active %d\n",
532 533
	frame,prach_resources->init_msg1,ra->ra_state,ra->RA_active);

534
  if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) {
cig's avatar
cig committed
535

536
    if (ra->RA_active == 0) {
537 538
      /* RA not active - checking if RRC is ready to initiate the RA procedure */

luis_pereira87's avatar
luis_pereira87 committed
539
      LOG_D(NR_MAC, "RA not active. Checking for data to transmit from upper layers...\n");
cig's avatar
cig committed
540

rmagueta's avatar
rmagueta committed
541 542 543
      uint8_t TBS_max = 8 + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
      payload = (uint8_t*) mac->CCCH_pdu.payload;

cig's avatar
cig committed
544 545
      num_sdus = 1;
      post_padding = 1;
rmagueta's avatar
rmagueta committed
546
      sdu_lcids[0] = lcid;
cig's avatar
cig committed
547

rmagueta's avatar
rmagueta committed
548
      // initialisation by RRC
549 550

      // TODO: To be removed after RA procedures fully implemented
551 552
      if(get_softmodem_params()->do_ra) {
        nr_rrc_ue_generate_RRCSetupRequest(mod_id,gNB_id);
cig's avatar
cig committed
553
      }
554

rmagueta's avatar
rmagueta committed
555 556 557 558 559
      // CCCH PDU
      size_sdu = (uint16_t) nr_mac_rrc_data_req_ue(mod_id, CC_id, gNB_id, frame, CCCH, mac_sdus);

      sdu_lengths[0] = size_sdu;

luis_pereira87's avatar
luis_pereira87 committed
560
      LOG_D(NR_MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
561

cig's avatar
cig committed
562
      if (size_sdu > 0) {
563

rmagueta's avatar
rmagueta committed
564 565 566 567 568
        // 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
        memcpy(ra->cont_res_id, mac_sdus, sizeof(uint8_t) * 6);

luis_pereira87's avatar
luis_pereira87 committed
569
        LOG_D(NR_MAC, "[UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", mod_id, frame, nr_slot_tx);
570

571
        ra->Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
572

cig's avatar
cig committed
573
        init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated);
cig's avatar
cig committed
574
        prach_resources->Msg3 = payload;
cig's avatar
cig committed
575
        nr_get_RA_window(mac);
576 577

        // Fill in preamble and PRACH resources
578
        if (ra->generate_nr_prach == GENERATE_PREAMBLE) {
cig's avatar
cig committed
579
          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
580
        }
cig's avatar
cig committed
581
        offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus,              // sdus buffer
cig's avatar
cig committed
582
                                       (uint8_t *) payload,               // UL MAC pdu pointer
cig's avatar
cig committed
583 584 585 586 587 588 589 590
                                       num_sdus,                          // num sdus
                                       sdu_lengths,                       // sdu length
                                       sdu_lcids,                         // sdu lcid
                                       0,                                 // power headroom
                                       0,                                 // crnti
                                       0,                                 // truncated bsr
                                       0,                                 // short bsr
                                       0,                                 // long_bsr
591 592
                                       post_padding,
                                       0);
cig's avatar
cig committed
593

rmagueta's avatar
rmagueta committed
594 595
        AssertFatal(TBS_max > offset, "Frequency resources are not enough for Msg3!\n");

cig's avatar
cig committed
596
        // Padding: fill remainder with 0
cig's avatar
cig committed
597
        if (post_padding > 0){
rmagueta's avatar
rmagueta committed
598 599
          for (int j = 0; j < (TBS_max - offset); j++)
            payload[offset + j] = 0;
cig's avatar
cig committed
600
        }
rmagueta's avatar
rmagueta committed
601 602 603 604 605 606 607 608
      }

      LOG_D(MAC,"size_sdu = %i\n", size_sdu);
      LOG_D(MAC,"offset = %i\n", offset);
      for(int k = 0; k < TBS_max; k++) {
        LOG_D(MAC,"(%i): %i\n", k, prach_resources->Msg3[k]);
      }

609
      // Msg3 was initialized with TBS_max bytes because the RA_Msg3_size will only be known after
rmagueta's avatar
rmagueta committed
610
      // receiving Msg2 (which contains the Msg3 resource reserve).
611
      // Msg3 will be transmitted with RA_Msg3_size bytes, removing unnecessary 0s.
rmagueta's avatar
rmagueta committed
612 613 614
      mac->ulsch_pdu.Pdu_size = TBS_max;
      memcpy(mac->ulsch_pdu.payload, prach_resources->Msg3, TBS_max);

615
    } else if (ra->RA_window_cnt != -1) { // RACH is active
616

617
      LOG_D(MAC, "In %s [%d.%d] RA is active: RA window count %d, RA backoff count %d\n", __FUNCTION__, frame, nr_slot_tx, ra->RA_window_cnt, ra->RA_backoff_cnt);
618

619 620
      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
621 622 623
      } else {
        prach_resources->RA_PREAMBLE_BACKOFF = 0;
      }
624

625
      if (ra->RA_window_cnt >= 0 && ra->RA_RAPID_found == 1) {
626

627 628 629 630
        if(ra->cfra) {
          // Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
          nr_ra_succeeded(mod_id, frame, nr_slot_tx);
        } else {
631
          ra->generate_nr_prach = GENERATE_IDLE;
632
        }
luis_pereira87's avatar
luis_pereira87 committed
633

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

cig's avatar
cig committed
636
        LOG_I(MAC, "[UE %d][%d:%d] RAR reception failed \n", mod_id, frame, nr_slot_tx);
637

638
        nr_ra_failed(mod_id, CC_id, prach_resources, frame, nr_slot_tx);
639

640
      } else if (ra->RA_window_cnt > 0) {
641

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

644
        // Fill in preamble and PRACH resources
645
        ra->RA_window_cnt--;
luis_pereira87's avatar
luis_pereira87 committed
646
        if (ra->generate_nr_prach == GENERATE_PREAMBLE) {
647
          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
luis_pereira87's avatar
luis_pereira87 committed
648
        }
649
      } else if (ra->RA_backoff_cnt > 0) {
cig's avatar
cig committed
650

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

653
        ra->RA_backoff_cnt--;
cig's avatar
cig committed
654

655
        if ((ra->RA_backoff_cnt > 0 && ra->generate_nr_prach == GENERATE_PREAMBLE) || ra->RA_backoff_cnt == 0) {
cig's avatar
cig committed
656
          nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
657
        }
658

659 660 661
      }
    }
  }
cig's avatar
cig committed
662

663
  if (ra->RA_contention_resolution_timer_active){
664
    nr_ue_contention_resolution(mod_id, CC_id, frame, nr_slot_tx, prach_resources);
665
  }
cig's avatar
cig committed
666

luis_pereira87's avatar
luis_pereira87 committed
667
  LOG_D(MAC,"ra->generate_nr_prach %d ra->ra_state %d (GENERATE_IDLE %d)\n",ra->generate_nr_prach,ra->ra_state,GENERATE_IDLE);
668 669 670 671 672
  if(ra->generate_nr_prach != GENERATE_IDLE) {
    return ra->generate_nr_prach;
  } else {
    return ra->ra_state;
  }
cig's avatar
cig committed
673

674
}
cig's avatar
cig committed
675 676 677 678

void nr_get_RA_window(NR_UE_MAC_INST_t *mac){

  uint8_t mu, ra_ResponseWindow;
679
  RA_config_t *ra = &mac->ra;
680 681 682 683
  NR_RACH_ConfigCommon_t *setup;
  if (mac->scc) setup = mac->scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
  else          setup = mac->scc_SIB->uplinkConfigCommon->initialUplinkBWP.rach_ConfigCommon->choice.setup;
  AssertFatal(&setup->rach_ConfigGeneric != NULL, "In %s: FATAL! rach_ConfigGeneric is NULL...\n", __FUNCTION__);
cig's avatar
cig committed
684
  NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
685
  long scs = (mac->scc) ? 
rmagueta's avatar
rmagueta committed
686 687
    mac->scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing :
    mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
688
 
cig's avatar
cig committed
689 690 691 692 693
  ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;

  if (setup->msg1_SubcarrierSpacing)
    mu = *setup->msg1_SubcarrierSpacing;
  else
694
    mu = scs;
cig's avatar
cig committed
695

696
  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
697 698

  switch (ra_ResponseWindow) {
cig's avatar
cig committed
699
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
700
      ra->RA_window_cnt += 1;
cig's avatar
cig committed
701
      break;
cig's avatar
cig committed
702
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
703
      ra->RA_window_cnt += 2;
cig's avatar
cig committed
704
      break;
cig's avatar
cig committed
705
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
706
      ra->RA_window_cnt += 4;
cig's avatar
cig committed
707
      break;
cig's avatar
cig committed
708
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
709
      ra->RA_window_cnt += 8;
cig's avatar
cig committed
710
      break;
cig's avatar
cig committed
711
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
712
      ra->RA_window_cnt += 10;
cig's avatar
cig committed
713
      break;
cig's avatar
cig committed
714
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
715
      ra->RA_window_cnt += 20;
cig's avatar
cig committed
716
      break;
cig's avatar
cig committed
717
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
718
      ra->RA_window_cnt += 40;
cig's avatar
cig committed
719
      break;
cig's avatar
cig committed
720
    case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
721
      ra->RA_window_cnt += 80;
cig's avatar
cig committed
722 723
      break;
  }
724
}
725 726 727 728 729 730 731 732 733 734 735

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

738
  if (ra->RA_contention_resolution_timer_active == 1) {
739

740
      ra->RA_contention_resolution_cnt--;
741

742
      LOG_D(MAC, "In %s: [%d.%d] RA contention resolution timer %d\n", __FUNCTION__, frame, slot, ra->RA_contention_resolution_cnt);
743

744 745 746 747
      if (ra->RA_contention_resolution_cnt == 0) {
        ra->t_crnti = 0;
        ra->RA_active = 0;
        ra->RA_contention_resolution_timer_active = 0;
748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
        // Signal PHY to quit RA procedure
        LOG_E(MAC, "[UE %d] CB-RA: Contention resolution timer has expired, RA procedure has failed...\n", module_id);
        nr_ra_failed(module_id, cc_id, prach_resources, frame, slot);
      }
    
  }
}

// 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
void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot){

  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
763
  RA_config_t *ra = &mac->ra;
764

765
  if (ra->cfra) {
766

767
    LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CF-RA: RAR successfully received.\n", mod_id, frame, slot);
768

769
    ra->RA_window_cnt = -1;
770
    mac->crnti = ra->t_crnti;
771 772 773

  } else {

774
    LOG_I(MAC, "[UE %d][%d.%d][RAPROC] RA procedure succeeded. CB-RA: Contention Resolution is successful.\n", mod_id, frame, slot);
775

776 777
    ra->RA_contention_resolution_cnt = -1;
    ra->RA_contention_resolution_timer_active = 0;
778
    mac->crnti = ra->t_crnti;
779
    ra->t_crnti = 0;
780 781 782 783 784 785 786

    LOG_D(MAC, "In %s: [UE %d][%d.%d] CB-RA: cleared contention resolution timer...\n", __FUNCTION__, mod_id, frame, slot);

  }

  LOG_D(MAC, "In %s: [UE %d] clearing RA_active flag...\n", __FUNCTION__, mod_id);
  ra->RA_active = 0;
787
  ra->generate_nr_prach = GENERATE_IDLE;
788 789 790 791
  ra->ra_state = RA_SUCCEEDED;

}

792
// Handling failure of RA procedure @ MAC layer
793 794 795 796 797 798
// according to section 5 of 3GPP TS 38.321 version 16.2.1 Release 16
// todo:
// - complete handling of received contention-based RA preamble
void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_resources, frame_t frame, int slot) {

  NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
799
  RA_config_t *ra = &mac->ra;
800

801
  ra->first_Msg3 = 1;
802
  ra->ra_PreambleIndex = -1;
803
  ra->generate_nr_prach = RA_FAILED;
804
  ra->ra_state = RA_UE_IDLE;
805 806 807

  prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER++;

808
  if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER == ra->preambleTransMax + 1){
809

810 811
    LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n",
          __FUNCTION__, mod_id, frame, slot, ra->preambleTransMax);
812

813 814 815 816
    ra->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
    prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
    prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
    prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
817

818 819 820
  } else {
    // Resetting RA window
    nr_get_RA_window(mac);
821 822 823
  }

}