- added some text descriptions - replaced active BWP with initial BWP in Msg3 scheduling (8.3 TS 38.213) - fixed logging - disabled Msg3 repetitions after first transmission (disabled RA @ MAC)
648 lines
26 KiB
C
648 lines
26 KiB
C
/*
|
|
* 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
|
|
*/
|
|
|
|
#include "mac.h"
|
|
|
|
/*
|
|
#include "common/utils/LOG/vcd_signal_dumper.h"
|
|
#include "PHY_INTERFACE/phy_interface_extern.h"
|
|
#include "SCHED_UE/sched_UE.h"
|
|
#include "COMMON/mac_rrc_primitives.h"
|
|
#include "RRC/LTE/rrc_extern.h"
|
|
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
|
|
#include "common/utils/LOG/log.h"
|
|
#include "UTIL/OPT/opt.h"
|
|
#include "OCG.h"
|
|
#include "OCG_extern.h"
|
|
#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/
|
|
|
|
/* Tools */
|
|
#include "SIMULATION/TOOLS/sim.h" // for taus
|
|
|
|
/* RRC */
|
|
#include "NR_RACH-ConfigCommon.h"
|
|
|
|
/* PHY */
|
|
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
|
|
#include "PHY/defs_common.h"
|
|
#include "PHY/defs_nr_common.h"
|
|
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
|
|
|
|
/* 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"
|
|
|
|
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
|
|
extern const uint8_t nr_slots_per_frame[5];
|
|
|
|
//extern uint8_t nfapi_mode;
|
|
|
|
void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
|
|
|
|
// WIP
|
|
// 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
|
|
void nr_get_prach_resources(module_id_t mod_id,
|
|
int CC_id,
|
|
uint8_t gNB_id,
|
|
uint8_t t_id,
|
|
uint8_t first_Msg3,
|
|
NR_PRACH_RESOURCES_t *prach_resources,
|
|
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
|
|
|
|
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
|
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
|
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
|
|
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric;
|
|
|
|
// NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo
|
|
|
|
int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA = 0, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0;
|
|
uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, prach_ConfigIndex, SFN_nbr, Msg3_size;
|
|
|
|
AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
|
|
nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
|
rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric;
|
|
|
|
// NR_RSRP_Range_t rsrp_ThresholdSSB; // todo
|
|
|
|
///////////////////////////////////////////////////////////
|
|
//////////* UE Random Access Resource Selection *//////////
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// todo:
|
|
// - 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
|
|
|
|
if (rach_ConfigDedicated) {
|
|
//////////* Contention free RA *//////////
|
|
// - the PRACH preamble for the UE to transmit is set through RRC configuration
|
|
// - this is the default mode in current implementation!
|
|
// Operation for contention-free RA resources when:
|
|
// - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
|
|
// - available CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
|
|
// - network controlled Mobility
|
|
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;
|
|
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-free random access procedure... \n", prach_resources->ra_PreambleIndex);
|
|
} else {
|
|
//////////* Contention-based RA preamble selection *//////////
|
|
// todo:
|
|
// - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB
|
|
// - todo determine next available PRACH occasion
|
|
|
|
// rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
|
|
|
|
Msg3_size = mac->RA_Msg3_size;
|
|
|
|
numberOfRA_Preambles = 64;
|
|
if(nr_rach_ConfigCommon->totalNumberOfRA_Preambles != NULL)
|
|
numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles);
|
|
|
|
if (!nr_rach_ConfigCommon->groupBconfigured) {
|
|
noGroupB = 1;
|
|
} else {
|
|
// RA preambles group B is configured
|
|
// - Defining the number of RA preambles in RA Preamble Group A for each SSB */
|
|
sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
|
|
switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
|
|
/* - 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:
|
|
AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
|
|
/* todo cases 10 -15*/
|
|
}
|
|
|
|
/* Power offset for preamble selection in dB */
|
|
messagePowerOffsetGroupB = -9999;
|
|
switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
|
|
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:
|
|
AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
|
|
}
|
|
|
|
// todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
|
|
mac->deltaPreamble_Msg3 = 0;
|
|
deltaPreamble_Msg3 = mac->deltaPreamble_Msg3;
|
|
}
|
|
|
|
PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
|
|
|
|
/* Msg3 has not been transmitted yet */
|
|
if (first_Msg3 == 1) {
|
|
if (noGroupB == 1) {
|
|
// use Group A preamble
|
|
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
|
|
mac->RA_usedGroupA = 1;
|
|
} else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) {
|
|
// Group B is configured and RA preamble Group A is used
|
|
// - todo add condition on CCCH_sdu_size for initiation by CCCH
|
|
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
|
|
mac->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
|
|
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
|
|
mac->RA_usedGroupA = 0;
|
|
}
|
|
} else { // Msg3 is being retransmitted
|
|
if (mac->RA_usedGroupA == 1 && noGroupB == 1) {
|
|
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
|
|
} else if (mac->RA_usedGroupA == 1 && noGroupB == 0){
|
|
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
|
|
} else {
|
|
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
|
|
}
|
|
}
|
|
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex);
|
|
}
|
|
|
|
// 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
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// todo:
|
|
// - 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
|
|
// - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded)
|
|
|
|
if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
|
|
mac->RA_PREAMBLE_POWER_RAMPING_COUNTER++;
|
|
|
|
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
|
|
|
|
// RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
|
|
// 1) this does not apply to contention-free RA Preamble for beam failure recovery request
|
|
// 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
|
|
|
|
prach_ConfigIndex = rach_ConfigGeneric->prach_ConfigurationIndex;
|
|
|
|
// ra_RNTI computation
|
|
// - todo: this is for TDD FR1 only
|
|
// - 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]
|
|
|
|
ul_carrier_id = 0; // NUL
|
|
f_id = rach_ConfigGeneric->msg1_FrequencyStart;
|
|
SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
|
|
s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5];
|
|
|
|
// Pick the first slot of the PRACH occasion in a system frame
|
|
for (i = 0; i < 10; i++){
|
|
if (((SFN_nbr & (1 << i)) >> i) == 1){
|
|
t_id = 2*i;
|
|
break;
|
|
}
|
|
}
|
|
prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
|
|
mac->ra_rnti = prach_resources->ra_RNTI;
|
|
|
|
LOG_D(MAC, "Computed ra_RNTI is %x \n", prach_resources->ra_RNTI);
|
|
}
|
|
|
|
// TbD: RA_attempt_number not used
|
|
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
|
|
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
|
|
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
|
mac->ra_state = WAIT_RAR;
|
|
// Start contention resolution timer
|
|
mac->RA_attempt_number++;
|
|
}
|
|
|
|
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
|
|
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
|
|
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP);
|
|
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
|
// start contention resolution timer
|
|
mac->RA_contention_resolution_cnt = 0;
|
|
mac->RA_contention_resolution_timer_active = 1;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
///////* Random Access Preamble Initialization (5.1.1 TS 38.321) *///////
|
|
/////////////////////////////////////////////////////////////////////////
|
|
/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300)
|
|
/// Only one RA procedure is ongoing at any point in time in a MAC entity
|
|
/// the RA procedure on a SCell shall only be initiated by PDCCH order
|
|
/// in the current implementation, RA is contention free only
|
|
|
|
// WIP
|
|
// todo TS 38.321:
|
|
// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX
|
|
// - BWP operation (subclause 5.15 TS 38.321)
|
|
// - handle initialization by beam failure recovery
|
|
// - handle initialization by handover
|
|
// - handle transmission on DCCH using PRACH (during handover, or sending SR for example)
|
|
// - 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 ...
|
|
// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
|
|
|
|
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
|
|
module_id_t mod_id,
|
|
int CC_id,
|
|
UE_MODE_t UE_mode,
|
|
frame_t frame,
|
|
uint8_t gNB_id,
|
|
int nr_tti_tx){
|
|
|
|
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
|
|
uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES];
|
|
uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload;
|
|
//uint8_t ra_ResponseWindow;
|
|
uint16_t size_sdu = 0;
|
|
unsigned short post_padding;
|
|
//fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
|
|
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
|
NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
|
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
|
|
//NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
|
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = mac->rach_ConfigDedicated;
|
|
|
|
// int32_t frame_diff = 0;
|
|
|
|
uint8_t sdu_lcids[NB_RB_MAX] = {0};
|
|
uint16_t sdu_lengths[NB_RB_MAX] = {0};
|
|
int TBS_bytes = 848, header_length_total=0, num_sdus, offset, preambleTransMax, mac_ce_len;
|
|
|
|
AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
|
|
|
|
if (UE_mode < PUSCH && prach_resources->init_msg1) {
|
|
|
|
LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active);
|
|
|
|
AssertFatal(setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
|
|
|
|
if (mac->RA_active == 0) {
|
|
/* RA not active - checking if RRC is ready to initiate the RA procedure */
|
|
|
|
LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n");
|
|
|
|
mac->RA_RAPID_found = 0;
|
|
|
|
/* Set RA_PREAMBLE_POWER_RAMPING_STEP */
|
|
switch (rach_ConfigGeneric->powerRampingStep){ // in dB
|
|
case 0:
|
|
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
|
|
break;
|
|
case 1:
|
|
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
|
|
break;
|
|
case 2:
|
|
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
|
|
break;
|
|
case 3:
|
|
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
|
|
break;
|
|
}
|
|
|
|
prach_resources->RA_PREAMBLE_BACKOFF = 0;
|
|
prach_resources->RA_SCALING_FACTOR_BI = 1;
|
|
prach_resources->RA_PCMAX = 0; // currently hardcoded to 0
|
|
|
|
payload = (uint8_t*) &mac->CCCH_pdu.payload;
|
|
|
|
mac_ce_len = 0;
|
|
num_sdus = 1;
|
|
post_padding = 1;
|
|
|
|
if (0){
|
|
// initialisation by RRC
|
|
// CCCH PDU
|
|
// size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id,
|
|
// CC_id,
|
|
// frame,
|
|
// CCCH,
|
|
// 1,
|
|
// mac_sdus,
|
|
// gNB_id,
|
|
// 0);
|
|
LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu);
|
|
} else {
|
|
// fill ulsch_buffer with random data
|
|
for (int i = 0; i < TBS_bytes; i++){
|
|
mac_sdus[i] = (unsigned char) (lrand48()&0xff);
|
|
}
|
|
//Sending SDUs with size 1
|
|
//Initialize elements of sdu_lcids and sdu_lengths
|
|
sdu_lcids[0] = lcid;
|
|
sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len;
|
|
header_length_total += 2 + (sdu_lengths[0] >= 128);
|
|
size_sdu += sdu_lengths[0];
|
|
}
|
|
|
|
//mac->RA_tx_frame = frame;
|
|
//mac->RA_tx_subframe = nr_tti_tx;
|
|
//mac->RA_backoff_frame = frame;
|
|
//mac->RA_backoff_subframe = nr_tti_tx;
|
|
|
|
if (size_sdu > 0) {
|
|
|
|
LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame);
|
|
|
|
mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
|
|
mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
|
|
mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT);
|
|
mac->RA_prachMaskIndex = 0;
|
|
// todo: add the backoff condition here
|
|
mac->RA_backoff_cnt = 0;
|
|
mac->RA_active = 1;
|
|
prach_resources->Msg3 = payload;
|
|
|
|
nr_get_RA_window(mac);
|
|
|
|
// Fill in preamble and PRACH resources
|
|
if (mac->generate_nr_prach == 1)
|
|
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated);
|
|
|
|
offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer
|
|
(uint8_t *) payload, // UL MAC pdu pointer
|
|
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
|
|
post_padding,
|
|
0);
|
|
|
|
// Padding: fill remainder with 0
|
|
if (post_padding > 0){
|
|
for (int j = 0; j < (TBS_bytes - offset); j++)
|
|
payload[offset + j] = 0; // mac_pdu[offset + j] = 0;
|
|
}
|
|
}
|
|
} else if (mac->RA_window_cnt != -1) { // RACH is active
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
/////* Random Access Response reception (5.1.4 TS 38.321) */////
|
|
////////////////////////////////////////////////////////////////
|
|
// Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER
|
|
// and RA_backoff_cnt
|
|
// todo:
|
|
// - handle beam failure recovery request
|
|
// - handle DL assignment on PDCCH for RA-RNTI
|
|
// - handle backoff and raResponseWindow params
|
|
|
|
// LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
|
|
// mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe);
|
|
|
|
if (mac->RA_BI_found){
|
|
prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * mac->RA_backoff_indicator;
|
|
} else {
|
|
prach_resources->RA_PREAMBLE_BACKOFF = 0;
|
|
}
|
|
|
|
if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) {
|
|
|
|
// Reset RA_active flag: it disables Msg3 retransmission (8.3 of TS 38.213)
|
|
// TbD Msg3 Retransmissions to be scheduled by DCI 0_0
|
|
mac->RA_active = 0;
|
|
mac->RA_window_cnt = -1;
|
|
mac->ra_state = RA_SUCCEEDED;
|
|
mac->generate_nr_prach = 2;
|
|
LOG_I(MAC, "[MAC][UE %d][RAPROC]: RAR successfully received \n", mod_id);
|
|
|
|
} else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) {
|
|
|
|
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception failed \n", mod_id, frame, nr_tti_tx);
|
|
|
|
mac->ra_state = RA_UE_IDLE;
|
|
mac->RA_PREAMBLE_TRANSMISSION_COUNTER++;
|
|
|
|
preambleTransMax = -1;
|
|
switch (rach_ConfigGeneric->preambleTransMax) {
|
|
case 0:
|
|
preambleTransMax = 3;
|
|
break;
|
|
case 1:
|
|
preambleTransMax = 4;
|
|
break;
|
|
case 2:
|
|
preambleTransMax = 5;
|
|
break;
|
|
case 3:
|
|
preambleTransMax = 6;
|
|
break;
|
|
case 4:
|
|
preambleTransMax = 7;
|
|
break;
|
|
case 5:
|
|
preambleTransMax = 8;
|
|
break;
|
|
case 6:
|
|
preambleTransMax = 10;
|
|
break;
|
|
case 7:
|
|
preambleTransMax = 20;
|
|
break;
|
|
case 8:
|
|
preambleTransMax = 50;
|
|
break;
|
|
case 9:
|
|
preambleTransMax = 100;
|
|
break;
|
|
case 10:
|
|
preambleTransMax = 200;
|
|
break;
|
|
}
|
|
|
|
// Resetting RA window
|
|
nr_get_RA_window(mac);
|
|
|
|
if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
|
|
LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax);
|
|
mac->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
|
|
mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
|
|
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1; // 2 dB increment
|
|
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
|
|
}
|
|
|
|
// compute backoff parameters
|
|
// if (mac->RA_backoff_cnt > 0){
|
|
// frame_diff = (sframe_t) frame - mac->RA_backoff_frame;
|
|
// if (frame_diff < 0) frame_diff = -frame_diff;
|
|
// mac->RA_backoff_frame = frame;
|
|
// mac->RA_backoff_subframe = nr_tti_tx;
|
|
// }
|
|
// compute RA window parameters
|
|
// if (mac->RA_window_cnt > 0){
|
|
// frame_diff = (frame_t) frame - mac->RA_tx_frame;
|
|
// if (frame_diff < 0) frame_diff = -frame_diff;
|
|
// mac->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - mac->RA_tx_subframe));
|
|
// LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, mac->RA_window_cnt);
|
|
// }
|
|
|
|
// mac->RA_tx_frame = frame;
|
|
// mac->RA_tx_subframe = nr_tti_tx;
|
|
|
|
// Fill in preamble and PRACH resources
|
|
if (mac->generate_nr_prach == 1)
|
|
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
|
|
|
|
} else {
|
|
|
|
mac->RA_window_cnt--;
|
|
|
|
LOG_D(MAC, "[MAC][UE %d][RAPROC][%d.%d]: RAR not received yet (RA window count %d) \n",
|
|
mod_id,
|
|
frame,
|
|
nr_tti_tx,
|
|
mac->RA_window_cnt);
|
|
|
|
// Fill in preamble and PRACH resources
|
|
if (mac->generate_nr_prach == 1)
|
|
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated);
|
|
|
|
}
|
|
}
|
|
} else if (UE_mode == PUSCH) {
|
|
LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id);
|
|
AssertFatal(1 == 0, "");
|
|
}
|
|
return mac->generate_nr_prach;
|
|
}
|
|
|
|
void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
|
|
|
|
uint8_t mu, ra_ResponseWindow;
|
|
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
|
NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup;
|
|
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
|
|
NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL;
|
|
|
|
ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow;
|
|
|
|
if (setup->msg1_SubcarrierSpacing)
|
|
mu = *setup->msg1_SubcarrierSpacing;
|
|
else
|
|
mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
|
|
|
mac->RA_window_cnt = mac->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB
|
|
|
|
switch (ra_ResponseWindow) {
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1:
|
|
mac->RA_window_cnt += 1;
|
|
break;
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2:
|
|
mac->RA_window_cnt += 2;
|
|
break;
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4:
|
|
mac->RA_window_cnt += 4;
|
|
break;
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8:
|
|
mac->RA_window_cnt += 8;
|
|
break;
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10:
|
|
mac->RA_window_cnt += 10;
|
|
break;
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20:
|
|
mac->RA_window_cnt += 20;
|
|
break;
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40:
|
|
mac->RA_window_cnt += 40;
|
|
break;
|
|
case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80:
|
|
mac->RA_window_cnt += 80;
|
|
break;
|
|
}
|
|
}
|