add channel simulator in rfsimulator
This commit is contained in:
@@ -619,8 +619,6 @@ set(HWLIB_TCP_BRIDGE_OAI_SOURCE
|
|||||||
add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} )
|
add_library(tcp_bridge_oai MODULE ${HWLIB_TCP_BRIDGE_OAI_SOURCE} )
|
||||||
set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
set_target_properties(tcp_bridge_oai PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
|
||||||
|
|
||||||
add_library(rfsimulator MODULE ${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c)
|
|
||||||
|
|
||||||
##########################################################
|
##########################################################
|
||||||
|
|
||||||
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
|
include_directories ("${OPENAIR_TARGETS}/ARCH/COMMON")
|
||||||
@@ -2127,6 +2125,12 @@ add_library(gnbScope MODULE
|
|||||||
)
|
)
|
||||||
target_link_libraries(gnbScope forms)
|
target_link_libraries(gnbScope forms)
|
||||||
|
|
||||||
|
add_library(rfsimulator MODULE
|
||||||
|
${OPENAIR_TARGETS}/ARCH/rfsimulator/simulator.c
|
||||||
|
)
|
||||||
|
target_link_libraries(rfsimulator SIMU ${ATLAS_LIBRARIES})
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
|
set(CMAKE_MODULE_PATH "${OPENAIR_DIR}/cmake_targets/tools/MODULES" "${CMAKE_MODULE_PATH}")
|
||||||
|
|
||||||
#include T directory even if the T is off because T macros are in the code
|
#include T directory even if the T is off because T macros are in the code
|
||||||
|
|||||||
+1
-1
@@ -1445,7 +1445,7 @@ static void *ru_thread( void *param ) {
|
|||||||
// wakeup all gNB processes waiting for this RU
|
// wakeup all gNB processes waiting for this RU
|
||||||
if (ru->num_gNB>0) wakeup_gNB_L1s(ru);
|
if (ru->num_gNB>0) wakeup_gNB_L1s(ru);
|
||||||
|
|
||||||
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_gNB==0) {
|
if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD && ru->num_gNB>0) {
|
||||||
// do TX front-end processing if needed (precoding and/or IDFTs)
|
// do TX front-end processing if needed (precoding and/or IDFTs)
|
||||||
if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
|
if (ru->feptx_prec) ru->feptx_prec(ru,proc->frame_tx,proc->tti_tx);
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ unsigned char NB_gNB_INST = 1;
|
|||||||
int UE_scan = 1;
|
int UE_scan = 1;
|
||||||
int UE_scan_carrier = 0;
|
int UE_scan_carrier = 0;
|
||||||
runmode_t mode = normal_txrx;
|
runmode_t mode = normal_txrx;
|
||||||
|
double snr_dB=20;
|
||||||
|
|
||||||
FILE *input_fd=NULL;
|
FILE *input_fd=NULL;
|
||||||
|
|
||||||
|
|||||||
+2
-147
@@ -1,93 +1,11 @@
|
|||||||
#ifndef NR_SOFTMODEM_H
|
#ifndef NR_SOFTMODEM_H
|
||||||
#define NR_SOFTMODEM_H
|
#define NR_SOFTMODEM_H
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#include <executables/nr-softmodem-common.h>
|
||||||
#include <execinfo.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <syscall.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
#include "targets/ARCH/COMMON/common_lib.h"
|
|
||||||
#undef MALLOC
|
|
||||||
#include "assertions.h"
|
|
||||||
#include "msc.h"
|
|
||||||
#include "PHY/types.h"
|
|
||||||
|
|
||||||
#include "flexran_agent.h"
|
#include "flexran_agent.h"
|
||||||
#include "PHY/defs_gNB.h"
|
#include "PHY/defs_gNB.h"
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
|
||||||
#if defined(ENABLE_USE_MME)
|
|
||||||
#include "s1ap_eNB.h"
|
|
||||||
#ifdef PDCP_USE_NETLINK
|
|
||||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
|
||||||
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
|
|
||||||
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
|
|
||||||
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
|
|
||||||
#define CONFIG_HLP_CALUERM ""
|
|
||||||
#define CONFIG_HLP_CALUERB ""
|
|
||||||
#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n"
|
|
||||||
#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n"
|
|
||||||
#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n"
|
|
||||||
#define CONFIG_HLP_UERXG "set UE RX gain\n"
|
|
||||||
#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n"
|
|
||||||
#define CONFIG_HLP_UETXG "set UE TX gain\n"
|
|
||||||
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
|
|
||||||
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
|
|
||||||
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
|
|
||||||
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
|
|
||||||
#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_DMAMAP "sets flag for improved EXMIMO UE performance\n"
|
|
||||||
#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n"
|
|
||||||
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
|
|
||||||
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
|
|
||||||
#define CONFIG_HLP_TADV "Set timing_advance\n"
|
|
||||||
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
|
|
||||||
#define CONFIG_HLP_CHOFF "Channel id offset\n"
|
|
||||||
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
|
|
||||||
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
|
|
||||||
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
|
|
||||||
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
|
|
||||||
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
|
|
||||||
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
|
|
||||||
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
|
|
||||||
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
|
|
||||||
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
|
|
||||||
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
|
|
||||||
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
|
|
||||||
#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n"
|
|
||||||
#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"
|
|
||||||
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
|
|
||||||
#define CONFIG_HLP_TPORT "tracer port\n"
|
|
||||||
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
|
|
||||||
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
|
|
||||||
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
|
|
||||||
|
|
||||||
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
|
|
||||||
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
|
|
||||||
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
|
|
||||||
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
|
|
||||||
|
|
||||||
/***************************************************************************************************************************************/
|
/***************************************************************************************************************************************/
|
||||||
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
|
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
|
||||||
@@ -98,25 +16,6 @@
|
|||||||
/* command line parameters defining UE running mode */
|
/* command line parameters defining UE running mode */
|
||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define CMDLINE_UEMODEPARAMS_DESC { \
|
|
||||||
{"calib-ue-rx", CONFIG_HLP_CALUER, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
|
||||||
{"calib-ue-rx-med", CONFIG_HLP_CALUERM, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
|
||||||
{"calib-ue-rx-byp", CONFIG_HLP_CALUERB, 0, iptr:&rx_input_level_dBm, defintval:0, TYPE_INT, 0}, \
|
|
||||||
{"debug-ue-prach", CONFIG_HLP_DBGUEPR, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
|
||||||
{"no-L2-connect", CONFIG_HLP_NOL2CN, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
|
||||||
{"calib-prach-tx", CONFIG_HLP_CALPRACH, PARAMFLAG_BOOL, uptr:NULL, defuintval:1, TYPE_INT, 0}, \
|
|
||||||
{"loop-memory", CONFIG_HLP_UELOOP, 0, strptr:&loopfile, defstrval:"iqs.in", TYPE_STRING,0}, \
|
|
||||||
{"ue-dump-frame", CONFIG_HLP_DUMPFRAME, PARAMFLAG_BOOL, iptr:&dumpframe, defintval:0, TYPE_INT, 0}, \
|
|
||||||
}
|
|
||||||
#define CMDLINE_CALIBUERX_IDX 0
|
|
||||||
#define CMDLINE_CALIBUERXMED_IDX 1
|
|
||||||
#define CMDLINE_CALIBUERXBYP_IDX 2
|
|
||||||
#define CMDLINE_DEBUGUEPRACH_IDX 3
|
|
||||||
#define CMDLINE_NOL2CONNECT_IDX 4
|
|
||||||
#define CMDLINE_CALIBPRACHTX_IDX 5
|
|
||||||
#define CMDLINE_MEMLOOP_IDX 6
|
|
||||||
#define CMDLINE_DUMPMEMORY_IDX 7
|
|
||||||
/*------------------------------------------------------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_DLF 2680000000
|
#define DEFAULT_DLF 2680000000
|
||||||
@@ -150,27 +49,10 @@
|
|||||||
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
|
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
|
||||||
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
|
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
|
||||||
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
|
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT,PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONFIG_HLP_FLOG "Enable online log \n"
|
|
||||||
#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
|
|
||||||
#define CONFIG_HLP_LOGV "Set the global log verbosity \n"
|
|
||||||
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
|
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
|
||||||
/* command line parameters for LOG utility */
|
|
||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
|
||||||
#define CMDLINE_LOGPARAMS_DESC { \
|
|
||||||
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
|
|
||||||
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
|
|
||||||
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \
|
|
||||||
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
|
|
||||||
}
|
|
||||||
#define CMDLINE_ONLINELOG_IDX 0
|
|
||||||
#define CMDLINE_GLOGLEVEL_IDX 1
|
|
||||||
#define CMDLINE_GLOGVERBO_IDX 2
|
|
||||||
#define CMDLINE_STARTTELN_IDX 3
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -183,33 +65,6 @@ extern int T_nowait;
|
|||||||
extern int T_dont_fork;
|
extern int T_dont_fork;
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************************************************/
|
|
||||||
/* */
|
|
||||||
extern pthread_cond_t sync_cond;
|
|
||||||
extern pthread_mutex_t sync_mutex;
|
|
||||||
extern int sync_var;
|
|
||||||
|
|
||||||
|
|
||||||
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
|
||||||
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
|
||||||
|
|
||||||
extern int rx_input_level_dBm;
|
|
||||||
extern uint8_t exit_missed_slots;
|
|
||||||
extern uint64_t num_missed_slots; // counter for the number of missed slots
|
|
||||||
|
|
||||||
extern int oaisim_flag;
|
|
||||||
extern volatile int oai_exit;
|
|
||||||
|
|
||||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
|
||||||
extern pthread_cond_t sync_cond;
|
|
||||||
extern pthread_mutex_t sync_mutex;
|
|
||||||
extern int sync_var;
|
|
||||||
extern int transmission_mode;
|
|
||||||
extern double cpuf;
|
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
|
||||||
extern volatile int start_gNB;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "threads_t.h"
|
#include "threads_t.h"
|
||||||
extern threads_t threads;
|
extern threads_t threads;
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ volatile int oai_exit = 0;
|
|||||||
|
|
||||||
static clock_source_t clock_source = internal;
|
static clock_source_t clock_source = internal;
|
||||||
int single_thread_flag=1;
|
int single_thread_flag=1;
|
||||||
|
double snr_dB=20;
|
||||||
|
|
||||||
int threequarter_fs=0;
|
int threequarter_fs=0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,100 +1,10 @@
|
|||||||
#ifndef NR_UESOFTMODEM_H
|
#ifndef NR_UESOFTMODEM_H
|
||||||
#define NR_UESOFTMODEM_H
|
#define NR_UESOFTMODEM_H
|
||||||
|
#include <executables/nr-softmodem-common.h>
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <execinfo.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <sched.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <syscall.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <sys/sysinfo.h>
|
|
||||||
#include "../../ARCH/COMMON/common_lib.h"
|
|
||||||
#undef MALLOC
|
|
||||||
#include "assertions.h"
|
|
||||||
#include "PHY/types.h"
|
|
||||||
#include "PHY/defs_nr_UE.h"
|
#include "PHY/defs_nr_UE.h"
|
||||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
||||||
#include <threadPool/thread-pool.h>
|
|
||||||
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
|
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
|
||||||
#if defined(ENABLE_USE_MME)
|
|
||||||
#include "s1ap_eNB.h"
|
|
||||||
#ifdef PDCP_USE_NETLINK
|
|
||||||
#include "SIMULATION/ETH_TRANSPORT/proto.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
|
||||||
#define CONFIG_HLP_RFCFGF "Configuration file for front-end (e.g. LMS7002M)\n"
|
|
||||||
#define CONFIG_HLP_ULMAXE "set the eNodeB max ULSCH erros\n"
|
|
||||||
#define CONFIG_HLP_CALUER "set UE RX calibration\n"
|
|
||||||
#define CONFIG_HLP_CALUERM ""
|
|
||||||
#define CONFIG_HLP_CALUERB ""
|
|
||||||
#define CONFIG_HLP_DBGUEPR "UE run normal prach power ramping, but don't continue random-access\n"
|
|
||||||
#define CONFIG_HLP_CALPRACH "UE run normal prach with maximum power, but don't continue random-access\n"
|
|
||||||
#define CONFIG_HLP_NOL2CN "bypass L2 and upper layers\n"
|
|
||||||
#define CONFIG_HLP_UERXG "set UE RX gain\n"
|
|
||||||
#define CONFIG_HLP_UERXGOFF "external UE amplifier offset\n"
|
|
||||||
#define CONFIG_HLP_UETXG "set UE TX gain\n"
|
|
||||||
#define CONFIG_HLP_UENANTR "set UE number of rx antennas\n"
|
|
||||||
#define CONFIG_HLP_UENANTT "set UE number of tx antennas\n"
|
|
||||||
#define CONFIG_HLP_UESCAN "set UE to scan around carrier\n"
|
|
||||||
#define CONFIG_HLP_UEFO "set UE to enable estimation and compensation of frequency offset\n"
|
|
||||||
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
|
|
||||||
#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_DMAMAP "sets flag for improved EXMIMO UE performance\n"
|
|
||||||
#define CONFIG_HLP_EXCCLK "tells hardware to use an external clock reference\n"
|
|
||||||
#define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n"
|
|
||||||
#define CONFIG_HLP_NOSNGLT "Disables single-thread mode in lte-softmodem\n"
|
|
||||||
#define CONFIG_HLP_TADV "Set timing_advance\n"
|
|
||||||
#define CONFIG_HLP_DLF "Set the downlink frequency for all component carriers\n"
|
|
||||||
#define CONFIG_HLP_CHOFF "Channel id offset\n"
|
|
||||||
#define CONFIG_HLP_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
|
|
||||||
#define CONFIG_HLP_EXMCAL "Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n"
|
|
||||||
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n"
|
|
||||||
#define CONFIG_HLP_DLMCS "Set the maximum downlink MCS\n"
|
|
||||||
#define CONFIG_HLP_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
|
|
||||||
#define CONFIG_HLP_PRB "Set the PRB, valid values: 6, 25, 50, 100 \n"
|
|
||||||
#define CONFIG_HLP_MSLOTS "Skip the missed slots/subframes \n"
|
|
||||||
#define CONFIG_HLP_ULMCS "Set the maximum uplink MCS\n"
|
|
||||||
#define CONFIG_HLP_TDD "Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n"
|
|
||||||
#define CONFIG_HLP_UE "Set the lte softmodem as a UE\n"
|
|
||||||
#define CONFIG_HLP_L2MONW "Enable L2 wireshark messages on localhost \n"
|
|
||||||
#define CONFIG_HLP_L2MONP "Enable L2 pcap messages on localhost \n"
|
|
||||||
#define CONFIG_HLP_VCD "Enable VCD (generated file will is named openair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n"
|
|
||||||
#define CONFIG_HLP_TQFS "Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n"
|
|
||||||
#define CONFIG_HLP_TPORT "tracer port\n"
|
|
||||||
#define CONFIG_HLP_NOTWAIT "don't wait for tracer, start immediately\n"
|
|
||||||
#define CONFIG_HLP_TNOFORK "to ease debugging with gdb\n"
|
|
||||||
|
|
||||||
#define CONFIG_HLP_NUMEROLOGY "adding numerology for 5G\n"
|
|
||||||
#define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n"
|
|
||||||
#define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n"
|
|
||||||
#define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n"
|
|
||||||
|
|
||||||
#define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n"
|
|
||||||
|
|
||||||
#define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n"
|
|
||||||
#define CONFIG_HLP_USRP_CLK_SRC "USRP clock source: 'internal' or 'external'\n"
|
|
||||||
|
|
||||||
/***************************************************************************************************************************************/
|
/***************************************************************************************************************************************/
|
||||||
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
|
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
|
||||||
when calling config_get or config_getlist functions */
|
when calling config_get or config_getlist functions */
|
||||||
@@ -174,27 +84,10 @@
|
|||||||
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
|
{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \
|
||||||
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
{"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
|
{"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \
|
||||||
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
|
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONFIG_HLP_FLOG "Enable online log \n"
|
|
||||||
#define CONFIG_HLP_LOGL "Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n"
|
|
||||||
#define CONFIG_HLP_LOGV "Set the global log verbosity \n"
|
|
||||||
#define CONFIG_HLP_TELN "Start embedded telnet server \n"
|
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
|
||||||
/* command line parameters for LOG utility */
|
|
||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
|
||||||
#define CMDLINE_LOGPARAMS_DESC { \
|
|
||||||
{"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \
|
|
||||||
{"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \
|
|
||||||
{"G" , CONFIG_HLP_LOGV, 0, uptr:&glog_verbosity, defintval:0, TYPE_UINT16, 0}, \
|
|
||||||
{"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \
|
|
||||||
}
|
|
||||||
#define CMDLINE_ONLINELOG_IDX 0
|
|
||||||
#define CMDLINE_GLOGLEVEL_IDX 1
|
|
||||||
#define CMDLINE_GLOGVERBO_IDX 2
|
|
||||||
#define CMDLINE_STARTTELN_IDX 3
|
|
||||||
|
|
||||||
|
|
||||||
extern int T_port;
|
extern int T_port;
|
||||||
@@ -203,35 +96,6 @@ extern int T_dont_fork;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************************************************************************/
|
|
||||||
|
|
||||||
extern pthread_cond_t sync_cond;
|
|
||||||
extern pthread_mutex_t sync_mutex;
|
|
||||||
extern int sync_var;
|
|
||||||
|
|
||||||
|
|
||||||
extern uint32_t downlink_frequency[MAX_NUM_CCs][4];
|
|
||||||
extern int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
|
|
||||||
|
|
||||||
extern int rx_input_level_dBm;
|
|
||||||
extern uint8_t exit_missed_slots;
|
|
||||||
extern uint64_t num_missed_slots; // counter for the number of missed slots
|
|
||||||
|
|
||||||
extern int oaisim_flag;
|
|
||||||
extern volatile int oai_exit;
|
|
||||||
|
|
||||||
extern openair0_config_t openair0_cfg[MAX_CARDS];
|
|
||||||
extern pthread_cond_t sync_cond;
|
|
||||||
extern pthread_mutex_t sync_mutex;
|
|
||||||
extern int sync_var;
|
|
||||||
extern int transmission_mode;
|
|
||||||
extern double cpuf;
|
|
||||||
|
|
||||||
#if defined(ENABLE_ITTI)
|
|
||||||
extern volatile int start_eNB;
|
|
||||||
extern volatile int start_UE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// In nr-ue.c
|
// In nr-ue.c
|
||||||
extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
|
extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
|
||||||
extern void fill_ue_band_info(void);
|
extern void fill_ue_band_info(void);
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_
|
|||||||
|
|
||||||
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
|
#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size)
|
||||||
|
|
||||||
#define sample_t uint32_t // 2*16 bits complex number
|
#define sample_t struct complex16 // 2*16 bits complex number
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t magic; // Magic value (see defines above)
|
uint64_t magic; // Magic value (see defines above)
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Then, you can use it freely
|
|||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
Setting the env variable RFSIMULATOR enables the RF board simulator
|
Setting the env variable RFSIMULATOR enables the RF board simulator
|
||||||
It should the set to "enb" in the eNB
|
It should the set to "server" in the eNB or gNB
|
||||||
|
|
||||||
## 4G case
|
## 4G case
|
||||||
For the UE, it should be set to the IP address of the eNB
|
For the UE, it should be set to the IP address of the eNB
|
||||||
@@ -62,6 +62,19 @@ sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000
|
|||||||
Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
|
Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
|
||||||
In UE, you can add "-d" to get the softscope
|
In UE, you can add "-d" to get the softscope
|
||||||
|
|
||||||
|
### Channel simulation
|
||||||
|
The RF channel simulator is called.
|
||||||
|
In current version all channel paramters are hard coded in the call to:
|
||||||
|
new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
|
||||||
|
AWGN,
|
||||||
|
bridge->sample_rate,
|
||||||
|
bridge->tx_bw,
|
||||||
|
0.0, // forgetting_factor
|
||||||
|
0, // maybe used for TA
|
||||||
|
0); // path_loss in dB
|
||||||
|
Only the input noise can be changed on command line with -s parameter.
|
||||||
|
With path loss = 0 set "-s 5" to see a little noise
|
||||||
|
|
||||||
#Caveacts
|
#Caveacts
|
||||||
Still issues in power control: txgain, rxgain are not used
|
Still issues in power control: txgain, rxgain are not used
|
||||||
|
|
||||||
|
|||||||
@@ -27,14 +27,23 @@
|
|||||||
#include "common_lib.h"
|
#include "common_lib.h"
|
||||||
#include <openair1/PHY/defs_eNB.h>
|
#include <openair1/PHY/defs_eNB.h>
|
||||||
#include "openair1/PHY/defs_UE.h"
|
#include "openair1/PHY/defs_UE.h"
|
||||||
|
#include <openair1/SIMULATION/TOOLS/sim.h>
|
||||||
|
|
||||||
#define PORT 4043 //TCP port for this simulator
|
#define PORT 4043 //TCP port for this simulator
|
||||||
#define CirSize 3072000 // 100ms is enough
|
#define CirSize 3072000 // 100ms is enough
|
||||||
#define sample_t uint32_t // 2*16 bits complex number
|
|
||||||
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
|
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
|
||||||
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
|
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
|
||||||
|
|
||||||
#define sample_t uint32_t //2*16 bits complex number
|
#define MAX_SIMULATION_CONNECTED_NODES 5
|
||||||
|
#define GENERATE_CHANNEL 10 //each frame in DL
|
||||||
|
|
||||||
|
// Fixme: datamodel, external variables in .h files, ...
|
||||||
|
#include <common/ran_context.h>
|
||||||
|
extern double snr_dB;
|
||||||
|
extern RAN_CONTEXT_t RC;
|
||||||
|
//
|
||||||
|
|
||||||
|
pthread_mutex_t Sockmutex;
|
||||||
|
|
||||||
typedef struct buffer_s {
|
typedef struct buffer_s {
|
||||||
int conn_sock;
|
int conn_sock;
|
||||||
@@ -46,6 +55,7 @@ typedef struct buffer_s {
|
|||||||
uint64_t remainToTransfer;
|
uint64_t remainToTransfer;
|
||||||
char *circularBufEnd;
|
char *circularBufEnd;
|
||||||
sample_t *circularBuf;
|
sample_t *circularBuf;
|
||||||
|
channel_desc_t *channel_model;
|
||||||
} buffer_t;
|
} buffer_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -55,8 +65,93 @@ typedef struct {
|
|||||||
char *ip;
|
char *ip;
|
||||||
int saveIQfile;
|
int saveIQfile;
|
||||||
buffer_t buf[FD_SETSIZE];
|
buffer_t buf[FD_SETSIZE];
|
||||||
|
int rx_num_channels;
|
||||||
|
int tx_num_channels;
|
||||||
|
double sample_rate;
|
||||||
|
double tx_bw;
|
||||||
} rfsimulator_state_t;
|
} rfsimulator_state_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Legacy study:
|
||||||
|
The parameters are:
|
||||||
|
gain&loss (decay, signal power, ...)
|
||||||
|
either a fixed gain in dB, a target power in dBm or ACG (automatic control gain) to a target average
|
||||||
|
=> don't redo the AGC, as it was used in UE case, that must have a AGC inside the UE
|
||||||
|
will be better to handle the "set_gain()" called by UE to apply it's gain (enable test of UE power loop)
|
||||||
|
lin_amp = pow(10.0,.05*txpwr_dBm)/sqrt(nb_tx_antennas);
|
||||||
|
a lot of operations in legacy, grouped in one simulation signal decay: txgain*decay*rxgain
|
||||||
|
|
||||||
|
multi_path (auto convolution, ISI, ...)
|
||||||
|
either we regenerate the channel (call again random_channel(desc,0)), or we keep it over subframes
|
||||||
|
legacy: we regenerate each sub frame in UL, and each frame only in DL
|
||||||
|
*/
|
||||||
|
void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_sig,
|
||||||
|
int rxAnt,
|
||||||
|
channel_desc_t *channelDesc,
|
||||||
|
int nbSamples,
|
||||||
|
uint64_t TS
|
||||||
|
) {
|
||||||
|
// channelDesc->path_loss_dB should contain the total path gain
|
||||||
|
// so, in actual RF: tx gain + path loss + rx gain (+antenna gain, ...)
|
||||||
|
// UE and NB gain control to be added
|
||||||
|
// Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
|
||||||
|
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
|
||||||
|
// Energy in one sample to calibrate input noise
|
||||||
|
//Fixme: modified the N0W computation, not understand the origin value
|
||||||
|
const double KT=1.38e-23*290; //Boltzman*temperature
|
||||||
|
// sampling rate is linked to acquisition band (the input pass band filter)
|
||||||
|
const double noise_figure_watt = KT*channelDesc->sampling_rate;
|
||||||
|
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
|
||||||
|
// the parameter "-s" is declared as SNR, but the input power is not well defined
|
||||||
|
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
|
||||||
|
const double rxGain= 132.24 - snr_dB;
|
||||||
|
const double noise_per_sample = sqrt(0.5*noise_figure_watt) * pow(10,rxGain/20);
|
||||||
|
|
||||||
|
// Fixme: we don't fill the offset length samples at begining ?
|
||||||
|
// anyway, in today code, channel_offset=0
|
||||||
|
const int dd = abs(channelDesc->channel_offset);
|
||||||
|
const int nbTx=channelDesc->nb_tx;
|
||||||
|
|
||||||
|
for (int i=0; i<((int)nbSamples-dd); i++) {
|
||||||
|
struct complex16 *out_ptr=after_channel_sig+dd+i;
|
||||||
|
struct complex rx_tmp= {0};
|
||||||
|
|
||||||
|
for (int txAnt=0; txAnt < nbTx; txAnt++) {
|
||||||
|
const struct complex *channelModel= channelDesc->ch[rxAnt+(txAnt*channelDesc->nb_rx)];
|
||||||
|
|
||||||
|
//const struct complex *channelModelEnd=channelModel+channelDesc->channel_length;
|
||||||
|
for (int l = 0; l<(int)channelDesc->channel_length; l++) {
|
||||||
|
// let's assume TS+i >= l
|
||||||
|
// fixme: the rfsimulator current structure is interleaved antennas
|
||||||
|
// this has been designed to not have to wait a full block transmission
|
||||||
|
// but it is not very usefull
|
||||||
|
// it would be better to split out each antenna in a separate flow
|
||||||
|
// that will allow to mix ru antennas freely
|
||||||
|
struct complex16 tx16=input_sig[((TS+i-l)*nbTx+txAnt)%CirSize];
|
||||||
|
rx_tmp.x += tx16.r * channelModel[l].x - tx16.i * channelModel[l].y;
|
||||||
|
rx_tmp.y += tx16.i * channelModel[l].x + tx16.r * channelModel[l].y;
|
||||||
|
} //l
|
||||||
|
}
|
||||||
|
|
||||||
|
out_ptr->r += round(rx_tmp.x*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||||
|
/*
|
||||||
|
printf("in: %d, out %d= %f*%f + %f*%f\n",
|
||||||
|
input_sig[((TS+i)*nbTx)%CirSize].r, out_ptr->r , rx_tmp.x,
|
||||||
|
pathLossLinear, noise_per_sample,gaussdouble(0.0,1.0));
|
||||||
|
*/
|
||||||
|
out_ptr->i += round(rx_tmp.y*pathLossLinear + noise_per_sample*gaussdouble(0.0,1.0));
|
||||||
|
out_ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (TS*nbTx)%CirSize+nbSamples <= CirSize )
|
||||||
|
// Cast to a wrong type for compatibility !
|
||||||
|
LOG_I(HW,"Input power %f, output power: %f, channel path loss %f, noise coeff: %f \n",
|
||||||
|
10*log10((double)signal_energy((int32_t*)&input_sig[(TS*nbTx)%CirSize], nbSamples)),
|
||||||
|
10*log10((double)signal_energy((int32_t*)after_channel_sig, nbSamples)),
|
||||||
|
channelDesc->path_loss_dB,
|
||||||
|
10*log10(noise_per_sample));
|
||||||
|
}
|
||||||
|
|
||||||
void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||||
buffer_t *ptr=&bridge->buf[sock];
|
buffer_t *ptr=&bridge->buf[sock];
|
||||||
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
|
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
|
||||||
@@ -73,12 +168,35 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
|||||||
ev.events = EPOLLIN | EPOLLRDHUP;
|
ev.events = EPOLLIN | EPOLLRDHUP;
|
||||||
ev.data.fd = sock;
|
ev.data.fd = sock;
|
||||||
AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, "");
|
AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, "");
|
||||||
|
// create channel simulation model for this mode reception
|
||||||
|
// snr_dB is pure global, coming from configuration paramter "-s"
|
||||||
|
// Fixme: referenceSignalPower should come from the right place
|
||||||
|
// but the datamodel is inconsistant
|
||||||
|
// legacy: RC.ru[ru_id]->frame_parms.pdsch_config_common.referenceSignalPower
|
||||||
|
// (must not come from ru[]->frame_parms as it doesn't belong to ru !!!)
|
||||||
|
// Legacy sets it as:
|
||||||
|
// ptr->channel_model->path_loss_dB = -132.24 + snr_dB - RC.ru[0]->frame_parms->pdsch_config_common.referenceSignalPower;
|
||||||
|
// we use directly the paramter passed on the command line ("-s")
|
||||||
|
// the value channel_model->path_loss_dB seems only a storage place (new_channel_desc_scm() only copy the passed value)
|
||||||
|
// Legacy changes directlty the variable channel_model->path_loss_dB place to place
|
||||||
|
// while calling new_channel_desc_scm() with path losses = 0
|
||||||
|
ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels,
|
||||||
|
AWGN,
|
||||||
|
bridge->sample_rate,
|
||||||
|
bridge->tx_bw,
|
||||||
|
0.0, // forgetting_factor
|
||||||
|
0, // maybe used for TA
|
||||||
|
0); // path_loss in dB
|
||||||
|
random_channel(ptr->channel_model,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
|
void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||||
AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
|
AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
|
||||||
close(sock);
|
close(sock);
|
||||||
free(bridge->buf[sock].circularBuf);
|
free(bridge->buf[sock].circularBuf);
|
||||||
|
// Fixme: no free_channel_desc_scm(bridge->buf[sock].channel_model) implemented
|
||||||
|
// a lot of mem leaks
|
||||||
|
free(bridge->buf[sock].channel_model);
|
||||||
memset(&bridge->buf[sock], 0, sizeof(buffer_t));
|
memset(&bridge->buf[sock], 0, sizeof(buffer_t));
|
||||||
bridge->buf[sock].conn_sock=-1;
|
bridge->buf[sock].conn_sock=-1;
|
||||||
}
|
}
|
||||||
@@ -126,8 +244,7 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AssertFatal(fd>=0 && _buf && count >0 && t,
|
AssertFatal(fd>=0 && _buf && count >0 && t,
|
||||||
"Bug: %d/%p/%zd/%p", fd, _buf, count, t);
|
"Bug: %d/%p/%zd/%p", fd, _buf, count, t);
|
||||||
|
|
||||||
char *buf = _buf;
|
char *buf = _buf;
|
||||||
ssize_t l;
|
ssize_t l;
|
||||||
setblocking(fd, notBlocking);
|
setblocking(fd, notBlocking);
|
||||||
@@ -140,8 +257,8 @@ void fullwrite(int fd, void *_buf, ssize_t count, rfsimulator_state_t *t) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(errno==EAGAIN) {
|
if(errno==EAGAIN) {
|
||||||
// The opposite side is saturated
|
// The opposite side is saturated
|
||||||
// we read incoming sockets meawhile waiting
|
// we read incoming sockets meawhile waiting
|
||||||
flushInput(t, 5);
|
flushInput(t, 5);
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else
|
||||||
@@ -234,12 +351,15 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
|
|||||||
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
|
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastW=timestamp;
|
lastW=timestamp;
|
||||||
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
|
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
|
||||||
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
|
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
|
||||||
// Let's verify we don't have incoming data
|
// Let's verify we don't have incoming data
|
||||||
// This is mandatory when the opposite side don't transmit
|
// This is mandatory when the opposite side don't transmit
|
||||||
|
// This is mandatory when the opposite side don't transmit
|
||||||
flushInput(t, 0);
|
flushInput(t, 0);
|
||||||
|
pthread_mutex_unlock(&Sockmutex);
|
||||||
return nsamps;
|
return nsamps;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,9 +370,9 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
|||||||
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout);
|
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, timeout);
|
||||||
|
|
||||||
if ( nfds==-1 ) {
|
if ( nfds==-1 ) {
|
||||||
if ( errno==EINTR || errno==EAGAIN )
|
if ( errno==EINTR || errno==EAGAIN ) {
|
||||||
return false;
|
return false;
|
||||||
else
|
} else
|
||||||
AssertFatal(false,"error in epoll_wait\n");
|
AssertFatal(false,"error in epoll_wait\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,26 +434,30 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
|||||||
if ( b->lastReceivedTS != b->th.timestamp) {
|
if ( b->lastReceivedTS != b->th.timestamp) {
|
||||||
int nbAnt= b->th.nbAnt;
|
int nbAnt= b->th.nbAnt;
|
||||||
|
|
||||||
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ )
|
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) {
|
||||||
for (int a=0; a < nbAnt; a++)
|
for (int a=0; a < nbAnt; a++) {
|
||||||
b->circularBuf[(index*nbAnt+a)%CirSize]=0;
|
b->circularBuf[(index*nbAnt+a)%CirSize].r=0;
|
||||||
|
b->circularBuf[(index*nbAnt+a)%CirSize].i=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
|
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
|
||||||
}
|
}
|
||||||
|
|
||||||
b->lastReceivedTS=b->th.timestamp;
|
b->lastReceivedTS=b->th.timestamp;
|
||||||
AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize),
|
AssertFatal(lastW == -1 || ( abs((double)lastW-b->lastReceivedTS) < (double)CirSize),
|
||||||
"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS);
|
"Tx/Rx shift too large Tx:%lu, Rx:%lu\n", lastW, b->lastReceivedTS);
|
||||||
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
|
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
|
||||||
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
|
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( b->headerMode==false ) {
|
if ( b->headerMode==false ) {
|
||||||
LOG_D(HW,"Set b->lastReceivedTS %ld\n", b->lastReceivedTS);
|
LOG_D(HW,"Set b->lastReceivedTS %ld\n", b->lastReceivedTS);
|
||||||
b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt);
|
b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt);
|
||||||
// First block in UE, resync with the eNB current TS
|
|
||||||
if ( t->nextTimestamp == 0 )
|
// First block in UE, resync with the eNB current TS
|
||||||
t->nextTimestamp=b->lastReceivedTS-b->th.size;
|
if ( t->nextTimestamp == 0 )
|
||||||
|
t->nextTimestamp=b->lastReceivedTS-b->th.size;
|
||||||
|
|
||||||
if ( b->remainToTransfer==0) {
|
if ( b->remainToTransfer==0) {
|
||||||
LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
|
LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
|
||||||
@@ -351,10 +475,10 @@ static bool flushInput(rfsimulator_state_t *t, int timeout) {
|
|||||||
|
|
||||||
int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
|
int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
|
||||||
if (nbAnt != 1) {
|
if (nbAnt != 1) {
|
||||||
LOG_E(HW, "rfsimulator: only 1 antenna tested\n");
|
LOG_W(HW, "rfsimulator: only 1 antenna tested\n");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&Sockmutex);
|
||||||
rfsimulator_state_t *t = device->priv;
|
rfsimulator_state_t *t = device->priv;
|
||||||
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
|
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
|
||||||
// deliver data from received data
|
// deliver data from received data
|
||||||
@@ -374,6 +498,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
|||||||
t->nextTimestamp+=nsamps;
|
t->nextTimestamp+=nsamps;
|
||||||
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
|
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
|
||||||
*ptimestamp = t->nextTimestamp-nsamps;
|
*ptimestamp = t->nextTimestamp-nsamps;
|
||||||
|
pthread_mutex_unlock(&Sockmutex);
|
||||||
return nsamps;
|
return nsamps;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -384,11 +509,11 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
|||||||
|
|
||||||
for ( int sock=0; sock<FD_SETSIZE; sock++) {
|
for ( int sock=0; sock<FD_SETSIZE; sock++) {
|
||||||
if ( t->buf[sock].circularBuf && t->buf[sock].alreadyRead )
|
if ( t->buf[sock].circularBuf && t->buf[sock].alreadyRead )
|
||||||
if ( t->buf[sock].lastReceivedTS == 0 ||
|
if ( t->buf[sock].lastReceivedTS == 0 ||
|
||||||
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
|
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
|
||||||
have_to_wait=true;
|
have_to_wait=true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_to_wait)
|
if (have_to_wait)
|
||||||
@@ -404,17 +529,26 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
|||||||
for (int a=0; a<nbAnt; a++)
|
for (int a=0; a<nbAnt; a++)
|
||||||
memset(samplesVoid[a],0,sampleToByte(nsamps,1));
|
memset(samplesVoid[a],0,sampleToByte(nsamps,1));
|
||||||
|
|
||||||
// Add all input signal in the output buffer
|
// Add all input nodes signal in the output buffer
|
||||||
for (int sock=0; sock<FD_SETSIZE; sock++) {
|
for (int sock=0; sock<FD_SETSIZE; sock++) {
|
||||||
buffer_t *ptr=&t->buf[sock];
|
buffer_t *ptr=&t->buf[sock];
|
||||||
|
|
||||||
if ( ptr->circularBuf && ptr->alreadyRead ) {
|
if ( ptr->circularBuf && ptr->alreadyRead ) {
|
||||||
for (int a=0; a<nbAnt; a++) {
|
bool reGenerateChannel=false;
|
||||||
sample_t *out=(sample_t *)samplesVoid[a];
|
|
||||||
|
//fixme: when do we regenerate
|
||||||
|
// it seems legacy behavior is: never in UL, each frame in DL
|
||||||
|
if (reGenerateChannel)
|
||||||
|
random_channel(ptr->channel_model,0);
|
||||||
|
|
||||||
|
for (int a=0; a<nbAnt; a++)
|
||||||
|
rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a],
|
||||||
|
a,
|
||||||
|
ptr->channel_model,
|
||||||
|
nsamps,
|
||||||
|
t->nextTimestamp
|
||||||
|
);
|
||||||
|
|
||||||
for ( int i=0; i < nsamps; i++ )
|
|
||||||
out[i]+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,10 +558,9 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo
|
|||||||
nsamps,
|
nsamps,
|
||||||
*ptimestamp, t->nextTimestamp,
|
*ptimestamp, t->nextTimestamp,
|
||||||
signal_energy(samplesVoid[0], nsamps));
|
signal_energy(samplesVoid[0], nsamps));
|
||||||
|
pthread_mutex_unlock(&Sockmutex);
|
||||||
return nsamps;
|
return nsamps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
|
int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
|
||||||
abort();
|
abort();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -452,11 +585,10 @@ int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cf
|
|||||||
int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
|
int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
__attribute__((__visibility__("default")))
|
__attribute__((__visibility__("default")))
|
||||||
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||||
//set_log(HW,OAILOG_DEBUG);
|
//set_log(HW,OAILOG_DEBUG);
|
||||||
|
set_log(TMR,OAILOG_DEBUG);
|
||||||
//set_log(PHY,OAILOG_DEBUG);
|
//set_log(PHY,OAILOG_DEBUG);
|
||||||
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
|
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
|
||||||
|
|
||||||
@@ -465,6 +597,8 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_init(&Sockmutex, NULL);
|
||||||
|
|
||||||
if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 ||
|
if ( strncasecmp(rfsimulator->ip,"enb",3) == 0 ||
|
||||||
strncasecmp(rfsimulator->ip,"server",3) == 0 )
|
strncasecmp(rfsimulator->ip,"server",3) == 0 )
|
||||||
rfsimulator->typeStamp = ENB_MAGICDL_FDD;
|
rfsimulator->typeStamp = ENB_MAGICDL_FDD;
|
||||||
@@ -504,5 +638,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
|||||||
rfsimulator->buf[i].conn_sock=-1;
|
rfsimulator->buf[i].conn_sock=-1;
|
||||||
|
|
||||||
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
|
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
|
||||||
|
// initialize channel simulation
|
||||||
|
rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
|
||||||
|
rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
|
||||||
|
rfsimulator->sample_rate=openair0_cfg->sample_rate;
|
||||||
|
rfsimulator->tx_bw=openair0_cfg->tx_bw;
|
||||||
|
randominit(0);
|
||||||
|
set_taus_seed(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user