Compare commits

..

5 Commits

Author SHA1 Message Date
Onur Yener
2707062b2e lte-ue errors 2022-06-16 11:45:05 +02:00
Onur Yener
2ae8159137 ue_decode_si error 2022-06-16 11:19:22 +02:00
Onur Yener
1d990120b9 MAX_MESSAGE_SIZE 2022-06-16 11:01:48 +02:00
Onur Yener
04e91c56a6 lte_frame_type_t error 2022-06-16 10:51:47 +02:00
Onur Yener
f97177c98f d2d merge on develop 2022-06-16 10:32:35 +02:00
570 changed files with 29028 additions and 182321 deletions

31
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,31 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/cmake_targets/ran_build/build/lte-softmodem",
"args": [
"-O", "../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf",
"--noS1"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/cmake_targets",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "${workspaceFolder}/cmake_targets/sudo-gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

View File

@@ -21,6 +21,8 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
servingCellConfigCommon = (
{
#spCellConfigCommon

View File

@@ -32,6 +32,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (
{

View File

@@ -21,6 +21,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -32,6 +32,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -21,6 +21,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -44,6 +44,7 @@ gNBs =
local_s_portd = 2152;
remote_s_portc = 500;
remote_s_portd = 2152;
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -36,6 +36,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -37,6 +37,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;

View File

@@ -38,6 +38,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;

View File

@@ -21,6 +21,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -21,6 +21,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -19,6 +19,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"

View File

@@ -41,6 +41,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"
do_SRS = 1;

View File

@@ -37,6 +37,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"

View File

@@ -37,6 +37,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pusch_AntennaPorts = 2;
ul_prbblacklist = "51,52,53,54"
do_SRS = 1;

View File

@@ -37,6 +37,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
#pusch_TargetSNRx10 = 200;
#pucch_TargetSNRx10 = 200;
ul_prbblacklist = "51,52,53,54"

View File

@@ -37,6 +37,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts_XP = 2;
pusch_AntennaPorts = 2;
#pusch_TargetSNRx10 = 200;

View File

@@ -21,6 +21,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -19,6 +19,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
servingCellConfigCommon = (
{

View File

@@ -20,6 +20,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 31; //0;
min_rxtxtime = 6;
servingCellConfigCommon = (

View File

@@ -32,6 +32,7 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
min_rxtxtime = 6;
pdcch_ConfigSIB1 = (

View File

@@ -32,6 +32,9 @@ gNBs =
////////// Physical parameters:
ssb_SubcarrierOffset = 0;
pdsch_AntennaPorts = 1;
pusch_AntennaPorts = 1;
sib1_tda = 15;
min_rxtxtime = 6;

View File

@@ -529,14 +529,14 @@ class Dashboard:
mr_notes = editable_mr.notes.list(all=True)
body = '[Consolidated Test Results](https://oaitestdashboard.s3.eu-west-1.amazonaws.com/MR'+mr+'/index.html)\\\n'
body += 'Tested CommitID: ' + commit
body += 'Tested CommitID: ' + commit + '\\\n'
for i in range(0,n_tests):
jobname = args[4*i]
buildurl = args[4*i+1]
buildid = args[4*i+2]
status = args[4*i+3]
body += '\\\n' + jobname + ': **'+status+'** ([' + buildid + '](' + buildurl + '))'
body += jobname+': **'+status+'** ([' + buildid + '](' + buildurl + '))\\\n'
#create new note
mr_note = editable_mr.notes.create({

View File

@@ -32,7 +32,7 @@
<testCase id="000001">
<class>Build_eNB</class>
<desc>Build gNB</desc>
<Build_eNB_args>-w USRP -c --gNB --ninja --noavx512</Build_eNB_args>
<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
<eNB_instance>0</eNB_instance>
<eNB_serverId>0</eNB_serverId>
<forced_workspace_cleanup>True</forced_workspace_cleanup>

View File

@@ -50,7 +50,7 @@
<testCase id="000002">
<class>Build_eNB</class>
<desc>Build gNB</desc>
<Build_eNB_args>-w USRP -c --gNB --ninja --noavx512</Build_eNB_args>
<Build_eNB_args>-w USRP -c --gNB --ninja</Build_eNB_args>
<eNB_instance>1</eNB_instance>
<eNB_serverId>1</eNB_serverId>
<backgroundBuild>True</backgroundBuild>

View File

@@ -34,7 +34,7 @@
<mode>TesteNB</mode>
<class>Build_eNB</class>
<desc>Build gNB (USRP)</desc>
<Build_eNB_args>--gNB -w USRP --ninja --cmake-opt -DBoost_INCLUDE_DIR=/usr/include/boost169 --noavx512</Build_eNB_args>
<Build_eNB_args>--gNB -w USRP --ninja --cmake-opt -DBoost_INCLUDE_DIR=/usr/include/boost169</Build_eNB_args>
<forced_workspace_cleanup>True</forced_workspace_cleanup>
</testCase>

View File

@@ -32,7 +32,7 @@
<testCase id="000001">
<class>Build_PhySim</class>
<desc>Build for physical simulator</desc>
<physim_build_args>--phy_simulators --ninja --noavx512</physim_build_args>
<physim_build_args>--phy_simulators --ninja</physim_build_args>
<forced_workspace_cleanup>FALSE</forced_workspace_cleanup>
</testCase>

View File

@@ -203,23 +203,17 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
else (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
if(EXISTS "/proc/cpuinfo")
file(STRINGS "/proc/cpuinfo" CPUINFO REGEX flags LIMIT_COUNT 1)
message("NOAVX512 is ${NOAVX512}")
if (CPUINFO MATCHES "avx512bw" AND "${NOAVX512}" STREQUAL "False")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx512bw -march=skylake-avx512 -mtune=skylake-avx512 " )
if (CPUINFO MATCHES "avx2")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2")
set(COMPILATION_AVX2 "True")
else()
if (CPUINFO MATCHES "avx2")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mavx2")
set(COMPILATION_AVX2 "True")
else()
set(COMPILATION_AVX2 "False")
endif()
if (CPUINFO MATCHES "sse4_1")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1 -mpclmul")
endif()
if (CPUINFO MATCHES "ssse3")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3")
endif()
set(COMPILATION_AVX2 "False")
endif()
if (CPUINFO MATCHES "sse4_1")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -msse4.1 -mpclmul")
endif()
if (CPUINFO MATCHES "ssse3")
set(C_FLAGS_PROCESSOR "${C_FLAGS_PROCESSOR} -mssse3")
endif()
else()
Message("/proc/cpuinfo does not exit. We will use manual CPU flags")
@@ -230,11 +224,11 @@ set(C_FLAGS_PROCESSOR " ${C_FLAGS_PROCESSOR} ${CFLAGS_PROCESSOR_USER}")
Message("C_FLAGS_PROCESSOR is ${C_FLAGS_PROCESSOR}")
#if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
# if ( (NOT( C_FLAGS_PROCESSOR MATCHES "ssse3")) OR (NOT( C_FLAGS_PROCESSOR MATCHES "msse4.1")) )
# Message(FATAL_ERROR "For x86 Architecture, you must have following flags: -mssse3 -msse4.1. The current detected flags are: ${C_FLAGS_PROCESSOR}. You can pass the flags manually in build script, for example: ./build_oai --cflags_processor \"-mssse3 -msse4.1 -mavx2\" ")
# endif()
#endif()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "x86")
if ( (NOT( C_FLAGS_PROCESSOR MATCHES "ssse3")) OR (NOT( C_FLAGS_PROCESSOR MATCHES "msse4.1")) )
Message(FATAL_ERROR "For x86 Architecture, you must have following flags: -mssse3 -msse4.1. The current detected flags are: ${C_FLAGS_PROCESSOR}. You can pass the flags manually in build script, for example: ./build_oai --cflags_processor \"-mssse3 -msse4.1 -mavx2\" ")
endif()
endif()
#
# add autotools definitions that were maybe used!
@@ -253,22 +247,6 @@ add_boolean_option(SANITIZE_ADDRESS False "enable the address sanitizer (ASan)")
if (SANITIZE_ADDRESS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -fno-common")
# There seems to be some incompatibility with pthread_create and the RT scheduler, which
# results in pthread_create hanging.
#
# When we switch from Ubuntu 16.04 to 18.04, we found that running with the address sanitizer,
# the pthread_create function calls were not working. The inital thought was that we were
# trying to create a thread that was not-blocking and would eventually crash the machine during
# the run. After more debugging, we found that we would never even start the thread. We narrowed
# down the first two instances of pthread_create in the gNB and NR UE to be sctp_eNB_task and
# one_thread, respectively. We found that adding sleeps, and various other pauses to the threads
# had not effect. From there, we found that if we add an abort(); prior to the thread loop, we
# do not execute that. This indicated to us that the problem is not likely to be a non-blocking
# thread, but perhaps and issue with pthread_create itself. From there we begain to research the
# issue on the web. See: https://github.com/google/sanitizers/issues/1125
#
# Google searching indicates this appears to be a problem since at least 2018. This could be something
# wrong in the pthread library, or something subtly wrong in this CMakeLists.txt. Use Ubuntu 20.04 instead.
endif ()
add_definitions("-DASN_DISABLE_OER_SUPPORT")
@@ -1406,11 +1384,8 @@ set(PHY_NR_CODINGIF
)
add_library(ldpc_orig MODULE ${PHY_LDPC_ORIG_SRC} )
target_link_libraries(ldpc_orig PRIVATE ldpc_gen_HEADERS)
add_library(ldpc_optim MODULE ${PHY_LDPC_OPTIM_SRC} )
target_link_libraries(ldpc_optim PRIVATE ldpc_gen_HEADERS)
add_library(ldpc_optim8seg MODULE ${PHY_LDPC_OPTIM8SEG_SRC} )
target_link_libraries(ldpc_optim8seg PRIVATE ldpc_gen_HEADERS)
add_library(ldpc_cl MODULE ${PHY_LDPC_CL_SRC} )
target_link_libraries(ldpc_cl OpenCL)
add_dependencies(ldpc_cl nrLDPC_decoder_kernels_CL)
@@ -1422,7 +1397,6 @@ if (CUDA_FOUND)
endif (CUDA_FOUND)
add_library(ldpc MODULE ${PHY_LDPC_OPTIM8SEGMULTI_SRC} )
target_link_libraries(ldpc PRIVATE ldpc_gen_HEADERS)
add_library(coding MODULE ${PHY_TURBOSRC} )
@@ -1433,9 +1407,13 @@ add_library(dfts MODULE ${OPENAIR1_DIR}/PHY/TOOLS/oai_dfts.c )
set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slss.c
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sldch.c
# ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slsch.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pbch.c #Source files that had to be added after merge with sidelink
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/ulsch_demodulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_modulation.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dlsch_coding.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pcfich.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/get_pmi.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/group_hopping.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/phich_common.c
@@ -1448,6 +1426,10 @@ set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/srs_modulation.c
${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c #Source files that had to be added after merge with sidelink
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/freq_equalization.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_uespec.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold.c
@@ -1543,6 +1525,9 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/prach_ue.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/pmch_ue.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/pch_ue.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/slpss.c #Transfer sidelink source files to LTE_TRANSPORT_UE
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/slsss.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/slbch.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/slss.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/sldch.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/slsch.c
@@ -1551,6 +1536,7 @@ set(PHY_SRC_UE
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/ulsch_coding.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/rar_tools_ue.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/initial_sync.c
${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/initial_syncSL.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep.c
${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_mbsfn.c
${OPENAIR1_DIR}/PHY/MODULATION/ul_7_5_kHz_ue.c
@@ -1952,7 +1938,6 @@ set (MAC_SRC_UE
set (MAC_NR_SRC_UE
${NR_UE_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_UE_PHY_INTERFACE_DIR}/NR_Packet_Drop.c
${NR_UE_MAC_DIR}/config_ue.c
${NR_UE_MAC_DIR}/mac_vars.c
${NR_UE_MAC_DIR}/main_ue_nr.c
@@ -3181,5 +3166,3 @@ ADD_CUSTOM_TARGET(oarf
)
include (${OPENAIR_DIR}/common/utils/telnetsrv/telnetsrv_CMakeLists.txt)
include(${OPENAIR1_DIR}/PHY/CODING/nrLDPC_decoder/nrLDPC_tools/CMakeLists.txt)
include (${OPENAIR_DIR}/common/utils/websrv/websrv_CMakeLists.txt)

View File

@@ -1062,8 +1062,7 @@
(Test3: PBCH-only, 217 PRB),
(Test4: PBCH and synchronization, 217 RPB),
(Test5: PBCH-only, 273 PRB),
(Test6: PBCH and synchronization, 273 PRB),
(Test7: PBCH and synchronization, 106PBR, SSB SC OFFSET 6)</desc>
(Test6: PBCH and synchronization, 273 PRB)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1075,9 +1074,8 @@
-s-11 -S-8 -n10 -R217
-s-11 -S-8 -n10 -o8000 -I -R217
-s-11 -S-8 -n10 -R273
-s-11 -S-8 -n10 -o8000 -I -R273
-s-11 -S-8 -n10 -R106 -O6</main_exec_args>
<tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6 nr_pbchsim.test7</tags>
-s-11 -S-8 -n10 -o8000 -I -R273</main_exec_args>
<tags>nr_pbchsim.test1 nr_pbchsim.test2 nr_pbchsim.test3 nr_pbchsim.test4 nr_pbchsim.test5 nr_pbchsim.test6</tags>
<search_expr_true>PBCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
@@ -1107,8 +1105,7 @@
(Test20: Mapping type B, 4 DMRS Symbols),
(Test21: 4x4 MIMO, 1 Layer),
(Test22: 4x4 MIMO, 2 Layers),
(Test23: 25 PRBs, 15 kHz SCS)
(Test24: MCS 0, low SNR performance)</desc>
(Test23: 25 PRBs, 15 kHz SCS)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1137,9 +1134,8 @@
-n100 -s2 -U 2 1 3
-n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4
-n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4
-n100 -m0 -e0 -R25 -b25 -i 2 1 0
-n100 -e0 -t95 -S-1.0 -i 2 1 0</main_exec_args>
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22 nr_dlsim.test23 nr_dlsim.test24</tags>
-n100 -m0 -e0 -R25 -b25 -i 2 1 0</main_exec_args>
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22 nr_dlsim.test23</tags>
<search_expr_true>PDSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>
@@ -1318,8 +1314,7 @@
(Test18: 25 PRBs, 15 kHz SCS),
(Test19: 3GPP G-FR1-A4-13 2 RX Antennas Requirements Test),
(Test20: 3GPP G-FR1-A4-13 4 RX Antennas Requirements Test),
(Test21: 3GPP G-FR1-A4-13 8 RX Antennas Requirements Test),
(Test22: MCS 0, low SNR performance)</desc>
(Test21: 3GPP G-FR1-A4-13 8 RX Antennas Requirements Test)</desc>
<pre_compile_prog></pre_compile_prog>
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
<compile_prog_args> --phy_simulators -c </compile_prog_args>
@@ -1346,9 +1341,9 @@
-n100 -u0 -m0 -R25 -r25 -i 2 1 0
-m16 -r106 -s8.8 -S9.4 -z2 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-m16 -r106 -s5.4 -S6 -z4 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-m16 -r106 -s3.4 -S3.8 -z8 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0
-n100 -m0 -S -0.6 -i 2 1 0</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18 nr_ulsim.test19 nr_ulsim.test20 nr_ulsim.test21 nr_ulsim.test22</tags>
-m16 -r106 -s3.4 -S3.8 -z8 -n200 -U 4 1 1 1 2 -gI -b14 -t70 -I15 -i 2 1 0</main_exec_args>
<tags>nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 nr_ulsim.test6 nr_ulsim.test7 nr_ulsim.test8 nr_ulsim.test9 nr_ulsim.test10 nr_ulsim.test11 nr_ulsim.test12 nr_ulsim.test13 nr_ulsim.test14 nr_ulsim.test15 nr_ulsim.test16 nr_ulsim.test17 nr_ulsim.test18 nr_ulsim.test19 nr_ulsim.test20 nr_ulsim.test21</tags>
<search_expr_true>PUSCH test OK</search_expr_true>
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
<nruns>3</nruns>

View File

@@ -55,10 +55,9 @@ BUILD_COVERITY_SCAN=0
DISABLE_HARDWARE_DEPENDENCY="False"
CMAKE_BUILD_TYPE="RelWithDebInfo"
CMAKE_CMD="$CMAKE"
NOAVX512="False"
BUILD_ECLIPSE=0
NR="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope websrv"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope"
RU=0
CMAKE_C_FLAGS=()
CMAKE_CXX_FLAGS=()
@@ -165,8 +164,6 @@ Options:
Build optional shared library, <libraries> can be one or several of $OPTIONAL_LIBRARIES or \"all\"
--usrp-recplay
Build for I/Q record-playback modes
--noavx512
Build without AVX512 if it is present on CPU
-k | --skip-shared-libraries
Skip build for shared libraries to reduce compilation time when building frequently for debugging purposes
--ninja
@@ -439,10 +436,6 @@ function main() {
fi
fi
shift 2;;
--noavx512)
NOAVX512="True"
echo_info "Disabling AVX512"
shift 1;;
-k | --skip-shared-libraries)
SKIP_SHARED_LIB_FLAG="True"
echo_info "Skipping build of shared libraries, rfsimulator and transport protocol libraries"
@@ -452,7 +445,6 @@ function main() {
MAKE_CMD=ninja
shift;;
--sanitize-address | -fsanitize=address)
grep -sq "Ubuntu 18.04" /etc/os-release && echo_error "Bug in OS with this option, see CMakeLists.txt"
CMAKE_CMD="$CMAKE_CMD -DSANITIZE_ADDRESS=True"
shift;;
--ittiSIM)
@@ -632,7 +624,6 @@ function main() {
cd $DIR/$BUILD_DIR/build
if [[ ${#CMAKE_C_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_C_FLAGS=\"${CMAKE_C_FLAGS[*]}\""; fi
if [[ ${#CMAKE_CXX_FLAGS[@]} > 0 ]]; then CMAKE_CMD="$CMAKE_CMD -DCMAKE_CXX_FLAGS=\"${CMAKE_CXX_FLAGS[*]}\""; fi
CMAKE_CMD="$CMAKE_CMD -DNOAVX512=\"${NOAVX512[*]}\""
echo_info "running $CMAKE_CMD"
eval $CMAKE_CMD ../..

View File

@@ -109,7 +109,6 @@ check_supported_distribution() {
"ubuntu18.04") return 0 ;;
"ubuntu16.04") return 0 ;;
"fedora35") return 0 ;;
"fedora36") return 0 ;;
"rhel7") return 0 ;;
"rhel7.6") return 0 ;;
"rhel7.7") return 0 ;;
@@ -197,8 +196,8 @@ check_warnings() {
#argument:
# $1: log file
check_errors() {
#we look for 'error:' in the compilation log file
error_count=`grep -c "error:" "$1"`
#we look for 'warning:' in the compilation log file
error_count=`grep "error:" "$1" | wc -l`
if [ $error_count -gt 0 ]; then
echo_error "ERROR: $error_count error. See $1"
fi
@@ -624,6 +623,7 @@ check_install_additional_tools (){
android-tools-adb \
wvdial \
sshpass \
nscd \
bc \
ntp"
elif [[ "$OS_DISTRO" == "rhel" ]] || [[ "$OS_DISTRO" == "centos" ]]; then
@@ -648,6 +648,7 @@ check_install_additional_tools (){
wvdial \
numpy \
sshpass \
nscd \
python2-paramiko \
python-pyroute2 \
python-netifaces \
@@ -675,6 +676,7 @@ check_install_additional_tools (){
wvdial \
python-numpy \
sshpass \
nscd \
python-paramiko \
python-pyroute2 \
python-netifaces \

View File

@@ -88,8 +88,6 @@ int processoption(paramdef_t *cfgoptions, char *value) {
config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval)+1);
sprintf(*(cfgoptions->strptr), "%s",tmpval);
} else {
AssertFatal( ( strlen(*(cfgoptions->strptr)) < cfgoptions->numelt), "[CONFIG] Error: %s too long, %s value cannot exceed %i bytes\n",
cfgoptions->optname,tmpval, cfgoptions->numelt) ;
sprintf( (char *)(cfgoptions->strptr), "%s",tmpval);
}

View File

@@ -88,32 +88,13 @@ int load_config_sharedlib(configmodule_interface_t *cfgptr) {
st = -1;
}
if ( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
sprintf (fname,"config_%s_set",cfgptr->cfgmode);
cfgptr->set = dlsym(lib_handle,fname);
if (cfgptr->set == NULL ) {
printf("[CONFIG] %s %d no function %s for config mode %s\n",
__FILE__, __LINE__,fname, cfgptr->cfgmode);
st = -1;
}
sprintf (fname,"config_%s_write_parsedcfg",cfgptr->cfgmode);
cfgptr->write_parsedcfg = dlsym(lib_handle,fname);
if (cfgptr->write_parsedcfg == NULL ) {
printf("[CONFIG] %s %d no function %s for config mode %s\n",
__FILE__, __LINE__,fname, cfgptr->cfgmode);
}
}
sprintf (fname,"config_%s_end",cfgptr->cfgmode);
cfgptr->end = dlsym(lib_handle,fname);
if (cfgptr->end == NULL ) {
if (cfgptr->getlist == NULL ) {
printf("[CONFIG] %s %d no function %s for config mode %s\n",
__FILE__, __LINE__,fname, cfgptr->cfgmode);
}
}
return st;
@@ -205,7 +186,6 @@ configmodule_interface_t *load_configmodule(int argc,
uint32_t initflags)
{
char *cfgparam=NULL;
char *modeparams=NULL;
char *cfgmode=NULL;
char *strtokctx=NULL;
@@ -213,8 +193,7 @@ configmodule_interface_t *load_configmodule(int argc,
uint32_t tmpflags=0;
int i;
int OoptIdx=-1;
int OWoptIdx=-1;
printf("CMDLINE: ");
for (int i=0; i<argc; i++)
printf("\"%s\" ", argv[i]);
@@ -229,11 +208,7 @@ configmodule_interface_t *load_configmodule(int argc,
cfgparam = argv[i+1];
OoptIdx=i;
}
char *OWopt = strstr(argv[i],"OW");
if ( OWopt == argv[i]+2) {
OWoptIdx=i;
}
if ( strstr(argv[i], "help_config") != NULL ) {
config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params),CONFIG_SECTIONNAME);
exit(0);
@@ -283,11 +258,6 @@ configmodule_interface_t *load_configmodule(int argc,
/* argv[0] is the exec name, always Ok */
cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED;
/* When reuested _(_--OW or rtflag is 5), a file with config parameters, as defined after all processing, will be created */
if (OWoptIdx >= 0) {
cfgptr->argv_info[OWoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED;
cfgptr->rtflags |= CONFIG_SAVERUNCFG ;
}
/* when OoptIdx is >0, -O option has been detected at position OoptIdx
* we must memorize arv[OoptIdx is Ok */
if (OoptIdx >= 0) {
@@ -324,18 +294,14 @@ configmodule_interface_t *load_configmodule(int argc,
printf("%s ",cfgptr->cfgP[i]);
}
if (cfgptr->rtflags & CONFIG_PRINTPARAMS) {
cfgptr->status = malloc(sizeof(configmodule_status_t));
}
printf(", debug flags: 0x%08x\n",cfgptr->rtflags);
if (strstr(cfgparam,CONFIG_CMDLINEONLY) == NULL) {
i=load_config_sharedlib(cfgptr);
if (i == 0) {
printf("[CONFIG] config module %s loaded\n",cfgmode);
int idx = config_paramidx_fromname(Config_Params, CONFIG_PARAMLENGTH(Config_Params), CONFIGP_DEBUGFLAGS);
Config_Params[idx].uptr=&(cfgptr->rtflags);
idx = config_paramidx_fromname(Config_Params, CONFIG_PARAMLENGTH(Config_Params), CONFIGP_TMPDIR);
Config_Params[idx].strptr=&(cfgptr->tmpdir);
Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags);
config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME );
} else {
fprintf(stderr,"[CONFIG] %s %d config module \"%s\" couldn't be loaded\n", __FILE__, __LINE__,cfgmode);
@@ -347,10 +313,7 @@ configmodule_interface_t *load_configmodule(int argc,
cfgptr->getlist = config_cmdlineonly_getlist;
cfgptr->end = (configmodule_endfunc_t)nooptfunc;
}
printf("[CONFIG] debug flags: 0x%08x\n",cfgptr->rtflags);
if (modeparams != NULL) free(modeparams);
if (cfgmode != NULL) free(cfgmode);
@@ -363,28 +326,10 @@ configmodule_interface_t *load_configmodule(int argc,
return cfgptr;
}
/* Possibly write config file, with parameters which have been read and after command line parsing */
void write_parsedcfg(void) {
if ( cfgptr->status && (cfgptr->rtflags & CONFIG_SAVERUNCFG)) {
printf_params("[CONFIG] Runtime params creation status: %i null values, %i errors, %i empty list or array, %i successfull \n",
cfgptr->status->num_err_nullvalue,
cfgptr->status->num_err_write,
cfgptr->status->emptyla,
cfgptr->status->num_write);
}
if (cfgptr != NULL) {
if (cfgptr->write_parsedcfg != NULL) {
printf ("[CONFIG] calling config module write_parsedcfg function...\n");
cfgptr->write_parsedcfg();
}
}
}
/* free memory allocated when reading parameters */
/* config module could be initialized again after this call */
void end_configmodule(void) {
write_parsedcfg();
if (cfgptr != NULL) {
if (cfgptr->end != NULL) {
printf ("[CONFIG] calling config module end function...\n");
@@ -410,10 +355,7 @@ void end_configmodule(void) {
void free_configmodule(void) {
if (cfgptr != NULL) {
end_configmodule();
if( cfgptr->status != NULL) {
free(cfgptr->status->debug_cfgname);
free(cfgptr->status);
}
if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode);
printf ("[CONFIG] free %i config parameter pointers\n",cfgptr->num_cfgP);

View File

@@ -54,7 +54,6 @@
#define CONFIG_DEBUGPTR (1<<1) // print memory allocation/free debug messages
#define CONFIG_DEBUGCMDLINE (1<<2) // print command line processing messages
#define CONFIG_NOABORTONCHKF (1<<4) // disable abort execution when parameter checking function fails
#define CONFIG_SAVERUNCFG (1<<5) // create config file with running values, as after cfg file + command line processing
#define CONFIG_NOEXITONHELP (1<<19) // do not exit after printing help
#define CONFIG_HELP (1<<20) // print help message
#define CONFIG_ABORT (1<<21) // config failed,abort execution
@@ -62,20 +61,7 @@
typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP);
typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix);
typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix);
typedef int(*configmodule_setfunc_t)(paramdef_t *cfgoptions, int numoptions, char *prefix );
typedef void(*configmodule_endfunc_t)(void);
typedef struct configmodule_status {
int num_paramgroups;
char ** paramgroups_names;
int num_err_nullvalue;
int emptyla;
int num_err_read;
int num_err_write;
int num_read;
int num_write;
char *debug_cfgname;
}configmodule_status_t;
typedef struct configmodule_interface {
int argc;
char **argv;
@@ -86,15 +72,11 @@ typedef struct configmodule_interface {
configmodule_initfunc_t init;
configmodule_getfunc_t get;
configmodule_getlistfunc_t getlist;
configmodule_setfunc_t set;
configmodule_endfunc_t end;
configmodule_endfunc_t write_parsedcfg;
uint32_t numptrs;
uint32_t rtflags;
char *ptrs[CONFIG_MAX_ALLOCATEDPTRS];
bool ptrsAllocated[CONFIG_MAX_ALLOCATEDPTRS];
char *tmpdir;
configmodule_status_t *status; // allocated in debug mode only
} configmodule_interface_t;
#ifdef CONFIG_LOADCONFIG_MAIN
@@ -107,19 +89,16 @@ static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugfl
incp parameter can be used to define the include path used for config files (@include directive)\n \
defaults is set to the path of the main config file.\n";
#define CONFIG_HELP_TMPDIR "<Repository to create temporary file>"
#define CONFIG_SECTIONNAME "config"
#define CONFIGP_DEBUGFLAGS "debugflags"
#define CONFIGP_TMPDIR "tmpdir"
#define CONFIGPARAM_DEBUGFLAGS_IDX 0
static paramdef_t Config_Params[] = {
/*--------------------------------------------------------------------------------------------------------------------------*/
/* config parameters for config module */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*--------------------------------------------------------------------------------------------------------------------------*/
{CONFIGP_DEBUGFLAGS, config_helpstr, 0, uptr:NULL, defintval:0, TYPE_MASK, 0},
{CONFIGP_TMPDIR, CONFIG_HELP_TMPDIR,PARAMFLAG_NOFREE, strptr:NULL, defstrval:"/tmp" ,TYPE_STRING, 0},
/*-----------------------------------------------------------------------------------------------------------------------*/
/* config parameters for config module */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-----------------------------------------------------------------------------------------------------------------------*/
{"debugflags", config_helpstr, 0, uptr:NULL, defintval:0, TYPE_MASK, 0},
};
#else
@@ -134,7 +113,6 @@ extern configmodule_interface_t *cfgptr;
#define CONFIG_ENABLECMDLINEONLY (1<<1)
extern configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags);
extern void end_configmodule(void);
extern void write_parsedcfg(void);
#define CONFIG_PRINTF_ERROR(f, x... ) if (isLogInitDone ()) { LOG_E(ENB_APP,f,x);} else {printf(f,x);}; if ( !CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) ) exit_fun("exit because configuration failed\n");

View File

@@ -46,7 +46,6 @@
#define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function
#define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1
#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
/* Flags used by config modules to return info to calling modules and/or to for internal usage*/
#define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module

View File

@@ -237,9 +237,6 @@ int config_get(paramdef_t *params, int numparams, char *prefix) {
if (ret >= 0) {
config_process_cmdline(params, numparams, prefix);
if ( cfgif->rtflags & CONFIG_SAVERUNCFG ) {
config_get_if()->set(params, numparams, prefix);
}
config_execcheck(params, numparams, prefix);
}
@@ -274,11 +271,9 @@ int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams
char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */
for (int i = 0; i < ParamList->numelt; ++i) {
// TODO config_process_cmdline?
sprintf(cfgpath, "%s.[%i]", newprefix, i);
config_process_cmdline(ParamList->paramarray[i],numparams,cfgpath);
if ( config_get_if()->rtflags & CONFIG_SAVERUNCFG ) {
config_get_if()->set(ParamList->paramarray[i], numparams,cfgpath );
}
config_execcheck(ParamList->paramarray[i], numparams, cfgpath);
}

View File

@@ -34,11 +34,8 @@
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <libgen.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <libgen.h>
#include "config_libconfig.h"
#include "config_libconfig_private.h"
@@ -90,222 +87,8 @@ int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpat
return cfgoptions->numelt;
}
int config_libconfig_setparams(paramdef_t *cfgoptions, int numoptions, config_setting_t * asetting, char * prefix) {
int status;
int errors=0;
int notused=0;
int emptyla=0;
#define LIBCONFIG_NOTUSED_PARAMS "Not used? (NULL value ptr)"
char *secprefix=(prefix==NULL)?"":prefix;
for(int i=0; i<numoptions; i++) {
if (cfgoptions[i].paramflags & PARAMFLAG_CMDLINEONLY) {
continue;
printf_params("[LIBCONFIG] setting %s.%s skipped (command line only) \n",secprefix,cfgoptions[i].optname);
}
status=CONFIG_FALSE;
config_setting_t * psetting;
char *spath=malloc(((prefix==NULL)?0:strlen(prefix))+strlen(cfgoptions[i].optname)+10);
sprintf(spath,"%s%s%s",secprefix, (prefix==NULL)?"":".", cfgoptions[i].optname);
psetting = config_lookup(&(libconfig_privdata.runtcfg),spath);
free(spath);
if (psetting != NULL) {
printf_params("[LIBCONFIG] setting %s.%s already created \n",secprefix,cfgoptions[i].optname);
continue;
}
switch(cfgoptions[i].type) {
case TYPE_STRING:
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_STRING);
if (psetting!= NULL) {
char *value;
if (cfgoptions[i].strptr == NULL) {
notused++;
value=LIBCONFIG_NOTUSED_PARAMS;
} else {
if (cfgoptions[i].numelt == 0 ) {
value = *(cfgoptions[i].strptr);
} else {
value = (char *)(cfgoptions[i].strptr);
}
}
status=config_setting_set_string(psetting, value);
}
break;
case TYPE_STRINGLIST:
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_LIST);
if (psetting!= NULL)
{
if(cfgoptions[i].numelt <= 0) {
emptyla++;
printf_params("[LIBCONFIG], no element in list %s\n",cfgoptions[i].optname);
status=CONFIG_TRUE;
}
for (int j=0; j<cfgoptions[i].numelt ; j++) {
config_setting_t *elemsetting=config_setting_set_string_elem(psetting, -1,cfgoptions[i].strptr[j] );
if (elemsetting == NULL) {
fprintf(stderr,"[LIBCONFIG] Error: Creating list %s element %i value %s\n",cfgoptions[i].optname,j,cfgoptions[i].strptr[j]);
break;
} else
status=CONFIG_TRUE;
}
}
break;
case TYPE_UINT8:
case TYPE_INT8:
case TYPE_UINT16:
case TYPE_INT16:
case TYPE_UINT32:
case TYPE_INT32:
case TYPE_MASK:
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_INT);
if (psetting!= NULL)
status=config_setting_set_int(psetting, (int)*(cfgoptions[i].iptr) );
break;
case TYPE_UINT64:
case TYPE_INT64:
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_INT64);
if (psetting!= NULL)
status=config_setting_set_int64(psetting, (int64_t)*(cfgoptions[i].i64ptr) );
break;
case TYPE_UINTARRAY:
case TYPE_INTARRAY:
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_ARRAY);
if (psetting!= NULL) {
if(cfgoptions[i].numelt <= 0) {
emptyla++;
printf_params("[LIBCONFIG], no element in array %s.%s\n",secprefix,cfgoptions[i].optname);
status=CONFIG_TRUE;
}
for (int j=0; j<cfgoptions[i].numelt ; j++) {
config_setting_t *elemsetting=config_setting_set_int_elem(psetting, -1,(int)(cfgoptions[i].iptr[j]) );
if (elemsetting == NULL) {
fprintf(stderr,"[LIBCONFIG] Error: Creating array %s.%s, at index %i value %i\n",secprefix,cfgoptions[i].optname,j,(int)(cfgoptions[i].iptr[j]));
break;
} else
status=CONFIG_TRUE;
}
}
break;
case TYPE_DOUBLE:
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_FLOAT);
if (psetting!= NULL)
status=config_setting_set_float(psetting, (double)*(cfgoptions[i].dblptr) );
break;
case TYPE_IPV4ADDR:
psetting =config_setting_add(asetting,cfgoptions[i].optname,CONFIG_TYPE_STRING);
if (psetting!= NULL) {
char ipstr[INET_ADDRSTRLEN];
if (inet_ntop(AF_INET, cfgoptions[i].uptr, ipstr, INET_ADDRSTRLEN) == NULL) {
notused++;
sprintf(ipstr,"undef");
} else {
status=config_setting_set_string(psetting, ipstr);
}
}
break;
case TYPE_LIST:
break;
default:
fprintf(stderr,"[LIBCONFIG] %s.%s type %i not supported\n",secprefix,cfgoptions[i].optname ,cfgoptions[i].type);
status=CONFIG_FALSE;
break;
} /* switch on param type */
if (status != CONFIG_TRUE) {
errors++;
fprintf(stderr,"[LIBCONFIG] Error creating setting %i: %s.%s type %i\n",i,secprefix,cfgoptions[i].optname ,cfgoptions[i].type);
}
}
printf_params("[LIBCONFIG], in group \"%s\" %i settings \n",secprefix,numoptions);
if (notused > 0)
printf_params("[LIBCONFIG], ..... %i settings with NULL value pointer\n",notused);
if (errors >0)
fprintf(stderr,"[LIBCONFIG] .....%i settings creation errors \n",errors);
if (emptyla >0)
fprintf(stderr,"[LIBCONFIG] .....%i empty lists or arrays settings \n",emptyla);
if ( cfgptr->status ) {
cfgptr->status->num_err_nullvalue += notused;
cfgptr->status->num_err_write += errors;
cfgptr->status->num_write += numoptions;
cfgptr->status->emptyla += emptyla;
}
return errors;
}
int config_libconfig_set(paramdef_t *cfgoptions, int numoptions, char *prefix ) {
char *tokctx1=NULL;
int listidx=-1;
char *prefixbck=NULL;
char *prefix_elem1=NULL;
config_setting_t * asetting = config_root_setting (&(libconfig_privdata.runtcfg));
if (prefix != NULL) {
prefixbck=strdup(prefix);
prefix_elem1 = strtok_r(prefixbck, ".", &tokctx1);
}
printf_params("[LIBCONFIG], processing prefix %s\n",(prefix==NULL)?"NULL":prefix);
/* parse the prefix , possibly creating groups, lists and list elements */
while (prefix_elem1 != NULL) {
int n1=strlen(prefix_elem1);
char *prefix_elem2 = prefix_elem1+n1+1 ;
printf_params("[LIBCONFIG], processing elem1 %s elem2 %s\n",prefix_elem1,prefix_elem2);
/* prefix (the path to the parameter name) may contain groups and elements from a list, which are specified with [] */
if (prefix_elem2[0] != '[') { // not a list
config_setting_t *tmpset = config_setting_lookup(asetting,prefix_elem1);
if (tmpset == NULL)
asetting = config_setting_add (asetting, prefix_elem1, CONFIG_TYPE_GROUP);
else
asetting = tmpset;
printf_params("[LIBCONFIG], creating or looking for group %s: %s\n",prefix_elem1,(asetting==NULL)?"NOK":"OK");
} else { // a list
listidx=(int)strtol(prefix_elem2+1,NULL,10);
if (errno == EINVAL || errno == ERANGE) {
printf_params("[LIBCONFIG], Error %s looking for list index in %s \n",strerror(errno), prefix_elem2);
break;
}
config_setting_t *tmpset = config_setting_lookup(asetting,prefix_elem1);
if (tmpset == NULL)
asetting = config_setting_add (asetting, prefix_elem1, CONFIG_TYPE_LIST);
else
asetting = tmpset;
printf_params("[LIBCONFIG], creating or looking for list %s: %s\n",prefix_elem1,(asetting==NULL)?"NOK":"OK");
if (asetting != NULL) {
tmpset = config_setting_get_elem (asetting, listidx);
if (tmpset == NULL)
asetting = config_setting_add (asetting, NULL, CONFIG_TYPE_GROUP);
else
asetting = tmpset;
printf_params("[LIBCONFIG], creating or looking for list element %i: %s\n",listidx,(asetting==NULL)?"NOK":"OK");
}
prefix_elem1 = strtok_r(NULL, ".", &tokctx1); //skip the [x] elements we already took care of it
if (prefix_elem1 == NULL) {
fprintf(stderr, "[LICONFIG] End of parsing %s \n",prefix);
break;
}
}
if (asetting == NULL) {
fprintf(stderr,"[LIBCONFIG] Error creating setting %s %s %i\n",prefix_elem1,prefix_elem2,listidx);
}
prefix_elem1 = strtok_r(NULL, ".", &tokctx1);
}
free(prefixbck);
if (asetting != NULL) {
config_libconfig_setparams(cfgoptions, numoptions,asetting,prefix);
printf_params("[LIBCONFIG] %i settings added in group %s\n",numoptions,(prefix==NULL)?"":prefix);
return 0;
} else {
fprintf(stderr,"[LIBCONFIG] Error parsing %s params, skipped...\n",(prefix==NULL)?"":prefix);
return -1;
}
}
int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) {
@@ -593,43 +376,14 @@ int config_libconfig_init(char *cfgP[], int numP) {
free(tmppath);
return -1;
}
/* possibly init a libconfig struct for saving really used params */
if( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
config_init ( &(libconfig_privdata.runtcfg));
// config_set_options (&(libconfig_privdata.runtcfg), CONFIG_OPTION_ALLOW_OVERRIDES, CONFIG_TRUE);
}
free(tmppath);
return 0;
}
void config_libconfig_write_parsedcfg(void) {
if( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
char *fname=strdup(libconfig_privdata.configfile);
int newcfgflen = strlen( libconfig_privdata.configfile) + strlen(cfgptr->tmpdir) + 20;
cfgptr->status->debug_cfgname = realloc(cfgptr->status->debug_cfgname, newcfgflen);
time_t t = time(NULL);
struct tm tm = *localtime(&t);
snprintf (cfgptr->status->debug_cfgname,newcfgflen, "%s/%s-run%d_%02d_%02d_%02d%02d",cfgptr->tmpdir,basename(fname),
tm.tm_year + 1900,tm.tm_mon + 1,tm.tm_mday, tm.tm_hour, tm.tm_min);
if ( config_write_file (&(libconfig_privdata.runtcfg) , cfgptr->status->debug_cfgname) != CONFIG_TRUE) {
fprintf(stderr,"[LIBCONFIG] %s %d file %s - line %d: %s\n",__FILE__, __LINE__,
cfgptr->status->debug_cfgname, config_error_line(&(libconfig_privdata.runtcfg)),
config_error_text(&(libconfig_privdata.runtcfg)));
} else {
printf("[LIBCONFIG] file %s created successfully\n", cfgptr->status->debug_cfgname);
}
free(fname);
} else {
printf("[LIBCONFIG] Cannot create config file after parsing: CONFIG_SAVERUNCFG flag not specified\n");
}
}
void config_libconfig_end(void ) {
config_destroy(&(libconfig_privdata.cfg));
if( cfgptr->rtflags & CONFIG_SAVERUNCFG ) {
config_destroy(&(libconfig_privdata.runtcfg));
}
if ( libconfig_privdata.configfile != NULL ) {
free(libconfig_privdata.configfile);
libconfig_privdata.configfile=NULL;

View File

@@ -40,11 +40,12 @@ extern "C"
#include "common/config/config_paramdesc.h"
typedef struct libconfig_privatedata {
char *configfile;
config_t cfg;
config_t runtcfg;
} libconfig_privatedata_t;
#ifdef __cplusplus

View File

@@ -302,8 +302,8 @@ void log_getconfig(log_t *g_log)
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) {
if(g_log->log_component[i].name == NULL) {
g_log->log_component[i].name = calloc(1,16);
snprintf((char *)g_log->log_component[i].name,15,"undefcomp%i",i);
g_log->log_component[i].name = malloc(16);
sprintf((char *)g_log->log_component[i].name,"comp%i?",i);
logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD;
logparams_level[i].paramflags = PARAMFLAG_DONOTREAD;
}

View File

@@ -80,7 +80,6 @@ paramdef_t telnetoptions[] = {
{"loopdelay", "<loop command delay (ms)>\n", 0, uptr:&(telnetparams.loopdelay), defuintval:5000, TYPE_UINT, 0 },
{"histfile", "<history file name>\n", PARAMFLAG_NOFREE, strptr:&(telnetparams.histfile), defstrval:"oaitelnet.history", TYPE_STRING, 0 },
{"histsize", "<history sizes>\n", 0, iptr:&(telnetparams.histsize), defuintval:50, TYPE_INT, 0 },
{"logfile", "log file hen redirecting", PARAMFLAG_NOFREE, strptr:&(telnetparams.logfile), defstrval:"oaisoftmodem.log", TYPE_STRING, 0 },
{"phypbsize", "<phy dump buff size (bytes)>\n",0, uptr:&(telnetparams.phyprntbuff_size),defuintval:65000, TYPE_UINT, 0 },
{TELNETSRV_OPTNAME_STATICMOD, "<static modules selection>\n", 0, strlistptr:NULL, defstrlistval:telnet_defstatmod,TYPE_STRINGLIST,(sizeof(telnet_defstatmod)/sizeof(char *))},
{TELNETSRV_OPTNAME_SHRMOD, "<dynamic modules selection>\n", 0, strlistptr:NULL, defstrlistval:NULL,TYPE_STRINGLIST,0 }
@@ -91,31 +90,25 @@ int get_phybsize(void) {
};
int add_telnetcmd(char *modulename,telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd );
int setoutput(char *buff, int debug, telnet_printfunc_t prnt);
int wsetoutput(char *buff, int debug, telnet_printfunc_t prnt, ... );
int setparam(char *buff, int debug, telnet_printfunc_t prnt);
int wsetparam(char *buff, int debug, telnet_printfunc_t prnt, ... );
int history_cmd(char *buff, int debug, telnet_printfunc_t prnt);
telnetshell_vardef_t telnet_vardef[] = {
{"debug", TELNET_VARTYPE_INT32,0,&telnetparams.telnetdbg},
{"prio", TELNET_VARTYPE_INT32,0,&telnetparams.priority},
{"loopc", TELNET_VARTYPE_INT32,0,&telnetparams.loopcount},
{"loopd", TELNET_VARTYPE_INT32,0,&telnetparams.loopdelay},
{"phypb", TELNET_VARTYPE_INT32,0,&telnetparams.phyprntbuff_size},
{"hsize", TELNET_VARTYPE_INT32,0,&telnetparams.histsize},
{"hfile", TELNET_VARTYPE_STRING,TELNET_CHECKVAL_RDONLY,&telnetparams.histfile},
{"logfile",TELNET_VARTYPE_STRING,0,&telnetparams.logfile},
{"",0,0,NULL}
{"debug",TELNET_VARTYPE_INT32,&telnetparams.telnetdbg},
{"prio",TELNET_VARTYPE_INT32,&telnetparams.priority},
{"loopc",TELNET_VARTYPE_INT32,&telnetparams.loopcount},
{"loopd",TELNET_VARTYPE_INT32,&telnetparams.loopdelay},
{"phypb",TELNET_VARTYPE_INT32,&telnetparams.phyprntbuff_size},
{"hsize",TELNET_VARTYPE_INT32,&telnetparams.histsize},
{"hfile",TELNET_VARTYPE_STRING,&telnetparams.histfile},
{"",0,NULL}
};
telnetshell_cmddef_t telnet_cmdarray[] = {
{"redirlog","[here,file,off]",setoutput,{NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
{"redirlog file","",setoutput,{NULL},TELNETSRV_CMDFLAG_WEBSRVONLY,NULL},
{"redirlog off","",setoutput,{NULL},TELNETSRV_CMDFLAG_WEBSRVONLY,NULL},
{"param","[prio]",setparam,{wsetparam},0,NULL},
{"history","[list,reset]",history_cmd,{NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
{"","",NULL,{NULL},0,NULL},
{"redirlog","[here,file,off]",setoutput},
{"param","[prio]",setparam},
{"history","[list,reset]",history_cmd},
{"","",NULL},
};
@@ -134,40 +127,36 @@ void client_printf(const char *message, ...) {
return ;
}
#define NICE_MAX 19
#define NICE_MIN -20
void set_sched(pthread_t tid, int pid, int priority) {
int rt;
struct sched_param schedp;
int policy;
char strpolicy[10];
int niceval=0;
if (priority < -100 && priority > -200) { //RR priority 1 to 99 (high) mapped to oai priority -101 to -199 (high)
policy=SCHED_RR;
sprintf(strpolicy,"%s","RR");
schedp.sched_priority= -(priority + 100 );
} else if (priority < 0 && priority > -100 ) {
//sched_get_priority_max(SCHED_FIFO)
if (priority < NICE_MIN) {
policy=SCHED_FIFO;
sprintf(strpolicy,"%s","fifo");
schedp.sched_priority= -priority ;//fifo priority 1 to 99 (high) mapped to oai priority -1 to -99 (high)
} else if (priority >= 0 && priority <= (NICE_MAX-NICE_MIN)) { // other (normal) nice value -20 to 19 mapped to oai priority 0 to 39
policy=SCHED_OTHER;
sprintf(strpolicy,"%s","other");
schedp.sched_priority=0;
niceval=priority+NICE_MIN;
} else if (priority > NICE_MAX-NICE_MIN && priority <= (2*(NICE_MAX-NICE_MIN)+1) ) {// batch (normal) nice value -20 to 19 mapped to oai priority 40 to 79
policy=SCHED_BATCH;
sprintf(strpolicy,"%s","batch");
niceval=priority+NICE_MIN-(NICE_MAX-NICE_MIN+1);
schedp.sched_priority=0;
} else if (priority > (2*(NICE_MAX-NICE_MIN)+1)){// fifo mapped to oai priority 80
schedp.sched_priority= NICE_MIN - priority ;
if ( (schedp.sched_priority < sched_get_priority_min(SCHED_FIFO)) ||
(schedp.sched_priority > sched_get_priority_max(SCHED_FIFO)) ) {
client_printf("Error: %i invalid prio, should be %i to %i, \n",
priority, NICE_MIN -sched_get_priority_min(SCHED_FIFO),
NICE_MIN - sched_get_priority_max(SCHED_FIFO) );
}
} else if (priority > NICE_MAX) {
policy=SCHED_IDLE;
sprintf(strpolicy,"%s","idle");
schedp.sched_priority=0;
} else {
client_printf("Error: %i invalid priority \n",priority );
return;
policy=SCHED_OTHER;
sprintf(strpolicy,"%s","other");
schedp.sched_priority=0;
}
if( tid != 0) {
rt = pthread_setschedparam(tid, policy, &schedp);
} else if(pid > 0) {
@@ -183,15 +172,15 @@ void set_sched(pthread_t tid, int pid, int priority) {
} else {
client_printf("policy set to %s, priority %i\n",strpolicy,schedp.sched_priority);
if ( policy==SCHED_OTHER || policy==SCHED_BATCH ) {
if ( policy==SCHED_OTHER) {
rt = getpriority(PRIO_PROCESS,tid);
if (rt != -1) {
rt = setpriority(PRIO_PROCESS,tid,niceval);
rt = setpriority(PRIO_PROCESS,tid,priority);
if (rt < 0) {
client_printf("Error %i: %s trying to set nice value of thread %u to %i\n",
errno,strerror(errno),tid,niceval);
errno,strerror(errno),tid,priority);
}
} else {
client_printf("Error %i: %s trying to get nice value of thread %u \n",
@@ -200,17 +189,17 @@ void set_sched(pthread_t tid, int pid, int priority) {
}
}
if ( policy == SCHED_OTHER || policy==SCHED_BATCH) {
if ( policy == SCHED_OTHER) {
if ( tid > 0 && tid != pthread_self()) {
client_printf("setting nice value using a thread id not implemented....\n");
} else if (pid > 0) {
errno=0;
rt = setpriority(PRIO_PROCESS,pid,niceval);
rt = setpriority(PRIO_PROCESS,pid,priority);
if (rt != 0) {
client_printf("Error %i: %s calling setpriority, \n",errno,strerror(errno));
} else {
client_printf("nice value set to %i\n",niceval);
client_printf("nice value set to %i\n",priority);
}
}
}
@@ -247,29 +236,20 @@ void redirstd(char *newfname,telnet_printfunc_t prnt ) {
fd=freopen(newfname, "w", stdout);
if (fd == NULL) {
prnt("ERROR: stdout redir to %s error %s\n",strerror(errno));
} else {
prnt("stdout redirected to %s\n",newfname);
prnt("ERROR: stdout redir to %s error %s",strerror(errno));
}
fd=freopen(newfname, "w", stderr);
if (fd == NULL) {
prnt("ERROR: stderr redir to %s error %s\n",strerror(errno));
} else {
prnt("stderr redirected to %s\n",newfname);
prnt("ERROR: stderr redir to %s error %s",strerror(errno));
}
}
int wsetoutput(char *buffer, int debug, telnet_printfunc_t prnt, ... ) {
return 0;
}
int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
char *logfname;
char stdout_str[64];
#define LOGFILE "logfile.log"
memset(cmds,0,sizeof(cmds));
sscanf(buff,"%9s %32s %9s %9s %9s", cmds[0],cmds[1],cmds[2],cmds[3],cmds[4] );
@@ -285,10 +265,10 @@ int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
if (strncasecmp(cmds[0],"file",4) == 0) {
if (cmds[1][0] == 0)
logfname=telnetparams.logfile;
logfname=LOGFILE;
else
logfname=cmds[1];
prnt("Log output redirected to (%s)\n",logfname);
fflush(stdout);
redirstd(logfname,prnt);
}
@@ -301,10 +281,6 @@ int setoutput(char *buff, int debug, telnet_printfunc_t prnt) {
return CMDSTATUS_FOUND;
} /* setoutput */
int wsetparam(char *buff, int debug, telnet_printfunc_t prnt, ...) {
return 0;
}
int setparam(char *buff, int debug, telnet_printfunc_t prnt) {
char cmds[TELNET_MAX_MSGLENGTH/TELNET_CMD_MAXSIZE][TELNET_CMD_MAXSIZE];
memset(cmds,0,sizeof(cmds));
@@ -368,98 +344,6 @@ int history_cmd(char *buff, int debug, telnet_printfunc_t prnt) {
/*
generic commands available for all modules loaded by the server
*/
char *telnet_getvarvalue(telnetshell_vardef_t *var, int varindex) {
char *val;
switch(var[varindex].vartype) {
case TELNET_VARTYPE_INT32:
val=malloc(64);
snprintf(val,64,"%i",*(int32_t *)(var[varindex].varvalptr));
break;
case TELNET_VARTYPE_INT64:
val=malloc(128);
snprintf(val,128,"%lli",(long long)*(int64_t *)(var[varindex].varvalptr));
break;
case TELNET_VARTYPE_INT16:
val=malloc(16);
snprintf(val,16,"%hi",*(short *)(var[varindex].varvalptr));
break;
case TELNET_VARTYPE_INT8:
val=malloc(16);
snprintf(val,16,"%i",(int)(*(int8_t *)(var[varindex].varvalptr)));
break;
case TELNET_VARTYPE_UINT:
val=malloc(64);
snprintf(val,64,"%u",*(unsigned int *)(var[varindex].varvalptr));
break;
case TELNET_VARTYPE_DOUBLE:
val=malloc(32);
snprintf(val,32,"%g\n",*(double *)(var[varindex].varvalptr));
break;
case TELNET_VARTYPE_STRING:
val = strdup(*(char **)(var[varindex].varvalptr));
break;
default:
val=malloc(64);
snprintf(val,64,"ERR:var %i unknown type",varindex);
break;
}
return val;
}
int telnet_setvarvalue(telnetshell_vardef_t *var,char *strval, telnet_printfunc_t prnt ) {
int st=0;
switch(var->vartype) {
case TELNET_VARTYPE_INT32:
*(int *)(var->varvalptr) = (int)strtol(strval,NULL,0);
if (prnt != NULL)
prnt("%i\n",*(int *)(var->varvalptr));
break;
case TELNET_VARTYPE_INT16:
*(short *)(var->varvalptr) = (short)strtol(strval,NULL,0);
if (prnt != NULL)
prnt("%hi\n",*(short *)(var->varvalptr));
break;
case TELNET_VARTYPE_INT8:
*(char *)(var->varvalptr) = (char)strtol(strval,NULL,0);
if (prnt != NULL)
prnt("%i\n",*(int *)(var->varvalptr));
break;
case TELNET_VARTYPE_UINT:
*(unsigned int *)(var->varvalptr) = (unsigned int)strtol(strval,NULL,0);
if (prnt != NULL)
prnt("%u\n",*(unsigned int *)(var->varvalptr));
break;
case TELNET_VARTYPE_DOUBLE:
*(double *)(var->varvalptr) = strtod(strval,NULL);
if (prnt != NULL)
prnt("%g\n",*(double *)(var->varvalptr));
break;
case TELNET_VARTYPE_STRING:
sprintf(*(char **)(var->varvalptr),"%s", strval);
if (prnt != NULL)
prnt("\"%s\"\n",*(char **)(var->varvalptr));
break;
default:
if (prnt != NULL)
prnt("unknown type\n");
st=-1;
break;
}
return st;
}
int setgetvar(int moduleindex,char getorset,char *params) {
int n,i;
@@ -473,15 +357,81 @@ int setgetvar(int moduleindex,char getorset,char *params) {
if (n > 0 && (getorset == 'g' || getorset == 'G')) {
client_printf("%s, %s = ", telnetparams.CmdParsers[moduleindex].module,
telnetparams.CmdParsers[moduleindex].var[i].varname );
char *strval=telnet_getvarvalue(telnetparams.CmdParsers[moduleindex].var, i);
client_printf("%s\n",strval);
free(strval);
switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) {
case TELNET_VARTYPE_INT32:
client_printf("%i\n",*(int32_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_INT64:
client_printf("%lli\n",*(int64_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_INT16:
client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_INT8:
client_printf("%i\n",(int)(*(int8_t *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr)));
break;
case TELNET_VARTYPE_UINT:
client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_DOUBLE:
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_STRING:
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
default:
client_printf("unknown type\n");
break;
}
}
if (n > 1 && (getorset == 's' || getorset == 'S')) {
client_printf("%s, %s set to \n", telnetparams.CmdParsers[moduleindex].module,
telnetparams.CmdParsers[moduleindex].var[i].varname);
telnet_setvarvalue(&(telnetparams.CmdParsers[moduleindex].var[i]),varval, client_printf);
switch(telnetparams.CmdParsers[moduleindex].var[i].vartype) {
case TELNET_VARTYPE_INT32:
*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (int)strtol(varval,NULL,0);
client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_INT16:
*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (short)strtol(varval,NULL,0);
client_printf("%hi\n",*(short *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_INT8:
*(char *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (char)strtol(varval,NULL,0);
client_printf("%i\n",*(int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_UINT:
*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = (unsigned int)strtol(varval,NULL,0);
client_printf("%u\n",*(unsigned int *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_DOUBLE:
*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr) = strtod(varval,NULL);
client_printf("%g\n",*(double *)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
case TELNET_VARTYPE_STRING:
sprintf(*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr),"%s", varval);
client_printf("\"%s\"\n",*(char **)(telnetparams.CmdParsers[moduleindex].var[i].varvalptr));
break;
default:
client_printf("unknown type\n");
break;
}
}
}
}
@@ -492,13 +442,6 @@ int setgetvar(int moduleindex,char getorset,char *params) {
return CMDSTATUS_VARNOTFOUND;
}
void telnetsrv_freetbldata(webdatadef_t *wdata) {
for(int i=0;i< wdata->numlines; i++)
for(int j=0;j< wdata->numcols ; j++)
if ( wdata->columns[j].coltype & TELNET_VAR_NEEDFREE )
free(wdata->lines[i].val[j]);
}
/*----------------------------------------------------------------------------------------------------*/
char *get_time(char *buff,int bufflen) {
struct tm tmstruct;
@@ -506,16 +449,6 @@ char *get_time(char *buff,int bufflen) {
strftime (buff, bufflen, "%Y-%m-%d %H:%M:%S.000", localtime_r(&now,&tmstruct));
return buff;
}
void telnet_pushcmd(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt) {
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL);
telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg);
cmddata->cmdfunc=(qcmdfunc_t)cmd->cmdfunc;
cmddata->prnt=prnt;
cmddata->debug=telnetparams.telnetdbg;
if (cmdbuff != NULL)
cmddata->cmdbuff=strdup(cmdbuff);
pushNotifiedFIFO(cmd->qptr, msg);
}
int process_command(char *buf) {
int i,j,k;
@@ -526,7 +459,7 @@ int process_command(char *buf) {
int rt;
memset(modulename,0,sizeof(modulename));
memset(cmd,0,sizeof(cmd));
extern char **environ;
if (strncasecmp(buf,"ex",2) == 0)
return CMDSTATUS_EXIT;
@@ -541,8 +474,6 @@ int process_command(char *buf) {
}
for(j=0; telnetparams.CmdParsers[i].cmd[j].cmdfunc != NULL ; j++) {
if ( telnetparams.CmdParsers[i].cmd[j].cmdflags & TELNETSRV_CMDFLAG_WEBSRVONLY )
continue;
client_printf(" %s %s %s\n",
telnetparams.CmdParsers[i].module,telnetparams.CmdParsers[i].cmd[j].cmdname,
telnetparams.CmdParsers[i].cmd[j].helpstr);
@@ -558,7 +489,7 @@ int process_command(char *buf) {
j = sscanf(buf,"%19s %19s %m[^\t\n]",modulename,cmd,&cmdb);
if (telnetparams.telnetdbg > 0)
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,(cmdb==NULL)?"":cmdb);
printf("process_command: %i words, module=%s cmd=%s, parameters= %s\n",j,modulename,cmd,cmdb);
for (i=0; j>=2 && telnetparams.CmdParsers[i].var != NULL && telnetparams.CmdParsers[i].cmd != NULL; i++) {
if ( (strncasecmp(telnetparams.CmdParsers[i].module,modulename,strlen(telnetparams.CmdParsers[i].module)) == 0)) {
@@ -573,10 +504,14 @@ int process_command(char *buf) {
} else {
for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) {
if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) {
if (telnetparams.CmdParsers[i].cmd[k].cmdflags & TELNETSRV_CMDFLAG_WEBSRVONLY)
continue;
if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) {
telnet_pushcmd(&(telnetparams.CmdParsers[i].cmd[k]), cmdb,client_printf );
notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL);
telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg);
cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc;
cmddata->prnt=client_printf;
cmddata->debug=telnetparams.telnetdbg;
cmddata->cmdbuff=strdup(cmdb);
pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg);
} else {
telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf);
}
@@ -924,14 +859,12 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde
strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1);
telnetparams.CmdParsers[i].cmd = cmd;
telnetparams.CmdParsers[i].var = var;
for (int j=0; cmd[j].cmdfunc != NULL ;j++) {
if (cmd[j].cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) {
if (afifo == NULL) {
afifo = malloc(sizeof(notifiedFIFO_t));
initNotifiedFIFO(afifo);
}
cmd[j].qptr = afifo;
}
cmd->qptr = afifo;
}
printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n",
i,telnetparams.CmdParsers[i].module);
@@ -961,16 +894,10 @@ int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildvers
}
int telnetsrv_getfarray(loader_shlibfunc_t **farray) {
*farray=malloc(sizeof(loader_shlibfunc_t)*3);
*farray=malloc(sizeof(loader_shlibfunc_t)*2);
(*farray)[0].fname=TELNET_ADDCMD_FNAME;
(*farray)[0].fptr=(int (*)(void) )add_telnetcmd;
(*farray)[1].fname=TELNET_POLLCMDQ_FNAME;
(*farray)[1].fptr=(int (*)(void) )poll_telnetcmdq;
(*farray)[2].fname=TELNET_PUSHCMD_FNAME;
(*farray)[2].fptr=(int (*)(void) )telnet_pushcmd;
return ( 3);
}
/* for webserver interface, needs access to some telnet server paramaters */
telnetsrv_params_t *get_telnetsrv_params(void) {
return &telnetparams;
return ( 2);
}

View File

@@ -48,55 +48,19 @@
#define CMDSTATUS_VARNOTFOUND 3
#define CMDSTATUS_NOTFOUND 4
/* definitions to store 2 dim table, used to store command results before */
/* displaying them either on console or web page */
#define TELNET_MAXLINE_NUM 100
#define TELNET_MAXCOL_NUM 10
typedef struct col {
char coltitle[TELNET_CMD_MAXSIZE];
unsigned int coltype;
} acol_t;
typedef struct line {
char *val[TELNET_MAXCOL_NUM];
} aline_t;
typedef struct webdatadef {
char tblname[TELNET_HELPSTR_SIZE];
int numlines;
int numcols;
acol_t columns[TELNET_MAXCOL_NUM];
aline_t lines[TELNET_MAXLINE_NUM];
} webdatadef_t;
/*----------------------------------------------------------------------------*/
/* structure to be used when adding a module to the telnet server */
/* This is the second parameter of the add_telnetcmd function, which can be used */
/* to add a set of new command to the telnet server shell */
typedef void(*telnet_printfunc_t)(const char* format, ...);
typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt);
typedef int(*webfunc_t)(char *cmdbuff, int debug, telnet_printfunc_t prnt, ... );
typedef int(*webfunc_getdata_t)(char *cmdbuff, int debug, void *data,telnet_printfunc_t prnt);
typedef int(*qcmdfunc_t)(char*, int, telnet_printfunc_t prnt,void *arg);
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue
#define TELNETSRV_CMDFLAG_GETWEBDATA (1<<1) // When called from web server, use the getdata variant of the function
#define TELNETSRV_CMDFLAG_TELNETONLY (1<<2) // Command only for telnet client connections
#define TELNETSRV_CMDFLAG_WEBSRVONLY (1<<3) // Command only for web server connections
#define TELNETSRV_CMDFLAG_CONFEXEC (1<<4) // Ask for confirm before exec
#define TELNETSRV_CMDFLAG_GETWEBTBLDATA (1<<8) // When called from web server, use the get table data variant of the function
#define TELNETSRV_CMDFLAG_PRINTWEBTBLDATA (1<<9) // websrv Print as a single column table
#define TELNETSRV_CMDFLAG_NEEDPARAM (1<<10) // websrv: The command needs a parameter
#define TELNETSRV_CMDFLAG_WEBSRV_SETRETURNTBL (1<<11) // websrv: set callback returns a new table
#define TELNETSRV_CMDFLAG_AUTOUPDATE (1<<12) // command can be re-submitted automatically for result update
#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue
typedef struct cmddef {
char cmdname[TELNET_CMD_MAXSIZE];
char helpstr[TELNET_HELPSTR_SIZE];
cmdfunc_t cmdfunc;
union {
webfunc_t webfunc;
webfunc_getdata_t webfunc_getdata;
};
cmdfunc_t cmdfunc;
unsigned int cmdflags;
void *qptr;
} telnetshell_cmddef_t;
@@ -114,8 +78,6 @@ typedef struct telnetsrv_qmsg {
/*structure to be used when adding a module to the telnet server */
/* This is the first parameter of the add_telnetcmd function, which can be used */
/* to add a set of new variables which can be got/set from the telnet server shell */
/* var type: bits 0-3, type value (1 to 15)
* type modifier, bits 4-31 */
#define TELNET_VARTYPE_INT32 1
#define TELNET_VARTYPE_INT16 2
#define TELNET_VARTYPE_INT64 3
@@ -123,18 +85,10 @@ typedef struct telnetsrv_qmsg {
#define TELNET_VARTYPE_DOUBLE 5
#define TELNET_VARTYPE_INT8 6
#define TELNET_VARTYPE_UINT 7
#define TELNET_CHECKVAL_RDONLY 16
#define TELNET_CHECKVAL_BOOL 32
#define TELNET_VAR_NEEDFREE 64
#define TELNET_CHECKVAL_LOGLVL 128
#define TELNET_CHECKVAL_SIMALGO 256
typedef struct variabledef {
char varname[TELNET_CMD_MAXSIZE];
char vartype;
char checkval;
void *varvalptr;
} telnetshell_vardef_t;
@@ -159,7 +113,6 @@ typedef struct {
int priority; // server running priority
char *histfile; // command history
int histsize; // command history length
char *logfile; // filename to use when redirecting output to file
int new_socket; // socket of the client connection
int logfilefd; // file id of the log file when log output is redirected to a file
int saved_stdout; // file id of the previous stdout, used to be able to restore original stdout
@@ -192,25 +145,14 @@ VT escape sequence definition, for smarter display....
#define STDFMT "\x1b[0m"
/*---------------------------------------------------------------------------------------------*/
#define NICE_MAX 19
#define NICE_MIN -20
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
#define TELNET_ADDCMD_FNAME "add_telnetcmd"
#define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq"
#define TELNET_PUSHCMD_FNAME "telnet_pushcmd"
typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *);
typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg);
typedef void(*push_telnetcmd_func_t)(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt);
#ifdef TELNETSERVERCODE
int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd);
void set_sched(pthread_t tid, int pid,int priority);
void set_affinity(pthread_t tid, int pid, int coreid);
extern int get_phybsize(void);
#endif
#ifdef WEBSERVERCODE
extern void telnet_pushcmd(telnetshell_cmddef_t *cmd, char *cmdbuff, telnet_printfunc_t prnt);
extern telnetsrv_params_t *get_telnetsrv_params(void);
extern char *telnet_getvarvalue(telnetshell_vardef_t *var, int varindex);
extern int telnet_setvarvalue(telnetshell_vardef_t *var,char *strval, telnet_printfunc_t prnt ) ;
extern void telnetsrv_freetbldata(webdatadef_t *wdata);
#endif
#endif

View File

@@ -30,6 +30,6 @@ endforeach()
install(TARGETS telnetsrv DESTINATION bin)
if (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
install(TARGETS telnetsrv DESTINATION ${OPENAIR_CMAKE}/ran_build/build)
endif (EXISTS "${OPENAIR_CMAKE}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_CMAKE}/ran_build/build")
if (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build")
install(TARGETS telnetsrv DESTINATION ${OPENAIR_BUILD_DIR}/ran_build/build)
endif (EXISTS "${OPENAIR_BUILD_DIR}/ran_build/build" AND IS_DIRECTORY "${OPENAIR_BUILD_DIR}/ran_build/build")

View File

@@ -110,8 +110,9 @@ int dump_phyvars(char *buf, int debug, telnet_printfunc_t prnt) {
telnetshell_cmddef_t phy_cmdarray[] = {
{"disp","[phycnt,uedump,uestat UE<x>]", dump_phyvars,{NULL},0,NULL},
{"","",NULL,{NULL},0,NULL},
{"disp","[phycnt,uedump,uestat UE<x>]", dump_phyvars},
{"","",NULL},
};

View File

@@ -42,29 +42,24 @@
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt);
telnetshell_cmddef_t loader_cmdarray[] = {
{"show","[params,modules]",loader_show_cmd,{(webfunc_t)loader_show_cmd},0,NULL},
{"","",NULL,{NULL},0,NULL},
{"show","[params,modules]",loader_show_cmd},
{"","",NULL},
};
/*-------------------------------------------------------------------------------------*/
int loader_show_cmd(char *buff, int debug, telnet_printfunc_t prnt)
{
if (buff == NULL) {
prnt("ERROR wrong loader SHOW command...\n");
return 0;
}
if (debug > 0)
prnt( "loader_show_cmd received %s\n",buff);
if (strcasestr(buff,"params") != NULL) {
prnt( "loader parameters:\n");
prnt( " Main executable build version: \"%s\"\n", loader_data.mainexec_buildversion);
prnt( " Default shared lib path: \"%s\"\n", loader_data.shlibpath);
prnt( " Max number of shared lib : %i\n", loader_data.maxshlibs);
}
else if (strcasestr(buff,"modules") != NULL || buff[0]==0 || strcasestr(buff,"show") != NULL) {
else if (strcasestr(buff,"modules") != NULL) {
prnt( "%i shared lib have been dynamicaly loaded by the oai loader\n", loader_data.numshlibs);
for (int i=0 ; i<loader_data.numshlibs ; i++) {
prnt( " Module %i: %s\n", i,loader_data.shlibs[i].name);

View File

@@ -39,11 +39,11 @@
telnetshell_vardef_t loader_globalvardef[] = {
{"mainversion",TELNET_VARTYPE_STRING,TELNET_CHECKVAL_RDONLY, &(loader_data.mainexec_buildversion)},
{"defpath",TELNET_VARTYPE_STRING,TELNET_CHECKVAL_RDONLY,&(loader_data.shlibpath)},
{"maxshlibs",TELNET_VARTYPE_INT32,TELNET_CHECKVAL_RDONLY,&(loader_data.maxshlibs)},
{"numshlibs",TELNET_VARTYPE_INT32,TELNET_CHECKVAL_RDONLY,&(loader_data.numshlibs)},
{"",0,0,NULL}
{"mainversion",TELNET_VARTYPE_STRING,&(loader_data.mainexec_buildversion)},
{"defpath",TELNET_VARTYPE_STRING,&(loader_data.shlibpath)},
{"maxshlibs",TELNET_VARTYPE_INT32,&(loader_data.maxshlibs)},
{"numshlibs",TELNET_VARTYPE_INT32,&(loader_data.numshlibs)},
{"",0,NULL}
};
telnetshell_vardef_t *loader_modulesvardef;

View File

@@ -92,7 +92,7 @@ telnetshell_cmddef_t measur_cmdarray[] = {
};
telnetshell_vardef_t measur_vardef[] = {
{"",0,0,NULL}
{"",0,NULL}
};
/* function to be implemented in any telnetsrv_xxx_measurements.c sources
to allow common measurment code to access measurments data */

View File

@@ -53,7 +53,7 @@ telnetshell_vardef_t phy_vardef[] = {
//{"txshift",TELNET_VARTYPE_INT32,NULL},
//{"rachemin",TELNET_VARTYPE_INT32,NULL},
//{"rachdmax",TELNET_VARTYPE_INT32,NULL},
{"",0,0,NULL}
{"",0,NULL}
};
#else

View File

@@ -57,121 +57,89 @@
#include "openair1/PHY/phy_extern.h"
#include "telnetsrv_proccmd.h"
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt,webdatadef_t *tdata)
void decode_procstat(char *record, int debug, telnet_printfunc_t prnt)
{
char prntline[160];
char *procfile_fields;
char *procfile_fiels;
char *strtokptr;
char *lptr;
int fieldcnt;
char toksep[2];
fieldcnt=0;
procfile_fields =strtok_r(record," ",&strtokptr);
procfile_fiels =strtok_r(record," ",&strtokptr);
lptr= prntline;
/*http://man7.org/linux/man-pages/man5/proc.5.html gives the structure of the stat file */
int priority=0;
int nice=0;
while( procfile_fields != NULL && fieldcnt < 42) {
while( procfile_fiels != NULL && fieldcnt < 42) {
long int policy;
if (strlen(procfile_fields) == 0)
if (strlen(procfile_fiels) == 0)
continue;
fieldcnt++;
sprintf(toksep," ");
switch(fieldcnt) {
case 1: /* id */
if (tdata != NULL) {
tdata->lines[tdata->numlines].val[0]=strdup(procfile_fields);
}
lptr+=sprintf(lptr,"%9.9s ",procfile_fields);
sprintf(toksep,")");
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
sprintf(toksep,")");
break;
case 2: /* name */
if (tdata != NULL) {
tdata->lines[tdata->numlines].val[1]=strdup(procfile_fields);
}
lptr+=sprintf(lptr,"%20.20s ",procfile_fields+1);
lptr+=sprintf(lptr,"%20.20s ",procfile_fiels+1);
break;
case 3: //thread state
lptr+=sprintf(lptr," %c ",procfile_fields[0]);
lptr+=sprintf(lptr," %c ",procfile_fiels[0]);
break;
case 14: //time in user mode
case 15: //time in kernel mode
lptr+=sprintf(lptr,"%9.9s ",procfile_fields);
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
break;
case 18: //priority column index 2 in tdata, -2 to -100 (1, min to 99, highest prio)
priority=strtol(procfile_fields,NULL,0);
case 19: //nice column index 3 in tdata 0 to 39 (-20, highest prio, to 19)
if (tdata != NULL) {
tdata->lines[tdata->numlines].val[fieldcnt-16]=strdup(procfile_fields);
}
lptr+=sprintf(lptr,"%3.3s ",procfile_fields);
nice=strtol(procfile_fields,NULL,0);
case 18: //priority
case 19: //nice
lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
break;
case 23: //vsize
lptr+=sprintf(lptr,"%9.9s ",procfile_fields);
lptr+=sprintf(lptr,"%9.9s ",procfile_fiels);
break;
case 39: //processor
if (tdata != NULL) {
tdata->lines[tdata->numlines].val[4]=strdup(procfile_fields);
}
lptr+=sprintf(lptr," %2.2s ",procfile_fields);
case 39: //processor
lptr+=sprintf(lptr," %2.2s ",procfile_fiels);
break;
case 41: //policy
lptr+=sprintf(lptr,"%3.3s ",procfile_fields);
policy=strtol(procfile_fields,NULL,0);
char strschedp[64];
lptr+=sprintf(lptr,"%3.3s ",procfile_fiels);
policy=strtol(procfile_fiels,NULL,0);
switch(policy) {
case SCHED_FIFO:
snprintf(strschedp,sizeof(strschedp),"%s ","rt:fifo");
priority= priority+1; //in /proc file system priority 1 to 99 mapped to -2 to -100
lptr+=sprintf(lptr,"%s ","rt: fifo");
break;
case SCHED_OTHER:
snprintf(strschedp,sizeof(strschedp),"%s ","other");
priority=nice-NICE_MIN; // linux nice is -20 to 19
lptr+=sprintf(lptr,"%s ","other");
break;
case SCHED_IDLE:
snprintf(strschedp,sizeof(strschedp),"%s ","idle");
priority=2*(NICE_MAX-NICE_MIN+1);
lptr+=sprintf(lptr,"%s ","idle");
break;
case SCHED_BATCH:
snprintf(strschedp,sizeof(strschedp),"%s ","batch");
priority=(NICE_MAX-NICE_MIN+1)+nice-NICE_MIN;
lptr+=sprintf(lptr,"%s ","batch");
break;
case SCHED_RR:
snprintf(strschedp,sizeof(strschedp),"%s ","rt:rr");
priority= priority-99 ;
lptr+=sprintf(lptr,"%s ","rt: rr");
break;
#ifdef SCHED_DEADLINE
case SCHED_DEADLINE:
snprintf(strschedp,sizeof(strschedp),"%s ","rt:deadline");
lptr+=sprintf(lptr,"%s ","rt: deadline");
break;
#endif
default:
snprintf(strschedp,sizeof(strschedp),"%s ","????");
lptr+=sprintf(lptr,"%s ","????");
break;
}
lptr+=sprintf(lptr,"%s ",strschedp);
if (tdata != NULL) {
tdata->lines[tdata->numlines].val[5]=strdup(strschedp);
tdata->lines[tdata->numlines].val[6]=malloc(10);
snprintf(tdata->lines[tdata->numlines].val[6],9,"%i",priority);
}
break;
default:
break;
}/* switch on fieldcnr */
procfile_fields =strtok_r(NULL,toksep,&strtokptr);
procfile_fiels =strtok_r(NULL,toksep,&strtokptr);
} /* while on proc_fields != NULL */
prnt("%s\n",prntline);
if (tdata != NULL) {
tdata->numlines++;
}
} /*decode_procstat */
void read_statfile(char *fname,int debug, telnet_printfunc_t prnt, webdatadef_t *tdata)
void read_statfile(char *fname,int debug, telnet_printfunc_t prnt)
{
FILE *procfile;
char arecord[1024];
@@ -189,55 +157,21 @@ char arecord[1024];
return;
}
fclose(procfile);
decode_procstat(arecord, debug, prnt,tdata);
decode_procstat(arecord, debug, prnt);
}
int nullprnt(char *fmt,...) {
return 0;
}
void proccmd_get_threaddata(char *buf, int debug, telnet_printfunc_t fprnt,webdatadef_t *tdata)
void print_threads(char *buf, int debug, telnet_printfunc_t prnt)
{
char aname[256];
DIR *proc_dir;
struct dirent *entry;
telnet_printfunc_t prnt = (fprnt != NULL)?fprnt:(telnet_printfunc_t)nullprnt;
if (tdata != NULL) {
tdata->numcols=7;
snprintf(tdata->columns[0].coltitle,sizeof(tdata->columns[0].coltitle),"thread id");
tdata->columns[0].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
snprintf(tdata->columns[1].coltitle,sizeof(tdata->columns[1].coltitle),"thread name");
tdata->columns[1].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
snprintf(tdata->columns[2].coltitle,sizeof(tdata->columns[2].coltitle),"priority");
tdata->columns[2].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
snprintf(tdata->columns[3].coltitle,sizeof(tdata->columns[3].coltitle),"nice");
tdata->columns[3].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
snprintf(tdata->columns[4].coltitle,sizeof(tdata->columns[4].coltitle),"core");
tdata->columns[4].coltype=TELNET_VARTYPE_STRING|TELNET_VAR_NEEDFREE;
snprintf(tdata->columns[5].coltitle,sizeof(tdata->columns[5].coltitle),"sched policy");
tdata->columns[5].coltype=TELNET_VARTYPE_STRING|TELNET_CHECKVAL_RDONLY|TELNET_VAR_NEEDFREE;
snprintf(tdata->columns[5].coltitle,sizeof(tdata->columns[5].coltitle),"sched policy");
tdata->columns[6].coltype=TELNET_VARTYPE_STRING|TELNET_VAR_NEEDFREE;
snprintf(tdata->columns[6].coltitle,sizeof(tdata->columns[6].coltitle),"oai priority");
tdata->numlines=0;
}
unsigned int eax=11,ebx=0,ecx=1,edx=0;
asm volatile("cpuid"
: "=a" (eax),
"=b" (ebx),
"=c" (ecx),
"=d" (edx)
: "0" (eax), "2" (ecx)
: );
prnt("System has %d cores %d threads %d Actual threads",eax,ebx,edx);
prnt("\n id name state USRmod KRNmod prio nice vsize proc pol \n\n");
prnt(" id name state USRmod KRNmod prio nice vsize proc pol \n\n");
snprintf(aname, sizeof(aname), "/proc/%d/stat", getpid());
read_statfile(aname,debug,prnt,NULL);
read_statfile(aname,debug,prnt);
prnt("\n");
snprintf(aname, sizeof(aname), "/proc/%d/task", getpid());
proc_dir = opendir(aname);
@@ -247,150 +181,20 @@ struct dirent *entry;
return;
}
while ((entry = readdir(proc_dir)) != NULL){
if(entry->d_name[0] != '.') {
snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name);
read_statfile(aname,debug,prnt,tdata);
}
} /* while entry != NULL */
while ((entry = readdir(proc_dir)) != NULL)
{
if(entry->d_name[0] == '.')
continue;
snprintf(aname, sizeof(aname), "/proc/%d/task/%.*s/stat", getpid(),(int)(sizeof(aname)-24),entry->d_name);
read_statfile(aname,debug,prnt);
} /* while entry != NULL */
closedir(proc_dir);
} /* print_threads */
void print_threads(char *buf, int debug, telnet_printfunc_t prnt) {
proccmd_get_threaddata(buf,debug,prnt,NULL);
}
int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data, telnet_printfunc_t prnt) {
webdatadef_t *logsdata = ( webdatadef_t *) data;
if (strncmp(cmdbuff,"set",3) == 0) {
telnet_printfunc_t printfunc = (prnt != NULL)?prnt:( telnet_printfunc_t)printf;
if (strcasestr(cmdbuff,"loglvl") != NULL) {
int level=map_str_to_int(log_level_names,logsdata->lines[0].val[1]);
int enabled=(strcmp(logsdata->lines[0].val[2],"true")==0)?1:0;
int loginfile=(strcmp(logsdata->lines[0].val[3],"true")==0)?1:0;
set_log(logsdata->numlines, level);
if (enabled==0)
set_log(logsdata->numlines, OAILOG_DISABLE);
if ( loginfile == 1 ) {
set_component_filelog(logsdata->numlines);
} else {
close_component_filelog(logsdata->numlines);
}
printfunc("%s log level %s is %s, output to %s\n",logsdata->lines[0].val[0],
logsdata->lines[0].val[1], enabled?"enabled":"disabled",loginfile?g_log->log_component[logsdata->numlines].filelog_name :"stdout");
}
if (strcasestr(cmdbuff,"logopt") != NULL) {
int optbit=map_str_to_int(log_options,logsdata->lines[0].val[0]);
if (optbit < 0) {
printfunc("option %s unknown\n",logsdata->lines[0].val[0]);
} else {
if(strcmp(logsdata->lines[0].val[1],"true")==0) {
SET_LOG_OPTION(optbit);
} else {
CLEAR_LOG_OPTION(optbit);
}
printfunc("%s log option %s\n",logsdata->lines[0].val[0],(strcmp(logsdata->lines[0].val[1],"true")==0)?"enabled":"disabled");
}
}
if (strcasestr(cmdbuff,"dbgopt") != NULL) {
int optbit=map_str_to_int(log_maskmap,logsdata->lines[0].val[0]);
if (optbit < 0) {
printfunc("debug option %s unknown\n",logsdata->lines[0].val[0]);
} else {
if(strcmp(logsdata->lines[0].val[1],"true")==0)
SET_LOG_DEBUG(optbit);
else
CLEAR_LOG_DEBUG(optbit);
if(strcmp(logsdata->lines[0].val[2],"true")==0)
SET_LOG_DUMP(optbit);
else
CLEAR_LOG_DUMP(optbit);
printfunc("%s debug %s dump %s\n",logsdata->lines[0].val[0],
(strcmp(logsdata->lines[0].val[1],"true")==0)?"enabled":"disabled",
(strcmp(logsdata->lines[0].val[2],"true")==0)?"enabled":"disabled");
}
}
if (strcasestr(cmdbuff,"threadsched") != NULL) {
unsigned int tid=strtoll(logsdata->lines[0].val[0],NULL,0);
unsigned int core=strtoll(logsdata->lines[0].val[4],NULL,0);
int priority=strtoll(logsdata->lines[0].val[6],NULL,0);
printfunc("Thread %s id %u set affinity to core %u\n",logsdata->lines[0].val[0],tid,core);
set_affinity( 0,(pid_t)tid, core) ;
set_sched(0, (pid_t)tid, priority) ;
}
} else { /* end of set, => show */
if (strcasestr(cmdbuff,"loglvl") != NULL) {
logsdata->numcols=4;
logsdata->numlines=0;
snprintf(logsdata->columns[0].coltitle,TELNET_CMD_MAXSIZE,"component");
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
snprintf(logsdata->columns[1].coltitle,TELNET_CMD_MAXSIZE,"level");
logsdata->columns[1].coltype = TELNET_VARTYPE_STRING|TELNET_CHECKVAL_LOGLVL;
snprintf(logsdata->columns[2].coltitle,TELNET_CMD_MAXSIZE,"enabled");
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
snprintf(logsdata->columns[3].coltitle,TELNET_CMD_MAXSIZE,"in file");
logsdata->columns[3].coltype = TELNET_CHECKVAL_BOOL;
for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) {
if (g_log->log_component[i].name != NULL) {
logsdata->numlines++;
logsdata->lines[i].val[0]= (char *)(g_log->log_component[i].name);
logsdata->lines[i].val[1]=map_int_to_str(log_level_names,(g_log->log_component[i].level>=0)?g_log->log_component[i].level:g_log->log_component[i].savedlevel);
logsdata->lines[i].val[2]=(g_log->log_component[i].level>=0)?"true":"false";
logsdata->lines[i].val[3]=(g_log->log_component[i].filelog>0)?"true":"false";
}
}
}
if (strcasestr(cmdbuff,"dbgopt") != NULL) {
webdatadef_t *logsdata = ( webdatadef_t *) data;
logsdata->numcols=3;
logsdata->numlines=0;
snprintf(logsdata->columns[0].coltitle,TELNET_CMD_MAXSIZE,"module");
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
snprintf(logsdata->columns[1].coltitle,TELNET_CMD_MAXSIZE,"debug");
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
snprintf(logsdata->columns[2].coltitle,TELNET_CMD_MAXSIZE,"dump");
logsdata->columns[2].coltype = TELNET_CHECKVAL_BOOL;
for (int i=0; log_maskmap[i].name != NULL ; i++) {
logsdata->numlines++;
logsdata->lines[i].val[0]= log_maskmap[i].name;
logsdata->lines[i].val[1]= (g_log->debug_mask & log_maskmap[i].value)?"true":"false";
logsdata->lines[i].val[2]=(g_log->dump_mask & log_maskmap[i].value)?"true":"false";
}
}
if (strcasestr(cmdbuff,"logopt") != NULL) {
webdatadef_t *logsdata = ( webdatadef_t *) data;
logsdata->numcols=2;
logsdata->numlines=0;
snprintf(logsdata->columns[0].coltitle,TELNET_CMD_MAXSIZE,"option");
logsdata->columns[0].coltype = TELNET_VARTYPE_STRING | TELNET_CHECKVAL_RDONLY;
snprintf(logsdata->columns[1].coltitle,TELNET_CMD_MAXSIZE,"enabled");
logsdata->columns[1].coltype = TELNET_CHECKVAL_BOOL;
for (int i=0; log_options[i].name != NULL; i++) {
logsdata->numlines++;
logsdata->lines[i].val[0]=log_options[i].name;
logsdata->lines[i].val[1]=(g_log->flag & log_options[i].value)?"true":"false";
}
}
if (strcasestr(cmdbuff,"threadsched") != NULL) {
proccmd_get_threaddata(cmdbuff, debug, prnt, ( webdatadef_t *) data);
}
} // show
return 0;
}
int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt)
{
if (buf == NULL) {
prnt("ERROR wrong softmodem SHOW command...\n");
return 0;
}
if (debug > 0)
prnt(" proccmd_show received %s\n",buf);
if (strcasestr(buf,"thread") != NULL) {
@@ -466,10 +270,6 @@ int bv1,bv2;
int res;
char sv1[64];
if (buf == NULL) {
prnt("ERROR wrong thread command...\n");
return 0;
}
bv1=0;
bv2=0;
sv1[0]=0;
@@ -484,7 +284,7 @@ char sv1[64];
prnt(" proccmd_thread: %i params = %i,%s,%i\n",res,bv1,sv1,bv2);
if(res != 3)
{
print_threads(buf, debug, prnt);
prnt("softmodem thread needs 3 params, %i received\n",res);
return 0;
}
@@ -507,20 +307,11 @@ int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt)
{
if (debug > 0)
prnt("process module received %s\n",buf);
end_configmodule();
exit_fun("telnet server received exit command\n");
return 0;
}
int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt)
{
if (debug > 0)
prnt("process module received %s\n",buf);
end_configmodule();
configmodule_interface_t *cfg = config_get_if();
execvpe(cfg->argv[0],cfg->argv ,environ);
return 0;
}
int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt)
{
@@ -605,7 +396,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
SET_LOG_DUMP(optbit);
else
CLEAR_LOG_DUMP(optbit);
proccmd_show("dump",debug,prnt);
proccmd_show("dbgopt",debug,prnt);
}
}
if (logparam != NULL) free(logparam);
@@ -644,7 +435,7 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
} else {
prnt("%s%s unknown log sub command \n",logparam, tmpstr);
}
} else {level=map_str_to_int(log_level_names,tmpstr);
} else {
prnt("%s unknown log sub command \n",logsubcmd);
}
if (logparam != NULL) free(logparam);
@@ -668,7 +459,6 @@ int s = sscanf(buf,"%ms %i-%i\n",&logsubcmd, &idx1,&idx2);
return 0;
}
/*-------------------------------------------------------------------------------------*/
void add_softmodem_cmds(void)

View File

@@ -44,11 +44,9 @@
extern int proccmd_show(char *buf, int debug, telnet_printfunc_t prnt);
extern int proccmd_thread(char *buf, int debug, telnet_printfunc_t prnt);
extern int proccmd_exit(char *buf, int debug, telnet_printfunc_t prnt);
extern int proccmd_restart(char *buf, int debug, telnet_printfunc_t prnt);
extern int proccmd_log(char *buf, int debug, telnet_printfunc_t prnt);
extern int proccmd_websrv_getdata(char *cmdbuff, int debug, void *data,telnet_printfunc_t prnt);
telnetshell_vardef_t proc_vardef[] = {
{"",0,0,NULL}
{"",0,NULL}
};
#define PROCCMD_LOG_HELP_STRING " log sub commands: \n\
show: display current log configuration \n\
@@ -67,26 +65,18 @@ telnetshell_vardef_t proc_vardef[] = {
#define PROCCMD_THREAD_HELP_STRING " thread sub commands: \n\
<thread id> aff <core> : set affinity of thread <thread id> to core <core> \n\
<thread id> prio <prio> : set scheduling parameters for thread <thread id> \n\
-100 < prio < 0: linux scheduling policy set to FIFO, priority -prio, \n\
-200 < prio < -100: linux scheduling policy set to RR, priority -(prio+100), \n\
0 <= prio < 40: linux scheduling policy set to NORMAL, nice value prio-20 \n\
40 <= prio < 80: linux scheduling policy set to BATCH, nice value prio-60 \n\
prio >=80: linux scheduling policy set to IDLE \n\
if prio < -20: linux scheduling policy set to FIFO, \n\
with priority = -20 - prio \n\
if prio > 19: linux scheduling policy set to OTHER, \n\
with priority (nice value) = prio \n\
use \"softmodem show thread\" to get <thread id> \n"
telnetshell_cmddef_t proc_cmdarray[] = {
{"show","loglvl|thread|config", proccmd_show,{(webfunc_t)proccmd_websrv_getdata},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
{"log","(enter help for details)", proccmd_log, {NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
{"show loglvl","", proccmd_log,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
{"show logopt","", proccmd_log,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
{"show dbgopt","", proccmd_log,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
{"show config","", proccmd_show,{(webfunc_t)proccmd_show}, TELNETSRV_CMDFLAG_WEBSRVONLY,NULL},
{"show thread","", proccmd_thread,{(webfunc_t)proccmd_show},TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_AUTOUPDATE,NULL},
{"thread","(enter help for details)",proccmd_thread,{NULL},TELNETSRV_CMDFLAG_TELNETONLY,NULL},
{"show threadsched","",proccmd_show,{(webfunc_t)proccmd_websrv_getdata}, TELNETSRV_CMDFLAG_WEBSRVONLY|TELNETSRV_CMDFLAG_GETWEBTBLDATA,NULL},
{"exit","", proccmd_exit,{NULL},TELNETSRV_CMDFLAG_CONFEXEC,NULL},
{"restart","",proccmd_restart,{NULL},TELNETSRV_CMDFLAG_CONFEXEC,NULL},
{"show","loglvl|thread|config", proccmd_show},
{"log","(enter help for details)", proccmd_log},
{"thread","(enter help for details)", proccmd_thread},
{"exit","", proccmd_exit},
{"","",NULL},
};
#else

View File

@@ -1,7 +0,0 @@
The oai web server is an optional monitoring and debugging tool. It gives access to the same functionalities as the telnet server via a web interface
* [Using the web server](webserverusage.md)
* [enhancing the webserver](webserverdevcmd.md)
* [web server architecture ](webserverarch.md)
[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home)

View File

@@ -1,31 +0,0 @@
# telnet server principles
The oai telnet server is implemented in shared libraries to be loaded by the [oai shared library loader](loader). `libtelnetsrv.so ` contains the code common to all oai softmodem executables, where `libtelnetsrv_<app>.so` contains the code specific to the executable identified by `app`.
| `<app>` | executable |
| :-----: | :---------------: |
| enb | `lte-softmodem` |
| gnb | `nr-softmodem` |
| 4Gue | `lte-uesoftmodem` |
| 5Gue | `nr-uesoftmodem` |
The implementation includes a `telnetsrv_autoinit` function which is automatically called at load time, starts the telnet server and registers a first set of commands, which are delivered with the server (telnet, softmodem, loader). it also uses the `get_softmodem_function` call to retrieve the running executable id and possibly loads the corresponding `libtelnetsrv_<app>.so`library.
Currently the telnet server only supports one user connection. The same dedicated thread is used to wait for a user connection and process the input received from this connection.
The telnet server provides an API which can be used by any oai component to add new CLI commands to the server. A pre-defined command can be used to get or set a list of variables.
# telnet server source files
telnet server source files are located in [common/utils/telnetsrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv)
1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the `telnet` CLI command. This implementation is compatible with all softmodem executables and is in charge of loading any additional `libtelnetsrv_<app> .so` containing code specific to the running executables.
1. [telnetsrv.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.h) is the telnet server include file containing both private and public data type definitions. It also contains API prototypes for functions that are used to register a new command in the server.
1. `telnetsrv_<XXX\>.c`: implementation of \<XXX\> CLI command which are delivered with the telnet server and are common to all softmodem executables.
1. `telnetsrv_<XXX\>.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file
1. `telnetsrv_<app>_<XXX>.c`: implementation of \<XXX\> CLI command specific to the executable identified by \<app\>.These sources are used to create `libtelnetsrv_<app>.so` at build time.
1. [telnetsrv_CMakeLists.txt](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv_CMakeLists.txt): CMakelists file containing the cmake instructions to build the telnet server. this file is included in the [global oai CMakelists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt).
[oai telnet server home](telnetsrv.md)

View File

@@ -1,40 +0,0 @@
# starting the softmodem with the telnet server
By default the embedded telnet server, which is implemented in a shared library, is not built. It can be built after compiling the softmodem executable using the `build_oai` script:
```bash
cd \<oai repository\>/openairinterface5g
source oaienv
cd cmake_targets
./build_oai --build-lib telnetsrv
```
This will create the `libtelnetsrv.so` and `libtelnetsrv_<app> file in the `targets/bin` and `cmake_targets/ran_build/build` sub directories of the oai repository. <app> can be "enb", "gnb", "4GUE" or "5GUE", each library containing functions specific to a given executable.
When starting the softmodem, you must specify the **_\-\-telnetsrv_** option to load and start the telnet server. The telnet server is loaded via the [oai shared library loader](loader).
# using the Command Line Interface
By default the telnet server listen on all the ip addresses configured on the system and on port 9090. This behavior can be changed using the `listenaddr` and `listenport` parameters.
The telnet server includes a basic help, listing available commands and some commands also provide a specific detailed help sub-command.
Below are examples of telnet sessions:
* [getting help](telnethelp.md)
* [using the history](telnethist.md)
* [using the get and set commands](telnetgetset.md)
* [using the loop command](telnetloop.md)
* [loader command](telnetloader.md)
* [log command](telnetlog.md)
* [measur command](telnetmeasur.md)
# telnet server parameters
The telnet server is using the [oai configuration module](Config/Rtusage). Telnet parameters must be specified in the `telnetsrv` section. Some parameters can be modified via the telnet telnet server command, as specified in the last column of the following table.
| name | type | default | description | dynamic |
|:---:|:---:|:---:|:----|:----:|
| `listenaddr` | `ipV4 address, ascii format` | "0.0.0.0" | local address the server is listening on| N |
| `listenport` | `integer` | 9090 | port number the server is listening on | N |
| `loopcount` | `integer` | 10 | number of iterations for the loop command | Y |
| `loopdelay` | `integer` | 5000 | delay (in ms) between 2 loop command iterations | Y |
| `histfile` | `character string` | "oaitelnet.history" | file used for command history persistency | Y |
| `histfsize` | `integer` | 50 | maximum number of commands saved in the history | Y |
[oai telnet server home](telnetsrv.md)

View File

@@ -1,17 +0,0 @@
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# For the full list of supported browsers by the Angular framework, please see:
# https://angular.io/guide/browser-support
# You can see what browsers were selected by your queries by running:
# npx browserslist
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major versions
last 2 iOS major versions
Firefox ESR
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.

View File

@@ -1,16 +0,0 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

View File

@@ -1,50 +0,0 @@
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
{
"files": [
"*.ts"
],
"parserOptions": {
"project": [
"common/utils/websrv/frontend/tsconfig.json"
],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
]
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
}
]
}

View File

@@ -1,50 +0,0 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
/out-tsc
/artifacts
/builds
# Only exists if Bazel was run
/bazel-out
# dependencies
/node_modules
# profiling files
chrome-profiler-events*.json
speed-measure-plugin*.json
# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# misc
/.angular/cache
/.sass-cache
/connect.lock
/coverage
/libpeerconnection.log
npm-debug.log
yarn-error.log
testem.log
/typings
# System Files
.DS_Store
Thumbs.db
config.toml

View File

@@ -1 +0,0 @@
# SoftModemNgx

View File

@@ -1,108 +0,0 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"cli": {
"analytics": false,
"schematicCollections": [
"@angular-eslint/schematics"
]
},
"version": 1,
"newProjectRoot": "projects",
"projects": {
"softmodemngx": {
"projectType": "application",
"schematics": {
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/softmodem-ngx",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"./node_modules/@angular/material/prebuilt-themes/purple-green.css",
"src/styles.css"
],
"scripts": [],
"allowedCommonJsDependencies": [
"@firebase/auth",
"firebase"
]
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "1.5mb",
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "softmodemngx:build:production"
},
"development": {
"browserTarget": "softmodemngx:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "softmodemngx:build"
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
}
}
}
}

View File

@@ -1,40 +0,0 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: ['--headless', '--no-sandbox']
}
},
directConnect: true,
SELENIUM_PROMISE_MANAGER: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function () { }
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: StacktraceOption.PRETTY
}
}));
}
};

View File

@@ -1,37 +0,0 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome'
},
directConnect: true,
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function () { }
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: StacktraceOption.PRETTY
}
}));
}
};

View File

@@ -1,23 +0,0 @@
import { browser, logging } from 'protractor';
import { AppPage } from './app.po';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
// it('should display welcome message', async () => {
// await page.navigateTo();
// expect(await page.getTitleText()).toEqual('example app is running!');
// });
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

View File

@@ -1,11 +0,0 @@
import { browser, by, element } from 'protractor';
export class AppPage {
async navigateTo(): Promise<unknown> {
return browser.get(browser.baseUrl);
}
async getTitleText(): Promise<string> {
return element(by.css('app-root .content span')).getText();
}
}

View File

@@ -1,10 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es2018",
"types": ["jasmine", "node"]
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,65 +0,0 @@
{
"name": "softmodemngx",
"version": "2.0.0",
"scripts": {
"lint": "ng lint",
"build": "ng build",
"dev": "ng serve --configuration=development",
"prod": "ng serve --configuration=production"
},
"private": true,
"dependencies": {
"@angular-slider/ngx-slider": "^2.0.4",
"@angular/animations": "^14.1.0",
"@angular/cdk": "^14.1.0",
"@angular/common": "^14.1.0",
"@angular/compiler": "^14.1.0",
"@angular/core": "^14.1.0",
"@angular/flex-layout": "^14.0.0-beta.40",
"@angular/forms": "^14.1.0",
"@angular/material": "^14.1.0",
"@angular/platform-browser": "^14.1.0",
"@angular/platform-browser-dynamic": "^14.1.0",
"@angular/router": "^14.1.0",
"chart.js": "^3.8.2",
"moment": "^2.29.3",
"ng2-charts": "^4.0.0",
"rxjs": "^6.6.6",
"tslib": "^2.0.0",
"zone.js": "^0.11.4"
},
"devDependencies": {
"@angular-devkit/architect": "^0.1401.0",
"@angular-devkit/build-angular": "^14.1.0",
"@angular-eslint/builder": "14.0.2",
"@angular-eslint/eslint-plugin": "14.0.2",
"@angular-eslint/eslint-plugin-template": "14.0.2",
"@angular-eslint/schematics": "14.0.2",
"@angular-eslint/template-parser": "14.0.2",
"@angular/cli": "^14.1.0",
"@angular/compiler-cli": "^14.1.0",
"@angular/language-service": "^14.1.0",
"@types/node": "^12.20.23",
"@typescript-eslint/eslint-plugin": "^5.29.0",
"@typescript-eslint/parser": "^5.29.0",
"eslint": "^8.18.0",
"fs-extra": "^10.0.0",
"fuzzy": "^0.1.3",
"husky": "^5.1.3",
"inquirer": "^6.2.2",
"inquirer-autocomplete-prompt": "^1.0.1",
"jasmine-core": "~3.7.1",
"jasmine-spec-reporter": "~5.0.0",
"jsonc-parser": "^3.0.0",
"open": "^7.0.3",
"ts-node": "^8.10.2",
"tslint-angular": "^3.0.3",
"typescript": "~4.6.4"
},
"husky": {
"hooks": {
"pre-commit": "pretty-quick --staged && ng lint && ng test",
"pre-push": "ng build --aot true"
}
}
}

View File

@@ -1,116 +0,0 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
export interface IInfo {
name: string;
value: string;
type: IArgType;
modifiable: boolean; //set command ?
}
export interface IModule {
name: string;
}
export enum ILogLvl {
error = "error",
warn = "warn",
analysis = "analysis",
info = "info",
debug = "debug",
trace = "trace"
}
export enum ILogOutput {
stdout = "stdout",
telnet = "telnet",
web = "web",
file = "/tmp/<component>.log",
}
export enum IArgType {
boolean = "boolean",
list = "list",
loglvl = "loglvl",
range = "range",
number = "number",
string = "string",
configfile = "configfile",
simuTypes = "simuTypes",
}
export enum ICommandOptions {
update = "update", // result can be updated, triggers update button on result page when set
}
export interface IVariable {
name: string;
value: string;
type: IArgType;
modifiable: boolean; //set command ?
}
export interface ICommand {
name: string;
confirm?: string;
question?: IQuestion;
param?: IVariable;
options?: ICommandOptions[];
}
export interface ITable {
columns: IColumn[];
rows: string[];
}
export interface IQuestion {
display: string;
pname: string;
type: IArgType;
}
export interface IResp {
display: string[],
table?: ITable
}
export interface IParam {
value: string,
col: IColumn
}
export interface IColumn { //should use IVariable ?
name: string;
type: IArgType;
modifiable: boolean; //set command ?
}
export interface IRow {
params: IParam[],
rawIndex: number,
cmdName: string
}
export const route = 'oaisoftmodem/';
@Injectable({
providedIn: 'root',
})
export class CommandsApi {
constructor(private httpClient: HttpClient) { }
public readInfos$ = () => this.httpClient.get<IInfo[]>('http://' + environment.backend + route + 'variables/');
public setInfo$ = (info: IInfo) => this.httpClient.post<IResp>('http://' + environment.backend + route + 'variables/', info);
public readModules$ = () => this.httpClient.get<IModule[]>('http://' + environment.backend + route + 'commands/');
public readVariables$ = (moduleName: string) => this.httpClient.get<IInfo[]>('http://' + environment.backend + route + moduleName + '/variables/');
public readCommands$ = (moduleName: string) => this.httpClient.get<ICommand[]>('http://' + environment.backend + route + moduleName + '/commands/');
public runCommand$ = (command: ICommand, moduleName: string) => this.httpClient.post<IResp>('http://' + environment.backend + route + moduleName + '/commands/', command);
public setCmdVariable$ = (variable: IInfo, moduleName: string) => this.httpClient.post<IResp>('http://' + environment.backend + route + moduleName + '/variables/', variable);
public setCmdParams$ = (row: IRow, moduleName: string) => this.httpClient.post<IResp>('http://' + environment.backend + route + moduleName + '/set/', row);
}

View File

@@ -1,47 +0,0 @@
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
export enum IScopeGraphType {
IQs = "IQs",
LLR = "LLR",
WF = "WF",
UNSUP = "UNSUP"
}
export interface IGraphDesc {
title: string;
type: IScopeGraphType;
id: number;
srvidx: number;
}
export interface IScopeDesc {
title: string;
graphs: IGraphDesc[];
}
export interface IScopeCmd {
name: string;
graphid?: number; // the graph srvidx
value: string;
}
export interface ISigDesc {
target_id: number;
antenna_id: number;
}
const route = 'oaisoftmodem/scopectrl/';
@Injectable({
providedIn: 'root',
})
export class ScopeApi {
constructor(private httpClient: HttpClient) { }
public getScopeInfos$ = () => this.httpClient.get<IScopeDesc>('http://' + environment.backend + route);
public setScopeParams$ = (cmd: IScopeCmd) => this.httpClient.post('http://' + environment.backend + route, cmd);
}

View File

@@ -1,16 +0,0 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { CommandsComponent } from './components/commands/commands.component';
const routes: Routes = [
{ path: '', redirectTo: '/websrv', pathMatch: 'full' },
{ path: 'websrv', component: AppComponent },
{ path: '**', redirectTo: '' },
];
@NgModule({
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule],
})
export class AppRoutingModule { }

View File

@@ -1,11 +0,0 @@
.mat-tab-group {
margin-bottom: 10px;
}
.mat-ink-bar{
height: 8px !important;
}
.mat-tab-label-active
{
color: #000000 !important;
}

View File

@@ -1,11 +0,0 @@
<mat-tab-group backgroundColor="primary" color="accent">
<mat-tab label="Commands">
<app-commands></app-commands>
</mat-tab>
<mat-tab label={{scopelabel}} disabled={{!isscopeavailable}}>
<app-scope (ScopeEnabled)="onScopeEnabled($event)"></app-scope>
</mat-tab>
<mat-tab label="Logger">
<app-logger></app-logger>
</mat-tab>
</mat-tab-group>

View File

@@ -1,22 +0,0 @@
import { Component } from '@angular/core';
import { MatTabsModule } from '@angular/material/tabs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'oai softmodem';
isscopeavailable = false;
scopelabel = '';
constructor() {
this.scopelabel = '';
this.isscopeavailable=false;
}
onScopeEnabled( enabled: boolean) {
this.isscopeavailable= enabled;
this.scopelabel= enabled ? 'Scope' : '';
}
}

View File

@@ -1,88 +0,0 @@
import { DragDropModule } from '@angular/cdk/drag-drop';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { FlexLayoutModule } from '@angular/flex-layout';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatChipsModule } from '@angular/material/chips';
import { MatDialogModule } from '@angular/material/dialog';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatSelectModule } from '@angular/material/select';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatSliderModule } from '@angular/material/slider';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTableModule } from '@angular/material/table';
import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgChartsModule } from 'ng2-charts';
import { CommandsApi } from './api/commands.api';
import { ScopeApi } from './api/scope.api';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CommandsComponent } from './components/commands/commands.component';
import { ConfirmDialogComponent } from './components/confirm/confirm.component';
import { DialogComponent } from './components/dialog/dialog.component';
import { QuestionDialogComponent } from './components/question/question.component';
import { ScopeComponent } from './components/scope/scope.component';
import { InterceptorProviders } from './interceptors/interceptors';
import { LoadingService } from './services/loading.service';
import { WebSocketService } from './services/websocket.service';
import { LoggerComponent } from './components/logger/logger.component';
@NgModule({
declarations: [
AppComponent,
CommandsComponent,
ConfirmDialogComponent,
QuestionDialogComponent,
DialogComponent,
ScopeComponent,
LoggerComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
BrowserAnimationsModule,
HttpClientModule,
MatButtonModule,
FlexLayoutModule,
MatDialogModule,
DragDropModule,
MatSliderModule,
MatFormFieldModule,
MatInputModule,
MatChipsModule,
MatProgressSpinnerModule,
MatToolbarModule,
MatTableModule,
MatListModule,
MatSelectModule,
MatSnackBarModule,
MatSlideToggleModule,
MatGridListModule,
MatCardModule,
MatTabsModule,
NgChartsModule,
],
providers: [
// services
LoadingService,
WebSocketService,
// api
CommandsApi,
ScopeApi,
// interceptors
InterceptorProviders,
],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@@ -1,127 +0,0 @@
<div class="grid-container" >
<mat-grid-list cols="2" rowHeight="15vh" >
<mat-grid-tile [colspan]="1" [rowspan]="2" >
<mat-card class="dashboard-card">
<mat-card-header >
<mat-card-title>Connection info</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div *ngIf="infos$ | async as infos">
<div class="spaceddiv" *ngFor="let info of infos">
<mat-form-field class="scrollablefield" >
<mat-label>{{ info.nameFC.value }}</mat-label>
<input matInput [formControl]="info.valueFC" [readonly]="!info.modifiableFC.value" />
</mat-form-field>
<button mat-raised-button color="primary" [disabled]="!info.modifiableFC.value"
(click)="onInfoSubmit(info)">
{{ info.btnTxtFC }}
</button>
</div>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile [colspan]="1" [rowspan]="2">
<mat-card class="dashboard-card">
<mat-card-header>
<mat-card-title>Softmodem commands</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div class="spaceddiv" *ngIf="modules$ | async as modules" fxLaypout="row">
<mat-form-field>
<mat-label>Module</mat-label>
<mat-select (selectionChange)="onModuleSelect($event.value)" [(value)]="selectedModule">
<mat-option *ngFor="let module of modules" [value]="module"> {{ module.name }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *ngIf="cmds$ | async as cmds">
<div *ngIf="cmds.length">
<mat-chip-list>
<mat-chip *ngFor="let cmd of cmds" (click)="onCmdSubmit(cmd)"> {{cmd.nameFC.value}}
</mat-chip>
</mat-chip-list>
</div>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile *ngIf="vars$ | async as vars" [colspan]="1" [rowspan]="4">
<mat-card *ngIf="vars.length" class="dashboard-card">
<mat-card-header>
<mat-card-title>{{ selectedModule!.name }} variables</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div class="spaceddiv" *ngFor="let variable of vars">
<mat-form-field class="scrollablefield">
<mat-label>{{ variable.nameFC.value }}</mat-label>
<input matInput [formControl]="variable.valueFC" [readonly]="!variable.modifiableFC.value" />
</mat-form-field>
<button mat-raised-button color="primary" [disabled]="!variable.modifiableFC.value"
(click)="onVarsubmit(variable)">
set
</button>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<mat-grid-tile *ngIf="(rows$ | async)?.length" [colspan]="1" [rowspan]="4">
<mat-card class="dashboard-card">
<mat-card-header>
<mat-card-title>{{ selectedModule!.name }} {{ selectedCmd!.name }} </mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div >
<mat-table mat-table [dataSource]="rows$" multiTemplateDataRows class="mat-elevation-z8">
<div class="TableRowdiv" *ngFor="let col of columns; index as colIndex" matColumnDef="{{col.name}}">
<mat-header-cell *matHeaderCellDef fxLayoutAlign="start center">
<div>
<h4>{{ col.name }}</h4>
</div>
</mat-header-cell>
<mat-cell *matCellDef="let row">
<div [ngSwitch]="col.type" [formGroup]="row" fxLayoutAlign="start center">
<mat-slide-toggle *ngSwitchCase="IArgType.boolean" [formControl]="row.paramsCtrls[colIndex].valueFC"
[checked]="row.paramsCtrls[colIndex].valueFC.value">
</mat-slide-toggle>
<mat-list-item role="listitem">
<mat-form-field *ngSwitchCase="IArgType.loglvl">
<mat-select [formControl]="row.paramsCtrls[colIndex].valueFC"
[(value)]="row.paramsCtrls[colIndex].valueFC.value">
<mat-option *ngFor="let level of logLvlValues" [value]="level"> {{ level }}
</mat-option>
</mat-select>
</mat-form-field>
</mat-list-item>
<div *ngSwitchDefault>
<mat-form-field>
<input matInput [formControl]="row.paramsCtrls[colIndex].valueFC" [readonly]="!col.modifiable" />
</mat-form-field>
</div>
</div>
</mat-cell>
</div>
<div matColumnDef="button">
<mat-header-cell *matHeaderCellDef> </mat-header-cell>
<mat-cell *matCellDef="let row" fxLayoutAlign="center">
<button class="TableBtn" mat-raised-button color="primary" (click)="onParamSubmit(row)" [disabled]="row.pristine"> set
</button>
</mat-cell>
</div>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
</mat-table>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
</mat-grid-list>
</div>

View File

@@ -1,80 +0,0 @@
.spaceddiv {
height: 45px;
width: 40vw;
display: flex;
justify-content: space-between;
margin: 0 auto;
padding: 10px 0;
}
.TableRowdiv {
height: 38px;
display: flex;
/* justify-content: space-between;*/
margin: 2px;
width: 95%;
.item:nth-child(1n){
width: 10%;
}
.item {
width: 4%;
margin: 10px;
}
}
.TableBtn {
height: 25px;
width: 35p;
display:flex;
padding-bottom:8px;
}
.TableText {
display: flex;
width: 8em;
overflow-x: auto;
}
.scrollablefield {
width: 80%;
height: 20px;
.mat-input-element {
overflow-x: auto;
}
}
.mat-card {
height: 95%;
overflow-y: auto;
overflow-x: scroll;
}
.status {
color: green;
font-weight: 800;
}
.ng-invalid .status {
color: red;
}
.grid-container {
margin: 20px;
}
.dashboard-card {
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
}
.more-button {
position: absolute;
top: 5px;
right: 10px;
}
.dashboard-card-content {
text-align: center;
}

View File

@@ -1,197 +0,0 @@
import { Component } from '@angular/core';
import { UntypedFormArray } from '@angular/forms';
import { BehaviorSubject, forkJoin, timer } from 'rxjs';
import { Observable } from 'rxjs';
import { of } from 'rxjs';
import { filter } from 'rxjs/operators';
import { map } from 'rxjs/operators';
import { tap } from 'rxjs/operators';
import { switchMap } from 'rxjs/operators';
import { CommandsApi, IArgType, IColumn, ICommand, IInfo, ILogLvl, IParam, IRow } from 'src/app/api/commands.api';
import { CmdCtrl } from 'src/app/controls/cmd.control';
import { InfoCtrl } from 'src/app/controls/info.control';
import { ModuleCtrl } from 'src/app/controls/module.control';
import { RowCtrl } from 'src/app/controls/row.control';
import { VarCtrl } from 'src/app/controls/var.control';
import { DialogService } from 'src/app/services/dialog.service';
import { DownloadService } from 'src/app/services/download.service';
import { LoadingService } from 'src/app/services/loading.service';
import { ViewEncapsulation } from '@angular/core';
const CHANNEL_MOD_MODULE = "channelmod"
const PREDEF_CMD = "show predef"
@Component({
selector: 'app-commands',
templateUrl: './commands.component.html',
styleUrls: ['./commands.component.scss'],
encapsulation: ViewEncapsulation.None,
})
export class CommandsComponent {
IArgType = IArgType;
logLvlValues = Object.values(ILogLvl)
// softmodem
infos$: Observable<VarCtrl[]>
modules$: Observable<ModuleCtrl[]>
// module
selectedModule?: ModuleCtrl
vars$?: Observable<VarCtrl[]>
cmds$?: Observable<CmdCtrl[]>
// command
selectedCmd?: ICommand
displayedColumns: string[] = []
rows$: BehaviorSubject<RowCtrl[]> = new BehaviorSubject<RowCtrl[]>([])
columns: IColumn[] = []
constructor(
public commandsApi: CommandsApi,
public loadingService: LoadingService,
public dialogService: DialogService,
public downloadService: DownloadService,
) {
this.infos$ = this.commandsApi.readInfos$().pipe(
map((infos) => infos.map(info => new InfoCtrl(info)))
);
this.modules$ = this.commandsApi.readModules$().pipe(
map(imodules => imodules.map(imodule => new ModuleCtrl(imodule))),
filter(controls => controls.length > 0),
tap(controls => this.onModuleSelect(controls[0]))
);
}
// get types$() {
// return this.modules$.pipe(
// filter(modules => modules.map(module => module.name).includes(CHANNEL_MOD_MODULE)),
// mergeMap(modules => this.commandsApi.readCommands$(modules[0]!.name)),
// map(icmds => icmds.filter(cmd => cmd.name === PREDEF_CMD)),
// filter(icmds => icmds.length > 0),
// map(icmds => new CmdCtrl(icmds[0])),
// mergeMap(control => this.commandsApi.runCommand$(control.api(), CHANNEL_MOD_MODULE)),
// map(resp => resp.display.map(line => line.match('/\s*[0-9]*\s*(\S*)\n/gm')![0])),
// tap(types => console.log(types.join(', ')))
// );
// }
onInfoSubmit(control: InfoCtrl) {
let info: IInfo = control.api();
if (info.type === IArgType.configfile) {
this.downloadService.getFile(info.value)
} else {
this.commandsApi.setInfo$(info).subscribe();
}
}
onModuleSelect(module: ModuleCtrl) {
this.selectedModule = module
this.selectedCmd = undefined
this.cmds$ = this.commandsApi.readCommands$(module.name).pipe(
map(icmds => icmds.map(icmd => new CmdCtrl(icmd))),
map(cmds => {
module.cmdsFA = new UntypedFormArray(cmds)
return module.cmdsFA.controls as CmdCtrl[]
})
)
this.vars$ = this.commandsApi.readVariables$(module.name).pipe(
map(ivars => ivars.map(ivar => new VarCtrl(ivar))),
map(vars => {
module.varsFA = new UntypedFormArray(vars)
return module.varsFA.controls as VarCtrl[]
})
)
}
onVarsubmit(control: VarCtrl) {
this.commandsApi.setCmdVariable$(control.api(), this.selectedModule!.name)
.pipe(
map(resp => this.dialogService.openVarRespDialog(resp))
).subscribe();
}
onCmdSubmit(control: CmdCtrl) {
this.selectedCmd = control.api()
const obsparam$ = forkJoin([control.confirm
? this.dialogService.openConfirmDialog(control.confirm)
: control.question
? this.dialogService.openQuestionDialog(this.selectedModule! + " " + this.selectedModule!.name, control)
: of(true)]);
obsparam$.pipe(
switchMap(results => {
if (!results[0])
return of(null);
if (control.isResUpdatable())
control.ResUpdTimer = timer(2000, 1000);
return this.execCmd$(control);
}))
.subscribe();
}
private execCmd$(control: CmdCtrl) {
if (control.isResUpdatable() && control.ResUpdTimer) {
if (!(control.ResUpdTimerSubscriber)) {
control.ResUpdTimerSubscriber = control.ResUpdTimer.subscribe(iteration => {
console.log("Update timer fired" + iteration);
if (control.updbtnname === "Stop update")
this.execCmd$(control);
});
}
}
this.commandsApi.runCommand$(control!.api(), this.selectedModule!.name).subscribe(resp => {
if (resp.display[0]) this.dialogService.updateCmdDialog(control, resp, 'cmd ' + control.nameFC.value + ' response:')
// else return of(resp)
const controls: RowCtrl[] = []
this.displayedColumns = []
if (resp.table) {
this.columns = resp.table.columns
this.displayedColumns = this.columns.map(col => col.name)
this.displayedColumns.push('button')
for (let rawIndex = 0; rawIndex < resp.table.rows.length; rawIndex++) {
let params: IParam[] = []
for (let i = 0; i < this.columns.length; i = i + 1) {
params.push({
value: resp.table.rows[rawIndex][i],
col: this.columns[i]
})
}
const irow: IRow = {
params: params,
rawIndex: rawIndex,
cmdName: this.selectedCmd!.name
}
controls[rawIndex] = new RowCtrl(irow)
}
}
this.rows$.next(controls)
},
err => console.error('execCmd error: ' + err),
() => console.log('execCmd completed: '),
) // map resp
return of(null);
}
onParamSubmit(control: RowCtrl) {
this.commandsApi.setCmdParams$(control.api(), this.selectedModule!.name).subscribe(() => this.execCmd$(new CmdCtrl(this.selectedCmd!)));
}
}

View File

@@ -1,5 +0,0 @@
<h3>{{ data.title }}</h3>
<div fxLayoutGap="10px" mat-dialog-actions fxLayout="row" fxLayoutAlign="center start">
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>Ok</button>
<button mat-button (click)="onNoClick()">Cancel</button>
</div>

View File

@@ -1,21 +0,0 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { Component, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'app-confirm',
templateUrl: './confirm.component.html',
styleUrls: ['./confirm.component.css']
})
export class ConfirmDialogComponent {
constructor(
public dialogRef: MatDialogRef<void>,
@Inject(MAT_DIALOG_DATA) public data: any) {
}
onNoClick() {
this.dialogRef.close();
}
}

View File

@@ -1,34 +0,0 @@
/* icon that can be used to drag a dialog */
::ng-deep.dialogdrag-handle {
top: 1px;
left: 1px;
color: #ccc;
cursor: move;
width: 24px;
height: 24px;
}
/* make dialog for command response using the display field scrollable */
::ng-deep.cmdRespDialog {
resize: both;
overflow: scroll;
}
/* make only the dialog for command response using the display field movable */
/* (hide the close button and the drag icon) */
::ng-deep.varRespDialog #dialogclose {
display:none ;
}
::ng-deep.varRespDialog #dialogdrag {
display:none;
}
::ng-deep.errRespDialog #dialogclose {
display:none ;
}
::ng-deep.errRespDialog #dialogdrag {
display:none;
}

View File

@@ -1,17 +0,0 @@
<div id="dialogdrag" cdkDrag cdkDragRootElement=".cdk-overlay-pane">
<div class="dialogdrag-handle" cdkDragHandle>
<svg width="24px" fill="currentColor" viewBox="0 0 24 24">
<path
d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z">
</path>
<path d="M0 0h24v24H0z" fill="none"></path>
</svg>
</div>
</div>
<h3> {{ data.title }}</h3>
<pre [innerHTML]="data.body"></pre>
<mat-dialog-actions fxLayoutAlign="end">
<button id="dialogclose" mat-button mat-dialog-close>Close</button>
<button id="dialogupdate" mat-button (click)="onUpdate(data.control)"
*ngIf="data.updatable">{{data.control.updbtnname}}</button>
</mat-dialog-actions>

View File

@@ -1,23 +0,0 @@
import { Component, ViewChild, ElementRef, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { DialogService } from 'src/app/services/dialog.service';
import { CmdCtrl } from 'src/app/controls/cmd.control';
@Component({
selector: 'app-dialog',
templateUrl: './dialog.component.html',
styleUrls: ['./dialog.component.css'],
})
export class DialogComponent {
constructor(@Inject(MAT_DIALOG_DATA) public data: any) {
}
onUpdate(control: CmdCtrl) {
if ( control.updbtnname==="Stop update" ){
control.stopUpdate();
} else {
control.startUpdate();
}
}
}

View File

@@ -1,5 +0,0 @@
<div id="logDisplay">
<ul>
<li *ngFor="let msg of messages">{{JSON.stringify(msg)}}</li>
</ul>
</div>

View File

@@ -1,23 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LoggerComponent } from './logger.component';
describe('LoggerComponent', () => {
let component: LoggerComponent;
let fixture: ComponentFixture<LoggerComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ LoggerComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(LoggerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,29 +0,0 @@
import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { Message, WebSocketService } from 'src/app/services/websocket.service';
@Component({
selector: 'app-logger',
templateUrl: './logger.component.html',
styleUrls: ['./logger.component.css']
})
export class LoggerComponent implements OnInit {
JSON = JSON
// websocket service object and related subscription for message reception
wsSubscription?: Subscription;
messages: Message[] = [];
constructor(
private wsService: WebSocketService
) { }
ngOnInit(): void {
this.wsSubscription = this.wsService.subject$.subscribe(
(msg: Message) => this.messages.push(msg)
)
}
}

View File

@@ -1,11 +0,0 @@
<h3>{{ data.title }}</h3>
<div mat-dialog-content >
<mat-form-field appearance="fill">
<label for="answer">{{data.control.question?.display}}</label>
<input id="answer" type="text" style="width:10vw" [formControl]="data.control.answerFC">
</mat-form-field>
</div>
<div fxLayoutGap=" 10px" mat-dialog-actions fxLayout="row" fxLayoutAlign="center start">
<button mat-button [mat-dialog-close]="true" cdkFocusInitial>Ok</button>
<button mat-button [mat-dialog-close]="false">Cancel</button>
</div>

View File

@@ -1,24 +0,0 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { Component, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { CmdCtrl } from 'src/app/controls/cmd.control';
export interface QuestionDialogData {
title: string;
control: CmdCtrl;
}
@Component({
selector: 'app-question',
templateUrl: './question.component.html',
styleUrls: ['./question.component.css']
})
export class QuestionDialogComponent {
constructor(
public dialogRef: MatDialogRef<QuestionDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: QuestionDialogData,
) { }
onNoClick() {
this.dialogRef.close();
}
}

View File

@@ -1,42 +0,0 @@
mat-form-field {
width: 80%;
}
.status {
color: green;
font-weight: 800;
}
.ng-invalid .status {
color: red;
}
.grid-container {
margin: 20px;
}
.dashboard-card {
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
}
.more-button {
position: absolute;
top: 5px;
right: 10px;
}
.dashboard-card-content {
text-align: center;
}
.scope-slider {
width: 90%;
}
.mat-mini-fab.mat-started {
background-color: #00a825;
}

View File

@@ -1,204 +0,0 @@
<div class="grid-container">
<mat-grid-list cols="11" rowHeight="100px">
<!-- top fullwidth area for scope status display -->
<mat-grid-tile [colspan]="11" [rowspan]="1">
<mat-card class="dashboard-card">
<mat-card-header>
<mat-card-title>{{ scopetitle }} {{ scopesubtitle }}</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<div FxLayoutAlign="row">
<label>{{ scopetime }} {{ scopestatus }} &nbsp; &nbsp; </label>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<!-- left full heigth, narrow width area, for global scope controls -->
<mat-grid-tile [colspan]="1" [rowspan]="8">
<mat-card class="dashboard-card">
<mat-card-header>
<mat-card-title>Scope control</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content">
<button mat-mini-fab color={{startstop_color}} (click)="startorstop()">{{startstop}}</button>
<br><br>
<div class="scope-slider-div">
<label id="scope-slider-refrate-labelid" class="scope-slider-label">refresh rate</label>
<label class="scope-slider-value-label"> {{rfrate}} </label>
</div>
<mat-slider class="scope-slider" min=".1" max="10" step="0.1" [value]="rfrate"
aria-labelledby="scope-slider-refrate-labelid" vertical="true" thumbLabel="true"
[(ngModel)]="rfrate" (change)="OnRefrateChange()" >
</mat-slider>
<br><br>
<mat-list-item class="sigselect" role="listitem">
<mat-form-field class="select-form">
<mat-select placeholder="sig select" name="SigSelect" class="SigSelect" [value]="selected_sig.target_id" (selectionChange)="SigChanged($event.value)" >
<mat-option *ngFor="let targetid of sig_list" [value]="targetid.target_id" >
{{targetid.target_id}}
</mat-option>
</mat-select>
</mat-form-field>
</mat-list-item>
<br><br>
<mat-slide-toggle [checked]="data_ACK" (change)="onDataACKchange()" [(ngModel)]="data_ACK">data ack
</mat-slide-toggle>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<!-- area for watter fall data display -->
<mat-grid-tile [colspan]="7" [rowspan]="3">
<mat-card class="dashboard-card">
<mat-card-content class="dashboard-card-content">
<div fxLayout="column">
<!-- area for the chart -->
<div fxFlex="1 1 90% " style="width:100%">
<canvas baseChart id="wf"
[datasets]="WFDatasets"
[options]="WFOptions"
[type]="'scatter'">
</canvas>
</div>
<br><br>
<!-- area for the control used to select WF data -->
<div fxFlex="0 1 10%" style="width:60%">
<mat-list-item class="WFselect" role="listitem">
<mat-form-field class="select-form">
<mat-select placeholder="select data" name="WFSelect" class="WFSelect" [value]="selected_WF" (selectionChange)="WFChanged($event.value)" >
<mat-option *ngFor="let graph of WFgraph_list" [value]="graph.title" >
{{graph.title}}
</mat-option>
<mat-option>none</mat-option>
</mat-select>
</mat-form-field>
</mat-list-item>
</div>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile>
<!-- right area for -->
<mat-grid-tile [colspan]="3" [rowspan]="2">
<mat-card class="dashboard-card">
<mat-card-content class="dashboard-card-content">
</mat-card-content>
</mat-card>
</mat-grid-tile>
<!-- area for LLR data display -->
<mat-grid-tile [colspan]="5" [rowspan]="4">
<mat-card class="dashboard-card">
<mat-card-content class="dashboard-card-content">
<div fxLayout="column">
<div fxFlex="1 1 90% ">
<canvas baseChart id="llr" width="90%"
[datasets]=" LLRDatasets"
[options]="LLROptions"
[type]="'scatter'">
</canvas>
</div>
<div fxFlex="0 1 5%" style="width:100%">
<div class="form-group" fxFlex="50%"> <mat-list-item class="llrchannelselect" role="listitem">
<mat-form-field class="select-form">
<mat-select placeholder="Channels(llr view)" name="llrChannelsSelect" class="ChannelsSelect" multiple [value]="selected_llrchannels" (selectionChange)="llrchannelsChanged($event.value)" >
<mat-option *ngFor="let graph of llrgraph_list" [value]="graph.title" >
{{graph.title}}
</mat-option>
</mat-select>
</mat-form-field>
</mat-list-item> </div>
<div class="form-group" fxFlex="50%">
<div class="scope-slider-div">
<label id="scope-slider-ythresh-labelid" class="scope-slider-label">y threshold </label>
<label class="scope-slider-value-label"> {{llrythresh}} </label>
</div>
<mat-slider class="scope-slider" min="0" max="100" step="1" [value]="llrythresh"
aria-labelledby="scope-slider-ythresh-labelid" thumbLabel="true"
[(ngModel)]="llrythresh" (change)="OnYthreshChange()" >
</mat-slider>
</div>
</div>
<div fxFlex="0 1 5%">
<div class="form-group" fxFlex="25%">
<mat-form-field appearance="fill">
<mat-label>xmin</mat-label>
<input matInput type="number" (change)="OnLLRxminChange()" [value]="llrxmin" [(ngModel)]="llrxmin" min="llrmin" [max]="llrmax">
</mat-form-field>
</div>
<div class="form-group" fxFlex="25%">
<mat-form-field appearance="fill">
<mat-label>xmax</mat-label>
<input matInput type="number" (change)="OnLLRxmaxChange()" [value]="llrxmax" [(ngModel)]="llrxmax" min="llrmin" [max]="llrmax">
</mat-form-field>
</div>
</div>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile> <!-- end of LLR area -->
<!-- area for iq constellation data display -->
<mat-grid-tile [colspan]="5" [rowspan]="6">
<mat-card class="dashboard-card">
<mat-card-content>
<div fxLayout="column">
<!-- area for the chart -->
<div fxFlex="1 1 80% " style="width:60%">
<canvas baseChart id="iqc"
[datasets]="IQDatasets"
[options]="IQOptions"
[type]="'scatter'">
</canvas>
</div>
<br><br>
<!-- area for the control used to select channel's -->
<div fxFlex="0 1 10%" style="width:60%">
<mat-list-item class="channelselect" role="listitem">
<mat-form-field class="select-form">
<mat-select placeholder="Channels(IQ view)" name="ChannelsSelect" class="ChannelsSelect" multiple [value]="selected_channels" (selectionChange)="channelsChanged($event.value)" >
<mat-option *ngFor="let graph of iqgraph_list" [value]="graph.title" >
{{graph.title}}
</mat-option>
</mat-select>
</mat-form-field>
</mat-list-item>
</div>
<!-- area for the 4 controls used to select x and y limits for data -->
<div fxFlex="0 1 5%">
<div class="form-group" fxFlex="25%">
<mat-form-field appearance="fill">
<mat-label>xmin</mat-label>
<input matInput type="number" (change)="OnIQxminChange()" [value]="iqxmin" [(ngModel)]="iqxmin" min="iqmin" [max]="iqmax">
</mat-form-field>
</div>
<div class="form-group" fxFlex="25%">
<mat-form-field appearance="fill">
<mat-label>xmax</mat-label>
<input matInput type="number" (change)="OnIQxmaxChange()" [value]="iqxmax" [(ngModel)]="iqxmax" min="iqmin" [max]="iqmax">
</mat-form-field>
</div>
<div class="form-group" fxFlex="25%">
<mat-form-field appearance="fill">
<mat-label>ymin</mat-label>
<input matInput type="number" (change)="OnIQyminChange()" [value]="iqymin" [(ngModel)]="iqymin" min="iqmin" [max]="iqmax">
</mat-form-field>
</div>
<div class="form-group" fxFlex="25%">
<mat-form-field appearance="fill">
<mat-label>ymax</mat-label>
<input matInput type="number" (change)="OnIQymaxChange()" [value]="iqymax" [(ngModel)]="iqymax" min="iqmin" [max]="iqmax">
</mat-form-field>
</div>
</div>
</div>
</mat-card-content>
</mat-card>
</mat-grid-tile> <!-- end of iq area -->
</mat-grid-list>
</div>

View File

@@ -1,584 +0,0 @@
import { Component, EventEmitter, OnDestroy, OnInit, Output, QueryList, ViewChildren } from "@angular/core";
import { Chart, ChartConfiguration } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts';
import { Subscription } from 'rxjs';
import { IGraphDesc, IScopeDesc, IScopeGraphType, ISigDesc, ScopeApi } from 'src/app/api/scope.api';
import { arraybuf_data_offset, Message, WebSocketService, webSockSrc } from "src/app/services/websocket.service";
export interface RxScopeMessage {
msgtype: number;
chartid: number;
dataid: number;
segnum: number;
update: boolean;
content: ArrayBuffer;
}
const deserialize = (fullbuff: ArrayBuffer): RxScopeMessage => {
const header = new DataView(fullbuff, 0, arraybuf_data_offset);
return {
// source: src.getUint8(0), //header
msgtype: header.getUint8(1), //header
chartid: header.getUint8(3), //header
dataid: header.getUint8(4), //header
segnum: header.getUint8(2), //header
update: (header.getUint8(5) == 1) ? true : false, //header
content: fullbuff.slice(arraybuf_data_offset) // data
};
}
const serialize = (msg: TxScopeMessage): ArrayBuffer => {
const byteArray = new TextEncoder().encode(msg.content);
let arr = new Uint8Array(byteArray.byteLength + arraybuf_data_offset);
arr.set(byteArray, arraybuf_data_offset) //data
let buffview = new DataView(arr.buffer);
buffview.setUint8(1, msg.msgtype); //header
return buffview.buffer;
}
export interface TxScopeMessage {
msgtype: number;
content: string;
}
/*------------------------------------*/
/* constants that must match backend (websrv.h or phy_scope.h) */
const SCOPEMSG_TYPE_STATUSUPD = 1;
const SCOPEMSG_TYPE_REFRATE = 2;
const SCOPEMSG_TYPE_TIME = 3;
const SCOPEMSG_TYPE_DATA = 10;
const SCOPEMSG_TYPE_DATAACK = 11;
const SCOPEMSG_DATA_IQ = 1;
const SCOPEMSG_DATA_LLR = 2;
const SCOPEMSG_DATA_WF = 3;
/*---------------------------------------*/
@Component({
selector: 'app-scope',
templateUrl: './scope.component.html',
styleUrls: ['./scope.component.css'],
})
export class ScopeComponent implements OnInit, OnDestroy {
//data for scope status area
scopetitle = '';
scopesubtitle = '';
scopetime = '';
scopestatus = 'stopped';
//data for scope control area
startstop = 'start';
startstop_color = 'warn';
rfrate = 2;
data_ACK = false;
//data for scope iq constellation area
iqgraph_list: IGraphDesc[] = [];
selected_channels = [""];
iqmax = 32767;
iqmin = -32767;
iqxmin = this.iqmin;
iqymin = this.iqmin;
iqxmax = this.iqmax;
iqymax = this.iqmax;
//data for scope LLR area
llrgraph_list: IGraphDesc[] = [];
selected_llrchannels = [""];
sig_list: ISigDesc[] = [{ target_id: 0, antenna_id: 0 },
{ target_id: 1, antenna_id: 0 },
{ target_id: 2, antenna_id: 0 },
{ target_id: 3, antenna_id: 0 },
];
selected_sig: ISigDesc = { target_id: 0, antenna_id: 0 };
llrythresh = 5;
llrmin = 0;
llrmax = 200000;
llrxmin = this.llrmin;
llrxmax = this.llrmax;
//data for scope WatterFall area
WFgraph_list: IGraphDesc[] = [];
selected_WF = "";
llrchart?: Chart;
iqcchart?: Chart;
wfchart?: Chart;
nwf: number[] = [0, 0, 0, 0];
// websocket service object and related subscription for message reception
wsSubscription?: Subscription;
@Output() ScopeEnabled = new EventEmitter<boolean>();
@ViewChildren(BaseChartDirective) charts?: QueryList<BaseChartDirective>;
public IQDatasets: ChartConfiguration<'scatter'>['data']['datasets'] = [
{
data: [],
label: 'C1',
pointRadius: 0.5,
showLine: false,
animation: false,
fill: false,
pointStyle: 'circle',
pointBackgroundColor: 'yellow',
backgroundColor: 'yellow',
borderWidth: 0,
pointBorderColor: 'yellow',
// parsing: false,
},
{
data: [],
label: 'C2',
pointRadius: 0.5,
showLine: false,
animation: false,
pointStyle: 'circle',
pointBackgroundColor: 'cyan',
backgroundColor: 'cyan',
borderWidth: 0,
pointBorderColor: 'cyan',
// parsing: false,
},
{
data: [],
label: 'C3',
pointRadius: 0.5,
showLine: false,
animation: false,
pointStyle: 'circle',
pointBackgroundColor: 'red',
backgroundColor: 'red',
borderWidth: 0,
pointBorderColor: 'red',
// parsing: false,
}
];
public LLRDatasets: ChartConfiguration<'scatter'>['data']['datasets'] = [
{
data: [],
label: 'LLR1',
pointRadius: 0.5,
showLine: false,
animation: false,
fill: false,
pointStyle: 'circle',
pointBackgroundColor: 'yellow',
backgroundColor: 'yellow',
borderWidth: 0,
pointBorderColor: 'yellow',
// parsing: false,
},
{
data: [],
label: 'LL2',
pointRadius: 0.5,
showLine: false,
animation: false,
pointStyle: 'circle',
pointBackgroundColor: 'cyan',
backgroundColor: 'cyan',
borderWidth: 0,
pointBorderColor: 'cyan',
parsing: false,
},
{
data: [],
label: 'LLR3',
pointRadius: 0.5,
showLine: false,
animation: false,
pointStyle: 'circle',
pointBackgroundColor: 'red',
backgroundColor: 'red',
borderWidth: 0,
pointBorderColor: 'red',
parsing: false,
}
];
public WFDatasets: ChartConfiguration<'scatter'>['data']['datasets'] = [
{
data: [],
label: 'WFblue',
pointRadius: 0.5,
showLine: false,
animation: false,
fill: false,
pointStyle: 'circle',
pointBackgroundColor: 'blue',
backgroundColor: 'blue',
borderWidth: 0,
pointBorderColor: 'blue',
// parsing: false,
},
{
data: [],
label: 'WFgreen',
pointRadius: 0.5,
showLine: false,
animation: false,
pointStyle: 'circle',
pointBackgroundColor: 'green',
backgroundColor: 'green',
borderWidth: 0,
pointBorderColor: 'green',
// parsing: false,
},
{
data: [],
label: 'WFyellow',
pointRadius: 0.5,
showLine: false,
animation: false,
pointStyle: 'circle',
pointBackgroundColor: 'yellow',
backgroundColor: 'yellow',
borderWidth: 0,
pointBorderColor: 'yellow',
// parsing: false,
},
{
data: [],
label: 'WFred',
pointRadius: 0.5,
showLine: false,
animation: false,
pointStyle: 'circle',
pointBackgroundColor: 'red',
backgroundColor: 'red',
borderWidth: 0,
pointBorderColor: 'red',
// parsing: false,
}
];
public IQOptions: ChartConfiguration<'scatter'>['options'] = {
responsive: true,
aspectRatio: 1,
// scales: {
// xAxes: {
// min: -5,
// max:5,
// }
// },
plugins: { legend: { display: true, labels: { boxWidth: 10, boxHeight: 10 } }, tooltip: { enabled: false, }, },
};
public LLROptions: ChartConfiguration<'scatter'>['options'] = {
responsive: true,
aspectRatio: 3,
scales: {
xAxes: {
min: 0,
},
// yAxes: {
// min: -100,
// max: 100
// }
},
plugins: { legend: { display: true, labels: { boxWidth: 10, boxHeight: 10 } }, tooltip: { enabled: false, }, },
};
public WFOptions: ChartConfiguration<'scatter'>['options'] = {
responsive: true,
aspectRatio: 5,
scales: {
xAxes: {
min: 0,
// max:800,
},
yAxes: {
min: 0,
max: 80,
reverse: true,
}
},
plugins: { legend: { display: true, labels: { boxWidth: 10, boxHeight: 10 } }, tooltip: { enabled: false, }, },
}
constructor(
private scopeApi: ScopeApi,
private wsService: WebSocketService
) {
console.log("Scope constructor ");
}
ngOnInit() {
console.log("Scope ngOnInit ");
this.scopeApi.getScopeInfos$().subscribe(resp => {
this.configScope(resp);
});
}
ngOnDestroy() {
console.log("Scope ngOnDestroy ");
this.wsSubscription?.unsubscribe();
}
DecodScopeBinmsgToString(message: ArrayBuffer) {
const enc = new TextDecoder("utf-8");
return enc.decode(message);
}
private configScope(resp: IScopeDesc) {
if (resp.title === "none") {
this.ScopeEnabled.emit(false);
} else {
this.ScopeEnabled.emit(true);
this.scopetitle = resp.title;
this.iqgraph_list.length = 0;
this.llrgraph_list.length = 0;
for (let graphIndex = 0; graphIndex < resp.graphs.length; graphIndex++) {
if (resp.graphs[graphIndex].type == IScopeGraphType.IQs) {
this.iqgraph_list.push(resp.graphs[graphIndex]);
this.IQDatasets[this.iqgraph_list.length - 1].label = resp.graphs[graphIndex].title;
}
if (resp.graphs[graphIndex].type == IScopeGraphType.LLR) {
this.llrgraph_list.push(resp.graphs[graphIndex]);
this.LLRDatasets[this.llrgraph_list.length - 1].label = resp.graphs[graphIndex].title;
}
if (resp.graphs[graphIndex].type == IScopeGraphType.WF) {
this.WFgraph_list.push(resp.graphs[graphIndex]);
}
}
this.charts?.forEach((child) => {
child.chart?.update()
});
}
}
private ProcessScopeMsg(message: RxScopeMessage) {
if (this.scopestatus === "starting") {
this.scopestatus = 'started';
this.startstop = 'stop';
this.startstop_color = 'started';
}
let d = 0;
let x = 0;
let y = 0;
switch (message.msgtype) {
case SCOPEMSG_TYPE_TIME:
this.scopetime = this.DecodScopeBinmsgToString(message.content);
break;
case SCOPEMSG_TYPE_DATA:
const bufferview = new DataView(message.content);
switch (message.chartid) {
case SCOPEMSG_DATA_IQ:
this.IQDatasets[message.dataid].data.length = 0;
if (message.update) {
console.log("Starting scope update chart " + message.chartid.toString() + ", dataset " + message.dataid.toString());
}
for (let i = 0; i < bufferview.byteLength; i = i + 4) {
this.IQDatasets[message.dataid].data[i / 4] = { x: bufferview.getInt16(i, true), y: bufferview.getInt16(i + 2, true) };
}
if (message.update) {
this.iqcchart!.update();
}
break;
case SCOPEMSG_DATA_LLR:
if (message.update) {
console.log("Starting scope update chart " + message.chartid.toString() + ", dataset " + message.dataid.toString());
}
this.LLRDatasets[message.dataid].data.length = 0;
let xoffset = 0;
d = 0;
for (let i = 4; i < (bufferview.byteLength - 2); i = i + 4) {
xoffset = xoffset + bufferview.getInt16(i + 2, true);
this.LLRDatasets[message.dataid].data[d] = { x: xoffset, y: bufferview.getInt16(i, true) };
d++;
}
this.LLRDatasets[message.dataid].data[d] = { x: bufferview.getInt32(0, true), y: 0 };
if (message.update) {
this.llrchart!.update();
}
break;
case SCOPEMSG_DATA_WF:
if (message.update) {
console.log("Starting scope update chart " + message.chartid.toString() + ", dataset " + message.dataid.toString());
if (message.segnum == 0) {
for (let i = 0; i < this.WFDatasets.length; i++) {
this.nwf[i] = 0;
this.WFDatasets[i].data.length = 0;
}
}
}
for (let i = 2; i < bufferview.byteLength - 2; i = i + 4) {// first 16 bits in buffer contains the number of points in the message
x = bufferview.getInt16(i, true);
y = bufferview.getInt16(i + 2, true);
this.wfchart!.scales.xAxes.max = bufferview.getInt16(bufferview.byteLength - 4, true);
this.WFDatasets[message.dataid].data[this.nwf[message.dataid]] = { x: x, y: y };
this.nwf[message.dataid]++;
}
if (message.update) {
this.wfchart!.update();
console.log(" scope update completed " + d.toString() + "points, ");
}
break;
default:
break;
}
this.sendMsg(SCOPEMSG_TYPE_DATAACK, "Chart " + message.chartid.toString() + ", dataset " + message.dataid.toString());
break;
default:
break;
}
}
private sendMsg(type: number, strmessage: string) {
this.wsService.send({
source: webSockSrc.softscope,
fullbuff: serialize({
msgtype: type,
content: strmessage
})
});
console.log("Scope sent msg type " + type.toString() + " " + strmessage);
}
private SendScopeParams(name: string, value: string, graphid: number) {
this.scopeApi.setScopeParams$({ name: name, value: value, graphid: graphid }).subscribe();
}
startorstop() {
if (this.scopestatus === 'stopped') {
this.scopeApi.setScopeParams$({ name: "startstop", value: "start" }).subscribe(
() => {
this.llrchart = Chart.getChart("llr");
this.iqcchart = Chart.getChart("iqc");
this.wfchart = Chart.getChart("wf");
this.IQDatasets.forEach((dataset) => { dataset.data.length = 0 });
this.LLRDatasets.forEach((dataset) => { dataset.data.length = 0 });
this.charts?.forEach((child, index) => { child.chart?.update() });
this.scopestatus = 'starting';
this.SigChanged(this.selected_sig.target_id);
this.OnRefrateChange();
this.OnIQxminChange();
this.OnIQxmaxChange();
this.OnIQyminChange();
this.OnIQymaxChange();
this.OnYthreshChange();
this.OnLLRxminChange();
this.OnLLRxmaxChange();
this.channelsChanged(this.selected_channels);
this.llrchannelsChanged(this.selected_llrchannels);
this.WFChanged(this.selected_WF);
for (let i = 0; i < this.WFDatasets.length; i++) {
this.nwf[i] = 0;
this.WFDatasets[i].data.length = 0;
}
this.wsSubscription = this.wsService.subject$.subscribe(
(msg: Message) => this.ProcessScopeMsg(deserialize(msg.fullbuff))
)
},
err => {
}
);
} else {
this.scopeApi.setScopeParams$({ name: "startstop", value: "stop" }).subscribe(
() => {
if (this.wsSubscription)
this.wsSubscription.unsubscribe();
this.scopestatus = 'stopped';
this.startstop = 'start';
this.startstop_color = 'warn';
this.charts?.forEach((child, index) => { child.chart?.update() });
},
err => {
}
);
}
}
OnRefrateChange() {
this.SendScopeParams("refrate", (this.rfrate * 10).toString(), 0);
}
OnLLRxminChange() {
this.SendScopeParams("llrxmin", (this.llrxmin).toString(), 0);
}
OnLLRxmaxChange() {
this.SendScopeParams("llrxmax", (this.llrxmax).toString(), 0);
}
OnIQxminChange() {
this.SendScopeParams("xmin", (this.iqxmin).toString(), 0);
}
OnIQxmaxChange() {
this.SendScopeParams("xmax", (this.iqxmax).toString(), 0);
}
OnIQyminChange() {
this.SendScopeParams("ymin", (this.iqymin).toString(), 0);
}
OnIQymaxChange() {
this.SendScopeParams("ymax", (this.iqymax).toString(), 0);
}
channelsChanged(titles: string[]) {
this.selected_channels = titles;
this.iqgraph_list.forEach(graph => {
const [enabled] = titles.filter(value => graph.title === value)
this.SendScopeParams("enabled", enabled ? "true" : "false", graph.srvidx);
})
}
llrchannelsChanged(titles: string[]) {
this.selected_llrchannels = titles;
this.llrgraph_list.forEach(graph => {
const [enabled] = titles.filter(value => graph.title === value)
this.SendScopeParams("enabled", enabled ? "true" : "false", graph.srvidx);
})
}
SigChanged(value: number) {
this.selected_sig.target_id = value;
if (this.scopetitle === "gNB")
this.scopesubtitle = " - sig from UE" + value.toString() + " antenna" + this.selected_sig.antenna_id;
else
this.scopesubtitle = " - sig from gNB" + value.toString() + " antenna" + this.selected_sig.antenna_id;;
this.SendScopeParams("TargetSelect", value.toString(), 0);
}
WFChanged(value: string) {
this.selected_WF = value;
for (let i = 0; i < this.WFgraph_list.length; i++) {
if (this.WFgraph_list[i].title === value) {
this.SendScopeParams("enabled", "true", this.WFgraph_list[i].srvidx);
this.WFDatasets[0].label = value;
this.WFDatasets[1].label = "(>avg*2)";
this.WFDatasets[2].label = "(>avg*10)";
this.WFDatasets[3].label = "(>avg*100)";
} else {
this.SendScopeParams("enabled", "false", this.WFgraph_list[i].srvidx);
}
}
for (let i = 0; i < this.WFDatasets.length; i++) {
this.nwf[i] = 0;
this.WFDatasets[i].data.length = 0;
}
}
onDataACKchange() {
this.SendScopeParams("DataAck", this.data_ACK.toString(), 0);
}
OnYthreshChange() {
this.SendScopeParams("llrythresh", this.llrythresh.toString(), 0);
}
}

View File

@@ -1,95 +0,0 @@
import { UntypedFormArray, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { Subscription } from 'rxjs';
import { Observable } from 'rxjs/internal/Observable';
import { ICommand, ICommandOptions, IQuestion } from 'src/app/api/commands.api';
const enum CmdFCN {
name = 'name',
vars = 'variables',
confirm = 'confirm',
answer = "answer"
}
export class CmdCtrl extends UntypedFormGroup {
confirm?: string
question?: IQuestion
cmdname: string
options?: ICommandOptions[]
public ResUpdTimer?: Observable<number>
public ResUpdTimerSubscriber?: Subscription
updbtnname: string
constructor(cmd: ICommand) {
super({});
this.addControl(CmdFCN.name, new UntypedFormControl(cmd.name));
this.addControl(CmdFCN.answer, new UntypedFormControl(""));
this.addControl(CmdFCN.vars, new UntypedFormArray([]));
this.confirm = cmd.confirm;
this.question = cmd.question;
this.cmdname = cmd.name;
this.options = cmd.options;
this.updbtnname = "Start update"
}
api() {
const doc: ICommand = {
name: this.nameFC.value,
param: this.question
? { name: this.question!.pname, value: this.answerFC.value, type: this.question!.type, modifiable: false }
: undefined,
options: this.options
};
return doc;
}
isResUpdatable(): boolean {
if (this.options) {
for (let opt = 0; opt < this.options.length; opt++) {
if (this.options[opt] == ICommandOptions.update)
return true;
}
} else {
return false;
}
return false;
}
stopUpdate() {
if (this.ResUpdTimerSubscriber) {
this.ResUpdTimerSubscriber.unsubscribe();
this.updbtnname = "Start update"
}
}
startUpdate() {
if (this.ResUpdTimerSubscriber && this.ResUpdTimer) {
this.ResUpdTimerSubscriber = this.ResUpdTimer.subscribe();
this.updbtnname = "Stop update"
}
}
get nameFC() {
return this.get(CmdFCN.name) as UntypedFormControl;
}
set nameFC(fc: UntypedFormControl) {
this.setControl(CmdFCN.name, fc);
}
get answerFC() {
return this.get(CmdFCN.answer) as UntypedFormControl;
}
get varsFA() {
return this.get(CmdFCN.vars) as UntypedFormArray;
}
set varsFA(fa: UntypedFormArray) {
this.setControl(CmdFCN.vars, fa);
}
}

View File

@@ -1,74 +0,0 @@
import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { IInfo } from '../api/commands.api';
import { IArgType } from '../api/commands.api';
const enum InfosFCN {
name = 'name',
value = "value",
type = "type",
modifiable = "modifiable"
}
export class InfoCtrl extends UntypedFormGroup {
type: IArgType;
constructor(ivar: IInfo) {
super({});
this.type = ivar.type;
this.addControl(InfosFCN.name, new UntypedFormControl(ivar.name));
this.addControl(InfosFCN.value, new UntypedFormControl(ivar.value));
this.addControl(InfosFCN.type, new UntypedFormControl(ivar.type));
this.addControl(InfosFCN.modifiable, new UntypedFormControl(ivar.modifiable));
}
api() {
const doc: IInfo = {
name: this.nameFC.value,
value: String(this.valueFC.value), //FIXME
type: this.typeFC.value,
modifiable: this.modifiableFC.value
};
return doc;
}
get nameFC() {
return this.get(InfosFCN.name) as UntypedFormControl;
}
set nameFC(control: UntypedFormControl) {
this.setControl(InfosFCN.name, control);
}
get valueFC() {
return this.get(InfosFCN.value) as UntypedFormControl;
}
set valueFC(control: UntypedFormControl) {
this.setControl(InfosFCN.value, control);
}
get typeFC() {
return this.get(InfosFCN.type) as UntypedFormControl;
}
set typeFC(control: UntypedFormControl) {
this.setControl(InfosFCN.type, control);
}
get modifiableFC() {
return this.get(InfosFCN.modifiable) as UntypedFormControl;
}
set modifiableFC(control: UntypedFormControl) {
this.setControl(InfosFCN.modifiable, control);
}
get btnTxtFC() {
if (this.type != IArgType.configfile)
return "set"
else
return "download"
}
}

View File

@@ -1,38 +0,0 @@
import { UntypedFormArray, UntypedFormGroup } from '@angular/forms';
import { IModule } from '../api/commands.api';
const enum ModuleFCN {
vars = 'variables',
cmds = 'commands'
}
export class ModuleCtrl extends UntypedFormGroup {
name: string
constructor(imodule: IModule) {
super({})
this.name = imodule.name
this.addControl(ModuleFCN.vars, new UntypedFormArray([]))
this.addControl(ModuleFCN.cmds, new UntypedFormArray([]))
}
get varsFA() {
return this.get(ModuleFCN.vars) as UntypedFormArray;
}
set varsFA(fa: UntypedFormArray) {
this.setControl(ModuleFCN.vars, fa);
}
get cmdsFA() {
return this.get(ModuleFCN.cmds) as UntypedFormArray;
}
set cmdsFA(fa: UntypedFormArray) {
this.setControl(ModuleFCN.cmds, fa);
}
}

View File

@@ -1,67 +0,0 @@
import { UntypedFormControl, UntypedFormGroup } from "@angular/forms";
import { IArgType, IColumn, IParam } from "../api/commands.api";
enum ParamFCN {
value = 'value',
}
export class ParamCtrl extends UntypedFormGroup {
col: IColumn
constructor(public param: IParam) {
super({})
this.col = param.col
let control: UntypedFormControl
switch (param.col.type) {
case IArgType.boolean:
control = new UntypedFormControl((param.value === 'true') ? true : false);
break;
case IArgType.loglvl:
control = new UntypedFormControl(param.value);
break;
default:
control = new UntypedFormControl(param.value)
}
if (!param.col.modifiable) control.disable()
this.addControl(ParamFCN.value, control)
}
get valueFC() {
return this.get(ParamFCN.value) as UntypedFormControl
}
set valueFC(fc: UntypedFormControl) {
this.setControl(ParamFCN.value, fc);
}
api() {
let value: string
switch (this.col.type) {
case IArgType.boolean:
value = String(this.valueFC.value);
break;
default:
value = this.valueFC.value
}
const doc: IParam = {
value: value,
col: this.col
}
return doc
}
}

View File

@@ -1,51 +0,0 @@
import { UntypedFormArray, FormControl, UntypedFormGroup } from '@angular/forms';
import { IArgType, IParam, IRow } from '../api/commands.api';
import { ParamCtrl } from './param.control';
enum RowFCN {
paramsFA = 'params',
}
export class RowCtrl extends UntypedFormGroup {
cmdName: string
rawIndex: number
constructor(row: IRow) {
super({})
this.cmdName = row.cmdName
this.rawIndex = row.rawIndex
this.addControl(RowFCN.paramsFA, new UntypedFormArray(row.params.map(param => new ParamCtrl(param))))
}
get paramsFA() {
return this.get(RowFCN.paramsFA) as UntypedFormArray
}
set paramsFA(fa: UntypedFormArray) {
this.setControl(RowFCN.paramsFA, fa);
}
get paramsCtrls(): ParamCtrl[] {
return this.paramsFA.controls as ParamCtrl[]
}
api() {
const doc: IRow = {
rawIndex: this.rawIndex,
cmdName: this.cmdName,
params: this.paramsCtrls.map(control => control.api())
}
return doc
}
}

View File

@@ -1,74 +0,0 @@
import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { IInfo } from '../api/commands.api';
import { IArgType } from '../api/commands.api';
const enum VariablesFCN {
name = 'name',
value = "value",
type = "type",
modifiable = "modifiable"
}
export class VarCtrl extends UntypedFormGroup {
type: IArgType;
constructor(ivar: IInfo) {
super({});
this.type = ivar.type;
this.addControl(VariablesFCN.name, new UntypedFormControl(ivar.name));
this.addControl(VariablesFCN.value, new UntypedFormControl(ivar.value));
this.addControl(VariablesFCN.type, new UntypedFormControl(ivar.type));
this.addControl(VariablesFCN.modifiable, new UntypedFormControl(ivar.modifiable));
}
api() {
const doc: IInfo = {
name: this.nameFC.value,
value: String(this.valueFC.value), //FIXME
type: this.typeFC.value,
modifiable: this.modifiableFC.value
};
return doc;
}
get nameFC() {
return this.get(VariablesFCN.name) as UntypedFormControl;
}
set nameFC(control: UntypedFormControl) {
this.setControl(VariablesFCN.name, control);
}
get valueFC() {
return this.get(VariablesFCN.value) as UntypedFormControl;
}
set valueFC(control: UntypedFormControl) {
this.setControl(VariablesFCN.value, control);
}
get typeFC() {
return this.get(VariablesFCN.type) as UntypedFormControl;
}
set typeFC(control: UntypedFormControl) {
this.setControl(VariablesFCN.type, control);
}
get modifiableFC() {
return this.get(VariablesFCN.modifiable) as UntypedFormControl;
}
set modifiableFC(control: UntypedFormControl) {
this.setControl(VariablesFCN.modifiable, control);
}
get btnTxtFC() {
if (this.type != IArgType.configfile)
return "set"
else
return "download"
}
}

View File

@@ -1,55 +0,0 @@
import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { DialogService as DialogService } from '../services/dialog.service';
@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
constructor(public dialogService: DialogService) { }
intercept(request: HttpRequest<unknown>, next: HttpHandler) {
return next.handle(request).pipe(
// tap((event: HttpEvent<any>) => {
// if (event instanceof HttpResponse) {
// switch (event.status) {
// case 200:
// case 201:
// this.log(GREEN, request.method + ' ' + event.status + ' Success');
// this.dialogService.openSnackBar(request.method + ' ' + event.status + ' Success');
// break;
// default:
// break;
// }
// // return throwError(event.body);
// }
// }),
catchError((error: HttpErrorResponse) => {
switch (error.status) {
case 400:
case 403:
case 501:
case 500:
this.log(YELLOW, request.method + ' ' + error.status + ' Error: ' + error.error);
this.dialogService.openErrorDialog(error);
break;
default:
break;
}
return throwError(error.error);
}),
);
}
private log = (color: string, txt: string) => console.log(color, '[API] ' + txt);
}
const RED = '\x1b[31m%s\x1b[0m';
const GREEN = '\x1b[32m%s\x1b[0m';
const YELLOW = '\x1b[33m%s\x1b[0m';
const MAGENTA = '\x1b[35m%s\x1b[0m';
const CYAN = '\x1b[36m%s%s\x1b[0m';

View File

@@ -1,8 +0,0 @@
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ErrorInterceptor } from './error.interceptor';
import { SpinnerInterceptor } from './spinner.interceptor';
export const InterceptorProviders = [
{ provide: HTTP_INTERCEPTORS, useClass: SpinnerInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
];

Some files were not shown because too many files have changed in this diff Show More