Merge branch 'develop' into ue-pdsch-pusch-parallel
This commit is contained in:
@@ -23,6 +23,7 @@ gNBs =
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts = 1;
|
||||
pusch_AntennaPorts = 1;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ gNBs =
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts = 1;
|
||||
pusch_AntennaPorts = 1;
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
@@ -185,7 +186,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -22,6 +22,7 @@ gNBs =
|
||||
|
||||
ssb_SubcarrierOffset = 31; //0;
|
||||
pdsch_AntennaPorts = 1;
|
||||
pusch_AntennaPorts = 1;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
|
||||
@@ -250,7 +251,7 @@ L1s = (
|
||||
{
|
||||
num_cc = 1;
|
||||
tr_n_preference = "local_mac";
|
||||
pusch_proc_threads = 8;
|
||||
pusch_proc_threads = 6;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1973,6 +1973,7 @@ set(NR_PDCP_SRC
|
||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_sdu.c
|
||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_timer_thread.c
|
||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
|
||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
|
||||
${OPENAIR2_DIR}/LAYER2/nr_pdcp/asn1_utils.c
|
||||
)
|
||||
|
||||
@@ -3323,7 +3324,7 @@ add_executable(nr_dlsim
|
||||
)
|
||||
target_link_libraries(nr_dlsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl
|
||||
)
|
||||
target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
|
||||
|
||||
@@ -3342,7 +3343,7 @@ add_executable(nr_prachsim
|
||||
${SHLIB_LOADER_SOURCES})
|
||||
target_link_libraries(nr_prachsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl)
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl)
|
||||
|
||||
add_executable(nr_ulschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
|
||||
@@ -3375,7 +3376,7 @@ add_executable(nr_ulsim
|
||||
)
|
||||
target_link_libraries(nr_ulsim
|
||||
-Wl,--start-group UTIL SIMU_COMMON SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_NR_UE SCHED_NR_LIB SCHED_NR_UE_LIB MAC_NR MAC_UE_NR MAC_NR_COMMON RRC_LIB NR_RRC_LIB CONFIG_LIB L2_LTE_NR L2_NR HASHTABLE X2AP_ENB X2AP_LIB SECU_CN NGAP_GNB -Wl,--end-group
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl
|
||||
m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} ${OPENSSL_LIBRARIES} dl
|
||||
)
|
||||
target_compile_definitions(nr_ulsim PUBLIC -DPHYSICAL_SIMULATOR)
|
||||
|
||||
|
||||
@@ -1330,7 +1330,8 @@
|
||||
(Test3: 30kHz SCS, 273 PRBs, Prach format A2),
|
||||
(Test4: 30kHz SCS, 106 PRBs, Prach format 0),
|
||||
(Test5: 120kHz SCS, 32 PRBs, Prach format A2),
|
||||
(Test6: 120kHz SCS, 66 PRBs, Prach format A2)</desc>
|
||||
(Test6: 120kHz SCS, 66 PRBs, Prach format A2),
|
||||
(Test7: 120kHz SCS, 66 PRBs, High Speed Enabled)</desc>
|
||||
<pre_compile_prog></pre_compile_prog>
|
||||
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
|
||||
<compile_prog_args> --phy_simulators -c </compile_prog_args>
|
||||
@@ -1342,8 +1343,9 @@
|
||||
-a -s -30 -n 100 -p 63 -R 273
|
||||
-a -s -30 -n 100 -p 63 -R 106 -c 4
|
||||
-a -s -30 -n 100 -p 32 -R 32 -m 3 -c52
|
||||
-a -s -30 -n 100 -p 32 -R 66 -m 3 -c52</main_exec_args>
|
||||
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6</tags>
|
||||
-a -s -30 -n 100 -p 32 -R 66 -m 3 -c52
|
||||
-a -s -30 -n 100 -R 66 -m 3 -c52 -H</main_exec_args>
|
||||
<tags>nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 nr_prachsim.test4 nr_prachsim.test5 nr_prachsim.test6 nr_prachsim.test7</tags>
|
||||
<search_expr_true>PRACH test OK</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
|
||||
@@ -470,15 +470,14 @@ void init_gNB(int single_thread_flag,int wait_for_sync) {
|
||||
PHY_VARS_gNB *gNB;
|
||||
|
||||
if (RC.gNB == NULL) {
|
||||
RC.gNB = (PHY_VARS_gNB **) malloc((1+RC.nb_nr_L1_inst)*sizeof(PHY_VARS_gNB *));
|
||||
RC.gNB = (PHY_VARS_gNB **) calloc(1+RC.nb_nr_L1_inst, sizeof(PHY_VARS_gNB *));
|
||||
LOG_I(PHY,"gNB L1 structure RC.gNB allocated @ %p\n",RC.gNB);
|
||||
}
|
||||
|
||||
for (inst=0; inst<RC.nb_nr_L1_inst; inst++) {
|
||||
|
||||
if (RC.gNB[inst] == NULL) {
|
||||
RC.gNB[inst] = (PHY_VARS_gNB *) malloc(sizeof(PHY_VARS_gNB));
|
||||
memset((void*)RC.gNB[inst],0,sizeof(PHY_VARS_gNB));
|
||||
RC.gNB[inst] = (PHY_VARS_gNB *) calloc(1, sizeof(PHY_VARS_gNB));
|
||||
LOG_I(PHY,"[nr-gnb.c] gNB structure RC.gNB[%d] allocated @ %p\n",inst,RC.gNB[inst]);
|
||||
}
|
||||
gNB = RC.gNB[inst];
|
||||
|
||||
@@ -972,7 +972,7 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
|
||||
int ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
|
||||
uint8_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
|
||||
uint8_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ typedef struct
|
||||
//table 3-23
|
||||
typedef struct
|
||||
{
|
||||
nfapi_uint32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
|
||||
nfapi_int32_tlv_t ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
|
||||
nfapi_uint8_tlv_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
|
||||
nfapi_uint8_tlv_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
|
||||
|
||||
|
||||
@@ -27,12 +27,9 @@
|
||||
uint32_t nr_subcarrier_spacing[MAX_NUM_SUBCARRIER_SPACING] = {15e3, 30e3, 60e3, 120e3, 240e3};
|
||||
uint16_t nr_slots_per_subframe[MAX_NUM_SUBCARRIER_SPACING] = {1, 2, 4, 8, 16};
|
||||
|
||||
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
|
||||
{
|
||||
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb) {
|
||||
|
||||
int mu = fp->numerology_index;
|
||||
uint8_t half_frame_index = fp->half_frame_bit;
|
||||
uint8_t i_ssb = fp->ssb_index;
|
||||
int symbol = 0;
|
||||
uint8_t n, n_temp;
|
||||
nr_ssb_type_e type = fp->ssb_type;
|
||||
@@ -69,9 +66,6 @@ int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp)
|
||||
AssertFatal(0==1, "Invalid numerology index %d for the synchronization block\n", mu);
|
||||
}
|
||||
|
||||
if (half_frame_index)
|
||||
symbol += (5 * fp->symbols_per_slot * fp->slots_per_subframe);
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,7 +392,7 @@ void phy_config_update_sib13_request(PHY_Config_t *phy_config);
|
||||
|
||||
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
|
||||
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
|
||||
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp);
|
||||
int nr_get_ssb_start_symbol(NR_DL_FRAME_PARMS *fp,uint8_t i_ssb);
|
||||
int nr_init_frame_parms(nfapi_nr_config_request_scf_t *config, NR_DL_FRAME_PARMS *frame_parms);
|
||||
int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *frame_parms, fapi_nr_config_request_t *config, uint16_t nr_band);
|
||||
int init_nr_ue_signal(PHY_VARS_NR_UE *ue,int nb_connected_eNB,uint8_t abstraction_flag);
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
*/
|
||||
|
||||
/*! \file PHY/NR_ESTIMATION/nr_measurements_gNB.c
|
||||
* \brief TA estimation for TA updates
|
||||
* \author Ahmed Hussein
|
||||
* \brief gNB measurement routines
|
||||
* \author Ahmed Hussein, G. Casati, K. Saaifan
|
||||
* \date 2019
|
||||
* \version 0.1
|
||||
* \company Fraunhofer IIS
|
||||
* \email: ahmed.hussein@iis.fraunhofer.de
|
||||
* \email: ahmed.hussein@iis.fraunhofer.de, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
@@ -35,6 +35,8 @@
|
||||
#include "PHY/phy_extern.h"
|
||||
#include "nr_ul_estimation.h"
|
||||
|
||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
int nr_est_timing_advance_pusch(PHY_VARS_gNB* gNB, int UE_id)
|
||||
{
|
||||
int i, aa, max_pos = 0, max_val = 0;
|
||||
@@ -73,14 +75,17 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB) {
|
||||
NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms;
|
||||
NR_gNB_COMMON *common_vars = &gNB->common_vars;
|
||||
PHY_MEASUREMENTS_gNB *measurements = &gNB->measurements;
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
double rx_gain = openair0_cfg[0].rx_gain[0];
|
||||
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
|
||||
uint32_t *rb_mask = gNB->rb_mask_ul;
|
||||
int symbol = gNB->ulmask_symb;
|
||||
int rb, offset, nb_rb;
|
||||
uint32_t n0_power_tot, n0_subband_power_temp=0;
|
||||
uint32_t n0_subband_power_temp = 0;
|
||||
int32_t *ul_ch;
|
||||
|
||||
if (symbol>-1) {
|
||||
n0_power_tot = 0;
|
||||
measurements->n0_power_tot = 0;
|
||||
for (int aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
|
||||
nb_rb = 0;
|
||||
for (rb=0; rb<frame_parms->N_RB_UL; rb++) {
|
||||
@@ -93,11 +98,76 @@ void gNB_I0_measurements(PHY_VARS_gNB *gNB) {
|
||||
n0_subband_power_temp += signal_energy_nodc(ul_ch,12);
|
||||
}
|
||||
}
|
||||
measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb;
|
||||
measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]);
|
||||
n0_power_tot += measurements->n0_power[aarx];
|
||||
|
||||
if (nb_rb != 0) {
|
||||
measurements->n0_power[aarx] = n0_subband_power_temp/nb_rb;
|
||||
measurements->n0_power_dB[aarx] = dB_fixed(measurements->n0_power[aarx]);
|
||||
measurements->n0_power_tot += measurements->n0_power[aarx];
|
||||
}
|
||||
|
||||
}
|
||||
measurements->n0_power_tot_dB = dB_fixed(n0_power_tot);
|
||||
|
||||
measurements->n0_power_tot_dB = dB_fixed(measurements->n0_power_tot);
|
||||
measurements->n0_power_tot_dBm = measurements->n0_power_tot_dB + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
|
||||
|
||||
LOG_D(PHY, "In %s: tot n0 power %d dBm for %d RBs (tot N0 power = %d)\n", __FUNCTION__, measurements->n0_power_tot_dBm, nb_rb, measurements->n0_power_tot);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Scope: This function computes the UL SNR from the UL channel estimates
|
||||
//
|
||||
// Todo:
|
||||
// - averaging IIR filter for RX power and noise
|
||||
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol){
|
||||
|
||||
int rx_power_tot[NUMBER_OF_NR_ULSCH_MAX];
|
||||
int rx_power[NUMBER_OF_NR_ULSCH_MAX][NB_ANTENNAS_RX];
|
||||
unsigned short rx_power_avg_dB[NUMBER_OF_NR_ULSCH_MAX];
|
||||
unsigned short rx_power_tot_dB[NUMBER_OF_NR_ULSCH_MAX];
|
||||
|
||||
double rx_gain = openair0_cfg[0].rx_gain[0];
|
||||
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
|
||||
PHY_MEASUREMENTS_gNB *meas = &gNB->measurements;
|
||||
NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
|
||||
int ch_offset = fp->ofdm_symbol_size * symbol;
|
||||
int N_RB_UL = gNB->ulsch[ulsch_id][0]->harq_processes[harq_pid]->ulsch_pdu.rb_size;
|
||||
|
||||
rx_power_tot[ulsch_id] = 0;
|
||||
|
||||
for (int aarx = 0; aarx < fp->nb_antennas_rx; aarx++){
|
||||
|
||||
rx_power[ulsch_id][aarx] = 0;
|
||||
|
||||
for (int aatx = 0; aatx < fp->nb_antennas_tx; aatx++){
|
||||
|
||||
meas->rx_spatial_power[ulsch_id][aatx][aarx] = (signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][ch_offset], N_RB_UL * NR_NB_SC_PER_RB));
|
||||
|
||||
if (meas->rx_spatial_power[ulsch_id][aatx][aarx] < 0) {
|
||||
meas->rx_spatial_power[ulsch_id][aatx][aarx] = 0;
|
||||
}
|
||||
|
||||
meas->rx_spatial_power_dB[ulsch_id][aatx][aarx] = (unsigned short) dB_fixed(meas->rx_spatial_power[ulsch_id][aatx][aarx]);
|
||||
rx_power[ulsch_id][aarx] += meas->rx_spatial_power[ulsch_id][aatx][aarx];
|
||||
|
||||
}
|
||||
|
||||
rx_power_tot[ulsch_id] += rx_power[ulsch_id][aarx];
|
||||
|
||||
}
|
||||
|
||||
rx_power_tot_dB[ulsch_id] = (unsigned short) dB_fixed(rx_power_tot[ulsch_id]);
|
||||
rx_power_avg_dB[ulsch_id] = rx_power_tot_dB[ulsch_id];
|
||||
|
||||
meas->wideband_cqi_tot[ulsch_id] = dB_fixed2(rx_power_tot[ulsch_id], meas->n0_power_tot);
|
||||
meas->rx_rssi_dBm[ulsch_id] = rx_power_avg_dB[ulsch_id] + 30 - 10 * log10(pow(2, 30)) - (rx_gain - rx_gain_offset) - dB_fixed(fp->ofdm_symbol_size);
|
||||
|
||||
LOG_D(PHY, "[ULSCH %d] RSSI %d dBm/RE, RSSI (digital) %d dB (N_RB_UL %d), WBand CQI tot %d dB, N0 Power tot %d\n",
|
||||
ulsch_id,
|
||||
meas->rx_rssi_dBm[ulsch_id],
|
||||
rx_power_avg_dB[ulsch_id],
|
||||
N_RB_UL,
|
||||
meas->wideband_cqi_tot[ulsch_id],
|
||||
meas->n0_power_tot);
|
||||
|
||||
}
|
||||
|
||||
@@ -49,8 +49,9 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB,
|
||||
|
||||
void gNB_I0_measurements(PHY_VARS_gNB *gNB);
|
||||
|
||||
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
|
||||
void nr_gnb_measurements(PHY_VARS_gNB *gNB, uint8_t ulsch_id, unsigned char harq_pid, unsigned char symbol);
|
||||
|
||||
int nr_est_timing_advance_pusch(PHY_VARS_gNB* phy_vars_gNB, int UE_id);
|
||||
|
||||
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
|
||||
NR_DL_FRAME_PARMS *frame_parms,
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include <LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
|
||||
|
||||
#include "nr_dci.h"
|
||||
#include "nr_dlsch.h"
|
||||
#include "nr_sch_dmrs.h"
|
||||
@@ -85,10 +85,7 @@ void nr_generate_dci(PHY_VARS_gNB *gNB,
|
||||
// compute rb_offset and n_prb based on frequency allocation
|
||||
nr_fill_cce_list(gNB,0,pdcch_pdu_rel15);
|
||||
get_coreset_rballoc(pdcch_pdu_rel15->FreqDomainResource,&n_rb,&rb_offset);
|
||||
cset_start_sc = frame_parms.first_carrier_offset + rb_offset*NR_NB_SC_PER_RB;
|
||||
if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) {
|
||||
cset_start_sc = cset_start_sc + RC.nrmac[gNB->Mod_id]->type0_PDCCH_CSS_config.cset_start_rb*NR_NB_SC_PER_RB;
|
||||
}
|
||||
cset_start_sc = frame_parms.first_carrier_offset + (pdcch_pdu_rel15->BWPStart + rb_offset) * NR_NB_SC_PER_RB;
|
||||
|
||||
for (int d=0;d<pdcch_pdu_rel15->numDlDci;d++) {
|
||||
/*The coreset is initialised
|
||||
|
||||
@@ -241,7 +241,7 @@ int nr_generate_pbch(NR_gNB_PBCH *pbch,
|
||||
///Payload generation
|
||||
memset((void *)pbch, 0, sizeof(NR_gNB_PBCH));
|
||||
pbch->pbch_a=0;
|
||||
uint8_t ssb_index = frame_parms->ssb_index;
|
||||
uint8_t ssb_index = ssb_pdu->ssb_pdu_rel15.SsbBlockIndex;
|
||||
uint8_t *pbch_pdu = (uint8_t*)&ssb_pdu->ssb_pdu_rel15.bchPayload;
|
||||
uint8_t Lmax = frame_parms->Lmax;
|
||||
for (int i=0; i<NR_PBCH_PDU_BITS; i++)
|
||||
|
||||
@@ -780,7 +780,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
}
|
||||
} else { // This is the high-speed case
|
||||
new_dft = 0;
|
||||
|
||||
nr_fill_du(N_ZC,prach_root_sequence_map);
|
||||
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
|
||||
// preamble index and find the corresponding cyclic shift
|
||||
// Check if all shifts for that root have been processed
|
||||
@@ -788,7 +788,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB,
|
||||
not_found = 1;
|
||||
new_dft = 1;
|
||||
preamble_index0 -= numshift;
|
||||
(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
|
||||
//(preamble_offset==0 && numshift==0) ? (preamble_offset) : (preamble_offset++);
|
||||
|
||||
while (not_found == 1) {
|
||||
// current root depending on rootSequenceIndex
|
||||
|
||||
@@ -73,6 +73,8 @@ void compute_nr_prach_seq(uint8_t short_sequence,
|
||||
uint8_t rootSequenceIndex,
|
||||
uint32_t X_u[64][839]);
|
||||
|
||||
void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map);
|
||||
|
||||
void init_nr_prach_tables(int N_ZC);
|
||||
|
||||
/**@}*/
|
||||
|
||||
@@ -1217,6 +1217,8 @@ int nr_rx_pusch(PHY_VARS_gNB *gNB,
|
||||
bwp_start_subcarrier,
|
||||
rel15_ul);
|
||||
|
||||
nr_gnb_measurements(gNB, ulsch_id, harq_pid, symbol);
|
||||
|
||||
for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) {
|
||||
gNB->pusch_vars[ulsch_id]->ulsch_power[aarx] = signal_energy_nodc(&gNB->pusch_vars[ulsch_id]->ul_ch_estimates[aarx][symbol*frame_parms->ofdm_symbol_size],
|
||||
rel15_ul->rb_size*12);
|
||||
|
||||
@@ -21,16 +21,17 @@
|
||||
|
||||
/*! \file nr_ue_measurements.c
|
||||
* \brief UE measurements routines
|
||||
* \author R. Knopp, G. Casati
|
||||
* \author R. Knopp, G. Casati, K. Saaifan
|
||||
* \date 2020
|
||||
* \version 0.1
|
||||
* \company Eurecom, Fraunhofer IIS
|
||||
* \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de
|
||||
* \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de, khodr.saaifan@iis.fraunhofer.de
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/nr-softmodem-common.h"
|
||||
#include "PHY/defs_nr_UE.h"
|
||||
#include "PHY/phy_extern_nr_ue.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
@@ -45,7 +46,7 @@
|
||||
//#define DEBUG_MEAS_UE
|
||||
//#define DEBUG_RANK_EST
|
||||
|
||||
// Returns the pathloss in dBm for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission
|
||||
// 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
|
||||
@@ -59,18 +60,17 @@ int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){
|
||||
if (get_softmodem_params()->do_ra){
|
||||
|
||||
long referenceSignalPower = ue->nrUE_config.ssb_config.ss_pbch_power;
|
||||
double rsrp_dBm = 10*log10(ue->measurements.rsrp[gNB_index]) + 30 - ue->rx_total_gain_dB;
|
||||
|
||||
pathloss = (int16_t)(10*log10(pow(10, (double)(referenceSignalPower)/10) - pow(10, (double)(rsrp_dBm)/10)));
|
||||
pathloss = (int16_t)(referenceSignalPower - ue->measurements.rsrp_dBm[gNB_index]);
|
||||
|
||||
LOG_D(MAC, "In %s: pathloss %d dBm, UE RX total gain %d dB, referenceSignalPower %ld dBm (%f mW), RSRP %f dBm (%f mW)\n",
|
||||
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),
|
||||
rsrp_dBm,
|
||||
pow(10, rsrp_dBm/10));
|
||||
ue->measurements.rsrp_dBm[gNB_index],
|
||||
pow(10, ue->measurements.rsrp_dBm[gNB_index]/10));
|
||||
|
||||
} else {
|
||||
|
||||
@@ -178,9 +178,9 @@ void nr_ue_measurements(PHY_VARS_NR_UE *ue,
|
||||
ue->measurements.rx_power_avg_dB[gNB_id] = dB_fixed( ue->measurements.rx_power_avg[gNB_id]);
|
||||
ue->measurements.wideband_cqi_tot[gNB_id] = dB_fixed2(ue->measurements.rx_power_tot[gNB_id], ue->measurements.n0_power_tot);
|
||||
ue->measurements.wideband_cqi_avg[gNB_id] = dB_fixed2(ue->measurements.rx_power_avg[gNB_id], ue->measurements.n0_power_avg);
|
||||
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] - ue->rx_total_gain_dB;
|
||||
ue->measurements.rx_rssi_dBm[gNB_id] = ue->measurements.rx_power_avg_dB[gNB_id] + 30 - 10*log10(pow(2, 30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
|
||||
LOG_D(PHY, "[gNB %d] Slot %d, RSSI %d dBm, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d\n",
|
||||
LOG_I(PHY, "[gNB %d] Slot %d, RSSI %d dBm/RE, RSSI (digital) %d dB, WBandCQI %d dB, rxPwrAvg %d, n0PwrAvg %d \n",
|
||||
gNB_id,
|
||||
slot,
|
||||
ue->measurements.rx_rssi_dBm[gNB_id],
|
||||
@@ -258,15 +258,20 @@ void nr_ue_rsrp_measurements(PHY_VARS_NR_UE *ue,
|
||||
|
||||
ue->measurements.rsrp_filtered[gNB_id] = ue->measurements.rsrp[gNB_id];
|
||||
|
||||
LOG_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %3.1f dBm/RE (%d W)\n",
|
||||
ue->measurements.rsrp_dBm[gNB_id] = 10*log10(ue->measurements.rsrp[gNB_id]) + 30 - 10*log10(pow(2,30)) - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - dB_fixed(ue->frame_parms.ofdm_symbol_size);
|
||||
|
||||
LOG_D(PHY, "In %s: [UE %d] slot %d SS-RSRP: %d dBm/RE (%d)\n",
|
||||
__FUNCTION__,
|
||||
ue->Mod_id,
|
||||
slot,
|
||||
10*log10(ue->measurements.rsrp[gNB_id]) + 30 - ue->rx_total_gain_dB,
|
||||
ue->measurements.rsrp_dBm[gNB_id],
|
||||
ue->measurements.rsrp[gNB_id]);
|
||||
|
||||
}
|
||||
|
||||
// This function computes the received noise power
|
||||
// Measurement units:
|
||||
// - psd_awgn (AWGN power spectral density): dBm/Hz
|
||||
void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
|
||||
UE_nr_rxtx_proc_t *proc,
|
||||
uint8_t slot){
|
||||
@@ -279,6 +284,9 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
|
||||
uint8_t k_length = 8;
|
||||
uint8_t l_sss = ue->symbol_offset + 2;
|
||||
unsigned int ssb_offset = ue->frame_parms.first_carrier_offset + ue->frame_parms.ssb_start_subcarrier;
|
||||
double rx_gain = openair0_cfg[0].rx_gain[0];
|
||||
double rx_gain_offset = openair0_cfg[0].rx_gain_offset[0];
|
||||
|
||||
ue->measurements.n0_power_tot = 0;
|
||||
|
||||
LOG_D(PHY, "In %s doing measurements for ssb_offset %d l_sss %d \n", __FUNCTION__, ssb_offset, l_sss);
|
||||
@@ -322,10 +330,17 @@ void nr_ue_rrc_measurements(PHY_VARS_NR_UE *ue,
|
||||
ue->measurements.n0_power_tot_dB = (unsigned short) dB_fixed(ue->measurements.n0_power_tot/aarx);
|
||||
|
||||
#ifdef DEBUG_MEAS_RRC
|
||||
int nf_usrp = ue->measurements.n0_power_tot_dB + 30 - ((int)openair0_cfg[0].rx_gain[0] - (int)openair0_cfg[0].rx_gain_offset[0]) - 90 - (-174 + dB_fixed(30000/*scs*/) + dB_fixed(ue->frame_parms.ofdm_symbol_size));
|
||||
LOG_D(PHY, "In %s slot %d NF USRP %d dBm\n", __FUNCTION__, nf_usrp);
|
||||
const int psd_awgn = -174;
|
||||
const int scs = 15000 * (1 << ue->frame_parms.numerology_index);
|
||||
const int nf_usrp = ue->measurements.n0_power_tot_dB + 3 + 30 - ((int)rx_gain - (int)rx_gain_offset) - 10 * log10(pow(2, 30)) - (psd_awgn + dB_fixed(scs) + dB_fixed(ue->frame_parms.ofdm_symbol_size));
|
||||
LOG_D(PHY, "In [%s][slot:%d] NF USRP %d dB\n", __FUNCTION__, slot, nf_usrp);
|
||||
#endif
|
||||
|
||||
LOG_D(PHY, "In %s slot %d Noise Level %d ue->measurements.n0_power_tot_dB %d \n", __FUNCTION__, slot, ue->measurements.n0_power_tot, ue->measurements.n0_power_tot_dB);
|
||||
LOG_D(PHY, "In [%s][slot:%d] Noise Level %d (digital level %d dB, noise power spectral density %f dBm/RE)\n",
|
||||
__FUNCTION__,
|
||||
slot,
|
||||
ue->measurements.n0_power_tot,
|
||||
ue->measurements.n0_power_tot_dB,
|
||||
ue->measurements.n0_power_tot_dB + 30 - 10*log10(pow(2, 30)) - dB_fixed(ue->frame_parms.ofdm_symbol_size) - ((int)rx_gain - (int)rx_gain_offset));
|
||||
|
||||
}
|
||||
|
||||
@@ -589,7 +589,9 @@ int nr_rx_pbch( PHY_VARS_NR_UE *ue,
|
||||
frame_parms->ssb_index += (((nr_ue_pbch_vars->xtra_byte>>(7-i))&0x01)<<(3+i));
|
||||
}
|
||||
|
||||
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
|
||||
ue->symbol_offset = nr_get_ssb_start_symbol(frame_parms,i_ssb);
|
||||
if (frame_parms->half_frame_bit)
|
||||
ue->symbol_offset += (frame_parms->slots_per_frame>>1)*frame_parms->symbols_per_slot;
|
||||
|
||||
uint8_t frame_number_4lsb = 0;
|
||||
for (int i=0; i<4; i++)
|
||||
|
||||
@@ -130,6 +130,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){
|
||||
#endif
|
||||
|
||||
not_found = 1;
|
||||
nr_fill_du(N_ZC,prach_root_sequence_map);
|
||||
preamble_index0 = preamble_index;
|
||||
// set preamble_offset to initial rootSequenceIndex and look if we need more root sequences for this
|
||||
// preamble index and find the corresponding cyclic shift
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -3103,10 +3103,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
|
||||
|
||||
dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
|
||||
dft64((int16_t*)(xtmp+32),(int16_t*)(ytmp+16),1);
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft128a.m","dfta",ytmp,64,1,1);
|
||||
LOG_M("dft128b.m","dftb",ytmp+16,64,1,1);
|
||||
}
|
||||
#endif
|
||||
for (i=0; i<16; i++) {
|
||||
bfly2_16(ytmpp,ytmpp+16,
|
||||
y128p,y128p+16,
|
||||
@@ -3155,10 +3157,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
|
||||
|
||||
|
||||
}
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft128out.m","dft128",y,128,1,1);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
|
||||
@@ -3183,18 +3187,20 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
|
||||
transpose4_ooff_simd256(x256+10,xtmp+5,8);
|
||||
transpose4_ooff_simd256(x256+12,xtmp+6,8);
|
||||
transpose4_ooff_simd256(x256+14,xtmp+7,8);
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft128ina_256.m","dftina",xtmp,64,1,1);
|
||||
LOG_M("dft128inb_256.m","dftinb",xtmp+8,64,1,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
dft64((int16_t*)(xtmp),(int16_t*)ytmp,1);
|
||||
dft64((int16_t*)(xtmp+8),(int16_t*)(ytmp+8),1);
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft128outa_256.m","dftouta",ytmp,64,1,1);
|
||||
LOG_M("dft128outb_256.m","dftoutb",ytmp+8,64,1,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
for (i=0; i<8; i++) {
|
||||
bfly2_16_256(ytmpp,ytmpp+8,
|
||||
y256p,y256p+8,
|
||||
@@ -3226,10 +3232,12 @@ void dft128(int16_t *x,int16_t *y,unsigned char scale)
|
||||
y256[15] = mulhi_int16_simd256(y256[15],ONE_OVER_SQRT2_Q15_256);
|
||||
|
||||
}
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft128.m","dft",y256,128,1,1);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6031,11 +6039,13 @@ void dft1536(int16_t *input, int16_t *output, unsigned char scale)
|
||||
tmpo[1][i] = tmpo[1][i<<1];
|
||||
tmpo[2][i] = tmpo[2][i<<1];
|
||||
}*/
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft1536out0.m","o0",tmpo[0],2048,1,1);
|
||||
LOG_M("dft1536out1.m","o1",tmpo[1],2048,1,1);
|
||||
LOG_M("dft1536out2.m","o2",tmpo[2],2048,1,1);
|
||||
}
|
||||
#endif
|
||||
for (i=0,i2=0; i<1024; i+=8,i2+=4) {
|
||||
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+1024+i),(simd_q15_t*)(output+2048+i),
|
||||
@@ -6193,14 +6203,14 @@ void idft6144(int16_t *input, int16_t *output,unsigned char scale)
|
||||
idft2048((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
|
||||
idft2048((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
|
||||
idft2048((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
|
||||
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("idft6144in.m","in",input,6144,1,1);
|
||||
LOG_M("idft6144out0.m","o0",tmpo[0],2048,1,1);
|
||||
LOG_M("idft6144out1.m","o1",tmpo[1],2048,1,1);
|
||||
LOG_M("idft6144out2.m","o2",tmpo[2],2048,1,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
for (i=0,i2=0; i<4096; i+=8,i2+=4) {
|
||||
ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
|
||||
@@ -6260,11 +6270,13 @@ void dft6144(int16_t *input, int16_t *output,unsigned char scale)
|
||||
tmpo[1][i] = tmpo[1][i<<1];
|
||||
tmpo[2][i] = tmpo[2][i<<1];
|
||||
}*/
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("ft6144out0.m","o0",tmpo[0],2048,1,1);
|
||||
LOG_M("ft6144out1.m","o1",tmpo[1],2048,1,1);
|
||||
LOG_M("ft6144out2.m","o2",tmpo[2],2048,1,1);
|
||||
}
|
||||
#endif
|
||||
for (i=0,i2=0; i<4096; i+=8,i2+=4) {
|
||||
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+4096+i),(simd_q15_t*)(output+8192+i),
|
||||
@@ -6336,11 +6348,13 @@ void dft12288(int16_t *input, int16_t *output,unsigned char scale)
|
||||
tmpo[1][i] = tmpo[1][i<<1];
|
||||
tmpo[2][i] = tmpo[2][i<<1];
|
||||
}*/
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft12288out0.m","o0",tmpo[0],4096,1,1);
|
||||
LOG_M("dft12288out1.m","o1",tmpo[1],4096,1,1);
|
||||
LOG_M("dft12288out2.m","o2",tmpo[2],4096,1,1);
|
||||
}
|
||||
#endif
|
||||
for (i=0,i2=0; i<8192; i+=8,i2+=4) {
|
||||
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
|
||||
@@ -6392,14 +6406,14 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale)
|
||||
idft4096((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),scale);
|
||||
idft4096((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),scale);
|
||||
idft4096((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),scale);
|
||||
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("idft12288in.m","in",input,12288,1,1);
|
||||
LOG_M("idft12288out0.m","o0",tmpo[0],4096,1,1);
|
||||
LOG_M("idft12288out1.m","o1",tmpo[1],4096,1,1);
|
||||
LOG_M("idft12288out2.m","o2",tmpo[2],4096,1,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
for (i=0,i2=0; i<8192; i+=8,i2+=4) {
|
||||
ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+8192+i),(simd_q15_t*)(output+16384+i),
|
||||
@@ -6429,9 +6443,11 @@ void idft12288(int16_t *input, int16_t *output,unsigned char scale)
|
||||
}
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("idft12288out.m","out",output,6144,1,1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int16_t twa18432[12288] __attribute__((aligned(32)));
|
||||
@@ -6560,11 +6576,13 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale)
|
||||
tmpo[1][i] = tmpo[1][i<<1];
|
||||
tmpo[2][i] = tmpo[2][i<<1];
|
||||
}*/
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft24576out0.m","o0",tmpo[0],8192,1,1);
|
||||
LOG_M("dft24576out1.m","o1",tmpo[1],8192,1,1);
|
||||
LOG_M("dft24576out2.m","o2",tmpo[2],8192,1,1);
|
||||
}
|
||||
#endif
|
||||
for (i=0,i2=0; i<16384; i+=8,i2+=4) {
|
||||
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
|
||||
@@ -6595,9 +6613,11 @@ void dft24576(int16_t *input, int16_t *output,unsigned char scale)
|
||||
}
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("out.m","out",output,24576,1,1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void idft24576(int16_t *input, int16_t *output,unsigned char scale)
|
||||
@@ -6617,14 +6637,14 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
|
||||
idft8192((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
|
||||
idft8192((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
|
||||
idft8192((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
|
||||
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("idft24576in.m","in",input,24576,1,1);
|
||||
LOG_M("idft24576out0.m","o0",tmpo[0],8192,1,1);
|
||||
LOG_M("idft24576out1.m","o1",tmpo[1],8192,1,1);
|
||||
LOG_M("idft24576out2.m","o2",tmpo[2],8192,1,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
for (i=0,i2=0; i<16384; i+=8,i2+=4) {
|
||||
ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+16384+i),(simd_q15_t*)(output+32768+i),
|
||||
@@ -6653,10 +6673,11 @@ void idft24576(int16_t *input, int16_t *output,unsigned char scale)
|
||||
}
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("idft24576out.m","out",output,24576,1,1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int16_t twa36864[24576] __attribute__((aligned(32)));
|
||||
@@ -6680,13 +6701,13 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
|
||||
dft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1);
|
||||
dft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1);
|
||||
dft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1);
|
||||
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("dft36864out0.m","o0",tmpo[0],12288,1,1);
|
||||
LOG_M("dft36864out1.m","o1",tmpo[1],12288,1,1);
|
||||
LOG_M("dft36864out2.m","o2",tmpo[2],12288,1,1);
|
||||
}
|
||||
|
||||
#endif
|
||||
for (i=0,i2=0; i<24576; i+=8,i2+=4) {
|
||||
bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]),
|
||||
(simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i),
|
||||
@@ -6716,9 +6737,11 @@ void dft36864(int16_t *input, int16_t *output,uint8_t scale) {
|
||||
}
|
||||
_mm_empty();
|
||||
_m_empty();
|
||||
#ifndef MR_MAIN
|
||||
if (LOG_DUMPFLAG(DEBUG_DFT)) {
|
||||
LOG_M("out.m","out",output,36864,1,1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void idft36864(int16_t *input, int16_t *output,uint8_t scale) {
|
||||
|
||||
@@ -182,7 +182,10 @@ typedef struct {
|
||||
int16_t sqrt_rho_b;
|
||||
} NR_gNB_DLSCH_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
bool active;
|
||||
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
|
||||
} NR_gNB_SSB_t;
|
||||
|
||||
typedef struct {
|
||||
int frame;
|
||||
@@ -711,10 +714,10 @@ typedef struct PHY_VARS_gNB_s {
|
||||
|
||||
// nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu;
|
||||
// nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu;
|
||||
nfapi_nr_dl_tti_ssb_pdu ssb_pdu;
|
||||
|
||||
uint16_t num_pdsch_rnti[80];
|
||||
NR_gNB_PBCH pbch;
|
||||
NR_gNB_SSB_t ssb[64];
|
||||
NR_gNB_PBCH pbch;
|
||||
nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL];
|
||||
NR_gNB_COMMON common_vars;
|
||||
NR_gNB_PRACH prach_vars;
|
||||
|
||||
@@ -142,6 +142,7 @@ typedef struct {
|
||||
uint32_t rsrp[7];
|
||||
float rsrp_filtered[7]; // after layer 3 filtering
|
||||
float rsrq_filtered[7];
|
||||
short rsrp_dBm[7];
|
||||
// common measurements
|
||||
//! estimated noise power (linear)
|
||||
unsigned int n0_power[NB_ANTENNAS_RX];
|
||||
|
||||
@@ -50,8 +50,15 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot,
|
||||
AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n",
|
||||
dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag);
|
||||
|
||||
LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
|
||||
memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
|
||||
uint8_t i_ssb = dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
|
||||
|
||||
LOG_D(PHY,"%d.%d : ssb index %d pbch_pdu: %x\n",frame,slot,i_ssb,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload);
|
||||
if (gNB->ssb[i_ssb].active)
|
||||
AssertFatal(1==0,"SSB PDU with index %d already active\n",i_ssb);
|
||||
else {
|
||||
gNB->ssb[i_ssb].active = true;
|
||||
memcpy((void*)&gNB->ssb[i_ssb].ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu));
|
||||
}
|
||||
}
|
||||
|
||||
/*void handle_nr_nfapi_pdsch_pdu(PHY_VARS_gNB *gNB,int frame,int subframe,gNB_L1_rxtx_proc_t *proc,
|
||||
@@ -166,14 +173,11 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
gNB->dlsch[i][0]->harq_mask=0;
|
||||
}
|
||||
|
||||
gNB->pbch_configured=0;
|
||||
|
||||
for (int i=0;i<number_dl_pdu;i++) {
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdu = &DL_req->dl_tti_request_body.dl_tti_pdu_list[i];
|
||||
LOG_D(PHY,"NFAPI: dl_pdu %d : type %d\n",i,dl_tti_pdu->PDUType);
|
||||
switch (dl_tti_pdu->PDUType) {
|
||||
case NFAPI_NR_DL_TTI_SSB_PDU_TYPE:
|
||||
gNB->pbch_configured=1;
|
||||
|
||||
if(NFAPI_MODE != NFAPI_MODE_VNF)
|
||||
handle_nr_nfapi_ssb_pdu(gNB,frame,slot,
|
||||
@@ -257,4 +261,4 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,85 +67,63 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME
|
||||
LOG_D(PHY, "SSB first subcarrier %d (%d,%d)\n", fp->ssb_start_subcarrier,cfg->ssb_table.ssb_offset_point_a.value,sco);
|
||||
}
|
||||
|
||||
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot) {
|
||||
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu) {
|
||||
|
||||
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
int **txdataF = gNB->common_vars.txdataF;
|
||||
uint8_t ssb_index, ssb_per_slot=0, n_hf;
|
||||
uint16_t ssb_start_symbol, rel_slot;
|
||||
uint8_t ssb_index, n_hf;
|
||||
uint16_t ssb_start_symbol;
|
||||
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
|
||||
uint16_t slots_per_hf = (fp->slots_per_frame)>>1;
|
||||
|
||||
n_hf = fp->half_frame_bit;
|
||||
if (slot<slots_per_hf)
|
||||
n_hf=0;
|
||||
else
|
||||
n_hf=1;
|
||||
|
||||
// if SSB periodicity is 5ms, they are transmitted in both half frames
|
||||
if ( cfg->ssb_table.ssb_period.value == 0) {
|
||||
if (slot<slots_per_hf)
|
||||
n_hf=0;
|
||||
else
|
||||
n_hf=1;
|
||||
ssb_index = ssb_pdu.ssb_pdu_rel15.SsbBlockIndex;
|
||||
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d ssb index %d\n",frame,slot,ssb_index);
|
||||
|
||||
int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp,ssb_index); // computing the starting symbol for current ssb
|
||||
ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot
|
||||
|
||||
nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
|
||||
|
||||
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
|
||||
nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
|
||||
if (cfg->carrier_config.num_tx_ant.value <= 4)
|
||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
else
|
||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
|
||||
if (T_ACTIVE(T_GNB_PHY_MIB)) {
|
||||
unsigned char bch[3];
|
||||
bch[0] = ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
|
||||
bch[1] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
|
||||
bch[2] = (ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
|
||||
T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
|
||||
}
|
||||
|
||||
// to set a effective slot number in the half frame where the SSB is supposed to be
|
||||
rel_slot = (n_hf)? (slot-slots_per_hf) : slot;
|
||||
|
||||
LOG_D(PHY,"common_signal_procedures: frame %d, slot %d\n",frame,slot);
|
||||
|
||||
if(rel_slot<38 && rel_slot>=0) { // there is no SSB beyond slot 37
|
||||
|
||||
for (int i=0; i<2; i++) { // max two SSB per slot
|
||||
|
||||
ssb_index = i + SSB_Table[rel_slot]; // computing the ssb_index
|
||||
|
||||
if ((ssb_index<64) && ((fp->L_ssb >> (63-ssb_index)) & 0x01)) { // generating the ssb only if the bit of L_ssb at current ssb index is 1
|
||||
ssb_per_slot++;
|
||||
fp->ssb_index = ssb_index;
|
||||
int ssb_start_symbol_abs = nr_get_ssb_start_symbol(fp); // computing the starting symbol for current ssb
|
||||
ssb_start_symbol = ssb_start_symbol_abs % fp->symbols_per_slot; // start symbol wrt slot
|
||||
|
||||
nr_set_ssb_first_subcarrier(cfg, fp); // setting the first subcarrier
|
||||
|
||||
LOG_D(PHY,"SS TX: frame %d, slot %d, start_symbol %d\n",frame,slot, ssb_start_symbol);
|
||||
nr_generate_pss(gNB->d_pss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
nr_generate_sss(gNB->d_sss, &txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
|
||||
if (cfg->carrier_config.num_tx_ant.value <= 4)
|
||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[n_hf][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
else
|
||||
nr_generate_pbch_dmrs(gNB->nr_gold_pbch_dmrs[0][ssb_index&7],&txdataF[0][txdataF_offset], AMP, ssb_start_symbol, cfg, fp);
|
||||
|
||||
if (T_ACTIVE(T_GNB_PHY_MIB)) {
|
||||
unsigned char bch[3];
|
||||
bch[0] = gNB->ssb_pdu.ssb_pdu_rel15.bchPayload & 0xff;
|
||||
bch[1] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 8) & 0xff;
|
||||
bch[2] = (gNB->ssb_pdu.ssb_pdu_rel15.bchPayload >> 16) & 0xff;
|
||||
T(T_GNB_PHY_MIB, T_INT(0) /* module ID */, T_INT(frame), T_INT(slot), T_BUFFER(bch, 3));
|
||||
}
|
||||
|
||||
nr_generate_pbch(&gNB->pbch,
|
||||
&gNB->ssb_pdu,
|
||||
gNB->nr_pbch_interleaver,
|
||||
&txdataF[0][txdataF_offset],
|
||||
AMP,
|
||||
ssb_start_symbol,
|
||||
n_hf, frame, cfg, fp);
|
||||
|
||||
// SSB beamforming is handled at PHY
|
||||
// currently our PHY does not support switching more than once a slot.
|
||||
if (ssb_per_slot>1) {
|
||||
LOG_W(PHY,"beamforming currently not supported for more than one SSB per slot\n");
|
||||
}
|
||||
else if (ssb_per_slot==1) {
|
||||
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
|
||||
for (int j=0;j<fp->symbols_per_slot;j++)
|
||||
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Beam_id is currently used only for FR2
|
||||
if (fp->freq_range==nr_FR2){
|
||||
LOG_D(PHY,"slot %d, ssb_index %d, beam %d\n",slot,ssb_index,cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value);
|
||||
for (int j=0;j<fp->symbols_per_slot;j++)
|
||||
gNB->common_vars.beam_id[0][slot*fp->symbols_per_slot+j] = cfg->ssb_table.ssb_beam_id_list[ssb_index].beam_id.value;
|
||||
}
|
||||
|
||||
nr_generate_pbch(&gNB->pbch,
|
||||
&ssb_pdu,
|
||||
gNB->nr_pbch_interleaver,
|
||||
&txdataF[0][txdataF_offset],
|
||||
AMP,
|
||||
ssb_start_symbol,
|
||||
n_hf, frame, cfg, fp);
|
||||
}
|
||||
|
||||
|
||||
void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
int frame,int slot,
|
||||
int do_meas) {
|
||||
@@ -153,11 +131,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
NR_DL_FRAME_PARMS *fp=&gNB->frame_parms;
|
||||
nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config;
|
||||
int offset = gNB->CC_id;
|
||||
uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
|
||||
int txdataF_offset = (slot%2)*fp->samples_per_slot_wCP;
|
||||
|
||||
if (cfg->ssb_table.ssb_period.value > 1)
|
||||
ssb_frame_periodicity = 1 <<(cfg->ssb_table.ssb_period.value -1) ;
|
||||
|
||||
if ((cfg->cell_config.frame_duplex_type.value == TDD) &&
|
||||
(nr_slot_select(cfg,frame,slot) == NR_UPLINK_SLOT)) return;
|
||||
@@ -174,8 +148,12 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,1);
|
||||
if (NFAPI_MODE == NFAPI_MONOLITHIC || NFAPI_MODE == NFAPI_MODE_PNF) {
|
||||
if ((!(frame%ssb_frame_periodicity))) // generate SSB only for given frames according to SSB periodicity
|
||||
nr_common_signal_procedures(gNB,frame, slot);
|
||||
for (int i=0; i<fp->Lmax; i++) {
|
||||
if (gNB->ssb[i].active) {
|
||||
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[i].ssb_pdu);
|
||||
gNB->ssb[i].active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_COMMON_TX,0);
|
||||
|
||||
@@ -468,7 +446,7 @@ void fill_ul_rb_mask(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) {
|
||||
(pucch->frame == frame_rx) &&
|
||||
(pucch->slot == slot_rx) ) {
|
||||
gNB->ulmask_symb = symbol;
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch[i].pucch_pdu;
|
||||
nfapi_nr_pucch_pdu_t *pucch_pdu = &pucch->pucch_pdu;
|
||||
if ((symbol>=pucch_pdu->start_symbol_index) &&
|
||||
(symbol<(pucch_pdu->start_symbol_index + pucch_pdu->nr_of_symbols))){
|
||||
for (rb=0; rb<pucch_pdu->prb_size; rb++) {
|
||||
|
||||
@@ -40,7 +40,7 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_
|
||||
void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
|
||||
void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx);
|
||||
void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot);
|
||||
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot);
|
||||
void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_dl_tti_ssb_pdu ssb_pdu);
|
||||
void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx);
|
||||
void nr_feptx0(RU_t *ru,int tti_tx,int first_symbol, int num_symbols, int aa);
|
||||
|
||||
@@ -2069,10 +2069,10 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t
|
||||
|
||||
if (ue->mac_enabled == 1) {
|
||||
int16_t pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id);
|
||||
int16_t ra_preamble_rx_power = (int16_t)(10*log10(pow(10, (double)(prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER)/10) + pow(10, (double)(pathloss)/10)));
|
||||
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_I(PHY,"[UE %d][RAPROC][%d.%d]: Generating PRACH Msg1 (preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %x)\n",
|
||||
LOG_I(PHY,"DEBUG [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",
|
||||
mod_id,
|
||||
frame_tx,
|
||||
nr_slot_tx,
|
||||
|
||||
@@ -173,6 +173,7 @@ int nr_derive_key(int alg_type, uint8_t alg_id,
|
||||
}
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
int pdsch_AntennaPorts,
|
||||
int pusch_AntennaPorts,
|
||||
NR_ServingCellConfigCommon_t *scc
|
||||
@@ -693,7 +694,7 @@ int main(int argc, char **argv)
|
||||
NR_ServingCellConfig_t *scd = calloc(1,sizeof(NR_ServingCellConfig_t));
|
||||
NR_CellGroupConfig_t *secondaryCellGroup=calloc(1,sizeof(*secondaryCellGroup));
|
||||
prepare_scc(rrc.carrier.servingcellconfigcommon);
|
||||
uint64_t ssb_bitmap;
|
||||
uint64_t ssb_bitmap = 1;
|
||||
fill_scc(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);
|
||||
ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
|
||||
fix_scc(scc,ssb_bitmap);
|
||||
@@ -877,7 +878,8 @@ int main(int argc, char **argv)
|
||||
// generate signal
|
||||
AssertFatal(input_fd==NULL,"Not ready for input signal file\n");
|
||||
gNB->pbch_configured = 1;
|
||||
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
|
||||
gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.bchPayload=0x001234;
|
||||
gNB->ssb[0].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
|
||||
|
||||
//Configure UE
|
||||
rrc.carrier.MIB = (uint8_t*) malloc(4);
|
||||
@@ -1003,7 +1005,7 @@ int main(int argc, char **argv)
|
||||
printf("[DLSIM] PTRS Symbols in a slot: %2u, RE per Symbol: %3u, RE in a slot %4d\n", ptrsSymbPerSlot,ptrsRePerSymb, ptrsSymbPerSlot*ptrsRePerSymb );
|
||||
}
|
||||
if (run_initial_sync)
|
||||
nr_common_signal_procedures(gNB,frame,slot);
|
||||
nr_common_signal_procedures(gNB,frame,slot,gNB->ssb[0].ssb_pdu);
|
||||
else
|
||||
phy_procedures_gNB_TX(gNB,frame,slot,0);
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ void nr_phy_config_request_sim_pbchsim(PHY_VARS_gNB *gNB,
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char c;
|
||||
int i,aa;//,l;
|
||||
int i,aa,start_symbol;
|
||||
double sigma2, sigma2_dB=10,SNR,snr0=-2.0,snr1=2.0;
|
||||
double cfo=0;
|
||||
uint8_t snr1set=0;
|
||||
@@ -426,29 +426,28 @@ int main(int argc, char **argv)
|
||||
|
||||
switch (mu) {
|
||||
case 1:
|
||||
scs = 30000;
|
||||
if (N_RB_DL == 217) {
|
||||
fs = 122.88e6;
|
||||
bw = 80e6;
|
||||
|
||||
}
|
||||
else if (N_RB_DL == 245) {
|
||||
fs = 122.88e6;
|
||||
bw = 90e6;
|
||||
}
|
||||
else if (N_RB_DL == 273) {
|
||||
fs = 122.88e6;
|
||||
bw = 100e6;
|
||||
}
|
||||
else if (N_RB_DL == 106) {
|
||||
fs = 61.44e6;
|
||||
bw = 40e6;
|
||||
}
|
||||
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
|
||||
break;
|
||||
|
||||
|
||||
scs = 30000;
|
||||
frame_parms->Lmax = 8;
|
||||
if (N_RB_DL == 217) {
|
||||
fs = 122.88e6;
|
||||
bw = 80e6;
|
||||
}
|
||||
else if (N_RB_DL == 245) {
|
||||
fs = 122.88e6;
|
||||
bw = 90e6;
|
||||
}
|
||||
else if (N_RB_DL == 273) {
|
||||
fs = 122.88e6;
|
||||
bw = 100e6;
|
||||
}
|
||||
else if (N_RB_DL == 106) {
|
||||
fs = 61.44e6;
|
||||
bw = 40e6;
|
||||
}
|
||||
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
|
||||
break;
|
||||
case 3:
|
||||
frame_parms->Lmax = 64;
|
||||
scs = 120000;
|
||||
if (N_RB_DL == 66) {
|
||||
fs = 122.88e6;
|
||||
@@ -457,6 +456,7 @@ int main(int argc, char **argv)
|
||||
else AssertFatal(1==0,"Unsupported numerology for mu %d, N_RB %d\n",mu, N_RB_DL);
|
||||
break;
|
||||
}
|
||||
|
||||
// cfo with respect to sub-carrier spacing
|
||||
eps = cfo/scs;
|
||||
|
||||
@@ -510,7 +510,6 @@ int main(int argc, char **argv)
|
||||
printf("Allocating %d samples for txdata\n",frame_length_complex_samples);
|
||||
txdata[i] = malloc(frame_length_complex_samples*sizeof(int));
|
||||
bzero(r_re[i],frame_length_complex_samples*sizeof(int));
|
||||
|
||||
}
|
||||
|
||||
if (pbch_file_fd!=NULL) {
|
||||
@@ -536,60 +535,68 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
nr_gold_pbch(UE);
|
||||
|
||||
// generate signal
|
||||
if (input_fd==NULL) {
|
||||
gNB->pbch_configured = 1;
|
||||
|
||||
gNB->ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
|
||||
|
||||
for (int slot=0;slot<frame_parms->slots_per_frame;slot++) {
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
|
||||
memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
|
||||
|
||||
nr_common_signal_procedures (gNB,frame,slot);
|
||||
for (i=0; i<frame_parms->Lmax; i++) {
|
||||
if((SSB_positions >> i) & 0x01) {
|
||||
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||
if (cyclic_prefix_type == 1) {
|
||||
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
|
||||
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
/* nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
|
||||
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
14,
|
||||
frame_parms);*/
|
||||
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
|
||||
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples0,
|
||||
CYCLIC_PREFIX);
|
||||
|
||||
apply_nr_rotation(frame_parms,
|
||||
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
slot,
|
||||
0,
|
||||
1,
|
||||
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
|
||||
PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
|
||||
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
13,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
apply_nr_rotation(frame_parms,
|
||||
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
|
||||
slot,
|
||||
1,
|
||||
13,
|
||||
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
|
||||
}
|
||||
}
|
||||
gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.bchPayload = 0x55dd33;
|
||||
gNB->ssb[i].ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i;
|
||||
|
||||
start_symbol = nr_get_ssb_start_symbol(frame_parms,i);
|
||||
int slot = start_symbol/14;
|
||||
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++)
|
||||
memset(gNB->common_vars.txdataF[aa],0,frame_parms->samples_per_slot_wCP*sizeof(int32_t));
|
||||
|
||||
nr_common_signal_procedures (gNB,frame,slot,gNB->ssb[i].ssb_pdu);
|
||||
|
||||
for (aa=0; aa<gNB->frame_parms.nb_antennas_tx; aa++) {
|
||||
if (cyclic_prefix_type == 1) {
|
||||
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
|
||||
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
12,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
} else {
|
||||
/*nr_normal_prefix_mod(gNB->common_vars.txdataF[aa],
|
||||
&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
14,
|
||||
frame_parms);*/
|
||||
PHY_ofdm_mod(gNB->common_vars.txdataF[aa],
|
||||
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
1,
|
||||
frame_parms->nb_prefix_samples0,
|
||||
CYCLIC_PREFIX);
|
||||
|
||||
apply_nr_rotation(frame_parms,
|
||||
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)],
|
||||
slot,
|
||||
0,
|
||||
1,
|
||||
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples0);
|
||||
|
||||
PHY_ofdm_mod(&gNB->common_vars.txdataF[aa][frame_parms->ofdm_symbol_size],
|
||||
(int*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
|
||||
frame_parms->ofdm_symbol_size,
|
||||
13,
|
||||
frame_parms->nb_prefix_samples,
|
||||
CYCLIC_PREFIX);
|
||||
|
||||
apply_nr_rotation(frame_parms,
|
||||
(int16_t*)&txdata[aa][frame_parms->get_samples_slot_timestamp(slot,frame_parms,0)+frame_parms->nb_prefix_samples0+frame_parms->ofdm_symbol_size],
|
||||
slot,
|
||||
1,
|
||||
13,
|
||||
frame_parms->ofdm_symbol_size+frame_parms->nb_prefix_samples);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_M("txsigF0.m","txsF0", gNB->common_vars.txdataF[0],frame_length_complex_samples_no_prefix,1,1);
|
||||
if (gNB->frame_parms.nb_antennas_tx>1)
|
||||
LOG_M("txsigF1.m","txsF1", gNB->common_vars.txdataF[1],frame_length_complex_samples_no_prefix,1,1);
|
||||
@@ -598,9 +605,9 @@ int main(int argc, char **argv)
|
||||
printf("Reading %d samples from file to antenna buffer %d\n",frame_length_complex_samples,0);
|
||||
UE->UE_fo_compensation = 1; // perform fo compensation when samples from file are used
|
||||
if (fread(txdata[0],
|
||||
sizeof(int32_t),
|
||||
frame_length_complex_samples,
|
||||
input_fd) != frame_length_complex_samples) {
|
||||
sizeof(int32_t),
|
||||
frame_length_complex_samples,
|
||||
input_fd) != frame_length_complex_samples) {
|
||||
printf("error reading from file\n");
|
||||
//exit(-1);
|
||||
}
|
||||
@@ -684,10 +691,9 @@ int main(int argc, char **argv)
|
||||
UE->rx_offset=0;
|
||||
uint8_t ssb_index = 0;
|
||||
while (!((SSB_positions >> ssb_index) & 0x01)) ssb_index++; // to select the first transmitted ssb
|
||||
frame_parms->ssb_index = ssb_index;
|
||||
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms);
|
||||
UE->symbol_offset = nr_get_ssb_start_symbol(frame_parms,ssb_index);
|
||||
|
||||
int ssb_slot = (ssb_index>>1)+(n_hf*frame_parms->slots_per_frame);
|
||||
int ssb_slot = (UE->symbol_offset/14)+(n_hf*(frame_parms->slots_per_frame>>1));
|
||||
for (int i=UE->symbol_offset+1; i<UE->symbol_offset+4; i++) {
|
||||
nr_slot_fep(UE,
|
||||
&proc,
|
||||
@@ -716,7 +722,7 @@ int main(int argc, char **argv)
|
||||
|
||||
payload_ret = (UE->pbch_vars[0]->xtra_byte == gNB_xtra_byte);
|
||||
for (i=0;i<3;i++){
|
||||
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
|
||||
payload_ret += (UE->pbch_vars[0]->decoded_output[i] == ((gNB->ssb[ssb_index].ssb_pdu.ssb_pdu_rel15.bchPayload>>(8*i)) & 0xff));
|
||||
}
|
||||
//printf("xtra byte gNB: 0x%02x UE: 0x%02x\n",gNB_xtra_byte, UE->pbch_vars[0]->xtra_byte);
|
||||
//printf("ret %d\n", payload_ret);
|
||||
|
||||
@@ -217,7 +217,7 @@ int main(int argc, char **argv){
|
||||
|
||||
randominit(0);
|
||||
|
||||
while ((c = getopt (argc, argv, "hHaA:Cc:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
|
||||
while ((c = getopt (argc, argv, "hHaA:Cc:l:r:p:g:m:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
printf("Running AWGN simulation\n");
|
||||
@@ -230,6 +230,10 @@ int main(int argc, char **argv){
|
||||
config_index = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
loglvl = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
msg1_frequencystart = atoi(optarg);
|
||||
break;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define TABLE_38213_13_1_NUM_INDEXES 15
|
||||
#define TABLE_38213_13_2_NUM_INDEXES 14
|
||||
@@ -418,14 +419,6 @@ typedef enum {
|
||||
NR_RNTI_MCS_C,
|
||||
} nr_rnti_type_t;
|
||||
|
||||
typedef enum subcarrier_spacing_e {
|
||||
scs_15kHz = 0x1,
|
||||
scs_30kHz = 0x2,
|
||||
scs_60kHz = 0x4,
|
||||
scs_120kHz = 0x8,
|
||||
scs_240kHz = 0x16
|
||||
} subcarrier_spacing_t;
|
||||
|
||||
typedef enum channel_bandwidth_e {
|
||||
bw_5MHz = 0x1,
|
||||
bw_10MHz = 0x2,
|
||||
@@ -462,6 +455,7 @@ typedef struct Type0_PDCCH_CSS_config_s {
|
||||
uint32_t ssb_length;
|
||||
uint32_t ssb_index;
|
||||
uint32_t cset_start_rb;
|
||||
bool active;
|
||||
} NR_Type0_PDCCH_CSS_config_t;
|
||||
|
||||
#endif /*__LAYER2_MAC_H__ */
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
|
||||
#define reserved 0xffff
|
||||
|
||||
// start symbols for SSB types A,B,C,D,E
|
||||
uint16_t symbol_ssb_AC[8]={2,8,16,22,30,36,44,50};
|
||||
uint16_t symbol_ssb_BD[64]={4,8,16,20,32,36,44,48,60,64,72,76,88,92,100,104,144,148,156,160,172,176,184,188,200,204,212,216,228,232,240,244,284,288,
|
||||
296,300,312,316,324,328,340,344,352,356,368,372,380,384,424,428,436,440,452,456,464,468,480,484,492,496,508,512,520,524};
|
||||
uint16_t symbol_ssb_E[64]={8,12,16,20,32,36,40,44,64,68,72,76,88,92,96,100,120,124,128,132,144,148,152,156,176,180,184,188,200,204,208,212,288,292,
|
||||
296,300,312,316,320,324,344,348,352,356,368,372,376,380,400,404,408,412,424,428,432,436,456,460,464,468,480,484,488,492};
|
||||
|
||||
const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160};
|
||||
|
||||
// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz
|
||||
@@ -3008,56 +3015,58 @@ bool set_dl_ptrs_values(NR_PTRS_DownlinkConfig_t *ptrs_config,
|
||||
return valid;
|
||||
}
|
||||
|
||||
uint32_t get_ssb_slot(uint32_t ssb_index){
|
||||
// this function now only support f <= 3GHz
|
||||
return ssb_index & 0x3 ;
|
||||
uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb) {
|
||||
|
||||
// return first_symbol(case, freq, ssb_index) / 14
|
||||
switch (scs) {
|
||||
case NR_SubcarrierSpacing_kHz15:
|
||||
return symbol_ssb_AC[i_ssb]; //type A
|
||||
case NR_SubcarrierSpacing_kHz30:
|
||||
if (band == 5 || band == 66)
|
||||
return symbol_ssb_BD[i_ssb]; //type B
|
||||
else
|
||||
return symbol_ssb_AC[i_ssb]; //type C
|
||||
case NR_SubcarrierSpacing_kHz120:
|
||||
return symbol_ssb_BD[i_ssb]; //type D
|
||||
case NR_SubcarrierSpacing_kHz240:
|
||||
return symbol_ssb_E[i_ssb];
|
||||
default:
|
||||
AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",scs);
|
||||
}
|
||||
}
|
||||
|
||||
int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
NR_MIB_t *mib,
|
||||
uint8_t extra_bits,
|
||||
uint32_t ssb_length,
|
||||
uint32_t ssb_index,
|
||||
uint32_t ssb_offset_point_a) {
|
||||
void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
frame_t frameP,
|
||||
NR_MIB_t *mib,
|
||||
uint8_t num_slot_per_frame,
|
||||
uint8_t ssb_subcarrier_offset,
|
||||
uint16_t ssb_start_symbol,
|
||||
NR_SubcarrierSpacing_t scs_ssb,
|
||||
frequency_range_t frequency_range,
|
||||
uint32_t ssb_index,
|
||||
uint32_t ssb_offset_point_a) {
|
||||
|
||||
// deafult for testing
|
||||
subcarrier_spacing_t scs_ssb = scs_30kHz;
|
||||
channel_bandwidth_t min_channel_bw = bw_10MHz;
|
||||
frequency_range_t frequency_range = FR1;
|
||||
const uint32_t num_slot_per_frame = 20;
|
||||
NR_SubcarrierSpacing_t scs_pdcch;
|
||||
|
||||
channel_bandwidth_t min_channel_bw = bw_10MHz; // TODO remove hardcoding and implement Table 5.3.5-1 in 38.104
|
||||
|
||||
if (frequency_range == FR2) {
|
||||
if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
|
||||
scs_pdcch = NR_SubcarrierSpacing_kHz60;
|
||||
else
|
||||
scs_pdcch = NR_SubcarrierSpacing_kHz120;
|
||||
}
|
||||
else {
|
||||
frequency_range = FR1;
|
||||
if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60)
|
||||
scs_pdcch = NR_SubcarrierSpacing_kHz15;
|
||||
else
|
||||
scs_pdcch = NR_SubcarrierSpacing_kHz30;
|
||||
}
|
||||
|
||||
type0_PDCCH_CSS_config->ssb_length = ssb_length;
|
||||
type0_PDCCH_CSS_config->ssb_index = ssb_index;
|
||||
type0_PDCCH_CSS_config->frame = (mib->systemFrameNumber.buf[0] >> mib->systemFrameNumber.bits_unused);
|
||||
type0_PDCCH_CSS_config->frame = frameP;
|
||||
|
||||
uint16_t frame_number_4lsb = 0;
|
||||
for (int i=0; i<4; i++) {
|
||||
frame_number_4lsb |= ((extra_bits>>i)&1)<<(3-i);
|
||||
}
|
||||
|
||||
uint8_t ssb_subcarrier_offset_msb = ( extra_bits >> 5 ) & 0x1; // extra bits[5]
|
||||
uint8_t ssb_subcarrier_offset = (uint8_t)mib->ssb_SubcarrierOffset;
|
||||
|
||||
type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame << 4;
|
||||
type0_PDCCH_CSS_config->frame = type0_PDCCH_CSS_config->frame | frame_number_4lsb;
|
||||
|
||||
if(type0_PDCCH_CSS_config->ssb_length == 64){
|
||||
type0_PDCCH_CSS_config->ssb_index = type0_PDCCH_CSS_config->ssb_index & (( extra_bits >> 2 ) & 0x1C ); // { extra_bits[5:7], ssb_index[2:0] }
|
||||
}else{
|
||||
if(ssb_subcarrier_offset_msb){
|
||||
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
|
||||
}
|
||||
}
|
||||
|
||||
// assume carrier frequency < 6GHz
|
||||
subcarrier_spacing_t scs_pdcch;
|
||||
if(mib->subCarrierSpacingCommon == NR_MIB__subCarrierSpacingCommon_scs15or60){
|
||||
scs_pdcch = scs_15kHz;
|
||||
}else{ //NR_MIB__subCarrierSpacingCommon_scs30or120
|
||||
scs_pdcch = scs_30kHz;
|
||||
}
|
||||
uint8_t ssb_slot = ssb_start_symbol/14;
|
||||
|
||||
uint32_t is_condition_A = (ssb_subcarrier_offset == 0); // 38.213 ch.13
|
||||
uint32_t index_4msb = (mib->pdcch_ConfigSIB1.controlResourceSetZero);
|
||||
@@ -3068,8 +3077,8 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
type0_PDCCH_CSS_config->rb_offset = -1;
|
||||
|
||||
// type0-pdcch coreset
|
||||
switch( (scs_ssb << 5) | scs_pdcch ){
|
||||
case (scs_15kHz << 5) | scs_15kHz :
|
||||
switch( (scs_ssb << 3) | scs_pdcch ){
|
||||
case (NR_SubcarrierSpacing_kHz15 << 5) | NR_SubcarrierSpacing_kHz15:
|
||||
AssertFatal(index_4msb < 15, "38.213 Table 13-1 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_1_c2[index_4msb];
|
||||
@@ -3077,7 +3086,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_1_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_15kHz << 5) | scs_30kHz:
|
||||
case (NR_SubcarrierSpacing_kHz15 << 3) | NR_SubcarrierSpacing_kHz30:
|
||||
AssertFatal(index_4msb < 14, "38.213 Table 13-2 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_2_c2[index_4msb];
|
||||
@@ -3085,7 +3094,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_2_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_30kHz << 5) | scs_15kHz:
|
||||
case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz15:
|
||||
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
|
||||
AssertFatal(index_4msb < 9, "38.213 Table 13-3 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
@@ -3102,7 +3111,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
|
||||
break;
|
||||
|
||||
case (scs_30kHz << 5) | scs_30kHz:
|
||||
case (NR_SubcarrierSpacing_kHz30 << 3) | NR_SubcarrierSpacing_kHz30:
|
||||
if((min_channel_bw & bw_5MHz) | (min_channel_bw & bw_10MHz)){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_4_c2[index_4msb];
|
||||
@@ -3118,7 +3127,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
}else{ ; }
|
||||
break;
|
||||
|
||||
case (scs_120kHz << 5) | scs_60kHz:
|
||||
case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz60:
|
||||
AssertFatal(index_4msb < 12, "38.213 Table 13-7 4 MSB out of range\n");
|
||||
if(index_4msb & 0x7){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
@@ -3135,7 +3144,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
}
|
||||
break;
|
||||
|
||||
case (scs_120kHz << 5) | scs_120kHz:
|
||||
case (NR_SubcarrierSpacing_kHz120 << 3) | NR_SubcarrierSpacing_kHz120:
|
||||
AssertFatal(index_4msb < 8, "38.213 Table 13-8 4 MSB out of range\n");
|
||||
if(index_4msb & 0x3){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
@@ -3152,7 +3161,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
}
|
||||
break;
|
||||
|
||||
case (scs_240kHz << 5) | scs_60kHz:
|
||||
case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz60:
|
||||
AssertFatal(index_4msb < 4, "38.213 Table 13-9 4 MSB out of range\n");
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
type0_PDCCH_CSS_config->num_rbs = table_38213_13_9_c2[index_4msb];
|
||||
@@ -3160,7 +3169,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
type0_PDCCH_CSS_config->rb_offset = table_38213_13_9_c4[index_4msb];
|
||||
break;
|
||||
|
||||
case (scs_240kHz << 5) | scs_120kHz:
|
||||
case (NR_SubcarrierSpacing_kHz240 << 3) | NR_SubcarrierSpacing_kHz120:
|
||||
AssertFatal(index_4msb < 8, "38.213 Table 13-10 4 MSB out of range\n");
|
||||
if(index_4msb & 0x3){
|
||||
type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern = 1;
|
||||
@@ -3231,7 +3240,7 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
type0_PDCCH_CSS_config->number_of_search_space_per_slot = table_38213_13_11_c2[index_4lsb];
|
||||
big_m = table_38213_13_11_c3[index_4lsb];
|
||||
|
||||
uint32_t temp = (uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
|
||||
uint32_t temp = (uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m);
|
||||
type0_PDCCH_CSS_config->n_c = temp / num_slot_per_frame;
|
||||
if((temp/num_slot_per_frame) & 0x1){
|
||||
type0_PDCCH_CSS_config->sfn_c = SFN_C_MOD_2_EQ_1;
|
||||
@@ -3267,12 +3276,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
/// MUX PATTERN 2
|
||||
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 2){
|
||||
|
||||
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_60kHz)){
|
||||
if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz60)){
|
||||
// 38.213 Table 13-13
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-13 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
|
||||
type0_PDCCH_CSS_config->n_c = ssb_slot;
|
||||
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
|
||||
case 0:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 0;
|
||||
@@ -3289,12 +3298,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
default: break;
|
||||
}
|
||||
|
||||
}else if((scs_ssb == scs_240kHz) && (scs_pdcch == scs_120kHz)){
|
||||
}else if((scs_ssb == NR_SubcarrierSpacing_kHz240) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
|
||||
// 38.213 Table 13-14
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-14 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
|
||||
type0_PDCCH_CSS_config->n_c = ssb_slot;
|
||||
switch(type0_PDCCH_CSS_config->ssb_index & 0x7){ // ssb_index(i) mod 8
|
||||
case 0:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 0;
|
||||
@@ -3310,11 +3319,11 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
break;
|
||||
case 4:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 12;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
|
||||
type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
|
||||
break;
|
||||
case 5:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 13;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index) - 1;
|
||||
type0_PDCCH_CSS_config->n_c = ssb_slot - 1;
|
||||
break;
|
||||
case 6:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 0;
|
||||
@@ -3331,12 +3340,12 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
|
||||
/// MUX PATTERN 3
|
||||
if(type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 3){
|
||||
if((scs_ssb == scs_120kHz) && (scs_pdcch == scs_120kHz)){
|
||||
if((scs_ssb == NR_SubcarrierSpacing_kHz120) && (scs_pdcch == NR_SubcarrierSpacing_kHz120)){
|
||||
// 38.213 Table 13-15
|
||||
AssertFatal(index_4lsb == 0, "38.213 Table 13-15 4 LSB out of range\n");
|
||||
// PDCCH monitoring occasions (SFN and slot number) same as SSB frame-slot
|
||||
// sfn_c = SFN_C_EQ_SFN_SSB;
|
||||
type0_PDCCH_CSS_config->n_c = get_ssb_slot(type0_PDCCH_CSS_config->ssb_index);
|
||||
type0_PDCCH_CSS_config->n_c = ssb_slot;
|
||||
switch(type0_PDCCH_CSS_config->ssb_index & 0x3){ // ssb_index(i) mod 4
|
||||
case 0:
|
||||
type0_PDCCH_CSS_config->first_symbol_index = 4;
|
||||
@@ -3373,10 +3382,9 @@ int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDC
|
||||
AssertFatal(type0_PDCCH_CSS_config->sfn_c!=SFN_C_IMPOSSIBLE,"");
|
||||
AssertFatal(type0_PDCCH_CSS_config->n_c!=UINT_MAX,"");
|
||||
|
||||
type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*scs_pdcch) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
|
||||
type0_PDCCH_CSS_config->n_0 = ((uint32_t)(big_o*(1<<scs_pdcch)) + (uint32_t)(type0_PDCCH_CSS_config->ssb_index*big_m))%num_slot_per_frame;
|
||||
type0_PDCCH_CSS_config->cset_start_rb = ssb_offset_point_a - type0_PDCCH_CSS_config->rb_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* extract UL PTRS values from RRC and validate it based upon 38.214 6.2.3 */
|
||||
|
||||
@@ -126,12 +126,18 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr
|
||||
uint8_t get_L_ptrs(uint8_t mcs1, uint8_t mcs2, uint8_t mcs3, uint8_t I_mcs, uint8_t mcs_table);
|
||||
uint8_t get_K_ptrs(uint16_t nrb0, uint16_t nrb1, uint16_t N_RB);
|
||||
|
||||
int get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
NR_MIB_t *mib,
|
||||
uint8_t extra_bits,
|
||||
uint32_t ssb_length,
|
||||
uint32_t ssb_index,
|
||||
uint32_t ssb_offset_point_a);
|
||||
void get_type0_PDCCH_CSS_config_parameters(NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
frame_t frameP,
|
||||
NR_MIB_t *mib,
|
||||
uint8_t num_slot_per_frame,
|
||||
uint8_t ssb_subcarrier_offset,
|
||||
uint16_t ssb_start_symbol,
|
||||
NR_SubcarrierSpacing_t scs_ssb,
|
||||
frequency_range_t frequency_range,
|
||||
uint32_t ssb_index,
|
||||
uint32_t ssb_offset_point_a);
|
||||
|
||||
uint16_t get_ssb_start_symbol(const long band, NR_SubcarrierSpacing_t scs, int i_ssb);
|
||||
|
||||
int16_t get_N_RA_RB (int delta_f_RA_PRACH,int delta_f_PUSCH);
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@ typedef struct {
|
||||
NR_TAG_Config_t *tag_Config;
|
||||
NR_PHR_Config_t *phr_Config;
|
||||
NR_RNTI_Value_t *cs_RNTI;
|
||||
NR_MIB_t *mib;
|
||||
NR_MIB_t *mib;
|
||||
|
||||
NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP];
|
||||
NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP];
|
||||
|
||||
@@ -104,7 +104,8 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
LOG_D(MAC,"[L2][MAC] decode mib\n");
|
||||
|
||||
NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
|
||||
|
||||
NR_ServingCellConfigCommon_t *scc = mac->scc;
|
||||
frequency_range_t frequency_range;
|
||||
nr_mac_rrc_data_ind_ue( module_id, cc_id, gNB_index, NR_BCCH_BCH, (uint8_t *) pduP, 3 ); // fixed 3 bytes MIB PDU
|
||||
|
||||
AssertFatal(mac->mib != NULL, "nr_ue_decode_mib() mac->mib == NULL\n");
|
||||
@@ -120,9 +121,11 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
frame = frame << 4;
|
||||
frame = frame | frame_number_4lsb;
|
||||
if(ssb_length == 64){
|
||||
frequency_range = FR2;
|
||||
for (int i=0; i<3; i++)
|
||||
ssb_index += (((extra_bits>>(7-i))&0x01)<<(3+i));
|
||||
}else{
|
||||
frequency_range = FR1;
|
||||
if(ssb_subcarrier_offset_msb){
|
||||
ssb_subcarrier_offset = ssb_subcarrier_offset | 0x10;
|
||||
}
|
||||
@@ -141,13 +144,37 @@ int8_t nr_ue_decode_mib(module_id_t module_id,
|
||||
//storing ssb index in the mac structure
|
||||
mac->mib_ssb = ssb_index;
|
||||
|
||||
get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config, mac->mib, extra_bits, ssb_length, ssb_index,
|
||||
mac->phy_config.config_req.ssb_table.ssb_offset_point_a);
|
||||
if (get_softmodem_params()->sa == 1) {
|
||||
|
||||
// TODO these values shouldn't be taken from SCC in SA
|
||||
uint8_t scs_ssb = *scc->ssbSubcarrierSpacing;
|
||||
uint32_t band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
int scs_scaling = 1<<scs_ssb;
|
||||
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000)
|
||||
scs_scaling = scs_scaling*3;
|
||||
if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA > 2016666)
|
||||
scs_scaling = scs_scaling>>2;
|
||||
uint32_t absolute_diff = (*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA);
|
||||
|
||||
uint16_t ssb_start_symbol = get_ssb_start_symbol(band,scs_ssb,ssb_index);
|
||||
|
||||
get_type0_PDCCH_CSS_config_parameters(&mac->type0_PDCCH_CSS_config,
|
||||
frame,
|
||||
mac->mib,
|
||||
nr_slots_per_frame[scs_ssb],
|
||||
ssb_subcarrier_offset,
|
||||
ssb_start_symbol,
|
||||
scs_ssb,
|
||||
frequency_range,
|
||||
ssb_index,
|
||||
absolute_diff/(12*scs_scaling)-10);
|
||||
|
||||
|
||||
mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
|
||||
mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
|
||||
mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
|
||||
}
|
||||
|
||||
ssb_index = mac->type0_PDCCH_CSS_config.ssb_index; // TODO: ssb_index should obtain from L1 in case Lssb != 64
|
||||
mac->type0_pdcch_ss_mux_pattern = mac->type0_PDCCH_CSS_config.type0_pdcch_ss_mux_pattern;
|
||||
mac->type0_pdcch_ss_sfn_c = mac->type0_PDCCH_CSS_config.sfn_c;
|
||||
mac->type0_pdcch_ss_n_c = mac->type0_PDCCH_CSS_config.n_c;
|
||||
mac->dl_config_request.sfn = mac->type0_PDCCH_CSS_config.frame;
|
||||
mac->dl_config_request.slot = (ssb_index>>1) + ((ssb_index>>4)<<1); // not valid for 240kHz SCS
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ extern RAN_CONTEXT_t RC;
|
||||
extern void mac_top_init_gNB(void);
|
||||
extern uint8_t nfapi_mode;
|
||||
|
||||
void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
|
||||
void config_common(int Mod_idP, int ssb_SubcarrierOffset, int pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) {
|
||||
|
||||
nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[Mod_idP]->config[0];
|
||||
RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon = scc;
|
||||
@@ -240,6 +240,9 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, int pusch_AntennaPorts,
|
||||
cfg->ssb_table.ssb_period.value = *scc->ssb_periodicityServingCell;
|
||||
cfg->ssb_table.ssb_period.tl.tag = NFAPI_NR_CONFIG_SSB_PERIOD_TAG;
|
||||
cfg->num_tlv++;
|
||||
cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
|
||||
cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
|
||||
cfg->num_tlv++;
|
||||
|
||||
switch (scc->ssb_PositionsInBurst->present) {
|
||||
case 1 :
|
||||
@@ -376,6 +379,7 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
LOG_I(MAC,"Configuring common parameters from NR ServingCellConfig\n");
|
||||
|
||||
config_common(Mod_idP,
|
||||
ssb_SubcarrierOffset,
|
||||
pdsch_AntennaPorts,
|
||||
pusch_AntennaPorts,
|
||||
scc);
|
||||
@@ -389,7 +393,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
printf("Waiting for PHY_config_req\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RC.nrmac[Mod_idP]->ssb_SubcarrierOffset = ssb_SubcarrierOffset;
|
||||
RC.nrmac[Mod_idP]->pusch_target_snrx10 = pusch_tgt_snrx10;
|
||||
RC.nrmac[Mod_idP]->pucch_target_snrx10 = pucch_tgt_snrx10;
|
||||
NR_PHY_Config_t phycfg;
|
||||
@@ -397,10 +402,6 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
phycfg.CC_id = 0;
|
||||
phycfg.cfg = &RC.nrmac[Mod_idP]->config[0];
|
||||
|
||||
phycfg.cfg->ssb_table.ssb_subcarrier_offset.value = ssb_SubcarrierOffset;
|
||||
phycfg.cfg->ssb_table.ssb_subcarrier_offset.tl.tag = NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG;
|
||||
phycfg.cfg->num_tlv++;
|
||||
|
||||
if (RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req) RC.nrmac[Mod_idP]->if_inst->NR_PHY_config_req(&phycfg);
|
||||
|
||||
find_SSB_and_RO_available(Mod_idP);
|
||||
|
||||
@@ -53,35 +53,12 @@
|
||||
#include "executables/softmodem-common.h"
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
uint8_t SSB_Slot[64]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,
|
||||
10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,
|
||||
20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,
|
||||
30,30,31,31,32,32,33,33,34,34,35,35,36,36,37,37};
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP,
|
||||
frame_t frameP,
|
||||
sub_frame_t slotP,
|
||||
uint8_t slots_per_frame,
|
||||
int nb_periods_per_frame){
|
||||
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc;
|
||||
|
||||
nfapi_nr_dl_tti_request_t *dl_tti_request;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req;
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu;
|
||||
uint16_t get_ssboffset_pointa(NR_ServingCellConfigCommon_t *scc,const long band) {
|
||||
|
||||
int mib_sdu_length;
|
||||
int CC_id;
|
||||
uint8_t beam_index = 0;
|
||||
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
cc = &gNB->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
|
||||
int ratio;
|
||||
switch (*scc->ssbSubcarrierSpacing) {
|
||||
int ratio;
|
||||
switch (*scc->ssbSubcarrierSpacing) {
|
||||
case NR_SubcarrierSpacing_kHz15:
|
||||
AssertFatal(band <= 79,
|
||||
"Band %ld is not possible for SSB with 15 kHz SCS\n",
|
||||
@@ -115,146 +92,197 @@ void schedule_nr_mib(module_id_t module_idP,
|
||||
default:
|
||||
AssertFatal(1 == 0, "SCS %ld not allowed for SSB \n",
|
||||
*scc->ssbSubcarrierSpacing);
|
||||
}
|
||||
}
|
||||
|
||||
// scheduling MIB every 8 frames, PHY repeats it in between
|
||||
const uint32_t ssb_offset0 = *scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB - scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA;
|
||||
|
||||
return (ssb_offset0/(ratio*12) - 10); // absoluteFrequencySSB is the center of SSB
|
||||
|
||||
}
|
||||
|
||||
|
||||
void schedule_ssb(frame_t frame, sub_frame_t slot,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
int i_ssb, uint8_t scoffset, uint16_t offset_pointa, uint32_t payload) {
|
||||
|
||||
uint8_t beam_index = 0;
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
|
||||
dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
|
||||
|
||||
AssertFatal(scc->physCellId!=NULL,"ServingCellConfigCommon->physCellId is null\n");
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = i_ssb;
|
||||
AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
|
||||
AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
|
||||
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = scoffset; //kSSB
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = offset_pointa;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = payload;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
|
||||
dl_req->nPDUs++;
|
||||
|
||||
LOG_D(MAC,"Scheduling ssb %d at frame %d and slot %d\n",i_ssb,frame,slot);
|
||||
|
||||
}
|
||||
|
||||
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, uint8_t slots_per_frame, int nb_periods_per_frame){
|
||||
|
||||
gNB_MAC_INST *gNB = RC.nrmac[module_idP];
|
||||
NR_COMMON_channels_t *cc;
|
||||
nfapi_nr_dl_tti_request_t *dl_tti_request;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req;
|
||||
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
|
||||
uint8_t num_tdd_period,num_ssb;
|
||||
int mib_sdu_length;
|
||||
int CC_id;
|
||||
|
||||
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
|
||||
cc = &gNB->common_channels[CC_id];
|
||||
NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon;
|
||||
dl_tti_request = &gNB->DL_req[CC_id];
|
||||
dl_req = &dl_tti_request->dl_tti_request_body;
|
||||
|
||||
// get MIB every 8 frames
|
||||
if((slotP == 0) && (frameP & 7) == 0) {
|
||||
dl_tti_request = &gNB->DL_req[CC_id];
|
||||
dl_req = &dl_tti_request->dl_tti_request_body;
|
||||
|
||||
mib_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, MIBCH, 1, &cc->MIB_pdu.payload[0]);
|
||||
|
||||
LOG_D(MAC, "Frame %d, slot %d: BCH PDU length %d\n", frameP, slotP, mib_sdu_length);
|
||||
|
||||
if (mib_sdu_length > 0) {
|
||||
LOG_D(MAC,
|
||||
"Frame %d, slot %d: Adding BCH PDU in position %d (length %d)\n",
|
||||
frameP,
|
||||
slotP,
|
||||
dl_req->nPDUs,
|
||||
mib_sdu_length);
|
||||
|
||||
if ((frameP & 1023) < 80){
|
||||
LOG_D(MAC,
|
||||
"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
|
||||
module_idP,
|
||||
frameP,
|
||||
CC_id,
|
||||
mib_sdu_length);
|
||||
}
|
||||
|
||||
dl_config_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void *) dl_config_pdu, 0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_config_pdu->PDUType = NFAPI_NR_DL_TTI_SSB_PDU_TYPE;
|
||||
dl_config_pdu->PDUSize =2 + sizeof(nfapi_nr_dl_tti_ssb_pdu_rel15_t);
|
||||
|
||||
AssertFatal(scc->physCellId!=NULL,"scc->physCellId is null\n");
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.PhysCellId = *scc->physCellId;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.BetaPss = 0;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbBlockIndex = 0;
|
||||
AssertFatal(scc->downlinkConfigCommon!=NULL,"scc->downlinkConfigCommonL is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB!=NULL,"scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count==1,"Frequency Band list does not have 1 element (%d)\n",
|
||||
scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.count);
|
||||
AssertFatal(scc->ssbSubcarrierSpacing,"ssbSubcarrierSpacing is null\n");
|
||||
AssertFatal(scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0],"band is null\n");
|
||||
|
||||
const nfapi_nr_config_request_scf_t *cfg = &RC.nrmac[module_idP]->config[0];
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.SsbSubcarrierOffset = cfg->ssb_table.ssb_subcarrier_offset.value; //kSSB
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.ssbOffsetPointA = ssb_offset0/(ratio*12) - 10; // absoluteFrequencySSB is the center of SSB
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag = 1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload = (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1);
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.num_prgs=1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prg_size=275; //1 PRG of max size for analogue beamforming
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.dig_bf_interfaces=1;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].pm_idx = 0;
|
||||
dl_config_pdu->ssb_pdu.ssb_pdu_rel15.precoding_and_beamforming.prgs_list[0].dig_bf_interface_list[0].beam_idx = beam_index;
|
||||
dl_req->nPDUs++;
|
||||
}
|
||||
|
||||
// Get type0_PDCCH_CSS_config parameters
|
||||
NR_DL_FRAME_PARMS *frame_parms = &RC.gNB[module_idP]->frame_parms;
|
||||
NR_MIB_t *mib = RC.nrrrc[module_idP]->carrier.mib.message.choice.mib;
|
||||
uint8_t gNB_xtra_byte = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
gNB_xtra_byte |= ((RC.gNB[module_idP]->pbch.pbch_a >> (31 - i)) & 1) << (7 - i);
|
||||
}
|
||||
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config, mib, gNB_xtra_byte, frame_parms->Lmax,
|
||||
frame_parms->ssb_index, frame_parms->ssb_start_subcarrier/NR_NB_SC_PER_RB);
|
||||
|
||||
LOG_D(MAC,
|
||||
"[gNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes\n",
|
||||
module_idP,
|
||||
frameP,
|
||||
CC_id,
|
||||
mib_sdu_length);
|
||||
}
|
||||
|
||||
// checking if there is any SSB in slot
|
||||
const int abs_slot = (slots_per_frame * frameP) + slotP;
|
||||
const int slot_per_period = (slots_per_frame>>1)<<(*scc->ssb_periodicityServingCell);
|
||||
int eff_120_slot;
|
||||
const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
|
||||
const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
|
||||
const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
|
||||
uint8_t buf = 0;
|
||||
switch (scc->ssb_PositionsInBurst->present) {
|
||||
case 1:
|
||||
// presence of ssbs possible in the first 2 slots of ssb period
|
||||
if ((abs_slot % slot_per_period) < 2 &&
|
||||
(((shortBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
|
||||
fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
|
||||
break;
|
||||
case 2:
|
||||
// presence of ssbs possible in the first 4 slots of ssb period
|
||||
if ((abs_slot % slot_per_period) < 4 &&
|
||||
(((mediumBitmap->buf[0]) >> (6 - (slotP << 1))) & 3) != 0)
|
||||
fill_ssb_vrb_map(cc, (ssb_offset0 / (ratio * 12) - 10), CC_id);
|
||||
break;
|
||||
case 3:
|
||||
AssertFatal(*scc->ssbSubcarrierSpacing ==
|
||||
NR_SubcarrierSpacing_kHz120,
|
||||
"240kHZ subcarrier spacing currently not supported for SSBs\n");
|
||||
if ((abs_slot % slot_per_period) < 8) {
|
||||
eff_120_slot = slotP;
|
||||
if((abs_slot % slot_per_period) < 3)
|
||||
buf = longBitmap->buf[0];
|
||||
else
|
||||
buf = longBitmap->buf[1];
|
||||
} else if ((abs_slot % slot_per_period) < 18) {
|
||||
eff_120_slot = slotP - 10;
|
||||
if((abs_slot % slot_per_period) < 13)
|
||||
buf = longBitmap->buf[2];
|
||||
else
|
||||
buf = longBitmap->buf[3];
|
||||
} else if ((abs_slot % slot_per_period) < 28) {
|
||||
eff_120_slot = slotP - 20;
|
||||
if((abs_slot % slot_per_period) < 23)
|
||||
buf = longBitmap->buf[4];
|
||||
else
|
||||
buf = longBitmap->buf[5];
|
||||
} else if ((abs_slot % slot_per_period) < 38) {
|
||||
eff_120_slot = slotP - 30;
|
||||
if((abs_slot % slot_per_period) < 33)
|
||||
buf = longBitmap->buf[6];
|
||||
else
|
||||
buf = longBitmap->buf[7];
|
||||
}
|
||||
if ((eff_120_slot>=0) && (((buf >> (6 - (eff_120_slot << 1))) & 3) != 0)) {
|
||||
AssertFatal(((buf >> (6 - (eff_120_slot << 1))) & 3)<3,"We only support 1 ssb per slot max in FR2 for the moment\n");
|
||||
fill_ssb_vrb_map(cc, ssb_offset0 / (ratio * 12) - 10, CC_id);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
|
||||
scc->ssb_PositionsInBurst->present);
|
||||
}
|
||||
// For FR2 beam ssb association at the beginning of every SSB period
|
||||
if((scc->ssb_PositionsInBurst->present==3) && (abs_slot%slot_per_period == 0)){
|
||||
uint8_t i_ssb,num_tdd_period;
|
||||
uint8_t num_ssb = 0;
|
||||
for (int i=0; i<64; i++){
|
||||
i_ssb=((longBitmap->buf[i/8])>>(7-(i%8)))&1;
|
||||
if(i_ssb==1){
|
||||
num_tdd_period = SSB_Slot[i]/(slots_per_frame/nb_periods_per_frame);
|
||||
gNB->tdd_beam_association[num_tdd_period]=num_ssb;
|
||||
num_ssb++;
|
||||
}
|
||||
int8_t ssb_period = *scc->ssb_periodicityServingCell;
|
||||
uint8_t ssb_frame_periodicity = 1; // every how many frames SSB are generated
|
||||
|
||||
if (ssb_period > 1) // 0 is every half frame
|
||||
ssb_frame_periodicity = 1 << (ssb_period -1);
|
||||
|
||||
if (!(frameP%ssb_frame_periodicity) &&
|
||||
((slotP<(slots_per_frame>>1)) || (ssb_period == 0))) {
|
||||
// schedule SSB only for given frames according to SSB periodicity
|
||||
// and in first half frame unless periodicity of 5ms
|
||||
int rel_slot;
|
||||
if (ssb_period == 0) // scheduling every half frame
|
||||
rel_slot = slotP%(slots_per_frame>>1);
|
||||
else
|
||||
rel_slot = slotP;
|
||||
|
||||
NR_SubcarrierSpacing_t scs = *scc->ssbSubcarrierSpacing;
|
||||
const long band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
uint16_t offset_pointa = get_ssboffset_pointa(scc,band);
|
||||
uint8_t ssbSubcarrierOffset = gNB->ssb_SubcarrierOffset;
|
||||
|
||||
const BIT_STRING_t *shortBitmap = &scc->ssb_PositionsInBurst->choice.shortBitmap;
|
||||
const BIT_STRING_t *mediumBitmap = &scc->ssb_PositionsInBurst->choice.mediumBitmap;
|
||||
const BIT_STRING_t *longBitmap = &scc->ssb_PositionsInBurst->choice.longBitmap;
|
||||
|
||||
uint16_t ssb_start_symbol;
|
||||
|
||||
switch (scc->ssb_PositionsInBurst->present) {
|
||||
case 1:
|
||||
// short bitmap (<3GHz) max 4 SSBs
|
||||
for (int i_ssb=0; i_ssb<4; i_ssb++) {
|
||||
if ((shortBitmap->buf[0]>>(7-i_ssb))&0x01) {
|
||||
ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
|
||||
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
|
||||
if ((ssb_start_symbol/14) == rel_slot){
|
||||
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
|
||||
fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
|
||||
if (get_softmodem_params()->sa == 1) {
|
||||
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
|
||||
frameP,
|
||||
mib,
|
||||
slots_per_frame,
|
||||
ssbSubcarrierOffset,
|
||||
ssb_start_symbol,
|
||||
scs,
|
||||
FR1,
|
||||
i_ssb,
|
||||
offset_pointa);
|
||||
gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
// medium bitmap (<6GHz) max 8 SSBs
|
||||
for (int i_ssb=0; i_ssb<8; i_ssb++) {
|
||||
if ((mediumBitmap->buf[0]>>(7-i_ssb))&0x01) {
|
||||
ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
|
||||
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
|
||||
if ((ssb_start_symbol/14) == rel_slot){
|
||||
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
|
||||
fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
|
||||
if (get_softmodem_params()->sa == 1) {
|
||||
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
|
||||
frameP,
|
||||
mib,
|
||||
slots_per_frame,
|
||||
ssbSubcarrierOffset,
|
||||
ssb_start_symbol,
|
||||
scs,
|
||||
FR1,
|
||||
i_ssb,
|
||||
offset_pointa);
|
||||
gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// long bitmap FR2 max 64 SSBs
|
||||
num_ssb = 0;
|
||||
for (int i_ssb=0; i_ssb<63; i_ssb++) {
|
||||
if ((longBitmap->buf[i_ssb/8]>>(7-i_ssb))&0x01) {
|
||||
ssb_start_symbol = get_ssb_start_symbol(band,scs,i_ssb);
|
||||
// if start symbol is in current slot, schedule current SSB, fill VRB map and call get_type0_PDCCH_CSS_config_parameters
|
||||
if ((ssb_start_symbol/14) == rel_slot){
|
||||
schedule_ssb(frameP, slotP, scc, dl_req, i_ssb, ssbSubcarrierOffset, offset_pointa, (*(uint32_t*)cc->MIB_pdu.payload) & ((1<<24)-1));
|
||||
fill_ssb_vrb_map(cc, offset_pointa, ssb_start_symbol, CC_id);
|
||||
num_tdd_period = rel_slot/(slots_per_frame/nb_periods_per_frame);
|
||||
gNB->tdd_beam_association[num_tdd_period]=i_ssb;
|
||||
num_ssb++;
|
||||
AssertFatal(num_ssb<2,"beamforming currently not supported for more than one SSB per slot\n");
|
||||
if (get_softmodem_params()->sa == 1) {
|
||||
get_type0_PDCCH_CSS_config_parameters(&gNB->type0_PDCCH_CSS_config[i_ssb],
|
||||
frameP,
|
||||
mib,
|
||||
slots_per_frame,
|
||||
ssbSubcarrierOffset,
|
||||
ssb_start_symbol,
|
||||
scs,
|
||||
FR2,
|
||||
i_ssb,
|
||||
offset_pointa);
|
||||
gNB->type0_PDCCH_CSS_config[i_ssb].active = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
|
||||
scc->ssb_PositionsInBurst->present);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,14 +293,22 @@ void schedule_nr_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframe
|
||||
//----------------------------------------
|
||||
}
|
||||
|
||||
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id) {
|
||||
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id) {
|
||||
|
||||
AssertFatal(*cc->ServingCellConfigCommon->ssbSubcarrierSpacing !=
|
||||
NR_SubcarrierSpacing_kHz240,
|
||||
"240kHZ subcarrier won't work with current VRB map because a single SSB might be across 2 slots\n");
|
||||
|
||||
uint16_t *vrb_map = cc[CC_id].vrb_map;
|
||||
|
||||
for (int rb = 0; rb < 20; rb++)
|
||||
vrb_map[rbStart + rb] = 1;
|
||||
vrb_map[rbStart + rb] = 15<<symStart;
|
||||
|
||||
}
|
||||
|
||||
void schedule_control_sib1(module_id_t module_id,
|
||||
int CC_id,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
int time_domain_allocation,
|
||||
uint8_t mcsTableIdx,
|
||||
uint8_t mcs,
|
||||
@@ -286,7 +322,6 @@ void schedule_control_sib1(module_id_t module_id,
|
||||
if (gNB_mac->sched_ctrlCommon == NULL){
|
||||
gNB_mac->sched_ctrlCommon = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon));
|
||||
gNB_mac->sched_ctrlCommon->search_space = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->search_space));
|
||||
gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
|
||||
gNB_mac->sched_ctrlCommon->coreset = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->coreset));
|
||||
gNB_mac->sched_ctrlCommon->active_bwp = calloc(1,sizeof(*gNB_mac->sched_ctrlCommon->active_bwp));
|
||||
fill_default_searchSpaceZero(gNB_mac->sched_ctrlCommon->search_space);
|
||||
@@ -313,8 +348,8 @@ void schedule_control_sib1(module_id_t module_id,
|
||||
|
||||
AssertFatal(gNB_mac->sched_ctrlCommon->cce_index >= 0, "Could not find CCE for coreset0\n");
|
||||
|
||||
const uint16_t bwpSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
int rbStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
|
||||
const uint16_t bwpSize = type0_PDCCH_CSS_config->num_rbs;
|
||||
int rbStart = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
|
||||
// Calculate number of symbols
|
||||
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
@@ -359,6 +394,7 @@ void schedule_control_sib1(module_id_t module_id,
|
||||
|
||||
void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
uint32_t TBS,
|
||||
int StartSymbolIndex,
|
||||
int NrOfSymbols) {
|
||||
@@ -381,6 +417,10 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
scc,
|
||||
bwp);
|
||||
|
||||
// TODO: This assignment should be done in function nr_configure_pdcch()
|
||||
pdcch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config->num_rbs;
|
||||
pdcch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config->cset_start_rb;
|
||||
|
||||
nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs];
|
||||
memset((void*)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t));
|
||||
dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE;
|
||||
@@ -394,8 +434,8 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
pdsch_pdu_rel15->rnti = SI_RNTI;
|
||||
pdsch_pdu_rel15->pduIndex = gNB_mac->pdu_index[0]++;
|
||||
|
||||
pdsch_pdu_rel15->BWPSize = gNB_mac->type0_PDCCH_CSS_config.num_rbs;
|
||||
pdsch_pdu_rel15->BWPStart = gNB_mac->type0_PDCCH_CSS_config.cset_start_rb;
|
||||
pdsch_pdu_rel15->BWPSize = type0_PDCCH_CSS_config->num_rbs;
|
||||
pdsch_pdu_rel15->BWPStart = type0_PDCCH_CSS_config->cset_start_rb;
|
||||
|
||||
pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
if (bwp->bwp_Common->genericParameters.cyclicPrefix) {
|
||||
@@ -452,7 +492,7 @@ void nr_fill_nfapi_dl_sib1_pdu(int Mod_idP,
|
||||
|
||||
// frequency domain assignment
|
||||
dci_payload.frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(
|
||||
pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, gNB_mac->type0_PDCCH_CSS_config.num_rbs);
|
||||
pdsch_pdu_rel15->rbSize, pdsch_pdu_rel15->rbStart, type0_PDCCH_CSS_config->num_rbs);
|
||||
|
||||
dci_payload.time_domain_assignment.val = gNB_mac->sched_ctrlCommon->time_domain_allocation;
|
||||
dci_payload.mcs = gNB_mac->sched_ctrlCommon->mcs;
|
||||
@@ -507,52 +547,80 @@ void schedule_nr_sib1(module_id_t module_idP, frame_t frameP, sub_frame_t slotP)
|
||||
uint8_t candidate_idx = 0;
|
||||
|
||||
gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP];
|
||||
NR_ServingCellConfigCommon_t *scc = gNB_mac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
|
||||
if( (frameP%2 == gNB_mac->type0_PDCCH_CSS_config.sfn_c) && (slotP == gNB_mac->type0_PDCCH_CSS_config.n_0) && (gNB_mac->type0_PDCCH_CSS_config.num_rbs > 0) ) {
|
||||
int L_max;
|
||||
switch (scc->ssb_PositionsInBurst->present) {
|
||||
case 1:
|
||||
L_max = 4;
|
||||
break;
|
||||
case 2:
|
||||
L_max = 8;
|
||||
break;
|
||||
case 3:
|
||||
L_max = 64;
|
||||
break;
|
||||
default:
|
||||
AssertFatal(0,"SSB bitmap size value %d undefined (allowed values 1,2,3)\n",
|
||||
scc->ssb_PositionsInBurst->present);
|
||||
}
|
||||
|
||||
LOG_D(MAC,"> SIB1 transmission\n");
|
||||
for (int i=0; i<L_max; i++) {
|
||||
|
||||
// Get SIB1
|
||||
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
|
||||
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
|
||||
LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
|
||||
LOG_D(MAC,"SIB1: \n");
|
||||
for (int i=0;i<sib1_sdu_length;i++) LOG_D(MAC,"byte %d : %x\n",i,((uint8_t*)sib1_payload)[i]);
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config = &gNB_mac->type0_PDCCH_CSS_config[i];
|
||||
|
||||
// Configure sched_ctrlCommon for SIB1
|
||||
schedule_control_sib1(module_idP, CC_id, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
|
||||
if((frameP%2 == type0_PDCCH_CSS_config->sfn_c) &&
|
||||
(slotP == type0_PDCCH_CSS_config->n_0) &&
|
||||
(type0_PDCCH_CSS_config->num_rbs > 0) &&
|
||||
(type0_PDCCH_CSS_config->active == true)) {
|
||||
|
||||
// Calculate number of symbols
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
LOG_D(MAC,"> SIB1 transmission\n");
|
||||
|
||||
// Calculate number of PRB_DMRS
|
||||
uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
|
||||
uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup, gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
|
||||
uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
|
||||
// Get SIB1
|
||||
uint8_t sib1_payload[NR_MAX_SIB_LENGTH/8];
|
||||
uint8_t sib1_sdu_length = mac_rrc_nr_data_req(module_idP, CC_id, frameP, BCCH, 1, sib1_payload);
|
||||
LOG_D(MAC,"sib1_sdu_length = %i\n", sib1_sdu_length);
|
||||
LOG_D(MAC,"SIB1: \n");
|
||||
for (int i=0;i<sib1_sdu_length;i++) LOG_D(MAC,"byte %d : %x\n",i,((uint8_t*)sib1_payload)[i]);
|
||||
|
||||
const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
|
||||
// Configure sched_ctrlCommon for SIB1
|
||||
schedule_control_sib1(module_idP, CC_id, type0_PDCCH_CSS_config, time_domain_allocation, mcsTableIdx, mcs, candidate_idx, sib1_sdu_length);
|
||||
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, TBS, startSymbolIndex, nrOfSymbols);
|
||||
// Calculate number of symbols
|
||||
int startSymbolIndex, nrOfSymbols;
|
||||
struct NR_PDSCH_TimeDomainResourceAllocationList *tdaList = gNB_mac->sched_ctrlCommon->active_bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList;
|
||||
const int startSymbolAndLength = tdaList->list.array[gNB_mac->sched_ctrlCommon->time_domain_allocation]->startSymbolAndLength;
|
||||
SLIV2SL(startSymbolAndLength, &startSymbolIndex, &nrOfSymbols);
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
// Calculate number of PRB_DMRS
|
||||
uint8_t N_PRB_DMRS = gNB_mac->sched_ctrlCommon->numDmrsCdmGrpsNoData * 6;
|
||||
uint16_t dlDmrsSymbPos = fill_dmrs_mask(gNB_mac->sched_ctrlCommon->active_bwp->bwp_Dedicated->pdsch_Config->choice.setup,
|
||||
gNB_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position, startSymbolIndex+nrOfSymbols);
|
||||
uint16_t dmrs_length = get_num_dmrs(dlDmrsSymbPos);
|
||||
|
||||
// Data to be transmitted
|
||||
bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
|
||||
memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
|
||||
const uint32_t TBS = nr_compute_tbs(nr_get_Qm_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
nr_get_code_rate_dl(gNB_mac->sched_ctrlCommon->mcs, gNB_mac->sched_ctrlCommon->mcsTableIdx),
|
||||
gNB_mac->sched_ctrlCommon->rbSize, nrOfSymbols, N_PRB_DMRS * dmrs_length,0 ,0 ,1 ) >> 3;
|
||||
|
||||
tx_req->PDU_length = TBS;
|
||||
tx_req->PDU_index = gNB_mac->pdu_index[0]++;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
gNB_mac->TX_req[CC_id].SFN = frameP;
|
||||
gNB_mac->TX_req[CC_id].Slot = slotP;
|
||||
nfapi_nr_dl_tti_request_body_t *dl_req = &gNB_mac->DL_req[CC_id].dl_tti_request_body;
|
||||
nr_fill_nfapi_dl_sib1_pdu(module_idP, dl_req, type0_PDCCH_CSS_config, TBS, startSymbolIndex, nrOfSymbols);
|
||||
|
||||
const int ntx_req = gNB_mac->TX_req[CC_id].Number_of_PDUs;
|
||||
nfapi_nr_pdu_t *tx_req = &gNB_mac->TX_req[CC_id].pdu_list[ntx_req];
|
||||
|
||||
// Data to be transmitted
|
||||
bzero(tx_req->TLVs[0].value.direct,MAX_NR_DLSCH_PAYLOAD_BYTES);
|
||||
memcpy(tx_req->TLVs[0].value.direct, sib1_payload, sib1_sdu_length);
|
||||
|
||||
tx_req->PDU_length = TBS;
|
||||
tx_req->PDU_index = gNB_mac->pdu_index[0]++;
|
||||
tx_req->num_TLV = 1;
|
||||
tx_req->TLVs[0].length = TBS + 2;
|
||||
gNB_mac->TX_req[CC_id].Number_of_PDUs++;
|
||||
gNB_mac->TX_req[CC_id].SFN = frameP;
|
||||
gNB_mac->TX_req[CC_id].Slot = slotP;
|
||||
|
||||
type0_PDCCH_CSS_config->active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ void set_cset_offset(uint16_t);
|
||||
void mac_top_init_gNB(void);
|
||||
|
||||
void config_common(int Mod_idP,
|
||||
int ssb_SubcarrierOffset,
|
||||
int pdsch_AntennaPorts,
|
||||
int pusch_AntennaPorts,
|
||||
NR_ServingCellConfigCommon_t *scc
|
||||
@@ -72,6 +73,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
|
||||
|
||||
void schedule_control_sib1(module_id_t module_id,
|
||||
int CC_id,
|
||||
NR_Type0_PDCCH_CSS_config_t *type0_PDCCH_CSS_config,
|
||||
int time_domain_allocation,
|
||||
uint8_t mcsTableIdx,
|
||||
uint8_t mcs,
|
||||
@@ -367,7 +369,7 @@ int binomial(int n, int k);
|
||||
|
||||
bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot);
|
||||
|
||||
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, int CC_id);
|
||||
void fill_ssb_vrb_map (NR_COMMON_channels_t *cc, int rbStart, uint16_t symStart, int CC_id);
|
||||
|
||||
|
||||
/* \brief Function to indicate a received SDU on ULSCH.
|
||||
|
||||
@@ -611,6 +611,8 @@ typedef struct gNB_MAC_INST_s {
|
||||
int pusch_target_snrx10;
|
||||
/// Pucch target SNR
|
||||
int pucch_target_snrx10;
|
||||
/// Subcarrier Offset
|
||||
int ssb_SubcarrierOffset;
|
||||
/// Common cell resources
|
||||
NR_COMMON_channels_t common_channels[NFAPI_CC_MAX];
|
||||
/// current PDU index (BCH,DLSCH)
|
||||
@@ -677,7 +679,7 @@ typedef struct gNB_MAC_INST_s {
|
||||
|
||||
NR_UE_sched_ctrl_t *sched_ctrlCommon;
|
||||
NR_CellGroupConfig_t *secondaryCellGroupCommon;
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config;
|
||||
NR_Type0_PDCCH_CSS_config_t type0_PDCCH_CSS_config[64];
|
||||
|
||||
} gNB_MAC_INST;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "nr_pdcp_security_nea2.h"
|
||||
#include "nr_pdcp_integrity_nia2.h"
|
||||
#include "nr_pdcp_sdu.h"
|
||||
|
||||
#include "LOG/log.h"
|
||||
@@ -54,17 +55,21 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||
}
|
||||
|
||||
if (entity->sn_size == 12) {
|
||||
rcvd_sn = (((unsigned char)buffer[0] & 0xf) << 8) |
|
||||
(unsigned char)buffer[1];
|
||||
rcvd_sn = ((buffer[0] & 0xf) << 8) |
|
||||
buffer[1];
|
||||
header_size = 2;
|
||||
} else {
|
||||
rcvd_sn = (((unsigned char)buffer[0] & 0x3) << 16) |
|
||||
((unsigned char)buffer[1] << 8) |
|
||||
(unsigned char)buffer[2];
|
||||
rcvd_sn = ((buffer[0] & 0x3) << 16) |
|
||||
(buffer[1] << 8) |
|
||||
buffer[2];
|
||||
header_size = 3;
|
||||
}
|
||||
|
||||
integrity_size = 0;
|
||||
if (entity->has_integrity) {
|
||||
integrity_size = 4;
|
||||
} else {
|
||||
integrity_size = 0;
|
||||
}
|
||||
|
||||
if (size < header_size + integrity_size + 1) {
|
||||
LOG_E(PDCP, "bad PDU received (size = %d)\n", size);
|
||||
@@ -86,9 +91,20 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
|
||||
|
||||
if (entity->has_ciphering)
|
||||
entity->cipher(entity->security_context,
|
||||
(unsigned char *)buffer+header_size, size-header_size,
|
||||
buffer+header_size, size-header_size,
|
||||
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
|
||||
|
||||
if (entity->has_integrity) {
|
||||
unsigned char integrity[4];
|
||||
entity->integrity(entity->integrity_context, integrity,
|
||||
buffer, size - integrity_size,
|
||||
entity->rb_id, rcvd_count, entity->is_gnb ? 0 : 1);
|
||||
if (memcmp(integrity, buffer, 4) != 0) {
|
||||
LOG_E(PDCP, "discard NR PDU, integrity failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rcvd_count < entity->rx_deliv
|
||||
|| nr_pdcp_sdu_in_list(entity->rx_list, rcvd_count)) {
|
||||
LOG_D(PDCP, "discard NR PDU rcvd_count=%d\n", rcvd_count);
|
||||
@@ -139,39 +155,62 @@ static void nr_pdcp_entity_recv_sdu(nr_pdcp_entity_t *entity,
|
||||
uint32_t count;
|
||||
int sn;
|
||||
int header_size;
|
||||
char buf[size+3+4];
|
||||
int integrity_size;
|
||||
char buf[size + 3 + 4];
|
||||
int dc_bit;
|
||||
|
||||
count = entity->tx_next;
|
||||
sn = entity->tx_next & entity->sn_max;
|
||||
|
||||
/* D/C bit is only to be set for DRBs */
|
||||
if (entity->type == NR_PDCP_DRB_AM || entity->type == NR_PDCP_DRB_UM) {
|
||||
dc_bit = 0x80;
|
||||
} else {
|
||||
dc_bit = 0;
|
||||
}
|
||||
|
||||
if (entity->sn_size == 12) {
|
||||
buf[0] = 0x80 | ((sn >> 8) & 0xf);
|
||||
buf[0] = dc_bit | ((sn >> 8) & 0xf);
|
||||
buf[1] = sn & 0xff;
|
||||
header_size = 2;
|
||||
} else {
|
||||
buf[0] = 0x80 | ((sn >> 16) & 0x3);
|
||||
buf[0] = dc_bit | ((sn >> 16) & 0x3);
|
||||
buf[1] = (sn >> 8) & 0xff;
|
||||
buf[2] = sn & 0xff;
|
||||
header_size = 3;
|
||||
}
|
||||
|
||||
memcpy(buf+header_size, buffer, size);
|
||||
if (entity->has_integrity) {
|
||||
integrity_size = 4;
|
||||
} else {
|
||||
integrity_size = 0;
|
||||
}
|
||||
|
||||
memcpy(buf + header_size, buffer, size);
|
||||
|
||||
if (entity->has_integrity)
|
||||
entity->integrity(entity->integrity_context,
|
||||
(unsigned char *)buf + header_size + size,
|
||||
(unsigned char *)buf, header_size + size,
|
||||
entity->rb_id, count, entity->is_gnb ? 1 : 0);
|
||||
|
||||
if (entity->has_ciphering)
|
||||
entity->cipher(entity->security_context,
|
||||
(unsigned char *)buf+header_size, size,
|
||||
(unsigned char *)buf + header_size, size + integrity_size,
|
||||
entity->rb_id, count, entity->is_gnb ? 1 : 0);
|
||||
|
||||
entity->tx_next++;
|
||||
|
||||
entity->deliver_pdu(entity->deliver_pdu_data, entity, buf,
|
||||
size+header_size, sdu_id);
|
||||
header_size + size + integrity_size, sdu_id);
|
||||
}
|
||||
|
||||
static void nr_pdcp_entity_set_integrity_key(nr_pdcp_entity_t *entity,
|
||||
char *key)
|
||||
{
|
||||
memcpy(entity->integrity_key, key, 16);
|
||||
LOG_E(PDCP, "%s: %d: %s: TODO? to remove?\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
//memcpy(entity->integrity_key, key, 16);
|
||||
}
|
||||
|
||||
static void check_t_reordering(nr_pdcp_entity_t *entity)
|
||||
@@ -232,6 +271,8 @@ void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity)
|
||||
}
|
||||
if (entity->free_security != NULL)
|
||||
entity->free_security(entity->security_context);
|
||||
if (entity->free_integrity != NULL)
|
||||
entity->free_integrity(entity->integrity_context);
|
||||
free(entity);
|
||||
}
|
||||
|
||||
@@ -298,9 +339,18 @@ nr_pdcp_entity_t *new_nr_pdcp_entity(
|
||||
}
|
||||
ret->is_gnb = is_gnb;
|
||||
|
||||
if (integrity_key != NULL) {
|
||||
printf("%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__);
|
||||
exit(1);
|
||||
if (integrity_key != NULL && integrity_algorithm != 0) {
|
||||
if (integrity_algorithm != 2) {
|
||||
LOG_E(PDCP, "FATAL: only nia2 supported for the moment\n");
|
||||
exit(1);
|
||||
}
|
||||
ret->has_integrity = 1;
|
||||
ret->integrity_algorithm = integrity_algorithm;
|
||||
memcpy(ret->integrity_key, integrity_key, 16);
|
||||
|
||||
ret->integrity_context = nr_pdcp_integrity_nia2_init(integrity_key);
|
||||
ret->integrity = nr_pdcp_integrity_nia2_integrity;
|
||||
ret->free_integrity = nr_pdcp_integrity_nia2_free_integrity;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -85,7 +85,12 @@ typedef struct nr_pdcp_entity_t {
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
void (*free_security)(void *security_context);
|
||||
/* security algorithms need to know uplink/downlink information
|
||||
void *integrity_context;
|
||||
void (*integrity)(void *integrity_context, unsigned char *out,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
void (*free_integrity)(void *integrity_context);
|
||||
/* security/integrity algorithms need to know uplink/downlink information
|
||||
* which is reverse for gnb and ue, so we need to know if this
|
||||
* pdcp entity is for a gnb or an ue
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "nr_pdcp_integrity_nia2.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <openssl/cmac.h>
|
||||
|
||||
void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key)
|
||||
{
|
||||
CMAC_CTX *ctx;
|
||||
|
||||
ctx = CMAC_CTX_new();
|
||||
if (ctx == NULL) abort();
|
||||
|
||||
CMAC_Init(ctx, integrity_key, 16, EVP_aes_128_cbc(), NULL);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void compute_t(unsigned char *t, uint32_t count, int bearer,
|
||||
int direction)
|
||||
{
|
||||
t[0] = (count >> 24) & 255;
|
||||
t[1] = (count >> 16) & 255;
|
||||
t[2] = (count >> 8) & 255;
|
||||
t[3] = (count ) & 255;
|
||||
t[4] = (bearer << 3) | (direction << 2);
|
||||
memset(&t[5], 0, 8-5);
|
||||
}
|
||||
|
||||
void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
|
||||
unsigned char *out,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction)
|
||||
{
|
||||
CMAC_CTX *ctx = integrity_context;
|
||||
unsigned char t[8];
|
||||
unsigned char mac[16];
|
||||
size_t maclen;
|
||||
|
||||
/* see 33.401 B.2.3 for the input to 128-EIA2
|
||||
* (which is identical to 128-NIA2, see 33.501 D.3.1.3) */
|
||||
compute_t(t, count, bearer, direction);
|
||||
|
||||
CMAC_Update(ctx, t, 8);
|
||||
CMAC_Update(ctx, buffer, length);
|
||||
CMAC_Final(ctx, mac, &maclen);
|
||||
|
||||
/* AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of
|
||||
* 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant
|
||||
* bit first (so seems to say 33.401 B.2.3)
|
||||
*/
|
||||
memcpy(out, mac, 4);
|
||||
}
|
||||
|
||||
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context)
|
||||
{
|
||||
CMAC_CTX *ctx = integrity_context;
|
||||
CMAC_CTX_free(ctx);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _NR_PDCP_INTEGRITY_NIA2_H_
|
||||
#define _NR_PDCP_INTEGRITY_NIA2_H_
|
||||
|
||||
void *nr_pdcp_integrity_nia2_init(unsigned char *integrity_key);
|
||||
|
||||
void nr_pdcp_integrity_nia2_integrity(void *integrity_context,
|
||||
unsigned char *out,
|
||||
unsigned char *buffer, int length,
|
||||
int bearer, int count, int direction);
|
||||
|
||||
void nr_pdcp_integrity_nia2_free_integrity(void *integrity_context);
|
||||
|
||||
#endif /* _NR_PDCP_INTEGRITY_NIA2_H_ */
|
||||
@@ -48,7 +48,8 @@ typedef enum {
|
||||
NAS_INT_ALG = 0x02,
|
||||
RRC_ENC_ALG = 0x03,
|
||||
RRC_INT_ALG = 0x04,
|
||||
UP_ENC_ALG = 0x05
|
||||
UP_ENC_ALG = 0x05,
|
||||
UP_INT_ALG = 0x06
|
||||
} algorithm_type_dist_t;
|
||||
|
||||
//int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
|
||||
|
||||
@@ -23,6 +23,7 @@ gNBs =
|
||||
|
||||
ssb_SubcarrierOffset = 0;
|
||||
pdsch_AntennaPorts = 1;
|
||||
pusch_AntennaPorts = 1;
|
||||
pusch_TargetSNRx10 = 200;
|
||||
pucch_TargetSNRx10 = 200;
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -177,7 +177,7 @@ gNBs =
|
||||
nrofUplinkSlots = 10;
|
||||
nrofUplinkSymbols = 0;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -188,7 +188,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -186,7 +186,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -186,7 +186,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -177,7 +177,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -186,7 +186,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -177,7 +177,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25; // -25 dBm/RE is the maximum measured power from USRP corresponding to att_tx = 0 dB
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -182,7 +182,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@@ -187,7 +187,7 @@ gNBs =
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = 10;
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user