diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index d3041f9112..9710d3a8ca 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2852,42 +2852,6 @@ target_link_libraries (nr-softmodem ${T_LIB}) add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) -add_executable(ocp-gnb - ${rrc_h} - ${nr_rrc_h} - ${s1ap_h} -# ${OPENAIR_BIN_DIR}/messages_xml.h - ${OPENAIR_DIR}/executables/ocp-gnb.c - ${OPENAIR_DIR}/executables/softmodem-common.c - ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c - ${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c - ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c - ${OPENAIR2_DIR}/RRC/NAS/nas_config.c - ${OPENAIR2_DIR}/RRC/NAS/rb_config.c - ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c - ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${PHY_INTERFACE_DIR}/queue_t.c - ${XFORMS_SOURCE_NR} - ${T_SOURCE} - ${SHLIB_LOADER_SOURCES} - ${XFORMSINTERFACE_SOURCE} - ) - -target_link_libraries (ocp-gnb - -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA - ITTI ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB - NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB - X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON - -Wl,--end-group z dl) - -target_link_libraries (ocp-gnb ${LIBXML2_LIBRARIES} ) -target_link_libraries (ocp-gnb pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES}) -target_link_libraries (ocp-gnb ${LIB_LMS_LIBRARIES}) -target_link_libraries (ocp-gnb ${T_LIB}) -add_dependencies(ocp-gnb ldpc_orig ldpc_optim ldpc_optim8seg ldpc params_libconfig rfsimulator oai_usrpdevif rfsimulator nrscope) - - # nr-uesoftmodem is UE implementation ####################################### @@ -2931,7 +2895,6 @@ add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc ) if (CUDA_FOUND) add_dependencies( nr-uesoftmodem ldpc_cuda) add_dependencies( nr-softmodem ldpc_cuda) - add_dependencies( ocp-gnb ldpc_cuda) endif (CUDA_FOUND) ###################################" # Addexecutables for tests diff --git a/doc/5Gnas.md b/doc/5Gnas.md index 3d33af426c..db0c19f07e 100644 --- a/doc/5Gnas.md +++ b/doc/5Gnas.md @@ -23,7 +23,6 @@ This tuto for 5G gNB NAS design # source files -executables/ocp-gnb.c: a main loop to create a debuggable gNB, see document SW_archi.md openair2/RRC/NR/nr_ngap_gNB.c: skeleton for interface with NGAP openair3/NAS/COMMON/milenage.h: a simple milenage implementation, depend only on crypto library openair3/NAS/COMMON/NR_NAS_defs.h: messages defined for NAS implemented in C: C struct, C enums and automatic conversion to labels for debug messages diff --git a/doc/SW_archi.md b/doc/SW_archi.md index 7648fb2e16..0a53bf3793 100644 --- a/doc/SW_archi.md +++ b/doc/SW_archi.md @@ -85,10 +85,6 @@ end This tuto for 5G gNB design, with Open Cells main {: .text-center} -# Top file: executables/ocp-gnb.c - -the function main() initializes the data from configuration file - # The main thread is in ru_thread() The infinite loop: ## rx_rf() diff --git a/executables/ocp-gnb.c b/executables/ocp-gnb.c deleted file mode 100644 index 23fd3ae132..0000000000 --- a/executables/ocp-gnb.c +++ /dev/null @@ -1,1006 +0,0 @@ -/* - * Author: Laurent Thomas, Open Cells Project - * all rights reserved - */ - -#define _GNU_SOURCE -#include -#include "assertions.h" -#include -#include - -#include "PHY/types.h" - -#include "PHY/INIT/phy_init.h" - -#include "PHY/defs_gNB.h" -#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 "../../ARCH/COMMON/common_lib.h" - -#include "PHY/phy_extern.h" -#include "LAYER2/MAC/mac.h" -#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" -#include "LAYER2/MAC/mac_proto.h" -#include "RRC/LTE/rrc_extern.h" -#include "PHY_INTERFACE/phy_interface.h" -#include "common/utils/LOG/log_extern.h" -#include "UTIL/OTG/otg_tx.h" -#include "UTIL/OTG/otg_externs.h" -#include "UTIL/MATH/oml.h" -#include "common/utils/LOG/vcd_signal_dumper.h" -#include "UTIL/OPT/opt.h" -#include "enb_config.h" -#include "s1ap_eNB.h" -#include "SIMULATION/ETH_TRANSPORT/proto.h" -#include -#include -#include -#include -#include -#include -#include -#include - -// should be in a shared lib -#include -#include -#include -#include - -// Global vars -#include -#include -#include -#include -volatile int oai_exit; -int single_thread_flag=1; -uint32_t do_forms=0; -unsigned int mmapped_dma=0; -int8_t threequarter_fs=0; - -int chain_offset=0; -uint16_t sl_ahead=6; -uint16_t sf_ahead=6; -uint32_t timing_advance = 0; -int transmission_mode=1; -int emulate_rf = 0; -int numerology = 0; - - -int config_sync_var=-1; -pthread_mutex_t nfapi_sync_mutex; -pthread_cond_t nfapi_sync_cond; -int nfapi_sync_var=-1; -double cpuf; - -THREAD_STRUCT thread_struct; - -pthread_cond_t sync_cond; -pthread_mutex_t sync_mutex; -int sync_var=-1; //!< protected by mutex \ref sync_mutex. - - -uint64_t downlink_frequency[MAX_NUM_CCs][4]; -int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; -time_stats_t softmodem_stats_mt; // main thread -time_stats_t softmodem_stats_hw; // hw acquisition -time_stats_t softmodem_stats_rxtx_sf; // total tx time -time_stats_t nfapi_meas; // total tx time -time_stats_t softmodem_stats_rx_sf; // total rx time -// not used but needed for link -openair0_config_t openair0_cfg[MAX_CARDS]; -uint16_t slot_ahead=6; -AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; -AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; -int flexran_agent_start(mid_t mod_id) { - memset (agent_rrc_xface, 0, sizeof(agent_rrc_xface)); - memset (agent_mac_xface, 0, sizeof(agent_mac_xface)); - return 0; -} -void flexran_agent_slice_update(mid_t module_idP) { -} -int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p) { - return 0; -} -void proto_agent_stop(mod_id_t mod_id) { -} -int split73=0; -void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_t *data, int dataLen, int r_offset) { - AssertFatal(false, "Must not be called in this context\n"); -} -int stop_L1L2(module_id_t gnb_id) { - AssertFatal(false, "Must not be called in this context\n"); -} -int restart_L1L2(module_id_t gnb_id) { - AssertFatal(false, "Must not be called in this context\n"); -} - -static int wait_for_sync = 0; -static double snr_dB=20; -static int DEFBANDS[] = {7}; -static int DEFENBS[] = {0}; -static int DEFBFW[] = {0x00007fff}; - -extern double cpuf; - -short nr_mod_table[NR_MOD_TABLE_SIZE_SHORT] = {0,0,16384,16384,-16384,-16384,16384,16384,16384,-16384,-16384,16384,-16384,-16384,7327,7327,7327,21981,21981,7327,21981,21981,7327,-7327,7327,-21981,21981,-7327,21981,-21981,-7327,7327,-7327,21981,-21981,7327,-21981,21981,-7327,-7327,-7327,-21981,-21981,-7327,-21981,-21981,10726,10726,10726,3576,3576,10726,3576,3576,10726,17876,10726,25027,3576,17876,3576,25027,17876,10726,17876,3576,25027,10726,25027,3576,17876,17876,17876,25027,25027,17876,25027,25027,10726,-10726,10726,-3576,3576,-10726,3576,-3576,10726,-17876,10726,-25027,3576,-17876,3576,-25027,17876,-10726,17876,-3576,25027,-10726,25027,-3576,17876,-17876,17876,-25027,25027,-17876,25027,-25027,-10726,10726,-10726,3576,-3576,10726,-3576,3576,-10726,17876,-10726,25027,-3576,17876,-3576,25027,-17876,10726,-17876,3576,-25027,10726,-25027,3576,-17876,17876,-17876,25027,-25027,17876,-25027,25027,-10726,-10726,-10726,-3576,-3576,-10726,-3576,-3576,-10726,-17876,-10726,-25027,-3576,-17876,-3576,-25027,-17876,-10726,-17876,-3576,-25027,-10726,-25027,-3576,-17876,-17876,-17876,-25027,-25027,-17876,-25027,-25027,8886,8886,8886,12439,12439,8886,12439,12439,8886,5332,8886,1778,12439,5332,12439,1778,5332,8886,5332,12439,1778,8886,1778,12439,5332,5332,5332,1778,1778,5332,1778,1778,8886,19547,8886,15993,12439,19547,12439,15993,8886,23101,8886,26655,12439,23101,12439,26655,5332,19547,5332,15993,1778,19547,1778,15993,5332,23101,5332,26655,1778,23101,1778,26655,19547,8886,19547,12439,15993,8886,15993,12439,19547,5332,19547,1778,15993,5332,15993,1778,23101,8886,23101,12439,26655,8886,26655,12439,23101,5332,23101,1778,26655,5332,26655,1778,19547,19547,19547,15993,15993,19547,15993,15993,19547,23101,19547,26655,15993,23101,15993,26655,23101,19547,23101,15993,26655,19547,26655,15993,23101,23101,23101,26655,26655,23101,26655,26655,8886,-8886,8886,-12439,12439,-8886,12439,-12439,8886,-5332,8886,-1778,12439,-5332,12439,-1778,5332,-8886,5332,-12439,1778,-8886,1778,-12439,5332,-5332,5332,-1778,1778,-5332,1778,-1778,8886,-19547,8886,-15993,12439,-19547,12439,-15993,8886,-23101,8886,-26655,12439,-23101,12439,-26655,5332,-19547,5332,-15993,1778,-19547,1778,-15993,5332,-23101,5332,-26655,1778,-23101,1778,-26655,19547,-8886,19547,-12439,15993,-8886,15993,-12439,19547,-5332,19547,-1778,15993,-5332,15993,-1778,23101,-8886,23101,-12439,26655,-8886,26655,-12439,23101,-5332,23101,-1778,26655,-5332,26655,-1778,19547,-19547,19547,-15993,15993,-19547,15993,-15993,19547,-23101,19547,-26655,15993,-23101,15993,-26655,23101,-19547,23101,-15993,26655,-19547,26655,-15993,23101,-23101,23101,-26655,26655,-23101,26655,-26655,-8886,8886,-8886,12439,-12439,8886,-12439,12439,-8886,5332,-8886,1778,-12439,5332,-12439,1778,-5332,8886,-5332,12439,-1778,8886,-1778,12439,-5332,5332,-5332,1778,-1778,5332,-1778,1778,-8886,19547,-8886,15993,-12439,19547,-12439,15993,-8886,23101,-8886,26655,-12439,23101,-12439,26655,-5332,19547,-5332,15993,-1778,19547,-1778,15993,-5332,23101,-5332,26655,-1778,23101,-1778,26655,-19547,8886,-19547,12439,-15993,8886,-15993,12439,-19547,5332,-19547,1778,-15993,5332,-15993,1778,-23101,8886,-23101,12439,-26655,8886,-26655,12439,-23101,5332,-23101,1778,-26655,5332,-26655,1778,-19547,19547,-19547,15993,-15993,19547,-15993,15993,-19547,23101,-19547,26655,-15993,23101,-15993,26655,-23101,19547,-23101,15993,-26655,19547,-26655,15993,-23101,23101,-23101,26655,-26655,23101,-26655,26655,-8886,-8886,-8886,-12439,-12439,-8886,-12439,-12439,-8886,-5332,-8886,-1778,-12439,-5332,-12439,-1778,-5332,-8886,-5332,-12439,-1778,-8886,-1778,-12439,-5332,-5332,-5332,-1778,-1778,-5332,-1778,-1778,-8886,-19547,-8886,-15993,-12439,-19547,-12439,-15993,-8886,-23101,-8886,-26655,-12439,-23101,-12439,-26655,-5332,-19547,-5332,-15993,-1778,-19547,-1778,-15993,-5332,-23101,-5332,-26655,-1778,-23101,-1778,-26655,-19547,-8886,-19547,-12439,-15993,-8886,-15993,-12439,-19547,-5332,-19547,-1778,-15993,-5332,-15993,-1778,-23101,-8886,-23101,-12439,-26655,-8886,-26655,-12439,-23101,-5332,-23101,-1778,-26655,-5332,-26655,-1778,-19547,-19547,-19547,-15993,-15993,-19547,-15993,-15993,-19547,-23101,-19547,-26655,-15993,-23101,-15993,-26655,-23101,-19547,-23101,-15993,-26655,-19547,-26655,-15993,-23101,-23101,-23101,-26655,-26655,-23101,-26655,-26655}; - -static inline int ocp_rxtx(PHY_VARS_gNB *gNB, gNB_L1_rxtx_proc_t *proc) { - nfapi_nr_config_request_scf_t *cfg = &gNB->gNB_config; - start_meas(&softmodem_stats_rxtx_sf); - - // ******************************************************************* - - if (nfapi_mode == NFAPI_MODE_PNF) { - // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick - //add_subframe(&frame, &subframe, 4); - //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); - //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); - start_meas(&nfapi_meas); - oai_subframe_ind(proc->frame_rx, proc->slot_rx); - stop_meas(&nfapi_meas); - /*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.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", - 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.cqi_ind.number_of_cqis, - frame_rx, slot_rx, - frame_tx, slot_tx); - }*/ - } - - /// NR disabling - // **************************************** - // Common RX procedures subframe n - pthread_mutex_lock(&gNB->UL_INFO_mutex); - gNB->UL_INFO.frame = proc->frame_rx; - gNB->UL_INFO.slot = proc->slot_rx; - gNB->UL_INFO.module_id = gNB->Mod_id; - gNB->UL_INFO.CC_id = gNB->CC_id; - gNB->if_inst->NR_UL_indication(&gNB->UL_INFO); - pthread_mutex_unlock(&gNB->UL_INFO_mutex); - // RX processing - int tx_slot_type = nr_slot_select(cfg,proc->frame_tx,proc->slot_tx); - int rx_slot_type = nr_slot_select(cfg,proc->frame_rx,proc->slot_rx); - - if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { - // Do PRACH RU processing - L1_nr_prach_procedures(gNB,proc->frame_rx,proc->slot_rx); - phy_procedures_gNB_uespec_RX(gNB, proc->frame_rx, proc->slot_rx); - } - - if (oai_exit) return(-1); - - // ***************************************** - // TX processing for subframe n+sf_ahead - // run PHY TX procedures the one after the other for all CCs to avoid race conditions - // (may be relaxed in the future for performance reasons) - // ***************************************** - - if (tx_slot_type == NR_DOWNLINK_SLOT || tx_slot_type == NR_MIXED_SLOT) { - phy_procedures_gNB_TX(gNB, proc->frame_tx,proc->slot_tx, 1); - } - - stop_meas( &softmodem_stats_rxtx_sf ); - LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->slot_rx, proc->frame_tx, proc->slot_tx); - return(0); -} - - -static void *process_stats_thread(void *param) { - PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param; - reset_meas(&gNB->dlsch_encoding_stats); - reset_meas(&gNB->dlsch_scrambling_stats); - reset_meas(&gNB->dlsch_modulation_stats); - - while(!oai_exit) { - sleep(1); - print_meas(&gNB->dlsch_encoding_stats, "pdsch_encoding", NULL, NULL); - print_meas(&gNB->dlsch_scrambling_stats, "pdsch_scrambling", NULL, NULL); - print_meas(&gNB->dlsch_modulation_stats, "pdsch_modulation", NULL, NULL); - } - - return(NULL); -} - -void init_gNB_proc(int inst) { - PHY_VARS_gNB *gNB = RC.gNB[inst]; - gNB_L1_proc_t *proc = &gNB->proc; - gNB_L1_rxtx_proc_t *L1_proc = &proc->L1_proc; - gNB_L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx; - L1_proc->instance_cnt = -1; - L1_proc_tx->instance_cnt = -1; - L1_proc->instance_cnt_RUs = 0; - L1_proc_tx->instance_cnt_RUs = 0; - proc->instance_cnt_prach = -1; - proc->instance_cnt_asynch_rxtx = -1; - proc->CC_id = 0; - proc->first_rx =1; - proc->first_tx =1; - proc->RU_mask =0; - proc->RU_mask_tx = (1<num_RU)-1; - proc->RU_mask_prach =0; - pthread_mutex_init( &gNB->UL_INFO_mutex, NULL); - gNB->threadPool = (tpool_t *)malloc(sizeof(tpool_t)); - gNB->respDecode = (notifiedFIFO_t *) malloc(sizeof(notifiedFIFO_t)); - char ul_pool[] = "-1,-1"; - initTpool(ul_pool, gNB->threadPool, false); - initNotifiedFIFO(gNB->respDecode); -} - -/// eNB kept in function name for nffapi calls, TO FIX -void init_gNB_phase2(RU_t *ru) { - int inst; - LOG_I(PHY,"%s() RC.nb_nr_inst:%d\n", __FUNCTION__, RC.nb_nr_inst); - - for (inst=0; instnum_RU:%d\n", gNB->num_RU); - phy_init_nr_gNB(gNB,0,0); - RC.gNB[inst]->num_RU=1; - RC.gNB[inst]->RU_list[0]=ru; - //init_precoding_weights(RC.gNB[inst][CC_id]); - } -} - -void init_gNB(int single_thread_flag,int wait_for_sync) { - for (int inst=0; instRCconfig_NR_L1\n"); - PHY_VARS_gNB *gNB= RC.gNB[inst]; - gNB->abstraction_flag = false; - gNB->single_thread_flag = true; - /*nr_polar_init(&gNB->nrPolar_params, - NR_POLAR_PBCH_MESSAGE_TYPE, - NR_POLAR_PBCH_PAYLOAD_BITS, - NR_POLAR_PBCH_AGGREGATION_LEVEL);*/ - LOG_I(PHY,"Registering with MAC interface module\n"); - AssertFatal((gNB->if_inst = NR_IF_Module_init(inst))!=NULL,"Cannot register interface"); - gNB->if_inst->NR_Schedule_response = nr_schedule_response; - gNB->if_inst->NR_PHY_config_req = nr_phy_config_request; - memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO)); - memset((void *)&gNB->UL_tti_req,0,sizeof(nfapi_nr_ul_tti_request_t)); - //memset((void *)&gNB->Sched_INFO,0,sizeof(gNB->Sched_INFO)); - LOG_I(PHY,"Setting indication lists\n"); - gNB->UL_INFO.rx_ind.pdu_list = gNB->rx_pdu_list; - gNB->UL_INFO.crc_ind.crc_list = gNB->crc_pdu_list; - /*gNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = gNB->sr_pdu_list; - gNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = gNB->harq_pdu_list; - gNB->UL_INFO.cqi_ind.cqi_pdu_list = gNB->cqi_pdu_list; - gNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = gNB->cqi_raw_pdu_list;*/ - gNB->prach_energy_counter = 0; - } - - LOG_I(PHY,"[nr-softmodem.c] gNB structure allocated\n"); -} - - -void stop_gNB(int nb_inst) { -} - -static void get_options(void) { - paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; - config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - - if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { - memset((void *)&RC,0,sizeof(RC)); - /* Read RC configuration file */ - NRRCConfig(); - printf("Configuration: nb_rrc_inst %d, nb_nr_L1_inst %d, nb_ru %hhd\n", RC.nb_nr_inst,RC.nb_nr_L1_inst,RC.nb_RU); - } - - AssertFatal(RC.nb_nr_L1_inst == 1 && RC.nb_RU == 1, "Only one gNB, one RU and one carrier is supported\n"); -} - -void set_default_frame_parms(nfapi_nr_config_request_t *config[MAX_NUM_CCs], - NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { - for (int CC_id=0; CC_idsubframe_config.numerology_index_mu.value =1; - config[CC_id]->subframe_config.duplex_mode.value = 1; //FDD - config[CC_id]->subframe_config.dl_cyclic_prefix_type.value = 0; //NORMAL - config[CC_id]->rf_config.dl_carrier_bandwidth.value = 106; - config[CC_id]->rf_config.ul_carrier_bandwidth.value = 106; - config[CC_id]->sch_config.physical_cell_id.value = 0; - } -} - -static void init_pdcp(void) { - //if (!NODE_IS_DU(RC.rrc[0]->node_type)) { - pdcp_layer_init(); - uint32_t pdcp_initmask = (IS_SOFTMODEM_NOS1) ? - (PDCP_USE_NETLINK_BIT | LINK_ENB_PDCP_TO_IP_DRIVER_BIT) : LINK_ENB_PDCP_TO_GTPV1U_BIT; - - if (IS_SOFTMODEM_NOS1) { - printf("IS_SOFTMODEM_NOS1 option enabled \n"); - pdcp_initmask = pdcp_initmask | ENB_NAS_USE_TUN_BIT | SOFTMODEM_NOKRNMOD_BIT ; - } - - nr_pdcp_module_init(pdcp_initmask, 0); - pdcp_set_rlc_data_req_func(rlc_data_req); - pdcp_set_pdcp_data_ind_func(pdcp_data_ind); -} - -void init_main_gNB(void) { - RCconfig_NR_L1(); - RCconfig_nr_macrlc(); - - if (RC.nb_nr_L1_inst>0) - AssertFatal(l1_north_init_gNB()==0,"could not initialize L1 north interface\n"); - - LOG_I(GNB_APP,"Allocating gNB_RRC_INST for %d instances\n",RC.nb_nr_inst); - RC.nrrrc = (gNB_RRC_INST **)calloc(RC.nb_nr_inst*sizeof(gNB_RRC_INST *),1); - LOG_I(PHY, "%s() RC.nb_nr_inst:%d RC.nrrrc:%p\n", __FUNCTION__, RC.nb_nr_inst, RC.nrrrc); - int gnb_id=0; // only 1 gnb per process, index 0 for now - RC.nrrrc[gnb_id] = (gNB_RRC_INST *)calloc(sizeof(gNB_RRC_INST),1); - MessageDef *msg_p = itti_alloc_new_message (TASK_GNB_APP, 0, NRRRC_CONFIGURATION_REQ); - RCconfig_NRRRC(msg_p,gnb_id, RC.nrrrc[gnb_id]); - openair_rrc_gNB_configuration(GNB_INSTANCE_TO_MODULE_ID(ITTI_MSG_DESTINATION_INSTANCE(msg_p)), &NRRRC_CONFIGURATION_REQ(msg_p)); - //AssertFatal(itti_create_task(TASK_GNB_APP, gNB_app_task, NULL) >= 0, ""); - AssertFatal(itti_create_task(TASK_RRC_GNB, rrc_gnb_task, NULL) >= 0, ""); - //AssertFatal(itti_create_task(TASK_X2AP, x2ap_task, NULL) >= 0, ""); -} - -static void wait_nfapi_init(char *thread_name) { - printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name); - pthread_mutex_lock( &nfapi_sync_mutex ); - - while (nfapi_sync_var<0) - pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex ); - - pthread_mutex_unlock(&nfapi_sync_mutex); - printf( "NFAPI: got sync (%s)\n", thread_name); -} - -void exit_function(const char *file, const char *function, const int line, const char *s) { - if (s != NULL) { - printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); - } - - oai_exit = 1; - sleep(1); //allow lte-softmodem threads to exit first - exit(1); -} - -void stop_RU(int nb_ru) { - return; -} - -void OCPconfig_RU(RU_t *ru) { - int i = 0, j = 0; // Ru and gNB cardinality - paramdef_t RUParams[] = RUPARAMS_DESC; - paramlist_def_t RUParamList = {CONFIG_STRING_RU_LIST,NULL,0}; - config_getlist( &RUParamList, RUParams, sizeof(RUParams)/sizeof(paramdef_t), NULL); - AssertFatal( RUParamList.numelt == 1 && RC.nb_nr_L1_inst ==1,"" ); - ru->idx=0; - ru->nr_frame_parms = (NR_DL_FRAME_PARMS *)calloc(sizeof(NR_DL_FRAME_PARMS),1); - ru->frame_parms = (LTE_DL_FRAME_PARMS *)calloc(sizeof(LTE_DL_FRAME_PARMS),1); - ru->if_timing = synch_to_ext_device; - ru->num_gNB = RUParamList.paramarray[j][RU_ENB_LIST_IDX].numelt; - ru->gNB_list[i] = &RC.gNB[RUParamList.paramarray[j][RU_ENB_LIST_IDX].iptr[i]][0]; - - if (config_isparamset(RUParamList.paramarray[j], RU_SDR_ADDRS)) { - ru->openair0_cfg.sdr_addrs = strdup(*(RUParamList.paramarray[j][RU_SDR_ADDRS].strptr)); - } - - if (config_isparamset(RUParamList.paramarray[j], RU_SDR_CLK_SRC)) { - if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "internal") == 0) { - ru->openair0_cfg.clock_source = internal; - LOG_D(PHY, "RU clock source set as internal\n"); - } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "external") == 0) { - ru->openair0_cfg.clock_source = external; - LOG_D(PHY, "RU clock source set as external\n"); - } else if (strcmp(*(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr), "gpsdo") == 0) { - ru->openair0_cfg.clock_source = gpsdo; - LOG_D(PHY, "RU clock source set as gpsdo\n"); - } else { - LOG_E(PHY, "Erroneous RU clock source in the provided configuration file: '%s'\n", *(RUParamList.paramarray[j][RU_SDR_CLK_SRC].strptr)); - } - } else { - ru->openair0_cfg.clock_source = unset; - } - - if (strcmp(*(RUParamList.paramarray[j][RU_LOCAL_RF_IDX].strptr), "yes") == 0) { - if ( !(config_isparamset(RUParamList.paramarray[j],RU_LOCAL_IF_NAME_IDX)) ) { - ru->if_south = REMOTE_IF5; //TBD: max value to avoid to call "ru" functions - ru->function = gNodeB_3GPP; - printf("Setting function for RU %d to gNodeB_3GPP\n",j); - } else { - } - - ru->max_pdschReferenceSignalPower = *(RUParamList.paramarray[j][RU_MAX_RS_EPRE_IDX].uptr);; - ru->max_rxgain = *(RUParamList.paramarray[j][RU_MAX_RXGAIN_IDX].uptr); - ru->num_bands = RUParamList.paramarray[j][RU_BAND_LIST_IDX].numelt; - - for (i=0; inum_bands; i++) ru->band[i] = RUParamList.paramarray[j][RU_BAND_LIST_IDX].iptr[i]; - } //strcmp(local_rf, "yes") == 0 - else { - } - - ru->nb_tx = *(RUParamList.paramarray[j][RU_NB_TX_IDX].uptr); - ru->nb_rx = *(RUParamList.paramarray[j][RU_NB_RX_IDX].uptr); - ru->att_tx = *(RUParamList.paramarray[j][RU_ATT_TX_IDX].uptr); - ru->att_rx = *(RUParamList.paramarray[j][RU_ATT_RX_IDX].uptr); - - if (config_isparamset(RUParamList.paramarray[j], RU_BF_WEIGHTS_LIST_IDX)) { - ru->nb_bfw = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].numelt; - - for (i=0; inum_gNB; i++) { - ru->bw_list[i] = (int32_t *)malloc16_clear((ru->nb_bfw)*sizeof(int32_t)); - - for (int b=0; bnb_bfw; b++) ru->bw_list[i][b] = RUParamList.paramarray[j][RU_BF_WEIGHTS_LIST_IDX].iptr[b]; - } - } - - return; -} - -// this is for RU with local RF unit -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 - 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; - fp->threequarter_fs=threequarter_fs; - - if (mu == NR_MU_0) { //or if LTE - if(N_RB == 100) { - if (fp->threequarter_fs) { - cfg->sample_rate=23.04e6; - cfg->samples_per_frame = 230400; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } else { - cfg->sample_rate=30.72e6; - cfg->samples_per_frame = 307200; - cfg->tx_bw = 10e6; - cfg->rx_bw = 10e6; - } - } else if(N_RB == 50) { - cfg->sample_rate=15.36e6; - cfg->samples_per_frame = 153600; - cfg->tx_bw = 5e6; - cfg->rx_bw = 5e6; - } else if (N_RB == 25) { - cfg->sample_rate=7.68e6; - cfg->samples_per_frame = 76800; - cfg->tx_bw = 2.5e6; - cfg->rx_bw = 2.5e6; - } else if (N_RB == 6) { - cfg->sample_rate=1.92e6; - cfg->samples_per_frame = 19200; - cfg->tx_bw = 1.5e6; - cfg->rx_bw = 1.5e6; - } else AssertFatal(1==0,"Unknown N_RB %d\n",N_RB); - } else if (mu == NR_MU_1) { - if(N_RB == 273) { - if (fp->threequarter_fs) { - AssertFatal(0 == 1,"three quarter sampling not supported for N_RB 273\n"); - } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } - } else if(N_RB == 217) { - if (fp->threequarter_fs) { - cfg->sample_rate=92.16e6; - cfg->samples_per_frame = 921600; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; - } else { - cfg->sample_rate=122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 80e6; - cfg->rx_bw = 80e6; - } - } else if(N_RB == 106) { - if (fp->threequarter_fs) { - cfg->sample_rate=46.08e6; - cfg->samples_per_frame = 460800; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } else { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 40e6; - cfg->rx_bw = 40e6; - } - } else { - AssertFatal(0==1,"N_RB %d not yet supported for numerology %d\n",N_RB,mu); - } - } else if (mu == NR_MU_3) { - if (N_RB == 66) { - cfg->sample_rate = 122.88e6; - cfg->samples_per_frame = 1228800; - cfg->tx_bw = 100e6; - cfg->rx_bw = 100e6; - } else if(N_RB == 32) { - cfg->sample_rate=61.44e6; - cfg->samples_per_frame = 614400; - cfg->tx_bw = 50e6; - cfg->rx_bw = 50e6; - } - } else { - AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); - } - - if (gNB_config->cell_config.frame_duplex_type.value==TDD) - cfg->duplex_mode = duplex_mode_TDD; - else //FDD - cfg->duplex_mode = duplex_mode_FDD; - - cfg->Mod_id = 0; - cfg->num_rb_dl=N_RB; - cfg->tx_num_channels=ru->nb_tx; - cfg->rx_num_channels=ru->nb_rx; - - for (i=0; inb_tx; i++) { - if (ru->if_frequency == 0) { - cfg->tx_freq[i] = (double)fp->dl_CarrierFreq; - cfg->rx_freq[i] = (double)fp->ul_CarrierFreq; - } else { - cfg->tx_freq[i] = (double)ru->if_frequency; - cfg->rx_freq[i] = (double)(ru->if_frequency+fp->ul_CarrierFreq-fp->dl_CarrierFreq); - } - - cfg->tx_gain[i] = ru->att_tx; - cfg->rx_gain[i] = ru->max_rxgain-ru->att_rx; - cfg->configFilename = rf_config_file; - printf("channel %d, Setting tx_gain offset %f, rx_gain offset %f, tx_freq %f, rx_freq %f\n", - i, cfg->tx_gain[i], - cfg->rx_gain[i], - cfg->tx_freq[i], - cfg->rx_freq[i]); - } -} - -/* this function maps the RU tx and rx buffers to the available rf chains. - Each rf chain is is addressed by the card number and the chain on the card. The - rf_map specifies for each antenna port, on which rf chain the mapping should start. Multiple - antennas are mapped to successive RF chains on the same card. */ -int setup_RU_buffers(RU_t *ru) { - int i,j; - int card,ant; - //uint16_t N_TA_offset = 0; - NR_DL_FRAME_PARMS *frame_parms; - nfapi_nr_config_request_scf_t *config = &ru->config; - - if (ru) { - frame_parms = ru->nr_frame_parms; - printf("setup_RU_buffers: frame_parms = %p\n",frame_parms); - } else { - 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 (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; inb_rx; i++) { - card = i/4; - ant = i%4; - printf("Mapping RU id %u, rx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); - free(ru->common.rxdata[i]); - ru->common.rxdata[i] = ru->openair0_cfg.rxbase[ru->rf_map.chain+ant]; - printf("rxdata[%d] @ %p\n",i,ru->common.rxdata[i]); - - for (j=0; j<16; j++) { - printf("rxbuffer %d: %x\n",j,ru->common.rxdata[i][j]); - ru->common.rxdata[i][j] = 16-j; - } - } - - for (i=0; inb_tx; i++) { - card = i/4; - ant = i%4; - printf("Mapping RU id %u, tx_ant %d, on card %d, chain %d\n",ru->idx,i,ru->rf_map.card+card, ru->rf_map.chain+ant); - free(ru->common.txdata[i]); - ru->common.txdata[i] = ru->openair0_cfg.txbase[ru->rf_map.chain+ant]; - printf("txdata[%d] @ %p\n",i,ru->common.txdata[i]); - - for (j=0; j<16; j++) { - printf("txbuffer %d: %x\n",j,ru->common.txdata[i][j]); - ru->common.txdata[i][j] = 16-j; - } - } - } else { // not memory-mapped DMA - //nothing to do, everything already allocated in lte_init - } - - return(0); -} -int rx_rf(int rxBufOffet, int nbSamples, int nb_rx, int32_t **rxdata, openair0_device *rfdevice, openair0_timestamp *HWtimeStamp) { - void *rxp[nb_rx]; - - for (int i=0; itrx_read_func(rfdevice, - HWtimeStamp, - rxp, - nbSamples, - nb_rx); - - if (rxs != nbSamples ) - LOG_E(PHY, "rx_rf: Asked for %d samples, got %d from USRP\n",nbSamples,rxs); - - return rxs; -} - -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; - int i,txsymb; - int slot_type = nr_slot_select(cfg,frame,slot%fp->slots_per_frame); - int prevslot_type = nr_slot_select(cfg,frame,(slot+(fp->slots_per_frame-1))%fp->slots_per_frame); - int nextslot_type = nr_slot_select(cfg,frame,(slot+1)%fp->slots_per_frame); - int sf_extension = 0; //sf_extension = ru->sf_extension; - int siglen=fp->get_samples_per_slot(slot,fp); - int flags=1; - - //nr_subframe_t SF_type = nr_slot_select(cfg,slot%fp->slots_per_frame); - if (slot_type == NR_DOWNLINK_SLOT || slot_type == NR_MIXED_SLOT || IS_SOFTMODEM_RFSIM) { - if(slot_type == NR_MIXED_SLOT) { - txsymb = 0; - - for(int symbol_count =0; symbol_counttdd_table.max_tdd_periodicity_list[slot].max_num_of_symbol_per_slot_list[symbol_count].slot_config.value==0) - txsymb++; - } - - AssertFatal(txsymb>0,"illegal txsymb %d\n",txsymb); - - if(slot%(fp->slots_per_subframe/2)) - siglen = txsymb * (fp->ofdm_symbol_size + fp->nb_prefix_samples); - else - siglen = (fp->ofdm_symbol_size + fp->nb_prefix_samples0) + (txsymb - 1) * (fp->ofdm_symbol_size + fp->nb_prefix_samples); - - //+ ru->end_of_burst_delay; - flags=3; // end of burst - } - - if (cfg->cell_config.frame_duplex_type.value == TDD && - slot_type == NR_DOWNLINK_SLOT && - prevslot_type == NR_UPLINK_SLOT) { - flags = 2; // start of burst - } - - if (cfg->cell_config.frame_duplex_type.value == TDD && - slot_type == NR_DOWNLINK_SLOT && - nextslot_type == NR_UPLINK_SLOT) { - flags = 3; // end of burst - } - - if (fp->freq_range==nr_FR2) { - // the beam index is written in bits 8-10 of the flags - // bit 11 enables the gpio programming - int beam=0; - - if (slot==0) beam = 11; //3 for boresight & 8 to enable - - /* - if (slot==0 || slot==40) beam=0&8; - if (slot==10 || slot==50) beam=1&8; - if (slot==20 || slot==60) beam=2&8; - if (slot==30 || slot==70) beam=3&8; - */ - flags |= beam<<8; - } - - void *txp[ru->nb_tx]; - - for (i=0; inb_tx; i++) - txp[i] = (void *)&ru->common.txdata[i][fp->get_samples_slot_timestamp(slot,fp,0)-sf_extension]; - - // prepare tx buffer pointers - unsigned int txs = ru->rfdevice.trx_write_func(&ru->rfdevice, - timestamp+ru->ts_offset-ru->openair0_cfg.tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - ru->nb_tx, - flags); - LOG_D(PHY,"[TXPATH] RU %d tx_rf, writing to TS %llu, frame %d, unwrapped_frame %d, slot %d\n",ru->idx, - (long long unsigned int)timestamp,frame,proc->frame_tx_unwrap,slot); - AssertFatal(txs == siglen+sf_extension,"TX : Timeout (sent %u/%d)\n", txs, siglen); - } -} - -static void *ru_thread( void *param ) { - RU_t *ru = (RU_t *)param; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,NB_functions[ru->function],NB_timing[ru->if_timing]); - nr_dump_frame_parms(fp); - AssertFatal(openair0_device_load(&ru->rfdevice,&ru->openair0_cfg)==0,"Cannot connect to local radio\n"); - AssertFatal(ru->rfdevice.trx_start_func(&ru->rfdevice) == 0,"Could not start the RF device\n"); - int64_t slot=-1; - int64_t nextHWTSshouldBe=0, nextRxTSlogical=0; - // weird globals, used in NR_IF_Module.c - sf_ahead = (uint16_t) ceil((float)6/(0x01<numerology_index)); - sl_ahead = sf_ahead*fp->slots_per_subframe; - - // This is a forever while loop, it loops over subframes which are scheduled by incoming samples from HW devices - - while (!oai_exit) { - int nextSlot=(slot+1)%fp->slots_per_frame; - uint32_t samples_per_slot = fp->get_samples_per_slot(nextSlot,fp); - int rxBuffOffset=fp->get_samples_slot_timestamp(nextSlot,fp,0); - AssertFatal(rxBuffOffset + samples_per_slot <= fp->samples_per_frame, "Will read outside allocated buffer\n"); - int samples=fp->get_samples_per_slot(nextSlot,fp); - openair0_timestamp HWtimeStamp=0; //for multi RU - int rxs=rx_rf(rxBuffOffset, - samples, - ru->nb_rx, - ru->common.rxdata, - &ru->rfdevice, - &HWtimeStamp); - LOG_D(PHY,"Reading %d samples for slot %d\n",samples_per_slot,nextSlot); - - if ( HWtimeStamp != nextHWTSshouldBe) - LOG_E(HW,"reading a stream must be continuous, %ld, %ld\n", HWtimeStamp, nextHWTSshouldBe); - - nextHWTSshouldBe=HWtimeStamp+rxs; - ru->proc.timestamp_rx=nextRxTSlogical; - nextRxTSlogical+=samples_per_slot; - int64_t HW_to_logical_RxTSoffset=(int64_t)HWtimeStamp-(int64_t)ru->proc.timestamp_rx; - ru->proc.frame_rx = (ru->proc.timestamp_rx / (fp->samples_per_subframe*10))&1023; - uint32_t idx_sf = ru->proc.timestamp_rx / fp->samples_per_subframe; - float offsetInSubframe=ru->proc.timestamp_rx % fp->samples_per_subframe; - ru->proc.tti_rx = (idx_sf * fp->slots_per_subframe + - lroundf(offsetInSubframe / fp->samples_per_slot0))% - fp->slots_per_frame; - LOG_D(PHY,"RU %d/%d TS %llu (off %d), frame %d, slot %d.%d / %d\n", - ru->idx, 0, - (unsigned long long int)ru->proc.timestamp_rx, - (int)ru->ts_offset,ru->proc.frame_rx,ru->proc.tti_rx,ru->proc.tti_tx,fp->slots_per_frame); - int slot_type = nr_slot_select(&ru->gNB_list[0]->gNB_config,ru->proc.frame_rx,ru->proc.tti_rx); - - if (slot_type == NR_UPLINK_SLOT || slot_type == NR_MIXED_SLOT) { - nr_fep_full(ru,ru->proc.tti_rx); - - for (int aa=0; aanb_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)); - - LOG_D(PHY, "rxdataF energy: %d\n", signal_energy(ru->common.rxdataF[0], fp->symbols_per_slot*fp->ofdm_symbol_size)); - } - - gNB_L1_proc_t *gNBproc=&RC.gNB[0][0].proc; - gNB_L1_rxtx_proc_t *L1_proc = &gNBproc->L1_proc; - NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - gNBproc->timestamp_rx = ru->proc.timestamp_rx; - L1_proc->frame_rx = gNBproc->frame_rx = gNBproc->frame_prach = ru->proc.frame_rx = - (ru->proc.timestamp_rx / (fp->samples_per_subframe*10))&1023; - L1_proc->slot_rx = gNBproc->slot_rx = gNBproc->slot_prach = - ru->proc.tti_rx; // computed before in caller function - L1_proc->timestamp_tx = gNBproc->timestamp_tx = ru->proc.timestamp_tx = - ru->proc.timestamp_rx + - sf_ahead*fp->samples_per_subframe; - L1_proc->frame_tx = gNBproc->frame_tx = ru->proc.frame_tx = - (gNBproc->timestamp_tx / (fp->samples_per_subframe*10))&1023; - L1_proc->slot_tx = ru->proc.tti_tx = - (L1_proc->slot_rx + sl_ahead)%fp->slots_per_frame; - - if (ocp_rxtx(&RC.gNB[0][0],L1_proc) < 0) - LOG_E(PHY,"gNB %d CC_id %d failed during execution\n",RC.gNB[0][0].Mod_id,RC.gNB[0][0].CC_id); - - // do TX front-end processing if needed (precoding and/or IDFTs) - //ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx); - nr_feptx_prec(ru,ru->proc.frame_tx,ru->proc.tti_tx); - // do OFDM with/without TX front-end processing if needed - //ru->feptx_ofdm - nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; - - if (nr_slot_select(cfg,ru->proc.frame_tx, ru->proc.tti_tx ) != NR_UPLINK_SLOT) { - int aa=0; // antenna 0 hardcoded - NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - nr_feptx0(ru,ru->proc.tti_tx,0,fp->symbols_per_slot,aa); - int *txdata = &ru->common.txdata[aa][fp->get_samples_slot_timestamp(ru->proc.tti_tx,fp,0)]; - int slot_sizeF = (fp->ofdm_symbol_size)* - ((NFAPI_CP_NORMAL == 1) ? 12 : 14); - LOG_D(PHY,"feptx_ofdm (TXPATH): frame %d, slot %d: txp (time %ld) %d dB, txp (freq) %d dB\n", - ru->proc.frame_tx,ru->proc.tti_tx,ru->proc.timestamp_tx, - dB_fixed(signal_energy((int32_t *)txdata,fp->get_samples_per_slot(ru->proc.tti_tx,fp))), - dB_fixed(signal_energy_nodc(ru->common.txdataF_BF[aa],2*slot_sizeF))); - } - - // do outgoing fronthaul (south) if needed - tx_rf(ru,ru->proc.frame_tx,ru->proc.tti_tx,ru->proc.timestamp_tx+HW_to_logical_RxTSoffset); - slot++; - } - - printf( "Exiting ru_thread \n"); - ru->rfdevice.trx_end_func(&ru->rfdevice); - static int ru_thread_status = 0; - return &ru_thread_status; -} - -void launch_NR_RU(RU_t *ru, char *rf_config_file) { - LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n", - RC.nb_nr_L1_inst,RC.nb_RU,get_nprocs()); - LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); - - for (int ru_id=0; ru_idrf_config_file = rf_config_file; - ru->idx = ru_id; - ru->ts_offset = 0; - // use gNB_list[0] as a reference for RU frame parameters - // NOTE: multiple CC_id are not handled here yet! - LOG_D(PHY, "%s() RC.ru[%d].num_gNB:%d ru->gNB_list[0]:%p rf_config_file:%s\n", - __FUNCTION__, ru_id, ru->num_gNB, ru->gNB_list[0], ru->rf_config_file); - LOG_E(PHY,"ru->gNB_list ru->num_gNB hardcoded: one RU connected to carrier 0 of gNB 0\n"); - ru->gNB_list[0] = &RC.gNB[0][0]; - ru->num_gNB=1; - LOG_I(PHY,"Copying frame parms from gNB in RC to ru %d and frame_parms in ru\n",ru->idx); - RU_proc_t *proc = &ru->proc; - threadCreate( &proc->pthread_FH, ru_thread, (void *)ru, "MainLoop", -1, OAI_PRIORITY_RT_MAX ); - } -} - -void init_eNB_afterRU(void) { - AssertFatal(false,""); -} - -int main( int argc, char **argv ) { - AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY), - "[SOFTMODEM] Error, configuration module init failed\n"); - logInit(); -#ifndef PACKAGE_VERSION -# define PACKAGE_VERSION "UNKNOWN" -#endif - LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - set_latency_target(); - get_options (); - get_common_options(SOFTMODEM_GNB_BIT ); - AssertFatal(!CONFIG_ISFLAGSET(CONFIG_ABORT),"Getting configuration failed\n"); - cpuf=get_cpu_freq_GHz(); - itti_init(TASK_MAX, tasks_info); - set_taus_seed (0); - init_opt(); - init_pdcp(); - init_main_gNB(); - init_gNB(true, wait_for_sync); - /* Start the agent. If it is turned off in the configuration, it won't start */ - RCconfig_nr_flexran(); - - for (int i = 0; i < RC.nb_nr_L1_inst; i++) { - flexran_agent_start(i); - } - - /* - *nfapi stuff very buggy in 4G, not yet implemented in 5G - */ - // init UE_PF_PO and mutex lock (paging from S1AP) - pthread_mutex_init(&ue_pf_po_mutex, NULL); - printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n"); - pthread_cond_init(&nfapi_sync_cond,NULL); - pthread_mutex_init(&nfapi_sync_mutex, NULL); - const char *nfapi_mode_str[] = { - "MONOLITHIC", "PNF", "VNF", - }; - AssertFatal(nfapi_mode < 3,""); - printf("NFAPI MODE:%s\n", nfapi_mode_str[nfapi_mode]); - - if (nfapi_mode==NFAPI_MODE_VNF) // VNF - wait_nfapi_init("main?"); - - for (int i=0; iconfigured, "Remain threads to manage\n"); - - printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU); - config_sync_var=0; - - if (nfapi_mode==NFAPI_MODE_PNF) { // PNF - wait_nfapi_init("main?"); - } - - printf("wait RUs\n"); - printf("ALL RUs READY!\n"); - printf("RC.nb_RU:%d\n", RC.nb_RU); - // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) - printf("ALL RUs ready - init gNBs\n"); - LOG_E(PHY,"configuring RU from file, hardcoded one gNB for one RU, one carrier\n"); - RU_t ru= {0}; - OCPconfig_RU(&ru); - ru.nr_frame_parms->threequarter_fs=threequarter_fs; - fill_rf_config(&ru,ru.rf_config_file); - init_gNB_phase2(&ru); - memcpy((void *)ru.nr_frame_parms,&RC.gNB[0][0].frame_parms,sizeof(NR_DL_FRAME_PARMS)); - memcpy((void *)&ru.config,(void *)&RC.gNB[0]->gNB_config,sizeof(ru.config)); - AssertFatal(setup_RU_buffers(&ru)==0,"Inconsistent configuration"); - nr_phy_init_RU(&ru); - init_gNB_proc(0); // only instance 0 (one gNB per process) - - if (RC.nb_RU >0) { - printf("Initializing RU threads\n"); - launch_NR_RU(&ru, get_softmodem_params()->rf_config_file); - } - - if (opp_enabled ==1) { - pthread_t t; - threadCreate(&t, process_stats_thread, - (void *)NULL, "time_meas", -1, OAI_PRIORITY_RT_LOW); - } - - if(IS_SOFTMODEM_DOSCOPE) { - scopeParms_t tmp= {&argc, argv, &ru, RC.gNB[0]}; - load_softscope("nr",&tmp); - } - - while(!oai_exit) - sleep(1); - - logClean(); - printf("Bye.\n"); - return 0; -}