Merge branch 'develop' into trx_thread_param

This commit is contained in:
WANG Tsu-Han
2020-06-29 10:30:55 +02:00
216 changed files with 14251 additions and 8154 deletions
+11 -4
View File
@@ -47,7 +47,7 @@
#include "SCHED/sched_eNB.h"
#include "SCHED_NR/sched_nr.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
@@ -162,14 +162,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
/*if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus||
gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs ||
gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs ||
gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles ||
gNB->UL_INFO.rach_ind.number_of_pdus ||
gNB->UL_INFO.cqi_ind.number_of_cqis
) {
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n",
NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus,
NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs,
NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs,
NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles,
gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus,
gNB->UL_INFO.cqi_ind.number_of_cqis,
frame_rx, slot_rx,
frame_tx, slot_tx);
@@ -202,6 +202,13 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t
if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) {
// UE-specific RX processing for subframe n
// TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT
// Do PRACH RU processing
int prach_id=find_nr_prach(gNB,frame_rx,slot_rx,0,SEARCH_EXIST);
if (prach_id>=0) {
L1_nr_prach_procedures(gNB,frame_rx,slot_rx,&gNB->prach_vars.list[prach_id].pdu);
gNB->prach_vars.list[prach_id].frame=-1;
}
phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx);
}
+84 -28
View File
@@ -51,6 +51,7 @@
#include "PHY/defs_nr_common.h"
#include "PHY/phy_extern.h"
#include "PHY/LTE_TRANSPORT/transport_proto.h"
#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
#include "PHY/INIT/phy_init.h"
#include "SCHED/sched_eNB.h"
#include "SCHED_NR/sched_nr.h"
@@ -290,7 +291,7 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
// southbound IF4p5 fronthaul
void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp)
{
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff );
LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx);
@@ -501,7 +502,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) {
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
RU_proc_t *proc = &ru->proc;
uint16_t packet_type;
uint32_t symbol_number,symbol_mask,symbol_mask_full=0;
@@ -698,7 +699,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) {
void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) {
RU_proc_t *proc = &ru->proc;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
void *txp[ru->nb_tx];
unsigned int txs;
int i,txsymb;
@@ -790,7 +791,7 @@ void *ru_thread_asynch_rxtx( void *param ) {
static int ru_thread_asynch_rxtx_status;
RU_t *ru = (RU_t *)param;
RU_proc_t *proc = &ru->proc;
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
int slot=0, frame=0;
// wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe
wait_sync("ru_thread_asynch_rxtx");
@@ -1035,10 +1036,10 @@ int wakeup_prach_ru(RU_t *ru) {
void fill_rf_config(RU_t *ru, char *rf_config_file) {
int i;
NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms;
nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index
nfapi_nr_config_request_scf_t *config = &ru->config; //tmp index
openair0_config_t *cfg = &ru->openair0_cfg;
int mu = gNB_config->ssb_config.scs_common.value;
int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
int mu = config->ssb_config.scs_common.value;
int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
if (mu == NR_MU_0) { //or if LTE
if(N_RB == 100) {
@@ -1123,7 +1124,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) {
AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu);
}
if (gNB_config->cell_config.frame_duplex_type.value==TDD)
if (config->cell_config.frame_duplex_type.value==TDD)
cfg->duplex_mode = duplex_mode_TDD;
else //FDD
cfg->duplex_mode = duplex_mode_FDD;
@@ -1162,7 +1163,7 @@ int setup_RU_buffers(RU_t *ru) {
int card,ant;
//uint16_t N_TA_offset = 0;
NR_DL_FRAME_PARMS *frame_parms;
//nfapi_nr_config_request_t *gNB_config = ru->gNB_list[0]->gNB_config; //tmp index
nfapi_nr_config_request_scf_t *config = &ru->config;
if (ru) {
frame_parms = ru->nr_frame_parms;
@@ -1171,12 +1172,54 @@ int setup_RU_buffers(RU_t *ru) {
printf("ru pointer is NULL\n");
return(-1);
}
int mu = config->ssb_config.scs_common.value;
int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value;
/* if (frame_parms->frame_type == TDD) {
if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624;
else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2;
else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4;
} */
if (config->cell_config.frame_duplex_type.value == TDD) {
int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
double factor=1;
switch (mu) {
case 0: //15 kHz scs
AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n");
if (N_RB <= 25) factor = .25; // 7.68 Ms/s
else if (N_RB <=50) factor = .5; // 15.36 Ms/s
else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
else AssertFatal(1==0,"Too many PRBS for mu=0\n");
break;
case 1: //30 kHz sc
AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n");
if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
break;
case 2: //60 kHz scs
AssertFatal(1==0,"scs_common should not be 60 kHz\n");
break;
case 3: //120 kHz scs
AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n");
break;
case 4: //240 kHz scs
AssertFatal(1==0,"scs_common should not be 60 kHz\n");
if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
break;
if (N_RB == 100) ru->N_TA_offset = 624;
else if (N_RB == 50) ru->N_TA_offset = 624/2;
else if (N_RB == 25) ru->N_TA_offset = 624/4;
}
if (frame_parms->threequarter_fs == 1) factor = factor*.75;
ru->N_TA_offset = (int)(N_TA_offset * factor);
LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor,
config->carrier_config.uplink_frequency.value, N_RB);
}
else ru->N_TA_offset = 0;
if (ru->openair0_cfg.mmapped_dma == 1) {
// replace RX signal buffers with mmaped HW versions
for (i=0; i<ru->nb_rx; i++) {
@@ -1389,7 +1432,7 @@ void *ru_thread( void *param ) {
int i = 0;
int aa;
nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
// set default return value
ru_thread_status = 0;
@@ -1401,7 +1444,7 @@ void *ru_thread( void *param ) {
if(emulate_rf) {
fill_rf_config(ru,ru->rf_config_file);
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
nr_phy_init_RU(ru);
@@ -1421,8 +1464,10 @@ void *ru_thread( void *param ) {
AssertFatal(ret==0,"Cannot connect to remote radio\n");
}
memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config));
if (ru->if_south == LOCAL_RF) { // configure RF parameters only
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp);
nr_init_frame_parms(&ru->config, fp);
nr_dump_frame_parms(fp);
fill_rf_config(ru,ru->rf_config_file);
nr_phy_init_RU(ru);
@@ -1535,6 +1580,17 @@ void *ru_thread( void *param ) {
for (aa=0;aa<ru->nb_rx;aa++)
memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa],
(void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t));
// Do PRACH RU processing
int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST);
if (prach_id>=0) {
rx_nr_prach_ru(ru,
ru->prach_list[prach_id].fmt,
ru->prach_list[prach_id].numRA,
ru->prach_list[prach_id].prachStartSymbol,
proc->frame_rx,proc->tti_rx);
free_nr_ru_prach_entry(ru,prach_id);
}
}
// At this point, all information for subframe has been received on FH interface
@@ -1906,7 +1962,7 @@ void configure_ru(int idx,
RU_t *ru = RC.ru[idx];
RRU_config_t *config = (RRU_config_t *)arg;
RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg;
nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
int ret;
LOG_I(PHY, "Received capabilities from RRU %d\n",idx);
@@ -1929,15 +1985,15 @@ void configure_ru(int idx,
//config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S;
config->att_tx[0] = ru->att_tx;
config->att_rx[0] = ru->att_rx;
config->N_RB_DL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
config->N_RB_UL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value;
config->N_RB_DL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
config->N_RB_UL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value;
config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs;
/* if (ru->if_south==REMOTE_IF4p5) {
config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset;
config->prach_ConfigIndex[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n",
config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);*/
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms);
nr_init_frame_parms(&ru->config, ru->nr_frame_parms);
nr_phy_init_RU(ru);
}
@@ -1945,23 +2001,23 @@ void configure_rru(int idx,
void *arg) {
RRU_config_t *config = (RRU_config_t *)arg;
RU_t *ru = RC.ru[idx];
nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config;
nfapi_nr_config_request_scf_t *cfg = &ru->config;
ru->nr_frame_parms->nr_band = config->band_list[0];
ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0];
ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0];
if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) {
gNB_config->cell_config.frame_duplex_type.value = TDD;
cfg->cell_config.frame_duplex_type.value = TDD;
//ru->nr_frame_parms->tdd_config = config->tdd_config[0];
//ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0];
} else
gNB_config->cell_config.frame_duplex_type.value = FDD;
cfg->cell_config.frame_duplex_type.value = FDD;
ru->att_tx = config->att_tx[0];
ru->att_rx = config->att_rx[0];
int mu = gNB_config->ssb_config.scs_common.value;
gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0];
gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0];
int mu = cfg->ssb_config.scs_common.value;
cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0];
cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0];
ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0];
//ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0];
@@ -1976,7 +2032,7 @@ void configure_rru(int idx,
}
fill_rf_config(ru,ru->rf_config_file);
nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms);
nr_init_frame_parms(&ru->config, ru->nr_frame_parms);
nr_phy_init_RU(ru);
}
+1
View File
@@ -57,6 +57,7 @@
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n"
#define CONFIG_HLP_EXCCLK "tells hardware to use a clock reference (0:internal(default), 1:external, 2:gpsdo)\n"
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
+36 -25
View File
@@ -178,6 +178,7 @@ extern void reset_opp_meas(void);
extern void print_opp_meas(void);
extern void init_eNB_afterRU(void);
extern void *udp_eNB_task(void *args_p);
int transmission_mode=1;
int emulate_rf = 0;
@@ -385,10 +386,10 @@ int create_gNB_tasks(uint32_t gnb_nb) {
if (gnb_nb > 0) {
/* Last task to create, others task must be ready before its start */
if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
/*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1;
}
}*/
if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
@@ -403,35 +404,39 @@ int create_gNB_tasks(uint32_t gnb_nb) {
}
}
/*
if (EPC_MODE_ENABLED) {
if (gnb_nb > 0) {
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
}
if (EPC_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) {
if (gnb_nb > 0) {
/*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
LOG_E(SCTP, "Create task for SCTP failed\n");
return -1;
}
if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
LOG_E(S1AP, "Create task for S1AP failed\n");
return -1;
}
if(!emulate_rf){
if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
LOG_E(UDP_, "Create task for UDP failed\n");
return -1;
}
}
if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
LOG_E(S1AP, "Create task for S1AP failed\n");
return -1;
}*/
if (itti_create_task (TASK_GTPV1_U, &gtpv1u_eNB_task, NULL) < 0) {
LOG_E(GTPU, "Create task for GTPV1U failed\n");
return -1;
}
if(!emulate_rf){
if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) {
LOG_E(UDP_, "Create task for UDP failed\n");
return -1;
}
}
if (itti_create_task (TASK_GTPV1_U, &gtpv1u_gNB_task, NULL) < 0) {
LOG_E(GTPU, "Create task for GTPV1U failed\n");
return -1;
}
}
*/
}
if (gnb_nb > 0) {
if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) {
LOG_E(GNB_APP, "Create task for gNB APP failed\n");
return -1;
}
LOG_I(NR_RRC,"Creating NR RRC gNB Task\n");
if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) {
@@ -820,6 +825,10 @@ int main( int argc, char **argv )
}
openair0_cfg[0].threequarter_fs = threequarter_fs;
EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test;
if (get_softmodem_params()->do_ra)
AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
#if T_TRACER
T_Config_Init();
@@ -955,7 +964,9 @@ if(!IS_SOFTMODEM_NOS1)
scopeParms_t p;
p.argc=&argc;
p.argv=argv;
startScope(&p);
p.gNB=RC.gNB[0];
p.ru=RC.ru[0];
gNBinitScope(&p);
}
if (nfapi_mode != 1 && nfapi_mode != 2) {
+55 -132
View File
@@ -21,7 +21,7 @@
#include "executables/thread-common.h"
#include "executables/nr-uesoftmodem.h"
#include "LAYER2/NR_MAC_UE/mac.h"
#include "NR_MAC_UE/mac.h"
//#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
@@ -32,7 +32,7 @@
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "NR_MAC_UE/mac_proto.h"
#include "RRC/NR_UE/rrc_proto.h"
//#ifndef NO_RAT_NR
@@ -142,15 +142,23 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue,
uint8_t abstraction_flag)
{
int nb_connected_gNB = 1, gNB_id;
memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS));
ue->Mod_id = UE_id;
ue->mac_enabled = 1;
// Setting UE mode to NOT_SYNCHED by default
for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){
ue->UE_mode[gNB_id] = NOT_SYNCHED;
ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t));
}
// initialize all signal buffers
init_nr_ue_signal(ue,1,abstraction_flag);
init_nr_ue_signal(ue, nb_connected_gNB, abstraction_flag);
// intialize transport
init_nr_ue_transport(ue,abstraction_flag);
init_nr_ue_transport(ue, abstraction_flag);
}
/*!
@@ -358,82 +366,31 @@ static void UE_synch(void *arg) {
void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
uint32_t rb_size, rb_start;
uint16_t rnti, l_prime_mask, n_rb0, n_rb1, pdu_bit_map;
uint8_t nr_of_symbols, start_symbol_index, mcs_index, mcs_table, nrOfLayers, harq_process_id, rv_index, dmrs_config_type;
uint8_t ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, ptrs_time_density, ptrs_freq_density;
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int tx_slot_type = nr_ue_slot_select(cfg, proc->frame_tx, proc->nr_tti_tx);
uint8_t gNB_id = 0;
// program PUSCH. this should actually be done by the MAC upon reception of an UL DCI
if (proc->nr_tti_tx == 8 || UE->frame_parms.frame_type == FDD){
if (tx_slot_type == NR_UPLINK_SLOT || tx_slot_type == NR_MIXED_SLOT){
dcireq.module_id = UE->Mod_id;
dcireq.gNB_index = 0;
dcireq.cc_id = 0;
dcireq.frame = proc->frame_rx;
dcireq.slot = proc->nr_tti_rx;
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
nr_uplink_indication_t ul_indication;
memset((void*)&ul_indication, 0, sizeof(ul_indication));
scheduled_response.dl_config = NULL;
scheduled_response.ul_config = &dcireq.ul_config_req;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = UE->Mod_id;
scheduled_response.CC_id = 0;
scheduled_response.frame = proc->frame_rx;
scheduled_response.slot = proc->nr_tti_rx;
//--------------------------Temporary configuration-----------------------------//
rnti = 0x1234;
rb_size = 50;
rb_start = 0;
nr_of_symbols = 12;
start_symbol_index = 2;
nrOfLayers = 1;
mcs_index = 9;
mcs_table = 0;
harq_process_id = 0;
rv_index = 0;
l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1);
dmrs_config_type = 0;
ptrs_mcs1 = 2;
ptrs_mcs2 = 4;
ptrs_mcs3 = 10;
n_rb0 = 25;
n_rb1 = 75;
pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA;
ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table);
ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size);
//------------------------------------------------------------------------------//
ul_indication.module_id = UE->Mod_id;
ul_indication.gNB_index = gNB_id;
ul_indication.cc_id = UE->CC_id;
ul_indication.frame_rx = proc->frame_rx;
ul_indication.slot_rx = proc->nr_tti_rx;
ul_indication.frame_tx = proc->frame_tx;
ul_indication.slot_tx = proc->nr_tti_tx;
scheduled_response.ul_config->slot = 8;
scheduled_response.ul_config->number_pdus = 1;
scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density;
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t));
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0;
if (1 << ptrs_time_density >= nr_of_symbols) {
scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS
UE->if_inst->ul_indication(&ul_indication);
}
nr_ue_scheduled_response(&scheduled_response);
if (UE->mode != loop_through_memory) {
uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx];
uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_rx];
phy_procedures_nrUE_TX(UE,proc,0,thread_id);
}
}
@@ -441,41 +398,26 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
nr_dcireq_t dcireq;
nr_scheduled_response_t scheduled_response;
uint8_t ssb_period = UE->nrUE_config.ssb_table.ssb_period;
fapi_nr_config_request_t *cfg = &UE->nrUE_config;
int rx_slot_type = nr_ue_slot_select(cfg, proc->frame_rx, proc->nr_tti_rx);
uint8_t gNB_id = 0;
//program DCI for slot 1
//TODO: all of this has to be moved to the MAC!!!
if (proc->nr_tti_rx == NR_DOWNLINK_SLOT || UE->frame_parms.frame_type == FDD){
dcireq.module_id = UE->Mod_id;
dcireq.gNB_index = 0;
dcireq.cc_id = 0;
dcireq.frame = proc->frame_rx;
dcireq.slot = proc->nr_tti_rx;
nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
if (rx_slot_type == NR_DOWNLINK_SLOT || rx_slot_type == NR_MIXED_SLOT){
// we should have received a DL DCI here, so configure DL accordingly
scheduled_response.dl_config = &dcireq.dl_config_req;
scheduled_response.ul_config = NULL;
scheduled_response.tx_request = NULL;
scheduled_response.module_id = UE->Mod_id;
scheduled_response.CC_id = 0;
if (!((proc->frame_rx)%(1<<(ssb_period-1)))) {
if(proc->frame_rx > dcireq.dl_config_req.sfn)
UE->frame_gap = proc->frame_rx - dcireq.dl_config_req.sfn;
if(proc->frame_rx < dcireq.dl_config_req.sfn)
UE->frame_gap = dcireq.dl_config_req.sfn - proc->frame_rx;
proc->frame_rx = dcireq.dl_config_req.sfn;
if(UE->if_inst != NULL && UE->if_inst->dl_indication != NULL) {
nr_downlink_indication_t dl_indication;
memset((void*)&dl_indication, 0, sizeof(dl_indication));
dl_indication.module_id = UE->Mod_id;
dl_indication.gNB_index = gNB_id;
dl_indication.cc_id = UE->CC_id;
dl_indication.frame = proc->frame_rx;
dl_indication.slot = proc->nr_tti_rx;
UE->if_inst->dl_indication(&dl_indication, NULL);
}
scheduled_response.frame = proc->frame_rx;
scheduled_response.slot = proc->nr_tti_rx;
nr_ue_scheduled_response(&scheduled_response);
}
// Process Rx data for one sub-frame
if ( proc->nr_tti_rx >=0 && proc->nr_tti_rx <= 1 ) {
#ifdef UE_SLOT_PARALLELISATION
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, UE->mode, no_relay, NULL );
#else
@@ -494,22 +436,6 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) {
pdcp_run(&ctxt);
}
}
// no UL for now
/*
if (UE->mac_enabled==1) {
// trigger L2 to run ue_scheduler thru IF module
// [TODO] mapping right after NR initial sync
if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) {
UE->ul_indication.module_id = 0;
UE->ul_indication.gNB_index = 0;
UE->ul_indication.cc_id = 0;
UE->ul_indication.frame = proc->frame_rx;
UE->ul_indication.slot = proc->nr_tti_rx;
UE->if_inst->ul_indication(&UE->ul_indication);
}
}
*/
}
/*!
@@ -526,7 +452,7 @@ typedef struct processingData_s {
} processingData_t;
void UE_processing(void *arg) {
processingData_t *rxtxD=(processingData_t *) arg;
processingData_t *rxtxD = (processingData_t *) arg;
UE_nr_rxtx_proc_t *proc = &rxtxD->proc;
PHY_VARS_NR_UE *UE = rxtxD->UE;
@@ -556,9 +482,7 @@ void UE_processing(void *arg) {
}
processSlotRX(UE, proc);
processSlotTX(UE, proc);
}
void dummyWrite(PHY_VARS_NR_UE *UE,openair0_timestamp timestamp, int writeBlockSize) {
@@ -633,11 +557,6 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
}
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
if (IS_SOFTMODEM_RFSIM) {
LOG_D(PHY,"SET rx_offset %d \n",UE->rx_offset);
//UE->rx_offset_diff=0;
return 0;
}
// compute TO compensation that should be applied for this frame
if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 &&
@@ -704,8 +623,11 @@ void *UE_thread(void *arg) {
if (res) {
syncRunning=false;
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
decoded_frame_rx=(tmp->proc.decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
if (UE->is_synchronized) {
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
decoded_frame_rx=(decoded_frame_rx + (!UE->init_sync_frame) + trashed_frames) % MAX_FRAME_NUMBER;
}
delNotifiedFIFO_elt(res);
} else {
readFrame(UE, &timestamp, true);
@@ -750,6 +672,7 @@ void *UE_thread(void *arg) {
absolute_slot++;
// whatever means thread_idx
// Fix me: will be wrong when slot 1 is slow, as slot 2 finishes
// Slot 3 will overlap if RX_NB_TH is 2
@@ -762,13 +685,13 @@ void *UE_thread(void *arg) {
curMsg->UE=UE;
// update thread index for received subframe
curMsg->UE->current_thread_id[slot_nr] = thread_idx;
curMsg->proc.CC_id = 0;
curMsg->proc.CC_id = UE->CC_id;
curMsg->proc.nr_tti_rx= slot_nr;
curMsg->proc.subframe_rx=slot_nr/(nb_slot_frame/10);
curMsg->proc.nr_tti_tx = (absolute_slot + DURATION_RX_TO_TX) % nb_slot_frame;
curMsg->proc.subframe_tx=curMsg->proc.nr_tti_rx;
curMsg->proc.frame_rx = ((absolute_slot/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
curMsg->proc.frame_tx = (((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame)+UE->frame_gap) % MAX_FRAME_NUMBER;
curMsg->proc.frame_rx = (absolute_slot/nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg->proc.frame_tx = ((absolute_slot+DURATION_RX_TO_TX)/nb_slot_frame) % MAX_FRAME_NUMBER;
curMsg->proc.decoded_frame_rx=-1;
//LOG_I(PHY,"Process slot %d thread Idx %d total gain %d\n", slot_nr, thread_idx, UE->rx_total_gain_dB);
+49 -70
View File
@@ -71,41 +71,16 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "PHY/INIT/phy_init.h"
#include "system.h"
#include <openair2/RRC/NR_UE/rrc_proto.h>
#include <openair2/LAYER2/NR_MAC_UE/mac_defs.h>
#include <openair2/LAYER2/NR_MAC_UE/mac_proto.h>
#include "NR_MAC_UE/mac_defs.h"
#include "NR_MAC_UE/mac_proto.h"
#include <openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h>
#include <openair1/SCHED_NR_UE/fapi_nr_ue_l1.h>
#include <forms.h>
/* Callbacks, globals and object handlers */
extern void reset_stats( FL_OBJECT *, long );
//extern void initTpool(char *params, tpool_t *pool, bool performanceMeas);
/* Forms and Objects */
typedef struct {
FL_FORM *stats_form;
void *vdata;
char *cdata;
long ldata;
FL_OBJECT *stats_text;
FL_OBJECT *stats_button;
} FD_stats_form;
extern FD_stats_form *create_form_stats_form( void );
#include "PHY/TOOLS/nr_phy_scope.h"
//#include "stats.h"
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
#include "PHY/TOOLS/nr_phy_scope.h"
// at eNB 0, an UL scope for every UE
FD_phy_scope_nrue *form_nrue[NUMBER_OF_UE_MAX];
//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
//FD_stats_form *form_stats=NULL,*form_stats_l2=NULL;
char title[255];
static pthread_t forms_thread; //xforms
#include <executables/nr-uesoftmodem.h>
#include "executables/softmodem-common.h"
@@ -304,35 +279,6 @@ void reset_stats(FL_OBJECT *button, long arg) {
}*/
}
static void *scope_thread(void *arg) {
sleep(5);
while (!oai_exit) {
phy_scope_nrUE(form_nrue[0],
PHY_vars_UE_g[0][0],
0,0,1);
usleep(100*1000);
}
pthread_exit((void *)arg);
}
void init_scope(void) {
int fl_argc=1;
if (do_forms==1) {
char *name="5G-UE-scope";
fl_initialize (&fl_argc, &name, NULL, 0, 0);
int UE_id = 0;
form_nrue[UE_id] = create_phy_scope_nrue();
sprintf (title, "NR DL SCOPE UE");
fl_show_form (form_nrue[UE_id]->phy_scope_nrue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);
threadCreate(&forms_thread, scope_thread, NULL, "scope", -1, OAI_PRIORITY_RT_LOW);
}
}
void *l2l1_task(void *arg) {
MessageDef *message_p = NULL;
int result;
@@ -720,6 +666,9 @@ int main( int argc, char **argv ) {
PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **));
PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs);
if (get_softmodem_params()->do_ra)
AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n");
for (int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
printf("frame_parms %d\n",frame_parms[CC_id]->ofdm_symbol_size);
frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx;
@@ -746,11 +695,6 @@ int main( int argc, char **argv ) {
init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag);
if (get_softmodem_params()->phy_test==1)
UE[CC_id]->mac_enabled = 0;
else
UE[CC_id]->mac_enabled = 1;
UE[CC_id]->mac_enabled = 1;
UE[CC_id]->if_inst = nr_ue_if_module_init(0);
UE[CC_id]->UE_scan = UE_scan;
@@ -763,15 +707,49 @@ int main( int argc, char **argv ) {
UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off;
UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
if (frame_parms[CC_id]->frame_type==FDD) {
if (UE[CC_id]->frame_parms.frame_type == FDD) {
UE[CC_id]->N_TA_offset = 0;
} else {
if (frame_parms[CC_id]->N_RB_DL == 100)
UE[CC_id]->N_TA_offset = 624;
else if (frame_parms[CC_id]->N_RB_DL == 50)
UE[CC_id]->N_TA_offset = 624/2;
else if (frame_parms[CC_id]->N_RB_DL == 25)
UE[CC_id]->N_TA_offset = 624/4;
int N_RB = UE[CC_id]->frame_parms.N_RB_DL;
int N_TA_offset = UE[CC_id]->frame_parms.ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2
double factor=1;
switch (UE[CC_id]->frame_parms.numerology_index) {
case 0: //15 kHz scs
AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n");
if (N_RB <= 25) factor = .25; // 7.68 Ms/s
else if (N_RB <=50) factor = .5; // 15.36 Ms/s
else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s
else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s
else AssertFatal(1==0,"Too many PRBS for mu=0\n");
break;
case 1: //30 kHz sc
AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n");
if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s
else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s
break;
case 2: //60 kHz scs
AssertFatal(1==0,"scs_common should not be 60 kHz\n");
break;
case 3: //120 kHz scs
AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n");
break;
case 4: //240 kHz scs
AssertFatal(1==0,"scs_common should not be 60 kHz\n");
if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s
else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s
else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB);
break;
if (N_RB == 100)
UE[CC_id]->N_TA_offset = 624;
else if (N_RB == 50)
UE[CC_id]->N_TA_offset = 624/2;
else if (N_RB == 25)
UE[CC_id]->N_TA_offset = 624/4;
}
if (UE[CC_id]->frame_parms.threequarter_fs == 1) factor = factor*.75;
UE[CC_id]->N_TA_offset = (int)(N_TA_offset * factor);
LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", UE[CC_id]->Mod_id, UE[CC_id]->N_TA_offset, factor, UE[CC_id]->frame_parms.ul_CarrierFreq, N_RB);
}
}
@@ -782,7 +760,8 @@ int main( int argc, char **argv ) {
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
configure_linux();
mlockall(MCL_CURRENT | MCL_FUTURE);
init_scope();
if (do_forms)
nrUEinitScope(PHY_vars_UE_g[0][0]);
number_of_cards = 1;
for(int CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-1
View File
@@ -4,7 +4,6 @@
#include <executables/softmodem-common.h>
#include "PHY/defs_nr_UE.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
+4
View File
@@ -55,6 +55,7 @@ extern "C"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n"
#define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0"
#define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n"
@@ -97,6 +98,7 @@ extern "C"
#define SPLIT73 softmodem_params.split73
#define TP_CONFIG softmodem_params.threadPoolConfig
#define PHY_TEST softmodem_params.phy_test
#define DO_RA softmodem_params.do_ra
#define WAIT_FOR_SYNC softmodem_params.wait_for_sync
#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag
#define CHAIN_OFFSET softmodem_params.chain_offset
@@ -114,6 +116,7 @@ extern "C"
{"split73", CONFIG_HLP_SPLIT73, 0, strptr:(char **)&SPLIT73, defstrval:NULL, TYPE_STRING, sizeof(SPLIT73)},\
{"thread-pool", CONFIG_HLP_TPOOL, 0, strptr:(char **)&TP_CONFIG, defstrval:"n", TYPE_STRING, sizeof(TP_CONFIG)}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \
{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \
{"clock-source", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \
{"time-source", CONFIG_HLP_TME, 0, uptr:&TIMING_SOURCE, defintval:0, TYPE_UINT, 0}, \
@@ -205,6 +208,7 @@ typedef struct {
char split73[1024];
char threadPoolConfig[1024];
int phy_test;
int do_ra;
uint8_t usim_test;
int emulate_rf;
int wait_for_sync; //eNodeB only