Commit f54f1fd6 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/NR_UE_improve_RA' into integration_2022_wk46

parents 0cacf29d 4e80dc4a
...@@ -2021,7 +2021,6 @@ set (MAC_NR_SRC_UE ...@@ -2021,7 +2021,6 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/nr_ue_procedures.c ${NR_UE_MAC_DIR}/nr_ue_procedures.c
${NR_UE_MAC_DIR}/nr_ue_scheduler.c ${NR_UE_MAC_DIR}/nr_ue_scheduler.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
${NR_UE_MAC_DIR}/nr_l1_helpers.c
${NR_UE_MAC_DIR}/nr_ra_procedures.c ${NR_UE_MAC_DIR}/nr_ra_procedures.c
) )
......
...@@ -162,10 +162,8 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, ...@@ -162,10 +162,8 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
ue->dci_thres = 0; ue->dci_thres = 0;
// Setting UE mode to NOT_SYNCHED by default // Setting UE mode to NOT_SYNCHED by default
for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){ for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++)
ue->UE_mode[gNB_id] = NOT_SYNCHED; ue->UE_mode[gNB_id] = NOT_SYNCHED;
ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t));
}
// initialize all signal buffers // initialize all signal buffers
init_nr_ue_signal(ue, nb_connected_gNB); init_nr_ue_signal(ue, nb_connected_gNB);
...@@ -268,7 +266,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) ...@@ -268,7 +266,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
} }
free_and_zero(rach_ind->pdu_list); free_and_zero(rach_ind->pdu_list);
free_and_zero(rach_ind); free_and_zero(rach_ind);
nr_Msg1_transmitted(0, 0, NFAPI_SFNSLOT2SFN(sfn_slot), 0); nr_Msg1_transmitted(0);
} }
if (dl_tti_request) if (dl_tti_request)
{ {
...@@ -300,7 +298,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot) ...@@ -300,7 +298,7 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn_slot)
} }
} }
static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info, NR_PRACH_RESOURCES_t *prach_resources) static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_info)
{ {
fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx); fapi_nr_ul_config_request_t *ul_config = get_ul_config_request(mac, ul_info->slot_tx);
if (!ul_config) if (!ul_config)
...@@ -313,8 +311,7 @@ static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_inf ...@@ -313,8 +311,7 @@ static void check_nr_prach(NR_UE_MAC_INST_t *mac, nr_uplink_indication_t *ul_inf
AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]), AssertFatal(ul_config->number_pdus < sizeof(ul_config->ul_config_list) / sizeof(ul_config->ul_config_list[0]),
"Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus); "Number of PDUS in ul_config = %d > ul_config_list num elements", ul_config->number_pdus);
fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; fapi_nr_ul_config_prach_pdu *prach_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu;
uint8_t nr_prach = nr_ue_get_rach(prach_resources, uint8_t nr_prach = nr_ue_get_rach(prach_pdu,
prach_pdu,
ul_info->module_id, ul_info->module_id,
ul_info->cc_id, ul_info->cc_id,
ul_info->frame_tx, ul_info->frame_tx,
...@@ -349,8 +346,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) ...@@ -349,8 +346,6 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
reset_queue(&nr_ul_dci_req_queue); reset_queue(&nr_ul_dci_req_queue);
reset_queue(&nr_ul_tti_req_queue); reset_queue(&nr_ul_tti_req_queue);
NR_PRACH_RESOURCES_t prach_resources;
memset(&prach_resources, 0, sizeof(prach_resources));
NR_UL_TIME_ALIGNMENT_t ul_time_alignment; NR_UL_TIME_ALIGNMENT_t ul_time_alignment;
memset(&ul_time_alignment, 0, sizeof(ul_time_alignment)); memset(&ul_time_alignment, 0, sizeof(ul_time_alignment));
int last_sfn_slot = -1; int last_sfn_slot = -1;
...@@ -462,7 +457,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg) ...@@ -462,7 +457,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
nr_ue_scheduler(NULL, &ul_info); nr_ue_scheduler(NULL, &ul_info);
nr_ue_prach_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx); nr_ue_prach_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx);
nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, NULL); nr_ue_pucch_scheduler(mod_id, ul_info.frame_tx, ul_info.slot_tx, NULL);
check_nr_prach(mac, &ul_info, &prach_resources); check_nr_prach(mac, &ul_info);
} }
if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) { if (!IS_SOFTMODEM_NOS1 && get_softmodem_params()->sa) {
NR_UE_MAC_INST_t *mac = get_mac_inst(0); NR_UE_MAC_INST_t *mac = get_mac_inst(0);
......
...@@ -191,7 +191,10 @@ typedef struct { ...@@ -191,7 +191,10 @@ typedef struct {
uint16_t freq_msg1; uint16_t freq_msg1;
// When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble // When multiple SSBs per RO is configured, this indicates which one is selected in this RO -> this is used to properly compute the PRACH preamble
uint8_t ssb_nb_in_ro; uint8_t ssb_nb_in_ro;
// nfapi_nr_ul_beamforming_t beamforming; /// Preamble index for PRACH (0-63)
uint8_t ra_PreambleIndex;
/// PRACH TX power (TODO possibly modify to uint)
int16_t prach_tx_power;
} fapi_nr_ul_config_prach_pdu; } fapi_nr_ul_config_prach_pdu;
typedef struct { typedef struct {
......
...@@ -416,11 +416,10 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -416,11 +416,10 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
nfapi_nr_prach_pdu_t *prach_pdu, nfapi_nr_prach_pdu_t *prach_pdu,
int prachOccasion, int prachOccasion,
int frame, int frame,
int subframe, int slot,
uint16_t *max_preamble, uint16_t *max_preamble,
uint16_t *max_preamble_energy, uint16_t *max_preamble_energy,
uint16_t *max_preamble_delay uint16_t *max_preamble_delay)
)
{ {
AssertFatal(gNB!=NULL,"Can only be called from gNB\n"); AssertFatal(gNB!=NULL,"Can only be called from gNB\n");
...@@ -481,7 +480,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -481,7 +480,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
prach_ifft = gNB->prach_vars.prach_ifft; prach_ifft = gNB->prach_vars.prach_ifft;
prachF = gNB->prach_vars.prachF; prachF = gNB->prach_vars.prachF;
if (LOG_DEBUGFLAG(PRACH)){ if (LOG_DEBUGFLAG(PRACH)){
if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, rootSequenceIndex %d\n", subframe,msg1_frequencystart,rootSequenceIndex); if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for slot %d, msg1_frequencystart %d, rootSequenceIndex %d\n", slot, msg1_frequencystart, rootSequenceIndex);
} }
start_meas(&gNB->rx_prach); start_meas(&gNB->rx_prach);
...@@ -506,7 +505,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -506,7 +505,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
if (LOG_DEBUGFLAG(PRACH)){ if (LOG_DEBUGFLAG(PRACH)){
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],(N_ZC==839) ? 840: 140)); int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],(N_ZC==839) ? 840: 140));
if (en>60) LOG_D(PHY,"frame %d, subframe %d : Trying preamble %d \n",frame,subframe,preamble_index); if (en>60) LOG_D(PHY,"frame %d, slot %d : Trying preamble %d \n",frame,slot,preamble_index);
} }
if (restricted_set == 0) { if (restricted_set == 0) {
// This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index
...@@ -585,8 +584,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, ...@@ -585,8 +584,8 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
// Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex
if (LOG_DEBUGFLAG(PRACH)) { if (LOG_DEBUGFLAG(PRACH)) {
int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840));
if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", if (en>60) LOG_D(PHY,"frame %d, slot %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n",
frame,subframe,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en); frame,slot,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en);
} }
LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset); LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset);
......
...@@ -110,8 +110,6 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, ...@@ -110,8 +110,6 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms,
//mac_resynch(); //mac_resynch();
//dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id); //dl_phy_sync_success(ue->Mod_id,frame,0,1);//ue->common_vars.eNb_id);
ue->UE_mode[0] = PRACH; ue->UE_mode[0] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else { } else {
ue->UE_mode[0] = PUSCH; ue->UE_mode[0] = PUSCH;
} }
......
...@@ -123,8 +123,6 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, ...@@ -123,8 +123,6 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
uint32_t rx_power_fil_dB, uint32_t rx_power_fil_dB,
uint8_t gNB_id); uint8_t gNB_id);
int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index);
void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue, void nr_pdsch_ptrs_processing(PHY_VARS_NR_UE *ue,
NR_UE_PDSCH **pdsch_vars, NR_UE_PDSCH **pdsch_vars,
NR_DL_FRAME_PARMS *frame_parms, NR_DL_FRAME_PARMS *frame_parms,
......
...@@ -46,42 +46,6 @@ ...@@ -46,42 +46,6 @@
//#define DEBUG_MEAS_UE //#define DEBUG_MEAS_UE
//#define DEBUG_RANK_EST //#define DEBUG_RANK_EST
// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16
// Assumptions:
// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE
// Measurement units:
// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm)
int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
int16_t pathloss;
if (get_softmodem_params()->do_ra){
long referenceSignalPower = ue->nrUE_config.ssb_config.ss_pbch_power;
pathloss = (int16_t)(referenceSignalPower - ue->measurements.rsrp_dBm[gNB_index]);
LOG_D(MAC, "In %s: pathloss %d dB, UE RX total gain %d dB, referenceSignalPower %ld dBm/RE (%f mW), RSRP %d dBm (%f mW)\n",
__FUNCTION__,
pathloss,
ue->rx_total_gain_dB,
referenceSignalPower,
pow(10, referenceSignalPower/10),
ue->measurements.rsrp_dBm[gNB_index],
pow(10, ue->measurements.rsrp_dBm[gNB_index]/10));
} else {
pathloss = ((int16_t)(((10*ue->rx_total_gain_dB) - dB_fixed_times10(ue->measurements.rsrp[gNB_index]))/10));
}
return pathloss;
}
uint32_t get_nr_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id) uint32_t get_nr_rx_total_gain_dB (module_id_t Mod_id,uint8_t CC_id)
{ {
......
...@@ -61,7 +61,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t ...@@ -61,7 +61,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
NR_DL_FRAME_PARMS *fp=&ue->frame_parms; NR_DL_FRAME_PARMS *fp=&ue->frame_parms;
fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config; fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config;
NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_id];
fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu; fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found; uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found;
...@@ -73,7 +72,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t ...@@ -73,7 +72,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu; int16_t Ncp = 0, amp, *prach, *prach2, *prachF, *Xu;
int32_t Xu_re, Xu_im; int32_t Xu_re, Xu_im;
int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot; int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k, prachStartSymbol, sample_offset_slot;
//int restricted_Type;
fd_occasion = 0; fd_occasion = 0;
prach_len = 0; prach_len = 0;
...@@ -91,12 +89,13 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t ...@@ -91,12 +89,13 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, int frame, uint8_t
n_ra_prb = nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,//prach_pdu->freq_msg1; n_ra_prb = nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].k1,//prach_pdu->freq_msg1;
NCS = prach_pdu->num_cs; NCS = prach_pdu->num_cs;
prach_fmt_id = prach_pdu->prach_format; prach_fmt_id = prach_pdu->prach_format;
preamble_index = prach_resources->ra_PreambleIndex; preamble_index = prach_pdu->ra_PreambleIndex;
kbar = 1; kbar = 1;
K = 24; K = 24;
k = 12*n_ra_prb - 6*fp->N_RB_UL; k = 12*n_ra_prb - 6*fp->N_RB_UL;
prachStartSymbol = prach_pdu->prach_start_symbol; prachStartSymbol = prach_pdu->prach_start_symbol;
//restricted_Type = 0;
LOG_D(PHY,"Generate NR PRACH %d.%d\n", frame, slot);
compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length, compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length,
nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences, nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences,
......
...@@ -590,11 +590,9 @@ typedef struct { ...@@ -590,11 +590,9 @@ typedef struct {
// when off, defaults to frequency domain interpolation // when off, defaults to frequency domain interpolation
int chest_freq; int chest_freq;
int chest_time; int chest_time;
int generate_ul_signal[NUMBER_OF_CONNECTED_gNB_MAX];
UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX]; UE_NR_SCAN_INFO_t scan_info[NB_BANDS_MAX];
NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX];
/// \brief ?. /// \brief ?.
/// - first index: gNB [0..NUMBER_OF_CONNECTED_gNB_MAX[ (hard coded) /// - first index: gNB [0..NUMBER_OF_CONNECTED_gNB_MAX[ (hard coded)
uint32_t total_TBS[NUMBER_OF_CONNECTED_gNB_MAX]; uint32_t total_TBS[NUMBER_OF_CONNECTED_gNB_MAX];
......
...@@ -93,7 +93,6 @@ ...@@ -93,7 +93,6 @@
#define NR_MAX_NB_HARQ_PROCESSES 16 #define NR_MAX_NB_HARQ_PROCESSES 16
#define NR_MAX_PDSCH_TBS 3824 #define NR_MAX_PDSCH_TBS 3824
#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.
#define MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER 36 #define MAX_NUM_NR_DLSCH_SEGMENTS_PER_LAYER 36
...@@ -203,39 +202,6 @@ typedef struct NR_BWP_PARMS { ...@@ -203,39 +202,6 @@ typedef struct NR_BWP_PARMS {
nr_prg_parms_t prg_parms; nr_prg_parms_t prg_parms;
} NR_BWP_PARMS; } NR_BWP_PARMS;
typedef struct {
/// PRACH format retrieved from prach_ConfigIndex
uint16_t prach_format;
/// Preamble index for PRACH (0-63)
uint8_t ra_PreambleIndex;
/// Preamble Tx Counter
uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
/// Preamble Power Ramping Counter
uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER;
/// 2-step RA power offset
int POWER_OFFSET_2STEP_RA;
/// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step.
int ra_PREAMBLE_RECEIVED_TARGET_POWER;
/// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex
uint8_t ra_TDD_map_index;
/// RA Preamble Power Ramping Step in dB
uint32_t RA_PREAMBLE_POWER_RAMPING_STEP;
///
uint8_t RA_PREAMBLE_BACKOFF;
///
uint8_t RA_SCALING_FACTOR_BI;
/// Indicating whether it is 2-step or 4-step RA
nr_ra_type_e RA_TYPE;
/// UE configured maximum output power
int RA_PCMAX;
/// Corresponding RA-RNTI for UL-grant
uint16_t ra_RNTI;
/// Frame of last completed synch
uint16_t sync_frame;
/// Flag to indicate that prach is ready to start: it is enabled with an initial delay after the sync
uint8_t init_msg1;
} NR_PRACH_RESOURCES_t;
typedef struct { typedef struct {
uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS]; uint8_t k_0_p[MAX_NUM_NR_SRS_AP][MAX_NUM_NR_SRS_SYMBOLS];
uint8_t srs_generated_signal_bits; uint8_t srs_generated_signal_bits;
......
...@@ -127,24 +127,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { ...@@ -127,24 +127,6 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
uint8_t prachStartSymbol; uint8_t prachStartSymbol;
uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format); uint8_t N_dur = get_nr_prach_duration(prach_pdu->prach_format);
/*
uint16_t format,RA_sfn_index;
uint8_t start_symbol,N_t_slot,N_dur,N_RA_slot,config_period;
get_nr_prach_info_from_index(gNB->gNB_config.prach_config.prach_ConfigurationIndex.value,
frame,slot,
gNB->gNB_config.carrier_config.dl_frequency.value,
gNB->frame_parms.numerology_index,
gNB->frame_parms.frame_type,
&format,
&start_symbol,
&N_t_slot,
&N_dur,
&RA_sfn_index,
&N_RA_slot,
&config_period);
*/
for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) { for(int prach_oc = 0; prach_oc < prach_pdu->num_prach_ocas; prach_oc++) {
for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) { for (ru_aa=0,aa=0;ru_aa<ru->nb_rx;ru_aa++,aa++) {
gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa]; gNB->prach_vars.rxsigF[aa] = ru->prach_rxsigF[prach_oc][ru_aa];
...@@ -160,8 +142,8 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) { ...@@ -160,8 +142,8 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot) {
slot, slot,
&max_preamble[0], &max_preamble[0],
&max_preamble_energy[0], &max_preamble_energy[0],
&max_preamble_delay[0] &max_preamble_delay[0]);
);
free_nr_prach_entry(gNB,prach_id); free_nr_prach_entry(gNB,prach_id);
LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n", LOG_D(PHY,"[RAPROC] Frame %d, slot %d, occasion %d (prachStartSymbol %d) : Most likely preamble %d, energy %d.%d dB delay %d (prach_energy counter %d)\n",
frame,slot,prach_oc,prachStartSymbol, frame,slot,prach_oc,prachStartSymbol,
......
...@@ -411,7 +411,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ ...@@ -411,7 +411,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0; uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, current_harq_pid, gNB_id = 0;
/* PRACH */ /* PRACH */
//NR_PRACH_RESOURCES_t *prach_resources;
fapi_nr_ul_config_prach_pdu *prach_config_pdu; fapi_nr_ul_config_prach_pdu *prach_config_pdu;
/* PUSCH */ /* PUSCH */
nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu; nfapi_nr_ue_pusch_pdu_t *pusch_config_pdu;
......
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
#include "executables/nr-uesoftmodem.h" #include "executables/nr-uesoftmodem.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h" #include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "LAYER2/NR_MAC_UE/nr_l1_helpers.h"
//#define DEBUG_PHY_PROC //#define DEBUG_PHY_PROC
#define NR_PDCCH_SCHED #define NR_PDCCH_SCHED
...@@ -391,8 +390,6 @@ static void nr_ue_pbch_procedures(uint8_t gNB_id, ...@@ -391,8 +390,6 @@ static void nr_ue_pbch_procedures(uint8_t gNB_id,
if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){ if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1){
if (get_softmodem_params()->do_ra) { if (get_softmodem_params()->do_ra) {
ue->UE_mode[gNB_id] = PRACH; ue->UE_mode[gNB_id] = PRACH;
ue->prach_resources[gNB_id]->sync_frame = frame_rx;
ue->prach_resources[gNB_id]->init_msg1 = 0;
} else { } else {
ue->UE_mode[gNB_id] = PUSCH; ue->UE_mode[gNB_id] = PUSCH;
} }
...@@ -1302,44 +1299,25 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t ...@@ -1302,44 +1299,25 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp int frame_tx = proc->frame_tx, nr_slot_tx = proc->nr_slot_tx, prach_power; // tx_amp
uint8_t mod_id = ue->Mod_id; uint8_t mod_id = ue->Mod_id;
NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id];
AssertFatal(prach_resources != NULL, "ue->prach_resources[%u] == NULL\n", gNB_id);
uint8_t nr_prach = 0; uint8_t nr_prach = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
if (ue->mac_enabled == 0){ nr_prach = nr_ue_get_rach(&ue->prach_vars[gNB_id]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx);
prach_resources->ra_TDD_map_index = 0;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
prach_resources->ra_RNTI = 0x1234;
nr_prach = 1;
prach_resources->init_msg1 = 1;
} else {
nr_prach = nr_ue_get_rach(prach_resources, &ue->prach_vars[0]->prach_pdu, mod_id, ue->CC_id, frame_tx, gNB_id, nr_slot_tx);
LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources : %d\n", __FUNCTION__, frame_tx, nr_slot_tx,nr_prach); LOG_D(PHY, "In %s:[%d.%d] getting PRACH resources : %d\n", __FUNCTION__, frame_tx, nr_slot_tx,nr_prach);
}
if (nr_prach == GENERATE_PREAMBLE) { if (nr_prach == GENERATE_PREAMBLE) {
if (ue->mac_enabled == 1) { fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu;
int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id); ue->tx_power_dBm[nr_slot_tx] = prach_pdu->prach_tx_power;
int16_t ra_preamble_rx_power = (int16_t)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
ue->tx_power_dBm[nr_slot_tx] = min(nr_get_Pcmax(mod_id), ra_preamble_rx_power);
LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d dB, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n", LOG_D(PHY, "In %s: [UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, P0_PRACH %d)\n",
__FUNCTION__, __FUNCTION__,
mod_id, mod_id,
frame_tx, frame_tx,
nr_slot_tx, nr_slot_tx,
prach_resources->ra_PreambleIndex, prach_pdu->ra_PreambleIndex,
pathloss, ue->tx_power_dBm[nr_slot_tx]);
ue->tx_power_dBm[nr_slot_tx],
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER,
prach_resources->ra_RNTI);
}
ue->prach_vars[gNB_id]->amp = AMP; ue->prach_vars[gNB_id]->amp = AMP;
...@@ -1358,9 +1336,6 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t ...@@ -1358,9 +1336,6 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
dB_fixed(prach_power), dB_fixed(prach_power),
ue->prach_vars[gNB_id]->amp); ue->prach_vars[gNB_id]->amp);
if (ue->mac_enabled == 1)
nr_Msg1_transmitted(mod_id, ue->CC_id, frame_tx, gNB_id);
} else if (nr_prach == WAIT_CONTENTION_RESOLUTION) { } else if (nr_prach == WAIT_CONTENTION_RESOLUTION) {
LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id); LOG_D(PHY, "In %s: [UE %d] RA waiting contention resolution\n", __FUNCTION__, mod_id);
ue->UE_mode[gNB_id] = RA_WAIT_CR; ue->UE_mode[gNB_id] = RA_WAIT_CR;
......
...@@ -213,12 +213,8 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue, ...@@ -213,12 +213,8 @@ void pucch_procedures_ue_nr(PHY_VARS_NR_UE *ue,
pucch_pdu = &pucch_vars->pucch_pdu[i]; pucch_pdu = &pucch_vars->pucch_pdu[i];
uint16_t nb_of_prbs = pucch_pdu->prb_size; uint16_t nb_of_prbs = pucch_pdu->prb_size;
/* Generate PUCCH signal according to its format and parameters */ /* Generate PUCCH signal according to its format and parameters */
ue->generate_ul_signal[gNB_id] = 1;
int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ int16_t pucch_tx_power = pucch_pdu->pucch_tx_power;
int contributor = (10 * log10((double)(pow(2,(ue->frame_parms.numerology_index)) * nb_of_prbs)));
int16_t pucch_tx_power = pucch_pdu->pucch_tx_power + contributor + PL;
if (pucch_tx_power > ue->tx_power_max_dBm) if (pucch_tx_power > ue->tx_power_max_dBm)
pucch_tx_power = ue->tx_power_max_dBm; pucch_tx_power = ue->tx_power_max_dBm;
......
...@@ -16,338 +16,5 @@ int32_t get_uldl_offset(int nr_bandP) { re ...@@ -16,338 +16,5 @@ int32_t get_uldl_offset(int nr_bandP) { re
NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);}
int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); }
int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); }
/*
* 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 "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"
#include "LAYER2/MAC/mac.h"
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
//extern uint8_t nfapi_mode;
// 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,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
// NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo
int messagePowerOffsetGroupB = 0, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, i, deltaPreamble_Msg3 = 0;
uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size;
// 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) { // This is for network controlled Mobility
// // operation for contention-free RA resources when:
// // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
// // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
// prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
// return;
// }
//////////* 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;
AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id);
nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon;
Msg3_size = mac->RA_Msg3_size;
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);
}
}
PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->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);
}
}
// 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_TRANSMISSION_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)
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used
case 0:
msg1_FDM = 1;
break;
case 1:
msg1_FDM = 2;
break;
case 2:
msg1_FDM = 4;
break;
case 3:
msg1_FDM = 8;
break;
default:
AssertFatal(1 == 0,"Unknown msg1_FDM %lu\n", nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM);
}
prach_ConfigIndex = nr_rach_ConfigCommon->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 = nr_rach_ConfigCommon->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 %d", 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, slot_t slotP, 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
// 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)
...@@ -264,7 +264,6 @@ int main(int argc, char **argv){ ...@@ -264,7 +264,6 @@ int main(int argc, char **argv){
int n_bytes=0; int n_bytes=0;
NR_DL_FRAME_PARMS *frame_parms; NR_DL_FRAME_PARMS *frame_parms;
NR_PRACH_RESOURCES_t prach_resources;
nfapi_nr_prach_config_t *prach_config; nfapi_nr_prach_config_t *prach_config;
nfapi_nr_prach_pdu_t *prach_pdu; nfapi_nr_prach_pdu_t *prach_pdu;
fapi_nr_prach_config_t *ue_prach_config; fapi_nr_prach_config_t *ue_prach_config;
...@@ -694,7 +693,6 @@ int main(int argc, char **argv){ ...@@ -694,7 +693,6 @@ int main(int argc, char **argv){
ue_prach_pdu = &UE->prach_vars[0]->prach_pdu; ue_prach_pdu = &UE->prach_vars[0]->prach_pdu;
ue_prach_config = &UE->nrUE_config.prach_config; ue_prach_config = &UE->nrUE_config.prach_config;
UE->prach_resources[0] = &prach_resources;
txdata = UE->common_vars.txdata; txdata = UE->common_vars.txdata;
UE->prach_vars[0]->amp = AMP; UE->prach_vars[0]->amp = AMP;
...@@ -717,8 +715,7 @@ int main(int argc, char **argv){ ...@@ -717,8 +715,7 @@ int main(int argc, char **argv){
if (n_frames == 1) if (n_frames == 1)
printf("raPreamble %d\n",preamble_tx); printf("raPreamble %d\n",preamble_tx);
UE->prach_resources[0]->ra_PreambleIndex = preamble_tx; ue_prach_pdu->ra_PreambleIndex = preamble_tx;
UE->prach_resources[0]->init_msg1 = 1;
// Configure channel // Configure channel
bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index); bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index);
...@@ -769,14 +766,7 @@ int main(int argc, char **argv){ ...@@ -769,14 +766,7 @@ int main(int argc, char **argv){
ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index,
UE->X_u); UE->X_u);
/*tx_lev = generate_nr_prach(UE, generate_nr_prach(UE, 0, frame, slot);
0, //gNB_id,
subframe); */ //commented for testing purpose
UE_nr_rxtx_proc_t proc={0};
proc.frame_tx = frame;
proc.nr_slot_tx = slot;
nr_ue_prach_procedures(UE, &proc, 0);
/* tx_lev_dB not used later, no need to set */ /* tx_lev_dB not used later, no need to set */
//tx_lev_dB = (unsigned int) dB_fixed(tx_lev); //tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
#include "NR_EUTRA-MBSFN-SubframeConfig.h" #include "NR_EUTRA-MBSFN-SubframeConfig.h"
#include "RRC/NR/MESSAGES/asn1_msg.h" #include "RRC/NR/MESSAGES/asn1_msg.h"
#include "RRC/NR/nr_rrc_extern.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
extern uint16_t sf_ahead; extern uint16_t sf_ahead;
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include "common/utils/nr/nr_common.h" #include "common/utils/nr/nr_common.h"
#include <math.h> #include <math.h>
#include "PHY/defs_nr_common.h"
//Table 5.1.2.2-2 //Table 5.1.2.2-2
uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824}; uint16_t Tbstable_nr[INDEX_MAX_TBS_TABLE] = {24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,208,224,240,256,272,288,304,320,336,352,368,384,408,432,456,480,504,528,552,576,608,640,672,704,736,768,808,848,888,928,984,1032,1064,1128,1160,1192,1224,1256,1288,1320,1352,1416,1480,1544,1608,1672,1736,1800,1864,1928,2024,2088,2152,2216,2280,2408,2472,2536,2600,2664,2728,2792,2856,2976,3104,3240,3368,3496,3624,3752,3824};
...@@ -48,7 +47,8 @@ uint32_t nr_compute_tbs(uint16_t Qm, ...@@ -48,7 +47,8 @@ uint32_t nr_compute_tbs(uint16_t Qm,
LOG_D(NR_MAC, "In %s: nb_symb_sch %d, nb_dmrs_prb %d, nb_rb %d, nb_rb_oh %d, tb_scaling %d Nl %d\n", __FUNCTION__, nb_symb_sch, nb_dmrs_prb, nb_rb, nb_rb_oh, tb_scaling, Nl); LOG_D(NR_MAC, "In %s: nb_symb_sch %d, nb_dmrs_prb %d, nb_rb %d, nb_rb_oh %d, tb_scaling %d Nl %d\n", __FUNCTION__, nb_symb_sch, nb_dmrs_prb, nb_rb, nb_rb_oh, tb_scaling, Nl);
const uint32_t nbp_re = NR_NB_SC_PER_RB * nb_symb_sch - nb_dmrs_prb - nb_rb_oh; const int nb_subcarrier_per_rb = 12;
const uint32_t nbp_re = nb_subcarrier_per_rb * nb_symb_sch - nb_dmrs_prb - nb_rb_oh;
const uint32_t nb_re = min(156, nbp_re) * nb_rb; const uint32_t nb_re = min(156, nbp_re) * nb_rb;
// Intermediate number of information bits // Intermediate number of information bits
// Rx1024 is tabulated as 10 times the actual code rate // Rx1024 is tabulated as 10 times the actual code rate
......
...@@ -632,7 +632,6 @@ int nr_rrc_mac_config_req_ue( ...@@ -632,7 +632,6 @@ int nr_rrc_mac_config_req_ue(
build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type); build_ssb_to_ro_map(mac);//->scc, mac->phy_config.config_req.cell_config.frame_duplex_type);
if (!get_softmodem_params()->emulate_l1) if (!get_softmodem_params()->emulate_l1)
mac->if_module->phy_config_request(&mac->phy_config); mac->if_module->phy_config_request(&mac->phy_config);
mac->common_configuration_complete = 1;
} }
if(scell_group_config != NULL ){ if(scell_group_config != NULL ){
mac->cg = scell_group_config; mac->cg = scell_group_config;
......
...@@ -38,9 +38,6 @@ ...@@ -38,9 +38,6 @@
#include <string.h> #include <string.h>
#include "platform_types.h" #include "platform_types.h"
/* PHY */
#include "PHY/defs_nr_common.h"
/* IF */ /* IF */
#include "NR_IF_Module.h" #include "NR_IF_Module.h"
#include "fapi_nr_ue_interface.h" #include "fapi_nr_ue_interface.h"
...@@ -64,10 +61,7 @@ ...@@ -64,10 +61,7 @@
#include "NR_CellGroupConfig.h" #include "NR_CellGroupConfig.h"
#include "NR_ServingCellConfig.h" #include "NR_ServingCellConfig.h"
#include "NR_MeasConfig.h" #include "NR_MeasConfig.h"
#include "fapi_nr_ue_interface.h"
#include "NR_IF_Module.h"
#include "PHY/defs_nr_common.h"
#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h"
// ========== // ==========
// NR UE defs // NR UE defs
...@@ -242,6 +236,31 @@ typedef enum { ...@@ -242,6 +236,31 @@ typedef enum {
RA_FAILED = 5 RA_FAILED = 5
} RA_state_t; } RA_state_t;
typedef struct {
/// PRACH format retrieved from prach_ConfigIndex
uint16_t prach_format;
/// Preamble Tx Counter
uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
/// Preamble Power Ramping Counter
uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER;
/// 2-step RA power offset
int POWER_OFFSET_2STEP_RA;
/// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step.
int ra_PREAMBLE_RECEIVED_TARGET_POWER;
/// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex
uint8_t ra_TDD_map_index;
/// RA Preamble Power Ramping Step in dB
uint32_t RA_PREAMBLE_POWER_RAMPING_STEP;
///
uint8_t RA_PREAMBLE_BACKOFF;
///
uint8_t RA_SCALING_FACTOR_BI;
/// Indicating whether it is 2-step or 4-step RA
nr_ra_type_e RA_TYPE;
/// UE configured maximum output power
int RA_PCMAX;
} NR_PRACH_RESOURCES_t;
typedef struct { typedef struct {
// pointer to RACH config dedicated // pointer to RACH config dedicated
...@@ -302,6 +321,8 @@ typedef struct { ...@@ -302,6 +321,8 @@ typedef struct {
/// RA SearchSpace /// RA SearchSpace
NR_SearchSpace_t *ss; NR_SearchSpace_t *ss;
NR_PRACH_RESOURCES_t prach_resources;
} RA_config_t; } RA_config_t;
typedef struct { typedef struct {
...@@ -344,6 +365,14 @@ typedef struct { ...@@ -344,6 +365,14 @@ typedef struct {
int8_t delta_pucch; int8_t delta_pucch;
} PUCCH_sched_t; } PUCCH_sched_t;
typedef struct {
uint32_t ssb_index;
/// SSB RSRP in dBm
short ssb_rsrp_dBm;
} NR_PHY_meas_t;
/*!\brief Top level UE MAC structure */ /*!\brief Top level UE MAC structure */
typedef struct { typedef struct {
...@@ -355,7 +384,7 @@ typedef struct { ...@@ -355,7 +384,7 @@ typedef struct {
NR_CSI_ReportConfig_t *csirc; NR_CSI_ReportConfig_t *csirc;
long physCellId; long physCellId;
//// MAC config //// MAC config
int common_configuration_complete; int first_sync_frame;
NR_DRX_Config_t *drx_Config; NR_DRX_Config_t *drx_Config;
NR_SchedulingRequestConfig_t *schedulingRequestConfig; NR_SchedulingRequestConfig_t *schedulingRequestConfig;
NR_BSR_Config_t *bsr_Config; NR_BSR_Config_t *bsr_Config;
...@@ -396,8 +425,6 @@ typedef struct { ...@@ -396,8 +425,6 @@ typedef struct {
RA_config_t ra; RA_config_t ra;
/// SSB index from MIB decoding /// SSB index from MIB decoding
uint8_t mib_ssb; uint8_t mib_ssb;
/// measured SSB RSRP in dBm
short ssb_rsrp_dBm;
nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG]; nr_csi_report_t csi_report_template[MAX_CSI_REPORTCONFIG];
...@@ -433,6 +460,8 @@ typedef struct { ...@@ -433,6 +460,8 @@ typedef struct {
uint16_t nr_band; uint16_t nr_band;
uint8_t ssb_subcarrier_offset; uint8_t ssb_subcarrier_offset;
NR_PHY_meas_t phy_measurements;
dci_pdu_rel15_t def_dci_pdu_rel15[8]; dci_pdu_rel15_t def_dci_pdu_rel15[8];
// Defined for abstracted mode // Defined for abstracted mode
......
...@@ -309,6 +309,7 @@ void select_pucch_resource(NR_UE_MAC_INST_t *mac, ...@@ -309,6 +309,7 @@ void select_pucch_resource(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch); PUCCH_sched_t *pucch);
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
int scs,
NR_PUCCH_Config_t *pucch_Config, NR_PUCCH_Config_t *pucch_Config,
PUCCH_sched_t *pucch, PUCCH_sched_t *pucch,
uint8_t format_type, uint8_t format_type,
...@@ -392,6 +393,8 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res ...@@ -392,6 +393,8 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res
void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot); void nr_ra_succeeded(module_id_t mod_id, frame_t frame, int slot);
void nr_get_RA_window(NR_UE_MAC_INST_t *mac);
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure. /* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure.
If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB
...@@ -403,8 +406,7 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 ...@@ -403,8 +406,7 @@ andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4
@param gNB_id gNB index @param gNB_id gNB index
@param nr_slot_tx slot for PRACH transmission @param nr_slot_tx slot for PRACH transmission
@returns indication to generate PRACH to phy */ @returns indication to generate PRACH to phy */
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
fapi_nr_ul_config_prach_pdu *prach_pdu,
module_id_t mod_id, module_id_t mod_id,
int CC_id, int CC_id,
frame_t frame, frame_t frame,
...@@ -424,7 +426,17 @@ void nr_get_prach_resources(module_id_t mod_id, ...@@ -424,7 +426,17 @@ void nr_get_prach_resources(module_id_t mod_id,
fapi_nr_ul_config_prach_pdu *prach_pdu, fapi_nr_ul_config_prach_pdu *prach_pdu,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated); NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id); void init_RA(module_id_t mod_id,
NR_PRACH_RESOURCES_t *prach_resources,
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon,
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric,
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated);
int16_t get_prach_tx_power(module_id_t mod_id);
void set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu);
void nr_Msg1_transmitted(module_id_t mod_id);
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id); void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot_t slotP, uint8_t gNB_id);
...@@ -451,6 +463,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl ...@@ -451,6 +463,8 @@ fapi_nr_ul_config_request_t *get_ul_config_request(NR_UE_MAC_INST_t *mac, int sl
void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type); void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, int slot_tx, uint8_t pdu_type);
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm);
// PUSCH scheduler: // PUSCH scheduler:
// - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2, // - Calculate the slot in which ULSCH should be scheduled. This is current slot + K2,
// - where K2 is the offset between the slot in which UL DCI is received and the slot // - where K2 is the offset between the slot in which UL DCI is received and the slot
......
...@@ -35,8 +35,6 @@ ...@@ -35,8 +35,6 @@
#include "radio/COMMON/common_lib.h" #include "radio/COMMON/common_lib.h"
//#undef MALLOC //#undef MALLOC
#include "assertions.h" #include "assertions.h"
#include "PHY/types.h"
#include "PHY/defs_UE.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h"
#include "executables/softmodem-common.h" #include "executables/softmodem-common.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp.h" #include "openair2/LAYER2/nr_pdcp/nr_pdcp.h"
...@@ -52,12 +50,12 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { ...@@ -52,12 +50,12 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) {
//init mac here //init mac here
nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST); nr_ue_mac_inst = (NR_UE_MAC_INST_t *)calloc(sizeof(NR_UE_MAC_INST_t),NB_NR_UE_MAC_INST);
nr_ue_mac_inst->first_sync_frame = -1;
for (int j=0;j<NB_NR_UE_MAC_INST;j++) { for (int j=0;j<NB_NR_UE_MAC_INST;j++) {
nr_ue_init_mac(j); nr_ue_init_mac(j);
} }
if (rrc_inst && rrc_inst->scell_group_config) { if (rrc_inst && rrc_inst->scell_group_config) {
nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,rrc_inst->scell_group_config); nr_rrc_mac_config_req_ue(0,0,0,NULL,NULL,NULL,rrc_inst->scell_group_config);
......
/*
* 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 nr_l1_helper.c
* \brief PHY/MAC helper functions
* \author Guido Casati
* \date 2019
* \version 2.0
* \email guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
#include "PHY/defs_nr_common.h"
//#include "PHY/impl_defs_top.h"
#include "mac_defs.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "LAYER2/NR_MAC_UE/nr_l1_helpers.h"
#include "NR_P-Max.h"
// Implementation of 6.2.4 Configured ransmitted power
// 3GPP TS 38.101-1 version 16.5.0 Release 16
// -
// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot.
// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c
// -
// Measurement units:
// - p_max: dBm
// - delta_TC_c: dB
// - P_powerclass: dBm
// - delta_P_powerclass: dB
// - MPR_c: dB
// - delta_MPR_c: dB
// - delta_T_IB_c dB
// - delta_rx_SRS dB
// note:
// - Assuming:
// -- Powerclass 3 capable UE (which is default power class unless otherwise stated)
// -- Maximum power reduction (MPR_c) for power class 3, QPSK, inner RB allocations
// -- no additional MPR (A_MPR_c)
// todo:
// - in current implementation delta_P_powerclass is not handling power classes different from 3
long nr_get_Pcmax(module_id_t mod_id){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint32_t band = (mac->scc!=NULL) ? *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] :
*mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
NR_P_Max_t p_max = 0;
uint8_t P_powerclass = 23;
uint8_t delta_P_powerclass = 0;
uint8_t MPR_c = 1.5;
uint8_t delta_MPR_c = 0;
uint8_t A_MPR_c = 0;
uint8_t delta_T_IB_c = 0;
uint8_t delta_TC_c = 0;
uint8_t delta_rx_SRS = 0;
uint8_t P_MPR_c = 0;
long P_cmax_l = 0;
long P_cmax_h = 0;
long P_cmax = 0;
if (band == 28 && mac->phy_config.config_req.carrier_config.uplink_bandwidth == 30){
delta_MPR_c = 0.5;
}
if (mac->cg && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){
if (*mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){
// TbD: assuming power class 3 capable UE operating in TDD bands n40, n41, n77, n78, and n79 with Pi/2 BPSK modulation
delta_P_powerclass = -3;
p_max += 3;
}
}
NR_P_Max_t *p_Max = (mac->scc!=NULL) ? mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max : mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.p_Max;
if (p_Max){
p_max += *p_Max;
LOG_D(MAC, "In %s maximum UL transmission power p_max is %ld dBm \n", __FUNCTION__, p_max);
P_cmax_l = min(p_max - delta_TC_c, (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c));
P_cmax_h = min(p_max, P_powerclass - delta_P_powerclass);
} else {
P_cmax_l = (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c);
P_cmax_h = P_powerclass - delta_P_powerclass;
}
P_cmax = (P_cmax_h + P_cmax_l) / 2;
LOG_D(MAC, "In %s configured maximum output power: %ld dBm <= PCMAX %ld dBm <= %ld dBm \n", __FUNCTION__, P_cmax_l, P_cmax, P_cmax_h);
return P_cmax;
}
/*
* 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
*/
/** \brief Function to compute configured maximum output power according to clause 6.2.4 of 3GPP TS 38.101-1 version 16.5.0 Release 16
@param Mod_id Module id of UE
*/
long nr_get_Pcmax(module_id_t mod_id);
/** @}*/
...@@ -34,18 +34,102 @@ ...@@ -34,18 +34,102 @@
#include "NR_RACH-ConfigCommon.h" #include "NR_RACH-ConfigCommon.h"
#include "RRC/NR_UE/rrc_proto.h" #include "RRC/NR_UE/rrc_proto.h"
/* PHY */
#include "PHY/NR_UE_ESTIMATION/nr_estimation.h"
/* MAC */ /* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h" #include "NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h" #include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "LAYER2/NR_MAC_UE/nr_l1_helpers.h"
#include <executables/softmodem-common.h> #include <executables/softmodem-common.h>
void nr_get_RA_window(NR_UE_MAC_INST_t *mac); // Implementation of 6.2.4 Configured ransmitted power
// 3GPP TS 38.101-1 version 16.5.0 Release 16
// -
// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot.
// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c
// -
// Measurement units:
// - p_max: dBm
// - delta_TC_c: dB
// - P_powerclass: dBm
// - delta_P_powerclass: dB
// - MPR_c: dB
// - delta_MPR_c: dB
// - delta_T_IB_c dB
// - delta_rx_SRS dB
// note:
// - Assuming:
// -- Powerclass 3 capable UE (which is default power class unless otherwise stated)
// -- Maximum power reduction (MPR_c) for power class 3, QPSK, inner RB allocations
// -- no additional MPR (A_MPR_c)
// todo:
// - in current implementation delta_P_powerclass is not handling power classes different from 3
long nr_get_Pcmax(module_id_t mod_id){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint32_t band = (mac->scc!=NULL) ? *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] :
*mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
NR_P_Max_t p_max = 0;
uint8_t P_powerclass = 23;
uint8_t delta_P_powerclass = 0;
uint8_t MPR_c = 1.5;
uint8_t delta_MPR_c = 0;
uint8_t A_MPR_c = 0;
uint8_t delta_T_IB_c = 0;
uint8_t delta_TC_c = 0;
uint8_t delta_rx_SRS = 0;
uint8_t P_MPR_c = 0;
long P_cmax_l = 0;
long P_cmax_h = 0;
long P_cmax = 0;
if (band == 28 && mac->phy_config.config_req.carrier_config.uplink_bandwidth == 30){
delta_MPR_c = 0.5;
}
if (mac->cg && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){
if (*mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){
// TbD: assuming power class 3 capable UE operating in TDD bands n40, n41, n77, n78, and n79 with Pi/2 BPSK modulation
delta_P_powerclass = -3;
p_max += 3;
}
}
NR_P_Max_t *p_Max = (mac->scc!=NULL) ? mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max : mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.p_Max;
if (p_Max){
p_max += *p_Max;
LOG_D(MAC, "In %s maximum UL transmission power p_max is %ld dBm \n", __FUNCTION__, p_max);
P_cmax_l = min(p_max - delta_TC_c, (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c));
P_cmax_h = min(p_max, P_powerclass - delta_P_powerclass);
} else {
P_cmax_l = (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c);
P_cmax_h = P_powerclass - delta_P_powerclass;
}
P_cmax = (P_cmax_h + P_cmax_l) / 2;
LOG_D(MAC, "In %s configured maximum output power: %ld dBm <= PCMAX %ld dBm <= %ld dBm \n", __FUNCTION__, P_cmax_l, P_cmax, P_cmax_h);
return P_cmax;
}
int16_t get_prach_tx_power(module_id_t mod_id) {
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra;
int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm);
int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
return min(nr_get_Pcmax(mod_id), ra_preamble_rx_power);
}
// Random Access procedure initialization as per 5.1.1 and initialization of variables specific // 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) // to Random Access type as specified in clause 5.1.1a (3GPP TS 38.321 version 16.2.1 Release 16)
...@@ -527,7 +611,6 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t ...@@ -527,7 +611,6 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r((unsigned int *)seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r((unsigned int *)seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
} }
} }
prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex;
} }
// RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted) // RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
...@@ -537,7 +620,7 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t ...@@ -537,7 +620,7 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
// - f_id: index of the PRACH occasion in the frequency domain // - f_id: index of the PRACH occasion in the frequency domain
// - s_id is starting symbol of the PRACH occasion [0...14] // - 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] // - 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){ void set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_pdu){
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
uint8_t ul_carrier_id = 0; // NUL uint8_t ul_carrier_id = 0; // NUL
...@@ -548,9 +631,6 @@ uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_p ...@@ -548,9 +631,6 @@ uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_p
ra->ra_rnti = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id; ra->ra_rnti = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
LOG_D(MAC, "Computed ra_RNTI is %x \n", ra->ra_rnti); LOG_D(MAC, "Computed ra_RNTI is %x \n", ra->ra_rnti);
return ra->ra_rnti;
} }
// This routine implements Section 5.1.2 (UE Random Access Resource Selection) // This routine implements Section 5.1.2 (UE Random Access Resource Selection)
...@@ -563,12 +643,12 @@ uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_p ...@@ -563,12 +643,12 @@ uint16_t set_ra_rnti(NR_UE_MAC_INST_t *mac, fapi_nr_ul_config_prach_pdu *prach_p
// -- else if CSI-RS is selected above // -- else if CSI-RS is selected above
// - switch initialisation cases // - switch initialisation cases
// -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321) // -- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
// --- SSB selection, set prach_resources->ra_PreambleIndex // --- SSB selection, set ra_PreambleIndex
// -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 // -- RA initiated by PDCCH: ra_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000
// --- set PREAMBLE_INDEX to ra_preamble_index // --- set PREAMBLE_INDEX to ra_preamble_index
// --- select the SSB signalled by PDCCH // --- select the SSB signalled by PDCCH
// -- RA initiated for SI request: // -- RA initiated for SI request:
// --- SSB selection, set prach_resources->ra_PreambleIndex // --- SSB selection, set ra_PreambleIndex
// - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) // - 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 // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
// - Contention-based RA preamble selection: // - Contention-based RA preamble selection:
...@@ -578,7 +658,7 @@ void nr_get_prach_resources(module_id_t mod_id, ...@@ -578,7 +658,7 @@ void nr_get_prach_resources(module_id_t mod_id,
uint8_t gNB_id, uint8_t gNB_id,
NR_PRACH_RESOURCES_t *prach_resources, NR_PRACH_RESOURCES_t *prach_resources,
fapi_nr_ul_config_prach_pdu *prach_pdu, fapi_nr_ul_config_prach_pdu *prach_pdu,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ NR_RACH_ConfigDedicated_t *rach_ConfigDedicated){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
...@@ -593,27 +673,26 @@ void nr_get_prach_resources(module_id_t mod_id, ...@@ -593,27 +673,26 @@ void nr_get_prach_resources(module_id_t mod_id,
if (rach_ConfigDedicated->cfra){ if (rach_ConfigDedicated->cfra){
uint8_t cfra_ssb_resource_idx = 0; uint8_t cfra_ssb_resource_idx = 0;
ra->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex; ra->ra_PreambleIndex = rach_ConfigDedicated->cfra->resources.choice.ssb->ssb_ResourceList.list.array[cfra_ssb_resource_idx]->ra_PreambleIndex;
prach_resources->ra_PreambleIndex = ra->ra_PreambleIndex; LOG_D(MAC, "In %s: selected RA preamble index %d for contention-free random access procedure for SSB with Id %d\n", __FUNCTION__, ra->ra_PreambleIndex, cfra_ssb_resource_idx);
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);
} }
} else { } else {
/* TODO: This controls the tx_power of UE and the ramping procedure of RA of UE. Later we /* 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. */ can abstract this, perhaps in the proxy. But for the time being lets leave it as below. */
int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? get_nr_PL(mod_id, CC_id, gNB_id) : 0; int16_t dl_pathloss = !get_softmodem_params()->emulate_l1 ? compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm) : 0;
ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu); ssb_rach_config(ra, prach_resources, nr_rach_ConfigCommon, prach_pdu);
ra_preambles_config(prach_resources, mac, dl_pathloss); ra_preambles_config(prach_resources, mac, dl_pathloss);
LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", prach_resources->ra_PreambleIndex); LOG_D(MAC, "[RAPROC] - Selected RA preamble index %d for contention-based random access procedure... \n", ra->ra_PreambleIndex);
} }
if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) if (prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER > 1)
prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER++; prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER++;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
prach_resources->ra_RNTI = set_ra_rnti(mac, prach_pdu);
} }
// TbD: RA_attempt_number not used // 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){ void nr_Msg1_transmitted(module_id_t mod_id){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
ra->ra_state = WAIT_RAR; ra->ra_state = WAIT_RAR;
...@@ -659,8 +738,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot ...@@ -659,8 +738,7 @@ void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, slot
* @gNB_id gNB ID * @gNB_id gNB ID
* @nr_slot_tx current UL TX slot * @nr_slot_tx current UL TX slot
*/ */
uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t nr_ue_get_rach(fapi_nr_ul_config_prach_pdu *prach_pdu,
fapi_nr_ul_config_prach_pdu *prach_pdu,
module_id_t mod_id, module_id_t mod_id,
int CC_id, int CC_id,
frame_t frame, frame_t frame,
...@@ -669,34 +747,29 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, ...@@ -669,34 +747,29 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
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__);
NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric;
NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated; NR_RACH_ConfigDedicated_t *rach_ConfigDedicated = ra->rach_ConfigDedicated;
NR_PRACH_RESOURCES_t *prach_resources = &ra->prach_resources;
// Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side // Delay init RA procedure to allow the convergence of the IIR filter on PRACH noise measurements at gNB side
if (!prach_resources->init_msg1) { if (ra->ra_state == RA_UE_IDLE) {
if ((mac->common_configuration_complete > 0 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) && if ((mac->first_sync_frame > -1 || get_softmodem_params()->do_ra || get_softmodem_params()->nsa) &&
((MAX_FRAME_NUMBER + frame - prach_resources->sync_frame) % MAX_FRAME_NUMBER) > 150) { ((MAX_FRAME_NUMBER + frame - mac->first_sync_frame) % MAX_FRAME_NUMBER) > 150) {
prach_resources->init_msg1 = 1; ra->ra_state = GENERATE_PREAMBLE;
} else { } else {
LOG_D(NR_MAC,"PRACH Condition not met: frame %d, prach_resources->sync_frame %d\n",frame,prach_resources->sync_frame); 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);
return 0; return 0;
} }
} }
LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: init_msg1 %d, ra_state %d, RA_active %d\n", LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: ra_state %d, RA_active %d\n",
__FUNCTION__, __FUNCTION__,
mod_id, mod_id,
frame, frame,
nr_slot_tx, nr_slot_tx,
prach_resources->init_msg1,
ra->ra_state, ra->ra_state,
ra->RA_active); ra->RA_active);
if (prach_resources->init_msg1 && ra->ra_state != RA_SUCCEEDED) { if (ra->ra_state > RA_UE_IDLE && ra->ra_state < RA_SUCCEEDED) {
if (ra->RA_active == 0) { if (ra->RA_active == 0) {
/* RA not active - checking if RRC is ready to initiate the RA procedure */ /* RA not active - checking if RRC is ready to initiate the RA procedure */
...@@ -775,17 +848,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, ...@@ -775,17 +848,10 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
} }
if (size_sdu > 0 && (ra->generate_nr_prach == GENERATE_PREAMBLE || get_softmodem_params()->nsa)) { if (size_sdu > 0 && (ra->ra_state == GENERATE_PREAMBLE || get_softmodem_params()->nsa)) {
LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx); LOG_D(NR_MAC, "In %s: [UE %d][%d.%d]: starting initialisation Random Access Procedure...\n", __FUNCTION__, mod_id, frame, nr_slot_tx);
// Init RA procedure
init_RA(mod_id, prach_resources, setup, rach_ConfigGeneric, rach_ConfigDedicated);
nr_get_RA_window(mac);
// Fill in preamble and PRACH resources
if (ra->generate_nr_prach == GENERATE_PREAMBLE)
nr_get_prach_resources(mod_id, CC_id, gNB_id, prach_resources, prach_pdu, rach_ConfigDedicated);
// Padding: fill remainder with 0 // Padding: fill remainder with 0
if (TBS_max - ra->Msg3_size > 0) { if (TBS_max - ra->Msg3_size > 0) {
AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__); AssertFatal(TBS_max > ra->Msg3_size, "In %s: allocated resources are not enough for Msg3!\n", __FUNCTION__);
...@@ -868,12 +934,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, ...@@ -868,12 +934,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources,
} }
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); 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);
if(ra->generate_nr_prach != GENERATE_IDLE) {
return ra->generate_nr_prach; return ra->generate_nr_prach;
} else {
return ra->ra_state;
}
} }
void nr_get_RA_window(NR_UE_MAC_INST_t *mac){ void nr_get_RA_window(NR_UE_MAC_INST_t *mac){
......
...@@ -374,7 +374,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id, ...@@ -374,7 +374,7 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
else else
ssb_sc_offset_norm = ssb_subcarrier_offset; ssb_sc_offset_norm = ssb_subcarrier_offset;
if (mac->common_configuration_complete == 0) if (mac->first_sync_frame == -1)
nr_ue_sib1_scheduler(module_id, nr_ue_sib1_scheduler(module_id,
cc_id, cc_id,
ssb_start_symbol, ssb_start_symbol,
...@@ -394,6 +394,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id, ...@@ -394,6 +394,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
mac->dl_config_request.sfn = frame; mac->dl_config_request.sfn = frame;
mac->dl_config_request.slot = ssb_start_symbol/14; mac->dl_config_request.slot = ssb_start_symbol/14;
if (mac->first_sync_frame == -1)
mac->first_sync_frame = frame;
return 0; return 0;
} }
...@@ -1744,6 +1746,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, ...@@ -1744,6 +1746,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
} }
pucch_pdu->pucch_tx_power = get_pucch_tx_power_ue(mac, pucch_pdu->pucch_tx_power = get_pucch_tx_power_ue(mac,
scs,
pucch_Config, pucch_Config,
pucch, pucch,
pucch_pdu->format_type, pucch_pdu->format_type,
...@@ -1793,6 +1796,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, ...@@ -1793,6 +1796,7 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
int scs,
NR_PUCCH_Config_t *pucch_Config, NR_PUCCH_Config_t *pucch_Config,
PUCCH_sched_t *pucch, PUCCH_sched_t *pucch,
uint8_t format_type, uint8_t format_type,
...@@ -1899,10 +1903,13 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, ...@@ -1899,10 +1903,13 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac,
return (PUCCH_POWER_DEFAULT); return (PUCCH_POWER_DEFAULT);
} }
int16_t pucch_power = P_O_PUCCH + delta_F_PUCCH + DELTA_TF + G_b_f_c; int16_t pathloss = compute_nr_SSB_PL(mac, mac->phy_measurements.ssb_rsrp_dBm);
int M_pucch_component = (10 * log10((double)(pow(2,scs) * nb_of_prbs)));
int16_t pucch_power = P_O_PUCCH + M_pucch_component + pathloss + delta_F_PUCCH + DELTA_TF + G_b_f_c;
NR_TST_PHY_PRINTF("PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n", NR_TST_PHY_PRINTF("PUCCH ( Tx power : %d dBm ) ( 10Log(...) : %d ) ( from Path Loss : %d ) ( delta_F_PUCCH : %d ) ( DELTA_TF : %d ) ( G_b_f_c : %d ) \n",
pucch_power, contributor, PL, delta_F_PUCCH, DELTA_TF, G_b_f_c); pucch_power, M_pucch_component, pathloss, delta_F_PUCCH, DELTA_TF, G_b_f_c);
return (pucch_power); return (pucch_power);
} }
...@@ -2635,7 +2642,7 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac, ...@@ -2635,7 +2642,7 @@ uint8_t get_ssb_rsrp_payload(NR_UE_MAC_INST_t *mac,
} }
} }
AssertFatal(*SSB_resource.list.array[ssb_rsrp[0][0]] == mac->mib_ssb, "Couldn't find corresponding SSB in csi_SSB_ResourceList\n"); AssertFatal(*SSB_resource.list.array[ssb_rsrp[0][0]] == mac->mib_ssb, "Couldn't find corresponding SSB in csi_SSB_ResourceList\n");
ssb_rsrp[1][0] = mac->ssb_rsrp_dBm; ssb_rsrp[1][0] = mac->phy_measurements.ssb_rsrp_dBm;
uint8_t ssbi; uint8_t ssbi;
...@@ -4223,5 +4230,32 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t ...@@ -4223,5 +4230,32 @@ int nr_ue_process_rar(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t
} }
return ret; return ret;
}
// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16
// Assumptions:
// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE
// Measurement units:
// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm)
int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm)
{
long referenceSignalPower;
//TODO improve PL measurements. Probably not correct as it is.
if (mac->scc)
referenceSignalPower = mac->scc->ss_PBCH_BlockPower;
else
referenceSignalPower = mac->scc_SIB->ss_PBCH_BlockPower;
int16_t pathloss = (int16_t)(referenceSignalPower - ssb_rsrp_dBm);
LOG_D(NR_MAC, "pathloss %d dB, referenceSignalPower %ld dBm/RE (%f mW), RSRP %d dBm (%f mW)\n",
pathloss,
referenceSignalPower,
pow(10, referenceSignalPower/10),
ssb_rsrp_dBm,
pow(10, ssb_rsrp_dBm/10));
return pathloss;
} }
...@@ -2699,11 +2699,14 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s ...@@ -2699,11 +2699,14 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
(int)slotP, (int)slotP,
&prach_occasion_info_p); &prach_occasion_info_p);
if (is_nr_prach_slot && ra->ra_state == RA_UE_IDLE) { if (is_nr_prach_slot && ra->ra_state == GENERATE_PREAMBLE) {
AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n"); AssertFatal(NULL != prach_occasion_info_p,"PRACH Occasion Info not returned in a valid NR Prach Slot\n");
ra->generate_nr_prach = GENERATE_PREAMBLE; ra->generate_nr_prach = GENERATE_PREAMBLE;
init_RA(module_idP, &ra->prach_resources, setup, rach_ConfigGeneric, ra->rach_ConfigDedicated);
nr_get_RA_window(mac);
format = prach_occasion_info_p->format; format = prach_occasion_info_p->format;
format0 = format & 0xff; // single PRACH format format0 = format & 0xff; // single PRACH format
format1 = (format >> 8) & 0xff; // dual PRACH format format1 = (format >> 8) & 0xff; // dual PRACH format
...@@ -2733,7 +2736,8 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s ...@@ -2733,7 +2736,8 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
prach_config_pdu->restricted_set = prach_config->restricted_set_config; prach_config_pdu->restricted_set = prach_config->restricted_set_config;
prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1; prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[prach_occasion_info_p->fdm].k1;
LOG_D(NR_MAC,"Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n", frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra); LOG_D(NR_MAC,"PRACH scheduler: Selected RO Frame %u, Slot %u, Symbol %u, Fdm %u\n",
frameP, prach_config_pdu->prach_slot, prach_config_pdu->prach_start_symbol, prach_config_pdu->num_ra);
// Search which SSB is mapped in the RO (among all the SSBs mapped to this RO) // Search which SSB is mapped in the RO (among all the SSBs mapped to this RO)
for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) { for (prach_config_pdu->ssb_nb_in_ro=0; prach_config_pdu->ssb_nb_in_ro<prach_occasion_info_p->nb_mapped_ssb; prach_config_pdu->ssb_nb_in_ro++) {
...@@ -2796,9 +2800,16 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s ...@@ -2796,9 +2800,16 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s
} }
} // if format1 } // if format1
nr_get_prach_resources(module_idP, 0, 0, &ra->prach_resources, prach_config_pdu, ra->rach_ConfigDedicated);
prach_config_pdu->ra_PreambleIndex = ra->ra_PreambleIndex;
prach_config_pdu->prach_tx_power = get_prach_tx_power(module_idP);
set_ra_rnti(mac, prach_config_pdu);
fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, NULL); fill_scheduled_response(&scheduled_response, NULL, ul_config, NULL, module_idP, 0 /*TBR fix*/, frameP, slotP, NULL);
if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL) if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
mac->if_module->scheduled_response(&scheduled_response); mac->if_module->scheduled_response(&scheduled_response);
nr_Msg1_transmitted(module_idP);
} // is_nr_prach_slot } // is_nr_prach_slot
} // if is_nr_UL_slot } // if is_nr_UL_slot
} }
......
...@@ -947,7 +947,7 @@ void nr_get_Msg3alloc(module_id_t module_id, ...@@ -947,7 +947,7 @@ void nr_get_Msg3alloc(module_id_t module_id,
tdd_beam_association[num_tdd_period] = ra->beam_id; tdd_beam_association[num_tdd_period] = ra->beam_id;
} }
LOG_D(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id); LOG_I(NR_MAC, "[RAPROC] Msg3 slot %d: current slot %u Msg3 frame %u k2 %u Msg3_tda_id %u\n", ra->Msg3_slot, current_slot, ra->Msg3_frame, k2,ra->Msg3_tda_id);
uint16_t *vrb_map_UL = uint16_t *vrb_map_UL =
&RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE]; &RC.nrmac[module_id]->common_channels[CC_id].vrb_map_UL[ra->Msg3_slot * MAX_BWP_SIZE];
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "common/utils/nr/nr_common.h" #include "common/utils/nr/nr_common.h"
#include "utils.h" #include "utils.h"
#include <openair2/UTIL/OPT/opt.h> #include <openair2/UTIL/OPT/opt.h>
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
//#define SRS_IND_DEBUG //#define SRS_IND_DEBUG
......
...@@ -1085,6 +1085,12 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t ...@@ -1085,6 +1085,12 @@ int handle_dci(module_id_t module_id, int cc_id, unsigned int gNB_index, frame_t
} }
void handle_ssb_meas(NR_UE_MAC_INST_t *mac, uint8_t ssb_index, int16_t rsrp_dbm)
{
mac->phy_measurements.ssb_index = ssb_index;
mac->phy_measurements.ssb_rsrp_dBm = rsrp_dbm;
}
// L2 Abstraction Layer // L2 Abstraction Layer
// Note: sdu should always be processed because data and timing advance updates are transmitted by the UE // Note: sdu should always be processed because data and timing advance updates are transmitted by the UE
int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){ int8_t handle_dlsch(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment, int pdu_id){
...@@ -1223,7 +1229,9 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ ...@@ -1223,7 +1229,9 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){ switch(dl_info->rx_ind->rx_indication_body[i].pdu_type){
case FAPI_NR_RX_PDU_TYPE_SSB: case FAPI_NR_RX_PDU_TYPE_SSB:
mac->ssb_rsrp_dBm = (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm; handle_ssb_meas(mac,
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.ssb_index,
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.rsrp_dBm);
ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data, ret_mask |= (handle_bcch_bch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->phy_data,
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits, (dl_info->rx_ind->rx_indication_body+i)->ssb_pdu.additional_bits,
......
...@@ -75,7 +75,6 @@ ...@@ -75,7 +75,6 @@
#include "NR_DLInformationTransfer.h" #include "NR_DLInformationTransfer.h"
#include "NR_RRCReestablishmentRequest.h" #include "NR_RRCReestablishmentRequest.h"
#include "NR_UE-CapabilityRequestFilterNR.h" #include "NR_UE-CapabilityRequestFilterNR.h"
#include "PHY/defs_nr_common.h"
#include "common/utils/nr/nr_common.h" #include "common/utils/nr/nr_common.h"
#if defined(NR_Rel16) #if defined(NR_Rel16)
#include "NR_SCS-SpecificCarrier.h" #include "NR_SCS-SpecificCarrier.h"
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac.h"
#include "LAYER2/RLC/rlc.h" #include "LAYER2/RLC/rlc.h"
#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1 - The physical layer imposes a limit to the maximum size a SIB can take. The maximum SIB1 or SI message size is 2976 bits.
extern UE_RRC_INST *UE_rrc_inst; extern UE_RRC_INST *UE_rrc_inst;
extern uint8_t DRB2LCHAN[8]; extern uint8_t DRB2LCHAN[8];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment