First implementation for KPI GUI with Qt5
Authors: Bo Zhao, Marwan Hammouda, Thomas Schlichter (Fraunhofer IIS) - CMakeLists modification: add QtWidgets library, add new source files, MOC (Meta-Object Compiler) on the given source file - build_oai modification - Activate new GUI with Qt on the UE side - 2 x 3 widget with I/Q sample for PDSCH - Drop-down list implementation
This commit is contained in:
committed by
Thomas Schlichter
parent
646cec27d0
commit
4d0762e43d
+14
-1
@@ -1005,7 +1005,7 @@ add_dependencies(ldpc_cl nrLDPC_decoder_kernels_CL)
|
|||||||
# Base CUDA setting
|
# Base CUDA setting
|
||||||
##############################################
|
##############################################
|
||||||
|
|
||||||
add_boolean_option(BUILD_CUDA False "Build support for CUDA" OFF)
|
add_boolean_option(ENABLE_LDPC_CUDA OFF "Build support for CUDA" OFF)
|
||||||
if (ENABLE_LDPC_CUDA)
|
if (ENABLE_LDPC_CUDA)
|
||||||
find_package(CUDA REQUIRED)
|
find_package(CUDA REQUIRED)
|
||||||
SET(CUDA_NVCC_FLAG "${CUDA_NVCC_FLAGS};-arch=sm_60;")
|
SET(CUDA_NVCC_FLAG "${CUDA_NVCC_FLAGS};-arch=sm_60;")
|
||||||
@@ -2040,6 +2040,19 @@ add_library(SIMU STATIC ${SIMUSRC} )
|
|||||||
target_include_directories(SIMU PUBLIC ${OPENAIR1_DIR}/SIMULATION/TOOLS ${OPENAIR1_DIR}/SIMULATION/RF)
|
target_include_directories(SIMU PUBLIC ${OPENAIR1_DIR}/SIMULATION/TOOLS ${OPENAIR1_DIR}/SIMULATION/RF)
|
||||||
target_link_libraries(SIMU PRIVATE asn1_nr_rrc asn1_lte_rrc)
|
target_link_libraries(SIMU PRIVATE asn1_nr_rrc asn1_lte_rrc)
|
||||||
|
|
||||||
|
# Qt-based scope
|
||||||
|
add_boolean_option(ENABLE_NRQTSCOPE OFF "Build the Qt-Scope" OFF)
|
||||||
|
if (ENABLE_NRQTSCOPE)
|
||||||
|
find_package(Qt5 REQUIRED COMPONENTS Widgets Charts)
|
||||||
|
message ("Qt5 Widgets and Charts found for nrqtscope")
|
||||||
|
set(QTSCOPE_SOURCE_NR ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.cpp)
|
||||||
|
# Creates rules for calling the Meta-Object Compiler (moc) on the given source files
|
||||||
|
qt5_wrap_cpp(QTSCOPE_SOURCE_NR ${OPENAIR1_DIR}/PHY/TOOLS/nr_phy_qt_scope.h)
|
||||||
|
add_library(nrqtscope MODULE ${QTSCOPE_SOURCE_NR})
|
||||||
|
target_link_libraries(nrqtscope PRIVATE Qt5::Widgets Qt5::Charts)
|
||||||
|
target_link_libraries(nrqtscope PRIVATE asn1_nr_rrc asn1_lte_rrc)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(SIMU_ETH
|
add_library(SIMU_ETH
|
||||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
||||||
|
|||||||
@@ -53,9 +53,10 @@ BUILD_COVERITY_SCAN=0
|
|||||||
DISABLE_HARDWARE_DEPENDENCY="False"
|
DISABLE_HARDWARE_DEPENDENCY="False"
|
||||||
CMAKE_BUILD_TYPE="RelWithDebInfo"
|
CMAKE_BUILD_TYPE="RelWithDebInfo"
|
||||||
CMAKE_CMD="$CMAKE"
|
CMAKE_CMD="$CMAKE"
|
||||||
|
MAKE_CMD=make
|
||||||
BUILD_ECLIPSE=0
|
BUILD_ECLIPSE=0
|
||||||
NR="False"
|
NR="False"
|
||||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope ldpc_cuda ldpc_t1 websrv"
|
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope nrqtscope ldpc_cuda ldpc_t1 websrv"
|
||||||
RU=0
|
RU=0
|
||||||
CMAKE_C_FLAGS=()
|
CMAKE_C_FLAGS=()
|
||||||
CMAKE_CXX_FLAGS=()
|
CMAKE_CXX_FLAGS=()
|
||||||
|
|||||||
@@ -551,6 +551,7 @@ check_install_additional_tools (){
|
|||||||
PACKAGE_LIST="\
|
PACKAGE_LIST="\
|
||||||
doxygen \
|
doxygen \
|
||||||
libpthread-stubs0-dev \
|
libpthread-stubs0-dev \
|
||||||
|
libqt5charts5-dev \
|
||||||
tshark \
|
tshark \
|
||||||
uml-utilities \
|
uml-utilities \
|
||||||
iperf3 \
|
iperf3 \
|
||||||
|
|||||||
+4
-2
@@ -2218,11 +2218,13 @@ INPUT = \
|
|||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.c \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_ESTIMATION/lte_sync_timefreq.c \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_ESTIMATION/filt16_32.h \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/LTE_ESTIMATION/filt16_32.h \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.c \
|
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cdot_prod.c \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/cdot_prod.c \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.h \
|
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.h \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.h \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.c \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/phy_scope_interface.c \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.h \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_scope.c \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_qt_scope.h \
|
||||||
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/nr_phy_qt_scope.cpp \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/file_output.c \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/file_output.c \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/dfts_load.c \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/dfts_load.c \
|
||||||
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/alaw_lut.h \
|
@CMAKE_CURRENT_SOURCE_DIR@/../openair1/PHY/TOOLS/alaw_lut.h \
|
||||||
|
|||||||
@@ -711,6 +711,15 @@ int main( int argc, char **argv ) {
|
|||||||
load_softscope("nr",&p);
|
load_softscope("nr",&p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(IS_SOFTMODEM_DOSCOPE_QT) {
|
||||||
|
scopeParms_t p;
|
||||||
|
p.argc = &argc;
|
||||||
|
p.argv = argv;
|
||||||
|
p.gNB = RC.gNB[0];
|
||||||
|
p.ru = RC.ru[0];
|
||||||
|
load_softscope("nrqt", &p);
|
||||||
|
}
|
||||||
|
|
||||||
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
|
if (NFAPI_MODE != NFAPI_MODE_PNF && NFAPI_MODE != NFAPI_MODE_VNF) {
|
||||||
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
|
printf("Not NFAPI mode - call init_eNB_afterRU()\n");
|
||||||
init_eNB_afterRU();
|
init_eNB_afterRU();
|
||||||
|
|||||||
@@ -522,6 +522,10 @@ int main( int argc, char **argv ) {
|
|||||||
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
|
memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
|
||||||
set_latency_target();
|
set_latency_target();
|
||||||
|
|
||||||
|
if(IS_SOFTMODEM_DOSCOPE_QT) {
|
||||||
|
load_softscope("nrqt",PHY_vars_UE_g[0][0]);
|
||||||
|
}
|
||||||
|
|
||||||
if(IS_SOFTMODEM_DOSCOPE) {
|
if(IS_SOFTMODEM_DOSCOPE) {
|
||||||
load_softscope("nr",PHY_vars_UE_g[0][0]);
|
load_softscope("nr",PHY_vars_UE_g[0][0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ void get_common_options(uint32_t execmask) {
|
|||||||
uint32_t start_telnetsrv = 0, start_telnetclt = 0;
|
uint32_t start_telnetsrv = 0, start_telnetclt = 0;
|
||||||
uint32_t start_websrv = 0;
|
uint32_t start_websrv = 0;
|
||||||
uint32_t noS1 = 0, nokrnmod = 1, nonbiot = 0;
|
uint32_t noS1 = 0, nokrnmod = 1, nonbiot = 0;
|
||||||
uint32_t rfsim = 0, do_forms = 0;
|
uint32_t rfsim = 0, do_forms = 0, do_forms_qt = 0;
|
||||||
int nfapi_index = 0;
|
int nfapi_index = 0;
|
||||||
char *logmem_filename = NULL;
|
char *logmem_filename = NULL;
|
||||||
check_execmask(execmask);
|
check_execmask(execmask);
|
||||||
@@ -161,6 +161,10 @@ void get_common_options(uint32_t execmask) {
|
|||||||
set_softmodem_optmask(SOFTMODEM_DOSCOPE_BIT);
|
set_softmodem_optmask(SOFTMODEM_DOSCOPE_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_forms_qt) {
|
||||||
|
set_softmodem_optmask(SOFTMODEM_DOSCOPE_QT_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
if (start_websrv) {
|
if (start_websrv) {
|
||||||
load_module_shlib("websrv", NULL, 0, NULL);
|
load_module_shlib("websrv", NULL, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ extern "C"
|
|||||||
#define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n"
|
#define CONFIG_HLP_ULF "Set the uplink frequency offset for all component carriers\n"
|
||||||
#define CONFIG_HLP_CHOFF "Channel id offset\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_SOFTS "Enable soft scope and L1 and L2 stats (Xforms)\n"
|
||||||
|
#define CONFIG_HLP_SOFTS_QT "Enable soft scope and L1 and L2 stats (QT)\n"
|
||||||
#define CONFIG_HLP_ITTIL "Generate ITTI analyzser logs (similar to wireshark logs but with more details)\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_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_STMON "Enable processing timing measurement of lte softmodem on per subframe basis \n"
|
||||||
@@ -151,17 +152,18 @@ extern int usrp_tx_thread;
|
|||||||
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \
|
{"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:0, TYPE_UINT64, 0}, \
|
||||||
{"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \
|
{"CO" , CONFIG_HLP_ULF, 0, iptr:&(uplink_frequency_offset[0][0]), defintval:0, TYPE_INT, 0}, \
|
||||||
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
|
{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \
|
||||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \
|
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:&do_forms, defintval:0, TYPE_UINT, 0}, \
|
||||||
|
{"dqt" , CONFIG_HLP_SOFTS_QT, PARAMFLAG_BOOL, uptr:&do_forms_qt, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
|
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \
|
||||||
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:1, TYPE_INT, 0}, \
|
{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:1, TYPE_INT, 0}, \
|
||||||
{"band" , CONFIG_HLP_BAND, PARAMFLAG_BOOL, iptr:&BAND, defintval:78, TYPE_INT, 0}, \
|
{"band" , CONFIG_HLP_BAND, PARAMFLAG_BOOL, iptr:&BAND, defintval:78, TYPE_INT, 0}, \
|
||||||
{"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:¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
{"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, strptr:¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
{"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:&worker_config, defstrval:NULL, TYPE_STRING, 0}, \
|
||||||
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \
|
{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_INT, 0}, \
|
{"rfsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&rfsim, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
|
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_UINT, 0}, \
|
||||||
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
|
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_UINT, 0}, \
|
||||||
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&CHEST_FREQ, defintval:0, TYPE_INT, 0}, \
|
{"chest-freq", CONFIG_HLP_CHESTFREQ, 0, iptr:&CHEST_FREQ, defintval:0, TYPE_INT, 0}, \
|
||||||
{"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&CHEST_TIME, defintval:0, TYPE_INT, 0}, \
|
{"chest-time", CONFIG_HLP_CHESTTIME, 0, iptr:&CHEST_TIME, defintval:0, TYPE_INT, 0}, \
|
||||||
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \
|
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \
|
||||||
@@ -208,6 +210,7 @@ extern int usrp_tx_thread;
|
|||||||
{ .s5 = { NULL } }, \
|
{ .s5 = { NULL } }, \
|
||||||
{ .s5 = { NULL } }, \
|
{ .s5 = { NULL } }, \
|
||||||
{ .s5 = { NULL } }, \
|
{ .s5 = { NULL } }, \
|
||||||
|
{ .s5 = { NULL } }, \
|
||||||
{ .s3a = { config_checkstr_assign_integer, \
|
{ .s3a = { config_checkstr_assign_integer, \
|
||||||
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
|
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
|
||||||
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
|
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
|
||||||
@@ -216,7 +219,6 @@ extern int usrp_tx_thread;
|
|||||||
{ .s5 = { NULL } }, \
|
{ .s5 = { NULL } }, \
|
||||||
{ .s5 = { NULL } }, \
|
{ .s5 = { NULL } }, \
|
||||||
{ .s5 = { NULL } }, \
|
{ .s5 = { NULL } }, \
|
||||||
{ .s5 = { NULL } }, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONFIG_HLP_NSA "Enable NSA mode \n"
|
#define CONFIG_HLP_NSA "Enable NSA mode \n"
|
||||||
@@ -264,6 +266,8 @@ extern int usrp_tx_thread;
|
|||||||
#define SOFTMODEM_4GUE_BIT (1<<22)
|
#define SOFTMODEM_4GUE_BIT (1<<22)
|
||||||
#define SOFTMODEM_5GUE_BIT (1<<23)
|
#define SOFTMODEM_5GUE_BIT (1<<23)
|
||||||
#define SOFTMODEM_NOSTATS_BIT (1<<24)
|
#define SOFTMODEM_NOSTATS_BIT (1<<24)
|
||||||
|
#define SOFTMODEM_DOSCOPE_QT_BIT (1<<25)
|
||||||
|
|
||||||
#define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT)
|
#define SOFTMODEM_FUNC_BITS (SOFTMODEM_ENB_BIT | SOFTMODEM_GNB_BIT | SOFTMODEM_5GUE_BIT | SOFTMODEM_4GUE_BIT)
|
||||||
#define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}}
|
#define MAPPING_SOFTMODEM_FUNCTIONS {{"enb",SOFTMODEM_ENB_BIT},{"gnb",SOFTMODEM_GNB_BIT},{"4Gue",SOFTMODEM_4GUE_BIT},{"5Gue",SOFTMODEM_5GUE_BIT}}
|
||||||
|
|
||||||
@@ -275,6 +279,7 @@ extern int usrp_tx_thread;
|
|||||||
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
|
#define IS_SOFTMODEM_SIML1 ( get_softmodem_optmask() & SOFTMODEM_SIML1_BIT)
|
||||||
#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
|
#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
|
||||||
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
|
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
|
||||||
|
#define IS_SOFTMODEM_DOSCOPE_QT ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_QT_BIT)
|
||||||
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
|
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
|
||||||
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
|
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
|
||||||
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
|
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ void nr_sort_asc_int16_1D_array_ind(int32_t *matrix,
|
|||||||
|
|
||||||
void nr_free_double_2D_array(double **input, uint16_t xlen);
|
void nr_free_double_2D_array(double **input, uint16_t xlen);
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
void updateLLR(uint8_t listSize,
|
void updateLLR(uint8_t listSize,
|
||||||
uint16_t row,
|
uint16_t row,
|
||||||
uint16_t col,
|
uint16_t col,
|
||||||
@@ -327,7 +328,7 @@ void updatePathMetric2(double *pathMetric,
|
|||||||
int ylen,
|
int ylen,
|
||||||
int zlen,
|
int zlen,
|
||||||
double llr[xlen][ylen][zlen]);
|
double llr[xlen][ylen][zlen]);
|
||||||
|
#endif
|
||||||
//Also nr_polar_rate_matcher
|
//Also nr_polar_rate_matcher
|
||||||
static inline void nr_polar_interleaver(uint8_t *input,
|
static inline void nr_polar_interleaver(uint8_t *input,
|
||||||
uint8_t *output,
|
uint8_t *output,
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include "executables/nr-uesoftmodem.h"
|
#include "executables/nr-uesoftmodem.h"
|
||||||
#include "PHY/CODING/nrLDPC_extern.h"
|
#include "PHY/CODING/nrLDPC_extern.h"
|
||||||
#include "common/utils/nr/nr_common.h"
|
#include "common/utils/nr/nr_common.h"
|
||||||
|
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
|
||||||
|
|
||||||
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
|
//#define ENABLE_PHY_PAYLOAD_DEBUG 1
|
||||||
|
|
||||||
@@ -53,10 +54,16 @@
|
|||||||
static uint64_t nb_total_decod =0;
|
static uint64_t nb_total_decod =0;
|
||||||
static uint64_t nb_error_decod =0;
|
static uint64_t nb_error_decod =0;
|
||||||
|
|
||||||
|
static extended_kpi_ue kpiStructure = {0};
|
||||||
|
|
||||||
notifiedFIFO_t freeBlocks_dl;
|
notifiedFIFO_t freeBlocks_dl;
|
||||||
notifiedFIFO_elt_t *msgToPush_dl;
|
notifiedFIFO_elt_t *msgToPush_dl;
|
||||||
int nbDlProcessing =0;
|
int nbDlProcessing =0;
|
||||||
|
|
||||||
|
extended_kpi_ue* getKPIUE(void) {
|
||||||
|
return &kpiStructure;
|
||||||
|
}
|
||||||
|
|
||||||
void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations) {
|
void nr_ue_dlsch_init(NR_UE_DLSCH_t *dlsch_list, int num_dlsch, uint8_t max_ldpc_iterations) {
|
||||||
for (int i=0; i < num_dlsch; i++) {
|
for (int i=0; i < num_dlsch; i++) {
|
||||||
NR_UE_DLSCH_t *dlsch = dlsch_list + i;
|
NR_UE_DLSCH_t *dlsch = dlsch_list + i;
|
||||||
@@ -99,6 +106,11 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
|
|||||||
|
|
||||||
// if all segments are done
|
// if all segments are done
|
||||||
if (last) {
|
if (last) {
|
||||||
|
kpiStructure.nb_total++;
|
||||||
|
kpiStructure.blockSize = dlsch->dlsch_config.TBS;
|
||||||
|
kpiStructure.dl_mcs = dlsch->dlsch_config.mcs;
|
||||||
|
kpiStructure.nofRBs = dlsch->dlsch_config.number_rbs;
|
||||||
|
|
||||||
if (decodeSuccess) {
|
if (decodeSuccess) {
|
||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for nr_slot_rx %d TBS %d mcs %d nb_rb %d harq_process->round %d\n",
|
||||||
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
// phy_vars_ue->Mod_id,nr_slot_rx,harq_process->TBS,harq_process->mcs,harq_process->nb_rb, harq_process->round);
|
||||||
@@ -114,6 +126,7 @@ bool nr_ue_postDecode(PHY_VARS_NR_UE *phy_vars_ue, notifiedFIFO_elt_t *req, bool
|
|||||||
dlsch->last_iteration_cnt = rdata->decodeIterations;
|
dlsch->last_iteration_cnt = rdata->decodeIterations;
|
||||||
LOG_D(PHY, "DLSCH received ok \n");
|
LOG_D(PHY, "DLSCH received ok \n");
|
||||||
} else {
|
} else {
|
||||||
|
kpiStructure.nb_nack++;
|
||||||
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
|
//LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n",
|
||||||
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
|
// phy_vars_ue->Mod_id, frame, nr_slot_rx, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round);
|
||||||
harq_process->ack = 0;
|
harq_process->ack = 0;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,468 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||||
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.openairinterface.org/?page_id=698
|
||||||
|
*
|
||||||
|
* Authors and copyright: Bo Zhao, Marwan Hammouda, Thomas Schlichter (Fraunhofer IIS)
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*-------------------------------------------------------------------------------
|
||||||
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||||
|
* contact@openairinterface.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef QT_SCOPE_MAINWINDOW_H
|
||||||
|
#define QT_SCOPE_MAINWINDOW_H
|
||||||
|
|
||||||
|
#include <QtCharts>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <simple_executable.h>
|
||||||
|
#include <common/utils/system.h>
|
||||||
|
#include "common/ran_context.h"
|
||||||
|
#include <openair1/PHY/defs_gNB.h>
|
||||||
|
#include "PHY/defs_gNB.h"
|
||||||
|
#include "PHY/defs_nr_UE.h"
|
||||||
|
#include "PHY/defs_RU.h"
|
||||||
|
#include "executables/softmodem-common.h"
|
||||||
|
#include "phy_scope_interface.h"
|
||||||
|
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
|
||||||
|
#include "PHY/CODING/nrPolar_tools/nr_polar_defs.h"
|
||||||
|
|
||||||
|
extern RAN_CONTEXT_t RC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is an enum class for the different gNB plot types
|
||||||
|
enum class PlotTypeGnb {
|
||||||
|
empty,
|
||||||
|
waterFall,
|
||||||
|
CIR,
|
||||||
|
puschLLR,
|
||||||
|
puschIQ,
|
||||||
|
puschSNR,
|
||||||
|
puschBLER,
|
||||||
|
puschMCS,
|
||||||
|
puschRETX,
|
||||||
|
puschThroughput,
|
||||||
|
pdschSNR,
|
||||||
|
pdschBLER,
|
||||||
|
pdschMCS,
|
||||||
|
pdschRETX,
|
||||||
|
pdschThroughput,
|
||||||
|
pdschRBs,
|
||||||
|
config
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This is an enum class fpr the different UE plot types
|
||||||
|
enum class PlotTypeUE {
|
||||||
|
empty,
|
||||||
|
waterFall,
|
||||||
|
CIR,
|
||||||
|
pbchLLR,
|
||||||
|
pbchIQ,
|
||||||
|
pdcchLLR,
|
||||||
|
pdcchIQ,
|
||||||
|
pdschLLR,
|
||||||
|
pdschIQ,
|
||||||
|
pdschSNR,
|
||||||
|
pdschBLER,
|
||||||
|
pdschMCS,
|
||||||
|
pdschThroughput,
|
||||||
|
pdschRBs,
|
||||||
|
frequencyOffset,
|
||||||
|
timingAdvance,
|
||||||
|
config
|
||||||
|
};
|
||||||
|
|
||||||
|
/// This abstract class defines an interface how the KPIPlot class can access values for the different KPI plot types
|
||||||
|
class ValueProvider {
|
||||||
|
public:
|
||||||
|
/// This pure virtual function is meant to provide the KPI value to be plotted
|
||||||
|
virtual float getValue() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// An editable GUI field for a dialog box to set certain KPI configurations
|
||||||
|
class ConfigBoxFloat : public QLineEdit {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param valuePtr Pointer to a float value, which can be edited through this ConfigBoxFloat
|
||||||
|
/// \param parent Optional pointer to parent QWidget
|
||||||
|
ConfigBoxFloat(float *valuePtr, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/// This function converts the value in the editable GUI field to float and writes it back to valuePtr
|
||||||
|
void readText();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Member variable keeping the pointer to the float value
|
||||||
|
float *valuePtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Dialog box for configuring gNB KPI Limits
|
||||||
|
class KPIConfigGnb : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param parent Optional pointer to parent QWidget
|
||||||
|
explicit KPIConfigGnb(QWidget *parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Dialog box for configuring UE KPI Limits
|
||||||
|
class KPIConfigUE : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param parent Optional pointer to parent QWidget
|
||||||
|
explicit KPIConfigUE(QWidget *parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// drop-down list gNB
|
||||||
|
class KPIListSelectGnb : public QComboBox {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param parent Optional pointer to parent QWidget
|
||||||
|
explicit KPIListSelectGnb(QWidget *parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// drop-down list UE
|
||||||
|
class KPIListSelectUE : public QComboBox {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param parent Optional pointer to parent QWidget
|
||||||
|
explicit KPIListSelectUE(QWidget *parent = nullptr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Waterfall plot of RX signal power
|
||||||
|
class WaterFall : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param values Pointer to the digital I/Q samples
|
||||||
|
/// \param frame_parms Pointer to the NR_DL_FRAME_PARMS
|
||||||
|
/// \param parent Optional pointer to parent QWidget
|
||||||
|
WaterFall(complex16 *values, NR_DL_FRAME_PARMS *frame_parms, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is triggered when the own timer expires. It reads data from values and updates the image
|
||||||
|
/// \param event Pointer to the timer event
|
||||||
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
/// This function is used to draw the image on the GUI
|
||||||
|
/// \param event Pointer to the paint event
|
||||||
|
virtual void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
|
/// This function is called to change the WaterFall size
|
||||||
|
/// \param event Pointer to the resize event
|
||||||
|
virtual void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the digital I/Q samples
|
||||||
|
complex16 *values;
|
||||||
|
|
||||||
|
/// Pointer to the NR_DL_FRAME_PARMS
|
||||||
|
NR_DL_FRAME_PARMS *frame_parms;
|
||||||
|
|
||||||
|
/// Pointer to the image
|
||||||
|
QImage *image;
|
||||||
|
|
||||||
|
/// Counter of the drawn lines
|
||||||
|
int iteration;
|
||||||
|
|
||||||
|
/// pointer to an array storing per-row average power values
|
||||||
|
double *waterFallAvg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Chart class for plotting the Channel Impulse Response
|
||||||
|
class CIRPlot : public QChart {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param data Pointer to the CIR data
|
||||||
|
/// \param len Length of the CIR data
|
||||||
|
CIRPlot(complex16 *data, int len);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is triggered when the own timer expires. It updates the plotted CIR
|
||||||
|
/// \param event Pointer to the timer event
|
||||||
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the CIR data
|
||||||
|
complex16 *data;
|
||||||
|
|
||||||
|
/// Length of the CIR data
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/// Line series used to plot the CIR in the chart
|
||||||
|
QLineSeries *series;
|
||||||
|
|
||||||
|
/// Horizontal axis of the chart
|
||||||
|
QValueAxis *axisX;
|
||||||
|
|
||||||
|
/// Vertical axis of the chart
|
||||||
|
QValueAxis *axisY;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Chart class for plotting LLRs
|
||||||
|
class LLRPlot : public QChart {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param data Pointer to the LLR data
|
||||||
|
/// \param len Length of the LLR data
|
||||||
|
LLRPlot(int16_t *data, int len);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is triggered when the own timer expires. It updates the plotted LLR
|
||||||
|
/// \param event Pointer to the timer event
|
||||||
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the LLR data
|
||||||
|
int16_t *data;
|
||||||
|
|
||||||
|
/// Length of the LLR data
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/// Scatter series used to plot the LLR in the chart
|
||||||
|
QScatterSeries *series;
|
||||||
|
|
||||||
|
/// Horizontal axis of the chart
|
||||||
|
QValueAxis *axisX;
|
||||||
|
|
||||||
|
/// Vertical axis of the chart
|
||||||
|
QValueAxis *axisY;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Chart class for plotting the I/Q constellation diagram
|
||||||
|
class IQPlot : public QChart {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param data Pointer to the complex I/Q data
|
||||||
|
/// \param len Length of the I/Q data
|
||||||
|
IQPlot(complex16 *data, int len);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is triggered when the own timer expires. It updates the plotted I/Q constellation diagram
|
||||||
|
/// \param event Pointer to the timer event
|
||||||
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the I/Q data
|
||||||
|
complex16 *data;
|
||||||
|
|
||||||
|
/// Length of the I/Q data
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/// Scatter series used to plot the I/Q constellation diagram
|
||||||
|
QScatterSeries *series;
|
||||||
|
|
||||||
|
/// Horizontal axis of the chart
|
||||||
|
QValueAxis *axisX;
|
||||||
|
|
||||||
|
/// Vertical axis of the chart
|
||||||
|
QValueAxis *axisY;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Generic class for plotting KPI values with min., max. and average bars
|
||||||
|
class KPIPlot : public QChart {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param valueProvider Pointer to an instance of a class that implements the ValueProvider interface
|
||||||
|
/// \param limits Optional parameter pointing to an array of two floating point values indicating lower and upper bounds
|
||||||
|
KPIPlot(ValueProvider *valueProvider, float *limits = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is triggered when the own timer expires. It updates the plotted KPI chart
|
||||||
|
/// \param event Pointer to the timer event
|
||||||
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to an instance of a class that implements the ValueProvider interface
|
||||||
|
ValueProvider *valueProvider;
|
||||||
|
|
||||||
|
/// Pointer to an array of two floating point values indicating lower and upper bounds
|
||||||
|
float *limits;
|
||||||
|
|
||||||
|
/// smallest observed KPI value
|
||||||
|
float minValue;
|
||||||
|
|
||||||
|
/// biggest observed KPI value
|
||||||
|
float maxValue;
|
||||||
|
|
||||||
|
/// Accumulated KPI valus, used to compute the average
|
||||||
|
float sumValue;
|
||||||
|
|
||||||
|
/// Index (horizontal position) of the last plotted KPI value
|
||||||
|
int plotIdx;
|
||||||
|
|
||||||
|
/// Line series used to plot the KPI values
|
||||||
|
QLineSeries *series;
|
||||||
|
|
||||||
|
/// Line series used to plot an indication of the smallest observed KPI value
|
||||||
|
QLineSeries *seriesMin;
|
||||||
|
|
||||||
|
/// Line series used to plot an indication of the biggest observed KPI value
|
||||||
|
QLineSeries *seriesMax;
|
||||||
|
|
||||||
|
/// Line series used to plot an indication of the average KPI value
|
||||||
|
QLineSeries *seriesAvg;
|
||||||
|
|
||||||
|
/// Horizontal axis of the chart
|
||||||
|
QValueAxis *axisX;
|
||||||
|
|
||||||
|
/// Vertical axis of the chart
|
||||||
|
QValueAxis *axisY;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Crart class for plotting HARQ retransmission counters
|
||||||
|
class RTXPlot : public QChart {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param rounds Pointer to the HARQ round counters
|
||||||
|
RTXPlot(uint64_t *rounds);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is triggered when the own timer expires. It updates the plotted HARQ retransmission counters
|
||||||
|
/// \param event Pointer to the timer event
|
||||||
|
virtual void timerEvent(QTimerEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the HARQ round counters
|
||||||
|
uint64_t *rounds;
|
||||||
|
|
||||||
|
/// Last stored HARQ round counters
|
||||||
|
uint64_t lastRounds[4];
|
||||||
|
|
||||||
|
/// Maximum observed HARQ retransmissions
|
||||||
|
int maxValue;
|
||||||
|
|
||||||
|
/// Index (horizontal position) of the last plotted HARQ retransmission value
|
||||||
|
int plotIdx;
|
||||||
|
|
||||||
|
/// Line series used to plot the four HARQ retransmission counters
|
||||||
|
QLineSeries *series[4];
|
||||||
|
|
||||||
|
/// Horizontal axis of the chart
|
||||||
|
QValueAxis *axisX;
|
||||||
|
|
||||||
|
/// Vertical axis of the chart
|
||||||
|
QValueAxis *axisY;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Widget showing one selectable gNB KPI
|
||||||
|
class PainterWidgetGnb : public QWidget, public ValueProvider {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param config Pointer to the dialog box for configuring gNB KPI Limits
|
||||||
|
/// \param comboBox Pointer to the drop-down list selecting the KPI to be shown here
|
||||||
|
/// \param p Pointer to the gNB parameters
|
||||||
|
PainterWidgetGnb(QWidget *config, QComboBox *comboBox, scopeData_t *p);
|
||||||
|
|
||||||
|
/// This function provides the current KPI value to be plotted
|
||||||
|
virtual float getValue() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is called to change the widget size
|
||||||
|
/// \param event Pointer to the resize event
|
||||||
|
virtual void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/// This function is called when a different KPI is selected
|
||||||
|
/// \param type selected KPI type
|
||||||
|
void makeConnections(int type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the dialog box for configuring gNB KPI Limits
|
||||||
|
QWidget *config;
|
||||||
|
|
||||||
|
/// Pointer to the drop-down list selecting the KPI to be shown here
|
||||||
|
QComboBox *comboBox;
|
||||||
|
|
||||||
|
/// Pointer to the gNB parameters
|
||||||
|
scopeData_t *p;
|
||||||
|
|
||||||
|
/// Pointer to a class to view all QChart based KPIs
|
||||||
|
QChartView *chartView;
|
||||||
|
|
||||||
|
/// Pointer to the waterfall diagram
|
||||||
|
WaterFall *waterFall;
|
||||||
|
|
||||||
|
/// Currently plotted KPI type
|
||||||
|
PlotTypeGnb plotType;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Widget showing one selectable UE KPI
|
||||||
|
class PainterWidgetUE : public QWidget, public ValueProvider {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor
|
||||||
|
/// \param config Pointer to the dialog box for configuring UE KPI Limits
|
||||||
|
/// \param comboBox Pointer to the drop-down list selecting the KPI to be shown here
|
||||||
|
/// \param ue Pointer to the UE parameters
|
||||||
|
PainterWidgetUE(QWidget *config, QComboBox *comboBox, PHY_VARS_NR_UE *ue);
|
||||||
|
|
||||||
|
/// This function provides the current KPI value to be plotted
|
||||||
|
virtual float getValue() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// This function is called to change the widget size
|
||||||
|
/// \param event Pointer to the resize event
|
||||||
|
virtual void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/// This function is called when a different KPI is selected
|
||||||
|
/// \param type selected KPI type
|
||||||
|
void makeConnections(int type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Pointer to the dialog box for configuring UE KPI Limits
|
||||||
|
QWidget *config;
|
||||||
|
|
||||||
|
/// Pointer to the drop-down list selecting the KPI to be shown here
|
||||||
|
QComboBox *comboBox;
|
||||||
|
|
||||||
|
/// Pointer to the UE parameters
|
||||||
|
PHY_VARS_NR_UE *ue;
|
||||||
|
|
||||||
|
/// Pointer to a class to view all QChart based KPIs
|
||||||
|
QChartView *chartView;
|
||||||
|
|
||||||
|
/// Pointer to the waterfall diagram
|
||||||
|
WaterFall *waterFall;
|
||||||
|
|
||||||
|
/// Currently plotted KPI type
|
||||||
|
PlotTypeUE plotType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QT_SCOPE_MAINWINDOW_H
|
||||||
@@ -1042,6 +1042,7 @@ STATICFORXSCOPE OAI_phy_scope_t *create_phy_scope_nrue(int ID)
|
|||||||
// LLR of PDCCH
|
// LLR of PDCCH
|
||||||
fdui->graph[5] = nrUEcommonGraph(uePcchLLR,
|
fdui->graph[5] = nrUEcommonGraph(uePcchLLR,
|
||||||
FL_POINTS_XYPLOT, 0, curY, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)", FL_CYAN );
|
FL_POINTS_XYPLOT, 0, curY, 500, 100, "PDCCH Log-Likelihood Ratios (LLR, mag)", FL_CYAN );
|
||||||
|
fl_set_xyplot_xgrid(fdui->graph[5].graph,FL_GRID_MAJOR);
|
||||||
fdui->graph[5].chartid = SCOPEMSG_DATAID_LLR; // tells websrv frontend to use LLR chart for displaying
|
fdui->graph[5].chartid = SCOPEMSG_DATAID_LLR; // tells websrv frontend to use LLR chart for displaying
|
||||||
fdui->graph[5].datasetid = 1; // tells websrv frontend to use dataset index 1 in LLR chart
|
fdui->graph[5].datasetid = 1; // tells websrv frontend to use dataset index 1 in LLR chart
|
||||||
// I/Q PDCCH comp
|
// I/Q PDCCH comp
|
||||||
@@ -1054,6 +1055,7 @@ STATICFORXSCOPE OAI_phy_scope_t *create_phy_scope_nrue(int ID)
|
|||||||
// LLR of PDSCH
|
// LLR of PDSCH
|
||||||
fdui->graph[7] = nrUEcommonGraph(uePdschLLR,
|
fdui->graph[7] = nrUEcommonGraph(uePdschLLR,
|
||||||
FL_POINTS_XYPLOT, 0, curY, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
|
FL_POINTS_XYPLOT, 0, curY, 500, 200, "PDSCH Log-Likelihood Ratios (LLR, mag)", FL_YELLOW );
|
||||||
|
fl_set_xyplot_xgrid(fdui->graph[7].graph,FL_GRID_MAJOR);
|
||||||
fdui->graph[7].chartid = SCOPEMSG_DATAID_LLR; // tells websrv frontend to use LLR chart for displaying
|
fdui->graph[7].chartid = SCOPEMSG_DATAID_LLR; // tells websrv frontend to use LLR chart for displaying
|
||||||
fdui->graph[7].datasetid = 2; // tells websrv frontend to use dataset index 2 in LLR chart
|
fdui->graph[7].datasetid = 2; // tells websrv frontend to use dataset index 2 in LLR chart
|
||||||
// I/Q PDSCH comp
|
// I/Q PDSCH comp
|
||||||
@@ -1139,49 +1141,6 @@ static void *nrUEscopeThread(void *arg) {
|
|||||||
|
|
||||||
pthread_mutex_t UEcopyDataMutex;
|
pthread_mutex_t UEcopyDataMutex;
|
||||||
|
|
||||||
void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) {
|
|
||||||
// Local static copy of the scope data bufs
|
|
||||||
// The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input)
|
|
||||||
// Index of "2" could be set to the number of Rx threads + 1
|
|
||||||
static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][3] = {0};
|
|
||||||
static int copyDataBufsIdx[UEdataTypeNumberOfItems] = {0};
|
|
||||||
|
|
||||||
scopeData_t *tmp=(scopeData_t *)ue->scopeData;
|
|
||||||
|
|
||||||
if (tmp) {
|
|
||||||
// Begin of critical zone between UE Rx threads that might copy new data at the same time:
|
|
||||||
pthread_mutex_lock(&UEcopyDataMutex);
|
|
||||||
int newCopyDataIdx = (copyDataBufsIdx[type]<2)?copyDataBufsIdx[type]+1:0;
|
|
||||||
copyDataBufsIdx[type] = newCopyDataIdx;
|
|
||||||
pthread_mutex_unlock(&UEcopyDataMutex);
|
|
||||||
// End of critical zone between UE Rx threads
|
|
||||||
|
|
||||||
// New data will be copied in a different buffer than the live one
|
|
||||||
scopeGraphData_t *copyData= copyDataBufs[type][newCopyDataIdx];
|
|
||||||
|
|
||||||
if (copyData == NULL || copyData->dataSize < elementSz*colSz*lineSz) {
|
|
||||||
scopeGraphData_t *ptr=realloc(copyData, sizeof(scopeGraphData_t) + elementSz*colSz*lineSz);
|
|
||||||
|
|
||||||
if (!ptr) {
|
|
||||||
LOG_E(PHY,"can't realloc\n");
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
copyData=ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
copyData->dataSize=elementSz*colSz*lineSz;
|
|
||||||
copyData->elementSz=elementSz;
|
|
||||||
copyData->colSz=colSz;
|
|
||||||
copyData->lineSz=lineSz;
|
|
||||||
memcpy(copyData+1, dataIn, elementSz*colSz*lineSz);
|
|
||||||
copyDataBufs[type][newCopyDataIdx] = copyData;
|
|
||||||
|
|
||||||
// The new data just copied in the local static buffer becomes live now
|
|
||||||
((scopeGraphData_t **)tmp->liveData)[type]=copyData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue)
|
STATICFORXSCOPE void nrUEinitScope(PHY_VARS_NR_UE *ue)
|
||||||
{
|
{
|
||||||
AssertFatal(ue->scopeData=malloc(sizeof(scopeData_t)),"");
|
AssertFatal(ue->scopeData=malloc(sizeof(scopeData_t)),"");
|
||||||
|
|||||||
@@ -40,13 +40,6 @@
|
|||||||
typedef c16_t scopeSample_t;
|
typedef c16_t scopeSample_t;
|
||||||
#define SquaredNorm(VaR) ((VaR).r * (VaR).r + (VaR).i * (VaR).i)
|
#define SquaredNorm(VaR) ((VaR).r * (VaR).r + (VaR).i * (VaR).i)
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int dataSize;
|
|
||||||
int elementSz;
|
|
||||||
int colSz;
|
|
||||||
int lineSz;
|
|
||||||
} scopeGraphData_t;
|
|
||||||
|
|
||||||
typedef struct OAIgraph {
|
typedef struct OAIgraph {
|
||||||
FL_OBJECT *graph;
|
FL_OBJECT *graph;
|
||||||
FL_OBJECT *text;
|
FL_OBJECT *text;
|
||||||
|
|||||||
@@ -52,3 +52,44 @@ int end_forms(void) {
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz) {
|
||||||
|
// Local static copy of the scope data bufs
|
||||||
|
// The active data buf is alterned to avoid interference between the Scope thread (display) and the Rx thread (data input)
|
||||||
|
// Index of "2" could be set to the number of Rx threads + 1
|
||||||
|
static scopeGraphData_t *copyDataBufs[UEdataTypeNumberOfItems][2] = {0};
|
||||||
|
static int copyDataBufsIdx[UEdataTypeNumberOfItems] = {0};
|
||||||
|
|
||||||
|
scopeData_t *tmp = (scopeData_t *)ue->scopeData;
|
||||||
|
|
||||||
|
if (tmp) {
|
||||||
|
// Begin of critical zone between UE Rx threads that might copy new data at the same time: might require a mutex
|
||||||
|
int newCopyDataIdx = (copyDataBufsIdx[type]==0)?1:0;
|
||||||
|
copyDataBufsIdx[type] = newCopyDataIdx;
|
||||||
|
// End of critical zone between UE Rx threads
|
||||||
|
|
||||||
|
// New data will be copied in a different buffer than the live one
|
||||||
|
scopeGraphData_t *copyData = copyDataBufs[type][newCopyDataIdx];
|
||||||
|
|
||||||
|
if (copyData == NULL || copyData->dataSize < elementSz*colSz*lineSz) {
|
||||||
|
scopeGraphData_t *ptr = (scopeGraphData_t*) realloc(copyData, sizeof(scopeGraphData_t) + elementSz*colSz*lineSz);
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
LOG_E(PHY,"can't realloc\n");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
copyData = ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copyData->dataSize = elementSz*colSz*lineSz;
|
||||||
|
copyData->elementSz = elementSz;
|
||||||
|
copyData->colSz = colSz;
|
||||||
|
copyData->lineSz = lineSz;
|
||||||
|
memcpy(copyData+1, dataIn, elementSz*colSz*lineSz);
|
||||||
|
copyDataBufs[type][newCopyDataIdx] = copyData;
|
||||||
|
|
||||||
|
// The new data just copied in the local static buffer becomes live now
|
||||||
|
((scopeGraphData_t **)tmp->liveData)[type] = copyData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,14 @@
|
|||||||
#include <openair1/PHY/defs_gNB.h>
|
#include <openair1/PHY/defs_gNB.h>
|
||||||
#include <openair1/PHY/defs_nr_UE.h>
|
#include <openair1/PHY/defs_nr_UE.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t nb_total;
|
||||||
|
uint32_t nb_nack;
|
||||||
|
uint32_t blockSize; // block size, to be used for throughput calculation
|
||||||
|
uint16_t nofRBs;
|
||||||
|
uint8_t dl_mcs;
|
||||||
|
} extended_kpi_ue;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int *argc;
|
int *argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
@@ -63,8 +71,19 @@ typedef struct scopeData_s {
|
|||||||
void (*copyData)(PHY_VARS_NR_UE *,enum UEdataType, void *data, int elementSz, int colSz, int lineSz);
|
void (*copyData)(PHY_VARS_NR_UE *,enum UEdataType, void *data, int elementSz, int colSz, int lineSz);
|
||||||
} scopeData_t;
|
} scopeData_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int dataSize;
|
||||||
|
int elementSz;
|
||||||
|
int colSz;
|
||||||
|
int lineSz;
|
||||||
|
} scopeGraphData_t;
|
||||||
|
|
||||||
int load_softscope(char *exectype, void *initarg);
|
int load_softscope(char *exectype, void *initarg);
|
||||||
int end_forms(void) ;
|
int end_forms(void) ;
|
||||||
|
void UEcopyData(PHY_VARS_NR_UE *ue, enum UEdataType type, void *dataIn, int elementSz, int colSz, int lineSz);
|
||||||
|
|
||||||
#define UEscopeCopy(ue, type, ...) if(ue->scopeData) ((scopeData_t*)ue->scopeData)->copyData(ue, type, ##__VA_ARGS__);
|
#define UEscopeCopy(ue, type, ...) if(ue->scopeData) ((scopeData_t*)ue->scopeData)->copyData(ue, type, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
extended_kpi_ue* getKPIUE();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
## xForms-based Scope
|
||||||
To use the scope, run the xNB or the UE with option "-d"
|
To use the scope, run the xNB or the UE with option "-d"
|
||||||
|
|
||||||
Usage in gdb
|
Usage in gdb
|
||||||
@@ -10,3 +10,22 @@ phy_scope_nrUE(0, PHY_vars_UE_g[0][0], 0, 0, 0)
|
|||||||
|
|
||||||
or
|
or
|
||||||
phy_scope_gNB(0, phy_vars_gnb, phy_vars_ru, UE_id)
|
phy_scope_gNB(0, phy_vars_gnb, phy_vars_ru, UE_id)
|
||||||
|
|
||||||
|
# Qt-based Scope
|
||||||
|
## Building Instuctions
|
||||||
|
For the new qt-based scopo designed for NR, please consider the following:
|
||||||
|
|
||||||
|
1. run the gNB or the UE with the option '--dqt'.
|
||||||
|
2. make sure to install the Qt5 packages before running the scope. Otherwise, the scope will NOT be displayed!
|
||||||
|
3. if you need only to build the new scope, then add 'nrqtscope' after the '--lib-build' option. So, the complete
|
||||||
|
command would be
|
||||||
|
|
||||||
|
```
|
||||||
|
./build_oai --gNB -w USRP --nrUE --build-lib nrqtscope
|
||||||
|
```
|
||||||
|
|
||||||
|
## New Features
|
||||||
|
1. New KPIs for both gNB and UE, e.g., BLER, MCS, throughout, and number of scheduled RBs.
|
||||||
|
2. For each of the gNB and UE, a main widget is created with a 3x2 grid of sub-widgets, each to dispaly one KPI.
|
||||||
|
3. Each of the sub-widgets has a drop-down list to choose the KPI to show in that sub-widget.
|
||||||
|
4. Both of the gNB and UE scopes can be resized using the mouse movement.
|
||||||
|
|||||||
@@ -36,8 +36,6 @@
|
|||||||
#include "defs_nr_common.h"
|
#include "defs_nr_common.h"
|
||||||
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
#include "CODING/nrPolar_tools/nr_polar_pbch_defs.h"
|
||||||
|
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ typedef struct TDD_UL_DL_configCommon_s {
|
|||||||
struct TDD_UL_DL_configCommon_s *p_next;
|
struct TDD_UL_DL_configCommon_s *p_next;
|
||||||
} TDD_UL_DL_configCommon_t;
|
} TDD_UL_DL_configCommon_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct TDD_UL_DL_SlotConfig_s {
|
||||||
/// \ Identifies a slot within a dl-UL-TransmissionPeriodicity (given in tdd-UL-DL-configurationCommon)
|
/// \ Identifies a slot within a dl-UL-TransmissionPeriodicity (given in tdd-UL-DL-configurationCommon)
|
||||||
uint16_t slotIndex;
|
uint16_t slotIndex;
|
||||||
/// \ The direction (downlink or uplink) for the symbols in this slot. "allDownlink" indicates that all symbols in this slot are used
|
/// \ The direction (downlink or uplink) for the symbols in this slot. "allDownlink" indicates that all symbols in this slot are used
|
||||||
@@ -154,7 +154,7 @@ typedef struct {
|
|||||||
/// Corresponds to L1 parameter 'number-of-UL-symbols-dedicated' (see 38.211, section FFS_Section)
|
/// Corresponds to L1 parameter 'number-of-UL-symbols-dedicated' (see 38.211, section FFS_Section)
|
||||||
uint16_t nrofUplinkSymbols;
|
uint16_t nrofUplinkSymbols;
|
||||||
/// \ for setting a sequence
|
/// \ for setting a sequence
|
||||||
struct TDD_UL_DL_SlotConfig_t *p_next_TDD_UL_DL_SlotConfig;
|
struct TDD_UL_DL_SlotConfig_s *p_next_TDD_UL_DL_SlotConfig;
|
||||||
} TDD_UL_DL_SlotConfig_t;
|
} TDD_UL_DL_SlotConfig_t;
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifdef XFORMS
|
#ifdef XFORMS
|
||||||
#include "PHY/TOOLS/nr_phy_scope.h"
|
#include "PHY/TOOLS/nr_phy_scope.h"
|
||||||
extern char do_forms;
|
extern uint32_t do_forms;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char* namepointer_chMag ;
|
extern char* namepointer_chMag ;
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ void add_tdd_dedicated_configuration_nr(NR_DL_FRAME_PARMS *frame_parms, int slot
|
|||||||
if (next == 0) {
|
if (next == 0) {
|
||||||
frame_parms->p_TDD_UL_DL_ConfigDedicated = p_TDD_UL_DL_ConfigDedicated;
|
frame_parms->p_TDD_UL_DL_ConfigDedicated = p_TDD_UL_DL_ConfigDedicated;
|
||||||
} else {
|
} else {
|
||||||
p_previous_TDD_UL_DL_ConfigDedicated->p_next_TDD_UL_DL_SlotConfig = (struct TDD_UL_DL_SlotConfig_t *)p_TDD_UL_DL_ConfigDedicated;
|
p_previous_TDD_UL_DL_ConfigDedicated->p_next_TDD_UL_DL_SlotConfig = (TDD_UL_DL_SlotConfig_t *)p_TDD_UL_DL_ConfigDedicated;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_TDD_UL_DL_ConfigDedicated->slotIndex = slotIndex;
|
p_TDD_UL_DL_ConfigDedicated->slotIndex = slotIndex;
|
||||||
|
|||||||
Reference in New Issue
Block a user