Compare commits
27 Commits
v1.1-stabl
...
bafef9c51c
Author | SHA1 | Date | |
---|---|---|---|
bafef9c51c | |||
196f7ae5a2 | |||
8813488df8 | |||
6464cda437 | |||
3537965393 | |||
a4214fd007 | |||
a5a9b0c4e5 | |||
790bfc06c2 | |||
cbd2adc1c8 | |||
1b8fd0d0bc | |||
e3a4bb8256 | |||
90c02eb63a | |||
e313027759 | |||
136d8dbb5b | |||
456faedf7d | |||
2c9d513613 | |||
46497bfda0 | |||
0982544c2e | |||
5a94f9a4fd | |||
4df06ee57b | |||
670780e328 | |||
25a3b11ba8 | |||
bf2d374705 | |||
a7242c186d | |||
44aec3a114 | |||
872b5e7b3d | |||
fc121c51b2 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,3 +5,7 @@ cert.pem
|
||||
key.pem
|
||||
dh.pem
|
||||
/web-action
|
||||
|
||||
# эти файлы после генерации должны быть перемещены в `/static`
|
||||
front-generator/main-scpc.html
|
||||
front-generator/main-tdma.html
|
||||
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "dependencies/control_system_client"]
|
||||
path = dependencies/control_system_client
|
||||
url = http://10.8.0.18/mf-tdma/protocol_processing/control_system_client.git
|
@@ -25,12 +25,31 @@ else()
|
||||
message(FATAL_ERROR "You must set `MODEM_TYPE` \"SCPC\" or \"TDMA\"!")
|
||||
endif()
|
||||
|
||||
add_compile_options(-Wall -Wextra -Wsign-conversion)
|
||||
SET(PROJECT_GIT_REVISION "0")
|
||||
FIND_PACKAGE(Git)
|
||||
IF (GIT_FOUND)
|
||||
EXECUTE_PROCESS (
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_HEAD
|
||||
# ERROR_VARIABLE ERROR_RESULT
|
||||
# RESULT_VARIABLE INFO_RESULT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
IF ( ${GIT_HEAD} MATCHES "^.+$" )
|
||||
STRING ( SUBSTRING ${GIT_HEAD} 0 8 VERSION_REVISION )
|
||||
SET ( PROJECT_GIT_REVISION ${VERSION_REVISION} )
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
add_compile_options(-Wall -Wextra -Wsign-conversion -DPROJECT_GIT_REVISION="${PROJECT_GIT_REVISION}")
|
||||
|
||||
# максимальный размер тела запроса 200mb
|
||||
add_definitions(-DHTTP_MAX_PAYLOAD=200000000)
|
||||
|
||||
add_subdirectory(dependencies/control_system)
|
||||
add_subdirectory(dependencies/control_system_client)
|
||||
|
||||
add_executable(terminal-web-server
|
||||
src/server/mime_types.hpp
|
||||
|
36
dependencies/control_system/CMakeLists.txt
vendored
36
dependencies/control_system/CMakeLists.txt
vendored
@@ -1,36 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
project(terminal)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 3.2)
|
||||
set(UPDATE_DISCONNECTED_IF_AVAILABLE "")
|
||||
else()
|
||||
set(UPDATE_DISCONNECTED_IF_AVAILABLE "UPDATE_DISCONNECTED 1")
|
||||
endif()
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
set(CMAKE_CXX_FLAGS -fPIC)
|
||||
|
||||
set(default_build_type "Release")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG ")
|
||||
message(${CMAKE_CXX_FLAGS})
|
||||
message("CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE})
|
||||
|
||||
message(${CMAKE_CXX_FLAGS})
|
||||
|
||||
add_library(terminal-client-api STATIC
|
||||
client/main.cpp
|
||||
client/sock_client.cpp
|
||||
client/system_client.cpp
|
||||
)
|
||||
|
||||
target_include_directories(terminal-client-api PUBLIC "include/")
|
||||
|
||||
find_package(Boost 1.53.0 COMPONENTS system log log_setup REQUIRED)
|
||||
find_package(cereal REQUIRED)
|
||||
target_link_libraries(terminal-client-api ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} cereal::cereal)
|
||||
target_include_directories(terminal-client-api PRIVATE ${Boost_INCLUDE_DIR})
|
1495
dependencies/control_system/client/main.cpp
vendored
1495
dependencies/control_system/client/main.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,51 +0,0 @@
|
||||
#include "sock_client.h"
|
||||
|
||||
client::client(boost::asio::io_context & io_context, const std::string & unix_file, std::function<void(const std::vector<uint8_t>&)> func_cb)
|
||||
: socket_(io_context)
|
||||
, callback_func(func_cb)
|
||||
{
|
||||
socket_.async_connect(seq_packet::seqpacket_protocol::endpoint(unix_file),
|
||||
std::bind(&client::handle_connect, this,
|
||||
std::placeholders::_1));
|
||||
}
|
||||
|
||||
client::~client()
|
||||
{
|
||||
do_close();
|
||||
}
|
||||
|
||||
void client::write(const std::vector<uint8_t> & data)
|
||||
{
|
||||
boost::asio::write(socket_, boost::asio::buffer(data));
|
||||
}
|
||||
|
||||
void client::do_close()
|
||||
{
|
||||
socket_.close();
|
||||
}
|
||||
|
||||
void client::start()
|
||||
{
|
||||
seq_packet::seqpacket_protocol::socket::message_flags in_flags { MSG_WAITALL };
|
||||
socket_.async_receive(boost::asio::buffer(data_), in_flags,
|
||||
std::bind(&client::handle_read, this,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2));
|
||||
}
|
||||
|
||||
void client::handle_connect(const boost::system::error_code & error)
|
||||
{
|
||||
if (!error)
|
||||
start();
|
||||
}
|
||||
|
||||
void client::handle_read(const boost::system::error_code & error, size_t bytes_transferred)
|
||||
{
|
||||
if (!error && callback_func && bytes_transferred)
|
||||
{
|
||||
callback_func(std::vector<uint8_t>(std::begin(data_), std::begin(data_) + bytes_transferred));
|
||||
start();
|
||||
}
|
||||
//else
|
||||
// do_close();
|
||||
}
|
24
dependencies/control_system/client/sock_client.h
vendored
24
dependencies/control_system/client/sock_client.h
vendored
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include "../common/seq_packet.h"
|
||||
|
||||
class client
|
||||
{
|
||||
public:
|
||||
client(boost::asio::io_context & io_context, const std::string & unix_file, std::function<void(const std::vector<uint8_t>&)> func_cb = nullptr);
|
||||
~client();
|
||||
|
||||
void write(const std::vector<uint8_t> & data);
|
||||
void do_close();
|
||||
|
||||
private:
|
||||
client(const client&) = delete;
|
||||
const client& operator=(const client&) = delete;
|
||||
|
||||
seq_packet::seqpacket_protocol::socket socket_;
|
||||
std::array<uint8_t, 2000> data_;
|
||||
std::function<void(const std::vector<uint8_t>&)> callback_func;
|
||||
|
||||
void handle_connect(const boost::system::error_code & error);
|
||||
void handle_read(const boost::system::error_code & error, size_t bytes_transferred);
|
||||
void start();
|
||||
};
|
1038
dependencies/control_system/client/system_client.cpp
vendored
1038
dependencies/control_system/client/system_client.cpp
vendored
File diff suppressed because it is too large
Load Diff
121
dependencies/control_system/client/system_client.h
vendored
121
dependencies/control_system/client/system_client.h
vendored
@@ -1,121 +0,0 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <any>
|
||||
#include "sock_client.h"
|
||||
#include "../common/protocol_commands.h"
|
||||
|
||||
enum class state
|
||||
{
|
||||
disconnected,
|
||||
connected,
|
||||
logged_in
|
||||
};
|
||||
|
||||
class system_client
|
||||
{
|
||||
public:
|
||||
system_client(const std::string & unix_file, std::function<void(const std::string&)> log_func = nullptr);
|
||||
~system_client();
|
||||
|
||||
state get_current_state() const;
|
||||
|
||||
response_type send_login_cmd (const std::string & username, const std::string & pass, access_rights & access);
|
||||
response_type send_logout_cmd ();
|
||||
response_type send_ping_cmd (const std::string & ip, size_t count);
|
||||
response_type send_traceroute_cmd (const std::string & ip);
|
||||
response_type send_show_interface_cmd(const interface_value & interface);
|
||||
response_type send_copy_cmd (const fm::side_description & src, const fm::side_description & dst);
|
||||
|
||||
response_type send_set_dem_freq_cmd(uint32_t freq);
|
||||
response_type send_get_dem_freq_cmd(uint32_t & freq);
|
||||
|
||||
response_type send_set_gain_param (const gain_value & interface_gain, double gain);
|
||||
response_type send_get_gain_param (const gain_value & interface_gain, double & gain);
|
||||
response_type send_radio_enable (const cmd_radio & enable_choice, bool enbl_);
|
||||
response_type send_modulator_param(const modulator_value & mod_val, uint32_t value);
|
||||
response_type send_get_modulator_param(const modulator_value & mod_val, uint32_t &value);
|
||||
response_type send_set_demodulator_param(const demodulator_value & demod_val, uint32_t value);
|
||||
response_type send_get_demodulator_param(const getdemodulator_value & demod_val, uint32_t &value);
|
||||
response_type send_zynq_cmd(const zynq_value & zynq_val, double & value);
|
||||
response_type send_network_settings(const network_value & cmd_netw, const std::string & value);
|
||||
response_type send_get_network_settings(const network_value & cmd_netw, std::string & value);
|
||||
response_type send_rollof_and_baudrate(double & rollof, double &baudrate);
|
||||
response_type send_get_level_dem(const cmd_level_dem & lvl_dem_val, double &value);
|
||||
response_type send_get_dma_debug(const cmd_get_dma_debugg_enum & dma_debug, std::string &value);
|
||||
response_type send_set_10g_config(const cmd_10g_config & _10g_config, std::string &value);
|
||||
response_type send_set_dma_debug(const cmd_dma_debugg & dma_debugg, std::string &value);
|
||||
response_type send_set_acm_params(const ACM_parameters_serv &acm_params);
|
||||
response_type send_get_acm_params(cmd_get_acm_param &acm_params);
|
||||
|
||||
response_type send_get_demodulator_state(demodulator_state_com &demodulator_state);
|
||||
response_type send_get_modulator_state(modulator_state_com &modulator_state);
|
||||
|
||||
response_type send_get_device_state(device_state_com &device_state);
|
||||
response_type send_get_cinc_state(CinC_state_com &cinc_state);
|
||||
|
||||
response_type send_set_modulator_settings(modulator_settings_com &settings);
|
||||
response_type send_set_demodulator_settings(demodulator_settings_com &settings);
|
||||
response_type send_get_modulator_settings(modulator_settings_com &settings);
|
||||
response_type send_get_demodulator_settings(demodulator_settings_com &settings);
|
||||
|
||||
response_type send_set_buc_lnb_settings(buc_lnb_settings_com &settings);
|
||||
response_type send_get_buc_lnb_settings(buc_lnb_settings_com &settings);
|
||||
|
||||
response_type send_set_dpdi_params(dpdi_parameters &dpdi_params);
|
||||
response_type send_get_dpdi_params(dpdi_parameters &dpdi_params);
|
||||
|
||||
response_type send_set_lbq_params(const uint32_t & tick_ms, const uint32_t & bucket_size);
|
||||
|
||||
response_type send_set_qos_params(const std::string &node, const name_classes_qos & class_qos);
|
||||
response_type send_get_qos_params(std::string &node, const name_classes_qos & class_qos);
|
||||
|
||||
response_type send_set_qos_settings_json(const std::string &json_string, bool is_enable);
|
||||
response_type send_get_qos_settings_json(std::string &json_string, bool &is_enable);
|
||||
|
||||
void set_stdout_callback(std::function<void(const char *, uint32_t)> cb);
|
||||
void abort();
|
||||
|
||||
private:
|
||||
system_client(const system_client&) = delete;
|
||||
const system_client& operator=(const system_client&) = delete;
|
||||
|
||||
boost::asio::io_context io_context;
|
||||
client clt;
|
||||
std::function<void(const std::string&)> log;
|
||||
std::thread ctx_thread;
|
||||
std::atomic<uint32_t> cmd_id;
|
||||
|
||||
std::mutex cb_mtx;
|
||||
std::function<void(const char *, uint32_t len)> stdout_cb;
|
||||
|
||||
std::mutex responses_mtx;
|
||||
std::map<uint32_t, std::queue<response_type>> responses;
|
||||
std::map<uint32_t, std::queue<std::any>> responses_data;
|
||||
std::condition_variable cv_resp;
|
||||
|
||||
state current_state;
|
||||
|
||||
std::mutex cmd_in_progress_mtx;
|
||||
|
||||
response_type wait_for_response (uint32_t id, const cmd_type & type, std::any & data);
|
||||
response_type wait_for_progressing_response(uint32_t c_id, const cmd_type & cmd_t);
|
||||
void process_response (uint32_t id, response_type resp, std::any && data);
|
||||
void data_received (const std::vector<uint8_t> & data);
|
||||
void send_abort (uint32_t id);
|
||||
|
||||
template<typename... Args>
|
||||
void send_to_socket(Args&&... args)
|
||||
{
|
||||
//TO-DO: need case for empty parameter pack?
|
||||
std::stringstream s;
|
||||
s << std::noskipws;
|
||||
{
|
||||
cereal::BinaryOutputArchive oarchive(s);
|
||||
oarchive(std::forward<Args>(args)...);
|
||||
}
|
||||
std::vector<uint8_t> data((std::istream_iterator<uint8_t>(s)), std::istream_iterator<uint8_t>());
|
||||
clt.write(data);
|
||||
|
||||
}
|
||||
};
|
@@ -1,865 +0,0 @@
|
||||
#pragma once
|
||||
#include <cereal/archives/binary.hpp>
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <cereal/types/string.hpp>
|
||||
|
||||
namespace fm
|
||||
{
|
||||
enum class side_type
|
||||
{
|
||||
local = 0,
|
||||
tftp = 1,
|
||||
config = 2
|
||||
};
|
||||
|
||||
struct side_description
|
||||
{
|
||||
side_type s_type;
|
||||
std::string filepath;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(s_type, filepath);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
enum class cmd_dma_debugg
|
||||
{
|
||||
start = 0,
|
||||
stop = 1,
|
||||
reset = 2,
|
||||
reinit = 3,
|
||||
modcod = 4,
|
||||
log_bool = 5,
|
||||
data_mode = 6,
|
||||
default_params = 7,
|
||||
buc_voltage = 8,
|
||||
lnb_voltage = 9,
|
||||
_10mhz_tx = 10,
|
||||
_10mhz_rx = 11,
|
||||
powerdown_plata = 12,
|
||||
_10MHz_out = 13,
|
||||
current_state_tx = 14,
|
||||
current_state_oib = 15,
|
||||
save_config = 16,
|
||||
begin_save_config = 17
|
||||
};
|
||||
|
||||
struct modulator_settings_com{
|
||||
uint32_t baudrate;
|
||||
double central_freq_in_kGz;
|
||||
double rollof;
|
||||
double attenuation;
|
||||
bool is_test_data;
|
||||
bool is_save_current_state;
|
||||
bool is_carrier;
|
||||
bool tx_is_on;
|
||||
bool is_cinc;
|
||||
uint32_t modcod_tx;
|
||||
};
|
||||
|
||||
struct modulator_state_com{
|
||||
bool is_tx_on;
|
||||
float snr_remote;
|
||||
uint16_t modcod;
|
||||
bool is_short;
|
||||
bool is_pilots;
|
||||
uint32_t speed_in_bytes_tx;
|
||||
uint32_t speed_in_bytes_tx_iface;
|
||||
};
|
||||
|
||||
struct demodulator_locks_com{
|
||||
bool pkt_sync;
|
||||
bool afc_lock;
|
||||
bool freq_lock;
|
||||
bool sym_sync_lock;
|
||||
};
|
||||
|
||||
struct demodulator_settings_com
|
||||
{
|
||||
uint32_t baudrate;
|
||||
double central_freq_in_kGz;
|
||||
double rollof;
|
||||
bool is_aru_on;
|
||||
bool is_rvt_iq;
|
||||
double gain;
|
||||
};
|
||||
|
||||
struct demodulator_state_com{
|
||||
float snr;
|
||||
uint16_t modcod;
|
||||
bool is_short;
|
||||
bool is_pilots;
|
||||
float rssi;
|
||||
double afc_err;
|
||||
double crs_freq_err;
|
||||
double sym_err;
|
||||
double fine_freq_err;
|
||||
double if_overload;
|
||||
uint32_t packet_ok_cnt;
|
||||
uint32_t packet_bad_cnt;;
|
||||
uint32_t dummy_cnt;
|
||||
uint32_t speed_in_bytes_rx;
|
||||
uint32_t speed_in_bytes_rx_iface;
|
||||
demodulator_locks_com locks;
|
||||
};
|
||||
|
||||
struct CinC_state_com{
|
||||
float ratio_signal_signal;
|
||||
bool carrier_lock;
|
||||
int32_t freq_error_offset;
|
||||
uint32_t delay_dpdi;
|
||||
int32_t freq_fine_estimate;
|
||||
uint32_t cnt_bad_lock;
|
||||
};
|
||||
|
||||
struct device_state_com{
|
||||
double adrv_temp;
|
||||
double zynq_temp;
|
||||
double pl_temp;
|
||||
};
|
||||
|
||||
enum class voltage_lnb_com{
|
||||
DISABLE = 0, _13V, _18V, _24V
|
||||
};
|
||||
enum class voltage_buc_com{
|
||||
DISABLE = 0, _24V, _48V
|
||||
};
|
||||
struct buc_lnb_settings_com
|
||||
{
|
||||
voltage_lnb_com lnb;
|
||||
bool is_ref_10MHz_lnb = false;
|
||||
voltage_buc_com buc;
|
||||
bool is_ref_10MHz_buc = false;
|
||||
bool is_ref_10MHz_output = false;
|
||||
bool is_save_current_state = false;
|
||||
};
|
||||
enum class name_classes_qos
|
||||
{
|
||||
realtime1 = 0,
|
||||
realtime2,
|
||||
realtime3,
|
||||
critical1,
|
||||
critical2,
|
||||
critical3,
|
||||
cir,
|
||||
pir,
|
||||
wcr1,
|
||||
wcr2,
|
||||
wcr3,
|
||||
enable,
|
||||
ful_node
|
||||
};
|
||||
|
||||
enum class cmd_get_dma_debugg_enum
|
||||
{
|
||||
speed_tx = 0,
|
||||
speed_rx = 1,
|
||||
modcod = 2,
|
||||
drop_bad_rx = 3,
|
||||
drop_full_rx = 4,
|
||||
packet_ok_rx = 5,
|
||||
packet_little_tx = 6,
|
||||
packet_big_tx = 7,
|
||||
bad_modcod_tx = 8,
|
||||
bad_length_tx = 9,
|
||||
reset_cnt_rx = 10,
|
||||
data_mode = 11,
|
||||
buc_voltage = 12,
|
||||
lnb_voltage = 13,
|
||||
_10mhz_tx = 14,
|
||||
_10mhz_rx = 15,
|
||||
powerdown_plata = 16,
|
||||
_10MHz_out = 17,
|
||||
current_state_tx = 18,
|
||||
real_dpdi_shift = 19,
|
||||
freq_error_offset = 20,
|
||||
freq_fine_estimate = 21,
|
||||
speed_tx_iface = 22,
|
||||
speed_rx_iface = 23,
|
||||
current_state_oib = 24,
|
||||
ratio_signal_signal = 25,
|
||||
status_init = 26
|
||||
};
|
||||
|
||||
enum class cmd_10g_config
|
||||
{
|
||||
udp_payload_lenght = 0,
|
||||
local_ip = 1,
|
||||
dest_ip = 2,
|
||||
gateway_ip = 3,
|
||||
subnet_mask = 4,
|
||||
udp_source_port = 5,
|
||||
udp_dest_port = 6,
|
||||
local_mac_31_0 = 7,
|
||||
local_mac_32_47 = 8,
|
||||
mtx_chan0 = 9,
|
||||
mtx_chan1 = 10
|
||||
};
|
||||
|
||||
enum class cmd_level_dem
|
||||
{
|
||||
//! ОСШ на входе
|
||||
snr = 0,
|
||||
//! RSSI на входе
|
||||
rssi = 1,
|
||||
sym_sync_lock = 2,
|
||||
freq_search_lock = 3,
|
||||
afc_lock = 4,
|
||||
pkt_sync = 5,
|
||||
phase_inv = 6,
|
||||
afc_error = 7,
|
||||
sym_error = 8,
|
||||
fine_freq_error = 9,
|
||||
crs_freq_error = 10,
|
||||
gc_gain_aru = 11,
|
||||
rollof = 12,
|
||||
carrier_lock = 13,
|
||||
filt_adapt_lock = 14,
|
||||
snr_acm = 15,
|
||||
modcod_tx = 16
|
||||
};
|
||||
|
||||
enum class interface_value
|
||||
{
|
||||
all = 0,
|
||||
sat0 = 1,
|
||||
gigabit = 2,
|
||||
modulator = 3,
|
||||
demodulator = 4
|
||||
};
|
||||
|
||||
enum class zynq_value
|
||||
{
|
||||
ps_volt = 0,
|
||||
pl_volt = 1,
|
||||
adrv_temp = 2,
|
||||
pl_temp = 3,
|
||||
ps_temp = 4,
|
||||
adrv_temp2 = 5
|
||||
};
|
||||
|
||||
enum class modulator_value
|
||||
{
|
||||
lo_freaquency = 0,
|
||||
baud_rate = 1,
|
||||
temp_treshold = 2,
|
||||
mod_reset = 3,
|
||||
modcod = 4,
|
||||
rollof = 5,
|
||||
mode_transmitt = 6,
|
||||
if_overload = 7,
|
||||
gold_seq = 8
|
||||
};
|
||||
|
||||
enum class demodulator_value
|
||||
{
|
||||
lo_freaquency = 0,
|
||||
baud_rate = 1,
|
||||
freq_search = 2,
|
||||
demod_reset = 3,
|
||||
fec_frame_size = 4,
|
||||
rvt = 5,
|
||||
mode_gain_control = 6,
|
||||
sig_min = 7,
|
||||
sig_max = 8,
|
||||
afc_rst = 9,
|
||||
mode_demod = 10,
|
||||
gold_seq = 11,
|
||||
attitude_signals = 12,
|
||||
is_reset_CinC = 13
|
||||
};
|
||||
enum class getdemodulator_value
|
||||
{
|
||||
lo_freaquency = 0,
|
||||
baud_rate = 1,
|
||||
dummy_counter = 2,
|
||||
modcod = 3,
|
||||
mode_gain_control = 4,
|
||||
sig_min = 5,
|
||||
sig_max = 6,
|
||||
rvt = 7,
|
||||
fec_size = 8,
|
||||
mode_demod = 9,
|
||||
cnt_bad_lock_cinc = 10,
|
||||
gold_seq = 11,
|
||||
attitude_signals = 12,
|
||||
cnt_dem_time_sinc = 13,
|
||||
cnt_dem_lock_afc = 14,
|
||||
cnt_dem_sync_pack = 15,
|
||||
cnt_dem_sinc_frec_corse = 16,
|
||||
freq_lock_estimate = 17,
|
||||
freq_fine_estimate = 18,
|
||||
is_reset_CinC = 19,
|
||||
type_pack = 20,
|
||||
is_pilots = 21
|
||||
};
|
||||
|
||||
enum class gain_value
|
||||
{
|
||||
tx1 = 0,
|
||||
tx2 = 1,
|
||||
rx1 = 2,
|
||||
rx2 = 3,
|
||||
txpwd = 4,
|
||||
rxpwd = 5
|
||||
};
|
||||
|
||||
enum class acm_value
|
||||
{
|
||||
enable = 0,
|
||||
modcod_min = 1,
|
||||
modcod_max = 2,
|
||||
attenuation_min = 3,
|
||||
attenuatin_max = 4,
|
||||
required_snr = 5
|
||||
};
|
||||
|
||||
enum class cmd_radio
|
||||
{
|
||||
tx1 = 0,
|
||||
tx2 = 1,
|
||||
rx1 = 2,
|
||||
rx2 = 3,
|
||||
global = 4,
|
||||
global2 = 5
|
||||
};
|
||||
|
||||
enum class network_value
|
||||
{
|
||||
network = 0,
|
||||
mode_interface = 1,
|
||||
version = 2,
|
||||
mask = 3,
|
||||
gateway = 4,
|
||||
dhcp_on = 5,
|
||||
dhcp_range = 6,
|
||||
network_data = 7,
|
||||
chip_id = 8,
|
||||
serial = 9,
|
||||
mac_eth0 = 10,
|
||||
mac_eth1 = 11,
|
||||
name_serv = 12,
|
||||
network_debug_send = 13,
|
||||
network_port_metric = 14,
|
||||
network_port_data = 15,
|
||||
periodic_send_metrics = 16,
|
||||
if_debug_mode = 17
|
||||
};
|
||||
|
||||
enum class cmd_type
|
||||
{
|
||||
login = 0,
|
||||
exit = 1,
|
||||
ping = 2,
|
||||
tracert = 3,
|
||||
interface = 4,
|
||||
copy = 5,
|
||||
abort = 6,
|
||||
set_demodulator_frequency = 7,
|
||||
get_demodulator_frequency = 8,
|
||||
set_gain_param = 9,
|
||||
get_gain_param = 10,
|
||||
radio_on_of = 11,
|
||||
modulator_param = 12,
|
||||
zynq_param = 13,
|
||||
set_demodulator_param = 14,
|
||||
get_demodulator_param = 15,
|
||||
get_modulator_param = 16,
|
||||
set_network = 17,
|
||||
get_level_dmd = 18,
|
||||
set_10g_config = 19,
|
||||
set_dma_debugg = 20,
|
||||
get_dma_debugg = 21,
|
||||
set_baudrate_rollof_dmd = 22,
|
||||
set_acm_params = 23,
|
||||
get_acm_params = 24,
|
||||
set_params_dpdi = 25,
|
||||
get_params_dpdi = 26,
|
||||
get_network = 27,
|
||||
set_qos_settings = 28,
|
||||
get_qos_settings = 29,
|
||||
set_lbq_params = 30,
|
||||
get_demodulator_state = 31,
|
||||
get_modulator_state = 32,
|
||||
get_cinc_state = 33,
|
||||
get_device_state = 34,
|
||||
set_modulator_settings = 35,
|
||||
set_demodulator_settings = 36,
|
||||
get_modulator_settings = 37,
|
||||
get_demodulator_settings = 38,
|
||||
set_lnb_buc_settings = 39,
|
||||
get_lnb_buc_settings = 40,
|
||||
set_qos_settings_json = 41,
|
||||
get_qos_settings_json = 42
|
||||
};
|
||||
|
||||
struct cmd_lbq_params
|
||||
{
|
||||
uint32_t tick_ms;
|
||||
uint32_t bucket_size;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(tick_ms, bucket_size);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_lnb_buc_settings{
|
||||
buc_lnb_settings_com buc_lnb;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(buc_lnb.buc, buc_lnb.is_ref_10MHz_buc, buc_lnb.lnb,buc_lnb.is_ref_10MHz_lnb, buc_lnb.is_ref_10MHz_output, buc_lnb.is_save_current_state);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_get_cinc_state
|
||||
{
|
||||
CinC_state_com cinc_state;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(cinc_state.carrier_lock, cinc_state.cnt_bad_lock,
|
||||
cinc_state.delay_dpdi, cinc_state.freq_error_offset,
|
||||
cinc_state.freq_fine_estimate,
|
||||
cinc_state.ratio_signal_signal);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_get_device_state
|
||||
{
|
||||
device_state_com device_state;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(device_state.adrv_temp, device_state.pl_temp, device_state.zynq_temp);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_demodulator_settings
|
||||
{
|
||||
demodulator_settings_com demodulator_settings;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(demodulator_settings.baudrate,demodulator_settings.central_freq_in_kGz,
|
||||
demodulator_settings.gain, demodulator_settings.is_aru_on,
|
||||
demodulator_settings.is_rvt_iq, demodulator_settings.rollof);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_get_demodulator_state
|
||||
{
|
||||
demodulator_state_com demodulator_state;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(demodulator_state.snr, demodulator_state.modcod, demodulator_state.is_short, demodulator_state.is_pilots,
|
||||
demodulator_state.rssi, demodulator_state.afc_err, demodulator_state.crs_freq_err,
|
||||
demodulator_state.sym_err, demodulator_state.fine_freq_err, demodulator_state.if_overload,
|
||||
demodulator_state.packet_ok_cnt, demodulator_state.packet_bad_cnt, demodulator_state.dummy_cnt,
|
||||
demodulator_state.speed_in_bytes_rx, demodulator_state.speed_in_bytes_rx_iface,
|
||||
demodulator_state.locks.afc_lock, demodulator_state.locks.freq_lock, demodulator_state.locks.pkt_sync, demodulator_state.locks.sym_sync_lock );
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_modulator_settings
|
||||
{
|
||||
modulator_settings_com modulator_settings;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(modulator_settings.attenuation,modulator_settings.baudrate, modulator_settings.central_freq_in_kGz,
|
||||
modulator_settings.is_carrier, modulator_settings.is_cinc,
|
||||
modulator_settings.is_save_current_state, modulator_settings.is_test_data,
|
||||
modulator_settings.rollof, modulator_settings.tx_is_on, modulator_settings.modcod_tx);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct cmd_get_modulator_state{
|
||||
modulator_state_com modulator_state;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(modulator_state.snr_remote, modulator_state.modcod, modulator_state.is_short, modulator_state.is_pilots,
|
||||
modulator_state.is_tx_on, modulator_state.speed_in_bytes_tx, modulator_state.speed_in_bytes_tx_iface);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct cmd_get_network
|
||||
{
|
||||
std::string network;
|
||||
network_value net_val;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(net_val, network);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_set_network
|
||||
{
|
||||
std::string network;
|
||||
network_value net_val;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(net_val, network);
|
||||
}
|
||||
};
|
||||
|
||||
struct dpdi_parameters
|
||||
{
|
||||
uint8_t latitude_station_grad = 0;
|
||||
uint8_t latitude_station_minute = 0;
|
||||
uint8_t longitude_station_grad = 0;
|
||||
uint8_t longitude_station_minute = 0;
|
||||
uint8_t longitude_sattelite_grad = 0;
|
||||
uint8_t longitude_sattelite_minute = 0;
|
||||
bool is_delay_window = 0;
|
||||
uint32_t max_delay = 1;
|
||||
uint32_t min_delay = 0;
|
||||
uint32_t freq_offset = 0;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(latitude_station_grad, latitude_station_minute,
|
||||
longitude_station_grad, longitude_station_minute,
|
||||
longitude_sattelite_grad, longitude_sattelite_minute,
|
||||
is_delay_window, max_delay, min_delay, freq_offset);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct ACM_parameters_serv
|
||||
{
|
||||
double snr_treashold = 0;
|
||||
double snr_treashold_acm = 0.5;
|
||||
uint32_t period_pack = 15;
|
||||
uint8_t max_modcod = 4;
|
||||
uint8_t min_modcod = 4;
|
||||
int max_attenuation = 0;
|
||||
int min_attenuation = 0;
|
||||
bool enable = false;
|
||||
bool enable_auto_atten = false;
|
||||
};
|
||||
|
||||
struct cmd_get_acm_param
|
||||
{
|
||||
double snr_treashold = 0;
|
||||
double snr_treashold_acm = 0.5;
|
||||
uint32_t period_pack = 15;
|
||||
uint8_t max_modcod = 4;
|
||||
uint8_t min_modcod = 4;
|
||||
int max_attenuation = 0;
|
||||
int min_attenuation = 0;
|
||||
bool enable = false;
|
||||
bool enable_auto_atten = false;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(enable, max_attenuation, max_modcod, min_attenuation, min_modcod, snr_treashold, enable_auto_atten, snr_treashold_acm, period_pack);
|
||||
}
|
||||
};
|
||||
struct cmd_qos_settings{
|
||||
std::string json_string;
|
||||
bool is_enable;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(json_string, is_enable);
|
||||
}
|
||||
};
|
||||
struct cmd_set_qos_settings
|
||||
{
|
||||
std::string node;
|
||||
name_classes_qos class_qos;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(node, class_qos);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_get_qos_settings
|
||||
{
|
||||
std::string node;
|
||||
name_classes_qos class_qos;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(node, class_qos);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_set_acm_param
|
||||
{
|
||||
ACM_parameters_serv acm_params;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(acm_params.enable, acm_params.max_attenuation, acm_params.max_modcod, acm_params.min_attenuation, acm_params.min_modcod, acm_params.snr_treashold, acm_params.enable_auto_atten, acm_params.snr_treashold_acm, acm_params.period_pack);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct cmd_get_dma_debug
|
||||
{
|
||||
std::string value;
|
||||
cmd_get_dma_debugg_enum dma_debugg;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(dma_debugg, value);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_set_dma_debug
|
||||
{
|
||||
std::string value;
|
||||
cmd_dma_debugg dma_debugg;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(dma_debugg, value);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_set_10g_config
|
||||
{
|
||||
std::string value;
|
||||
cmd_10g_config _10g_config;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(_10g_config, value);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_get_level_dem
|
||||
{
|
||||
double value;
|
||||
cmd_level_dem lvl_dem;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(lvl_dem, value);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_zynq_param
|
||||
{
|
||||
zynq_value cmd_zynq;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(cmd_zynq);
|
||||
}
|
||||
};
|
||||
|
||||
struct radio_enable
|
||||
{
|
||||
cmd_radio cmd_radio_;
|
||||
bool enbl;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(cmd_radio_, enbl);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_set_modulator_param
|
||||
{
|
||||
modulator_value mod_val;
|
||||
long long value;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(mod_val,value);
|
||||
}
|
||||
};
|
||||
struct cmd_get_modulator_param
|
||||
{
|
||||
modulator_value mod_val;
|
||||
uint32_t value;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(mod_val,value);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_set_rollof_and_demod
|
||||
{
|
||||
double baudrate;
|
||||
double rollof;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(baudrate,rollof);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct cmd_set_demodulator_param
|
||||
{
|
||||
demodulator_value demod_val;
|
||||
uint32_t value;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(demod_val,value);
|
||||
}
|
||||
};
|
||||
|
||||
struct cmd_get_demodulator_param
|
||||
{
|
||||
getdemodulator_value demod_val;
|
||||
uint32_t value;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(demod_val,value);
|
||||
}
|
||||
};
|
||||
|
||||
struct set_gain_par
|
||||
{
|
||||
gain_value g_val;
|
||||
double _gain;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(g_val,_gain);
|
||||
}
|
||||
};
|
||||
|
||||
struct get_gain_par
|
||||
{
|
||||
gain_value g_val;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(g_val);
|
||||
}
|
||||
};
|
||||
|
||||
struct set_dem_freq_cmd
|
||||
{
|
||||
uint32_t frequency;
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(frequency);
|
||||
}
|
||||
};
|
||||
|
||||
enum class response_type
|
||||
{
|
||||
ok = 0,
|
||||
error = 1,
|
||||
in_progress = 3,
|
||||
abort = 4,
|
||||
busy = 5
|
||||
};
|
||||
|
||||
enum class access_rights
|
||||
{
|
||||
not_allowed = 0,
|
||||
user = 1,
|
||||
admin = 2
|
||||
};
|
||||
|
||||
struct cmd_header
|
||||
{
|
||||
uint32_t id;
|
||||
cmd_type cmd;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(id, cmd);
|
||||
}
|
||||
};
|
||||
|
||||
struct login_cmd
|
||||
{
|
||||
std::string username;
|
||||
std::string pass;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(username, pass);
|
||||
}
|
||||
};
|
||||
|
||||
struct ping_cmd
|
||||
{
|
||||
std::string ip_address;
|
||||
size_t count;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(ip_address, count);
|
||||
}
|
||||
};
|
||||
|
||||
struct tracert_cmd
|
||||
{
|
||||
std::string ip_address;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(ip_address);
|
||||
}
|
||||
};
|
||||
|
||||
struct interface_cmd
|
||||
{
|
||||
interface_value val;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(val);
|
||||
}
|
||||
};
|
||||
|
||||
struct copy_cmd
|
||||
{
|
||||
fm::side_description src;
|
||||
fm::side_description dst;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(src, dst);
|
||||
}
|
||||
};
|
||||
|
||||
struct response_header
|
||||
{
|
||||
uint32_t id;
|
||||
cmd_type cmd;
|
||||
response_type rsp;
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive(id, cmd, rsp);
|
||||
}
|
||||
};
|
23
dependencies/control_system/common/seq_packet.h
vendored
23
dependencies/control_system/common/seq_packet.h
vendored
@@ -1,23 +0,0 @@
|
||||
#pragma once
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace seq_packet
|
||||
{
|
||||
using namespace boost::asio::local;
|
||||
|
||||
struct seqpacket_protocol
|
||||
{
|
||||
int type() const { return SOCK_SEQPACKET; }
|
||||
int protocol() const { return 0; }
|
||||
int family() const { return AF_UNIX; }
|
||||
|
||||
using endpoint = basic_endpoint<seqpacket_protocol>;
|
||||
using socket = boost::asio::basic_stream_socket<seqpacket_protocol>;
|
||||
using acceptor = boost::asio::basic_socket_acceptor<seqpacket_protocol>;
|
||||
|
||||
#if !defined(BOOST_ASIO_NO_IOSTREAM)
|
||||
/// The UNIX domain iostream type.
|
||||
typedef boost::asio::basic_socket_iostream<seqpacket_protocol> iostream;
|
||||
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
|
||||
};
|
||||
}
|
@@ -1,76 +0,0 @@
|
||||
#include "include/terminal_api/ControlProtoCInterface.h"
|
||||
#include <iostream>
|
||||
int main()
|
||||
{
|
||||
TSID sid{0};
|
||||
unsigned int access{0};
|
||||
if(CP_Login("admin","pass",&sid,&access) == OK)
|
||||
{
|
||||
std::cout << "Succsec" << std::endl;
|
||||
}
|
||||
CinC_state state_cinc;
|
||||
state_cinc.carrier_lock = false;
|
||||
CP_GetCinCState(sid,state_cinc);
|
||||
std::cout << state_cinc.carrier_lock << std::endl;
|
||||
std::cout << state_cinc.freq_error_offset << std::endl;
|
||||
std::cout << state_cinc.delay_dpdi << std::endl;
|
||||
std::cout << state_cinc.cnt_bad_lock << std::endl;
|
||||
modulator_state modulator;
|
||||
CP_GetModulatorState(sid, modulator);
|
||||
std::cout << modulator.is_pilots << "\n"
|
||||
<< modulator.modcod << "\n"
|
||||
<< modulator.snr_remote << "\n";
|
||||
demodulator_state demodulator;
|
||||
demodulator.dummy_cnt = 11111;
|
||||
CP_GetDemodulatorState(sid, demodulator);
|
||||
std::cout << "end CP_GetDemodulatorState" << std::endl;
|
||||
std::cout << demodulator.is_short << std::endl;
|
||||
std::cout << demodulator.modcod << std::endl;
|
||||
std::cout << "afc_lock: " <<demodulator.locks.afc_lock << std::endl;
|
||||
std::cout << "sym_sync_lock: " <<demodulator.locks.sym_sync_lock << std::endl;
|
||||
std::cout << "freq_lock: " <<demodulator.locks.freq_lock << std::endl;
|
||||
std::cout << "pkt_sync: " << demodulator.locks.pkt_sync << std::endl;
|
||||
modulator_settings setting_modulator;
|
||||
setting_modulator.baudrate = 2000000;
|
||||
setting_modulator.central_freq_in_kGz = 1340000.24;
|
||||
setting_modulator.rollof = 0.25;
|
||||
setting_modulator.tx_is_on = true;
|
||||
setting_modulator.is_test_data = false;
|
||||
setting_modulator.is_save_current_state = true;
|
||||
setting_modulator.is_cinc = false;
|
||||
setting_modulator.is_carrier = true;
|
||||
CP_SetModulatorSettings(sid, setting_modulator);
|
||||
demodulator_settings demodulator_sett;
|
||||
demodulator_sett.baudrate = 1340000;
|
||||
demodulator_sett.central_freq_in_kGz = 2400000.34;
|
||||
demodulator_sett.is_rvt_iq = true;
|
||||
demodulator_sett.is_aru_on = true;
|
||||
demodulator_sett.gain = 13;
|
||||
demodulator_sett.rollof = 0.15;
|
||||
if(CP_SetDemodulatorSettings(sid, demodulator_sett)== OK)
|
||||
{
|
||||
std::cout << "OK SET DEMODULATOR SETTINGS" << std::endl;
|
||||
}
|
||||
demodulator_settings demodulator_settings_;
|
||||
if(CP_GetDemodulatorSettings(sid,demodulator_settings_) == OK)
|
||||
{
|
||||
std::cout << "OK GET DEMODULATOR SETTINGS" << std::endl;
|
||||
std::cout << demodulator_settings_.baudrate << std::endl;
|
||||
std::cout << demodulator_settings_.gain<< std::endl;
|
||||
std::cout << demodulator_settings_.rollof << std::endl;
|
||||
std::cout << demodulator_settings_.is_aru_on << std::endl;
|
||||
std::cout << demodulator_settings_.is_rvt_iq << std::endl;
|
||||
std::cout << demodulator_settings_.central_freq_in_kGz << std::endl;
|
||||
}
|
||||
modulator_settings modulator_settings_;
|
||||
if(CP_GetModulatorSettings(sid,modulator_settings_)== OK)
|
||||
{
|
||||
std::cout << "OK GET MODULATOR SETTINGS" << std::endl;
|
||||
std::cout << modulator_settings_.baudrate << std::endl;
|
||||
std::cout << modulator_settings_.attenuation << std::endl;
|
||||
std::cout << modulator_settings_.central_freq_in_kGz << std::endl;
|
||||
std::cout << modulator_settings_.is_carrier << std::endl;
|
||||
std::cout << modulator_settings_.is_cinc << std::endl;
|
||||
std::cout << modulator_settings_.rollof << std::endl;
|
||||
}
|
||||
}
|
@@ -1,329 +0,0 @@
|
||||
#ifndef __CONTROL_PROTO_COMMANDS__
|
||||
#define __CONTROL_PROTO_COMMANDS__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERNC extern "C"
|
||||
#else
|
||||
#define EXTERNC extern
|
||||
#endif
|
||||
|
||||
typedef unsigned int TSID;
|
||||
|
||||
typedef enum CP_Res {
|
||||
OK = 0,
|
||||
TIMEOUT,
|
||||
ERROR,
|
||||
ABORT,
|
||||
BUSY
|
||||
} CP_Result;
|
||||
|
||||
typedef void (*CP_cmd_stdout_cb)(const char * str, uint32_t len);
|
||||
|
||||
/*
|
||||
cb - callback for receive stdout of command
|
||||
*/
|
||||
EXTERNC void CP_SetCmdStdoutCallback(TSID sid, CP_cmd_stdout_cb cb);
|
||||
/*
|
||||
sid -- current session ID
|
||||
*/
|
||||
EXTERNC void CP_CmdAbort(TSID sid);
|
||||
/*
|
||||
host -- host name
|
||||
user -- user name
|
||||
pwd -- password hash
|
||||
sid -- output session ID (used for all requests)
|
||||
access -- output type of privilegies {admin|operator|...etc}
|
||||
*/
|
||||
EXTERNC CP_Result CP_Login(const char * user, const char * pwd, TSID * sid, unsigned int * access);
|
||||
/*
|
||||
sid -- current session ID
|
||||
*/
|
||||
EXTERNC CP_Result CP_Logout(TSID sid);
|
||||
/*
|
||||
sid -- current session ID
|
||||
ip_address -- IP address of the host
|
||||
packet_count -- count of packets to send
|
||||
*/
|
||||
EXTERNC CP_Result CP_GetDmaDebug(TSID sid, const char *command, std::string *val);
|
||||
|
||||
EXTERNC CP_Result CP_SetDemFreq(TSID sid, uint32_t freq);
|
||||
|
||||
EXTERNC CP_Result CP_GetDemFreq(TSID sid, uint32_t * freq);
|
||||
|
||||
EXTERNC CP_Result CP_SetDmaDebug(TSID sid, const char *command, std::string val);
|
||||
|
||||
EXTERNC CP_Result CP_Set10gConfig(TSID sid, const char *parameter, std::string val);
|
||||
|
||||
EXTERNC CP_Result CP_SetRollofBaudrate(TSID sid, double rollof,double baudrate);
|
||||
|
||||
//interfaces<TX1><TX2><RX1><RX2>
|
||||
EXTERNC CP_Result CP_GetGain(TSID sid, const char *gain_interface, double *gain);
|
||||
//interfaces<TX1><TX2><RX1><RX2>
|
||||
EXTERNC CP_Result CP_SetGain(TSID sid, const char *gain_interface, double gain);
|
||||
//interfaces<TX1><TX2><RX1><RX2>
|
||||
EXTERNC CP_Result CP_RadioEnable(TSID sid, const char *radio_interface, bool on_of);
|
||||
//interfaces<TX1><TX2><RX1><RX2>
|
||||
/*
|
||||
BOD -- baud_rate
|
||||
SPREAD -- koef spread
|
||||
LO -- lo frequency
|
||||
*/
|
||||
EXTERNC CP_Result CP_ModulatorParams(TSID sid, const char *modulator_param, uint32_t value);
|
||||
|
||||
struct modulator_state{
|
||||
bool is_tx_on;
|
||||
float snr_remote;
|
||||
uint16_t modcod;
|
||||
bool is_short;
|
||||
bool is_pilots;
|
||||
uint32_t speed_in_bytes_tx;
|
||||
uint32_t speed_in_bytes_tx_iface;
|
||||
};
|
||||
EXTERNC CP_Result CP_GetModulatorState(TSID sid, modulator_state &state);
|
||||
|
||||
struct demodulator_locks{
|
||||
bool pkt_sync;
|
||||
bool afc_lock;
|
||||
bool freq_lock;
|
||||
bool sym_sync_lock;
|
||||
};
|
||||
struct demodulator_state{
|
||||
float snr;
|
||||
uint16_t modcod;
|
||||
bool is_short;
|
||||
bool is_pilots;
|
||||
float rssi;
|
||||
double afc_err;
|
||||
double crs_freq_err;
|
||||
double sym_err;
|
||||
double fine_freq_err;
|
||||
double if_overload;
|
||||
uint32_t packet_ok_cnt;
|
||||
uint32_t packet_bad_cnt;
|
||||
uint32_t dummy_cnt;
|
||||
uint32_t speed_in_bytes_rx;
|
||||
uint32_t speed_in_bytes_rx_iface;
|
||||
demodulator_locks locks;
|
||||
};
|
||||
EXTERNC CP_Result CP_GetDemodulatorState(TSID sid, demodulator_state &state);
|
||||
|
||||
struct CinC_state{
|
||||
float ratio_signal_signal;
|
||||
bool carrier_lock;
|
||||
int32_t freq_error_offset;
|
||||
uint32_t delay_dpdi;
|
||||
int32_t freq_fine_estimate;
|
||||
uint32_t cnt_bad_lock;
|
||||
};
|
||||
EXTERNC CP_Result CP_GetCinCState(TSID sid, CinC_state &state);
|
||||
|
||||
struct device_state{
|
||||
double adrv_temp;
|
||||
double zynq_temp;
|
||||
double pl_temp;
|
||||
};
|
||||
EXTERNC CP_Result CP_GetDeviceState(TSID sid, device_state &state);
|
||||
|
||||
struct modulator_settings{
|
||||
uint32_t baudrate;
|
||||
double central_freq_in_kGz;
|
||||
double rollof;
|
||||
double attenuation;
|
||||
bool is_test_data;
|
||||
bool is_save_current_state;
|
||||
bool is_carrier;
|
||||
bool tx_is_on;
|
||||
bool is_cinc;
|
||||
uint32_t modcod_tx;
|
||||
};
|
||||
|
||||
EXTERNC CP_Result CP_SetModulatorSettings(TSID sid, modulator_settings& settings);
|
||||
EXTERNC CP_Result CP_GetModulatorSettings(TSID sid, modulator_settings& settings);
|
||||
|
||||
struct demodulator_settings
|
||||
{
|
||||
uint32_t baudrate;
|
||||
double central_freq_in_kGz;
|
||||
double rollof;
|
||||
bool is_aru_on;
|
||||
bool is_rvt_iq;
|
||||
double gain;
|
||||
};
|
||||
|
||||
EXTERNC CP_Result CP_SetDemodulatorSettings(TSID sid, demodulator_settings& settings);
|
||||
EXTERNC CP_Result CP_GetDemodulatorSettings(TSID sid, demodulator_settings& settings);
|
||||
|
||||
enum class voltage_lnb{
|
||||
DISABLE = 0, _13V, _18V, _24V
|
||||
};
|
||||
enum class voltage_buc{
|
||||
DISABLE = 0, _24V, _48V
|
||||
};
|
||||
struct buc_lnb_settings
|
||||
{
|
||||
voltage_lnb lnb;
|
||||
bool is_ref_10MHz_lnb = false;
|
||||
voltage_buc buc;
|
||||
bool is_ref_10MHz_buc = false;
|
||||
bool is_ref_10MHz_output = false;
|
||||
bool is_save_current_state = false;
|
||||
};
|
||||
|
||||
EXTERNC CP_Result CP_SetBUC_LNB_settings(TSID sid, buc_lnb_settings &settings);
|
||||
EXTERNC CP_Result CP_GetBUC_LNB_settings(TSID sid, buc_lnb_settings &settings);
|
||||
|
||||
EXTERNC CP_Result CP_SetQoSSettings(TSID sid, const std::string &qos_settings_json, bool is_enable);
|
||||
EXTERNC CP_Result CP_GetQoSSettings(TSID sid, std::string &qos_settings_json, bool &is_enable);
|
||||
|
||||
EXTERNC CP_Result CP_GetModulatorParams(TSID sid, const char *modulator_param, uint32_t *value);
|
||||
|
||||
EXTERNC CP_Result CP_GetDemodulatorParams(TSID sid, const char *demodulator_param, uint32_t *value);
|
||||
|
||||
EXTERNC CP_Result CP_GetLevelDemod(TSID sid, const char * param ,double *value);
|
||||
|
||||
EXTERNC CP_Result CP_DemodulatorParams(TSID sid, const char *demodulator_param, uint32_t value);
|
||||
|
||||
EXTERNC CP_Result CP_SetLBQParams(TSID sid, const uint32_t &tick_ms, const uint32_t &bucket_size);
|
||||
|
||||
EXTERNC CP_Result CP_SetQoSParams(TSID sid, const std::string &type_node, const std::string & node);
|
||||
|
||||
EXTERNC CP_Result CP_GetQoSParams(TSID sid, const std::string &type_node, std::string * node);
|
||||
|
||||
struct ACM_parameters_serv_
|
||||
{
|
||||
double snr_treashold = 0;
|
||||
double snr_treashold_acm = 0.5;
|
||||
uint32_t period_pack = 15;
|
||||
uint8_t max_modcod = 4;
|
||||
uint8_t min_modcod = 4;
|
||||
int max_attenuation = 0;
|
||||
int min_attenuation = 0;
|
||||
bool enable = false;
|
||||
bool enable_auto_atten = false;
|
||||
};
|
||||
|
||||
struct DPDI_parmeters
|
||||
{
|
||||
uint8_t latitude_station_grad = 0;
|
||||
uint8_t latitude_station_minute = 0;
|
||||
uint8_t longitude_station_grad = 0;
|
||||
uint8_t longitude_station_minute = 0;
|
||||
uint8_t longitude_sattelite_grad = 0;
|
||||
uint8_t longitude_sattelite_minute = 0;
|
||||
bool is_delay_window = 0;
|
||||
uint32_t max_delay = 1;
|
||||
uint32_t min_delay = 0;
|
||||
uint32_t freq_offset = 0;
|
||||
};
|
||||
|
||||
EXTERNC CP_Result CP_SetAcmParams(TSID sid, ACM_parameters_serv_ acm_params);
|
||||
EXTERNC CP_Result CP_GetAcmParams(TSID sid, ACM_parameters_serv_ *acm_params);
|
||||
|
||||
EXTERNC CP_Result CP_SetDpdiParams(TSID sid, DPDI_parmeters dpdi_params);
|
||||
EXTERNC CP_Result CP_GetDpdiParams(TSID sid, DPDI_parmeters *dpdi_pars_get);
|
||||
|
||||
/*
|
||||
PSV
|
||||
PLV
|
||||
PST
|
||||
PLT
|
||||
ADRVT
|
||||
*/
|
||||
EXTERNC CP_Result CP_ZynqParams(TSID sid, const char *zynq_param, double *value);
|
||||
|
||||
EXTERNC CP_Result CP_SetNetwork(TSID sid, const char *param_name, const char *val);
|
||||
EXTERNC CP_Result CP_GetNetwork(TSID sid, const char *param_name, std::string *val);
|
||||
/*
|
||||
ip_address -- new IP address fot the host
|
||||
*/
|
||||
|
||||
EXTERNC CP_Result CP_Ping(TSID sid, const char * ip_address, int packet_count);
|
||||
/*
|
||||
sid -- current session ID
|
||||
ip_address -- IP address of the host
|
||||
*/
|
||||
EXTERNC CP_Result CP_Traceroute(TSID sid, const char * ip_address);
|
||||
/*
|
||||
sid -- current session ID
|
||||
src -- {"running-config"|"startup-config"|host_address}
|
||||
dst -- {"running-config"|"startup-config"|host_address}
|
||||
NOTE:
|
||||
src and dst both must be different
|
||||
*/
|
||||
EXTERNC CP_Result CP_Copy(TSID sid, const char * src, const char * dst);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"all"|"sat0"|"gigabit"|"modulator"|"demodulator"}
|
||||
output data goes to callback
|
||||
*/
|
||||
EXTERNC CP_Result CP_ShowInterface(TSID sid, const char * interface);
|
||||
/*
|
||||
sid -- current session ID
|
||||
out_startup_config -- received information about startup config
|
||||
*/
|
||||
EXTERNC CP_Result CP_ShowStartupConfig(TSID sid, char ** out_startup_config);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"all"|"sat0"|"gigabit"|"modulator"|"demodulator"}
|
||||
out_startup_config -- received information about startup config
|
||||
*/
|
||||
EXTERNC CP_Result CP_ShowStartupConfigInterface(TSID sid, const char * interface, char ** out_startup_config);
|
||||
|
||||
// Demodulator
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
rate -- symbol rate
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetDemodSymrate(TSID sid, const char * interface, uint32_t rate);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
rate -- frequency value in Hertz
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetDemodFrequency(TSID sid, const char * interface, uint32_t freq);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
mode -- {"on"|"off"|"auto"}
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetDemodSpectrum(TSID sid, const char * interface, const char * mode);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
mode -- {"on"|"off"}
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetDemodReference(TSID sid, const char * interface, const char * mode);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
rate -- frequency value in Hertz
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetDemodSearch(TSID sid, const char * interface, uint32_t freq);
|
||||
|
||||
// Modulator
|
||||
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
rate -- symbol rate
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetModSymrate(TSID sid, const char * interface, uint32_t rate);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
rate -- frequency value in Hertz
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetModSymFrequency(TSID sid, const char * interface, uint32_t freq);
|
||||
/*
|
||||
sid -- current session ID
|
||||
interface -- {"SAT"|"Ethernet"|"Loopback"}
|
||||
mode -- {"on"|"off"}
|
||||
*/
|
||||
EXTERNC CP_Result CP_SetModReference(TSID sid, const char * interface, const char * mode);
|
||||
#endif
|
1
dependencies/control_system_client
vendored
Submodule
1
dependencies/control_system_client
vendored
Submodule
Submodule dependencies/control_system_client added at cd6e4f08d5
@@ -1,74 +1,336 @@
|
||||
{
|
||||
"monitoring-params": {},
|
||||
"params": {
|
||||
"rxtx": {
|
||||
"rx.en": {
|
||||
"model": "w:switch",
|
||||
"label": "Включить передатчик"
|
||||
},
|
||||
"rx.isTestInputData": {
|
||||
"model": "w:select",
|
||||
"label": "Включить передатчик",
|
||||
"items": [
|
||||
{"value": "false", "label": "Ethernet"},
|
||||
{"value": "true", "label": "Тест (CW)"}
|
||||
]
|
||||
},
|
||||
"rx.freqKhz": {
|
||||
"model": "w:number",
|
||||
"number.type": "int",
|
||||
"number.step": 1,
|
||||
"number.min": 500000,
|
||||
"number.max": 15000000
|
||||
}
|
||||
}
|
||||
},
|
||||
"modem_types": {
|
||||
"tdma": {
|
||||
"modem_name": "RCSM-101 TDMA",
|
||||
"groupsList": ["rxtx"],
|
||||
"dangerousParamGroups": {
|
||||
"buclnb": "Применение неправильных настроек может вывести из строя оборудование! Продолжить?",
|
||||
"network": "Применение этих настроек может сделать модем недоступным! Продолжить?"
|
||||
},
|
||||
"params": {
|
||||
"rxtx": [
|
||||
{"widget": "h2", "label": "Настройки приема/передачи"},
|
||||
{
|
||||
"widget": "flex-container",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки передатчика"},
|
||||
{"widget": "checkbox", "label": "Включить передатчик", "name": "txEn"},
|
||||
{
|
||||
"widget": "select", "label": "Режим работы модулятора", "name": "txModulatorIsTest",
|
||||
"values": [{"label": "Нормальный", "value": "false"}, {"label": "Тест (CW)", "value": "true"}]
|
||||
},
|
||||
{"widget": "number", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 900000, "step": 0.01, "v_show": "paramRxtx.txModulatorIsTest"},
|
||||
{"widget": "number", "label": "Ослабление, дБ", "name": "txAttenuation", "min": 0, "step": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{ "widget": "h3", "label": "Настройки приемника" },
|
||||
{
|
||||
"widget": "select", "label": "Режим управления усилением", "name": "rxAgcEn",
|
||||
"values": [
|
||||
{"label": "АРУ", "value": "true"},
|
||||
{"label": "РРУ", "value": "false"}
|
||||
]
|
||||
},
|
||||
{"widget": "number", "label": "Ручное усиление, дБ", "name": "rxManualGain", "v_show": "!paramRxtx.rxAgcEn", "min": -40},
|
||||
{"widget": "checkbox", "label": "Инверсия спектра", "name": "rxSpectrumInversion"},
|
||||
{"widget": "number", "label": "Центральная частота, КГц", "name": "rxCentralFreq", "min": 900000, "step": 0.01},
|
||||
{"widget": "number", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 0, "step": 1},
|
||||
{
|
||||
"widget": "select", "label": "Roll-off", "name": "rxRolloff",
|
||||
"values": [{"label": "0.02", "value": "2"}, {"label": "0.05", "value": "5"}, {"label": "0.10", "value": "10"}, {"label": "0.15", "value": "15"}, {"label": "0.20", "value": "20"}, {"label": "0.25", "value": "25"}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"buclnb": [
|
||||
{"widget": "h2", "label": "Настройки питания и опорного генератора"},
|
||||
{
|
||||
"widget": "flex-container",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки BUC"},
|
||||
{"widget": "checkbox", "label": "Подача опоры 10МГц", "name": "bucRefClk10M"},
|
||||
{
|
||||
"widget": "select", "label": "Питание BUC", "name": "bucPowering",
|
||||
"values": [
|
||||
{"label": "Выкл", "value": "0"},
|
||||
{"label": "24В", "value": "24"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки LNB"},
|
||||
{"widget": "checkbox", "label": "Подача опоры 10МГц", "name": "lnbRefClk10M"},
|
||||
{
|
||||
"widget": "select", "label": "Питание LNB", "name": "lnbPowering",
|
||||
"values": [
|
||||
{"label": "Выкл", "value": "0"},
|
||||
{"label": "13В", "value": "13"},
|
||||
{"label": "18В", "value": "18"},
|
||||
{"label": "24В", "value": "24"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Сервисные настройки"},
|
||||
{"widget": "checkbox", "label": "Подача опоры 10МГц на 'Выход 10МГц'", "name": "srvRefClk10M"},
|
||||
{"widget": "checkbox", "label": "Автозапуск BUC и LNB при включении", "name": "bucLnbAutoStart"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"network": [
|
||||
{"widget": "h2", "label": "Настройки сети"},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки интерфейса управления"},
|
||||
{"widget": "ip-address", "label": "Интерфейс управления (/24)", "name": "netManagementIp"},
|
||||
{
|
||||
"widget": "select", "label": "Режим сети", "name": "netIsL2",
|
||||
"values": [{"label": "Маршрутизатор", "value": "false"}, {"label": "Коммутатор", "value": "true"}]
|
||||
},
|
||||
{"widget": "ip-address", "label": "Интерфейс данных (/24)", "name": "netDataIp", "v_show": "paramNetwork.netIsL2 === false"},
|
||||
{"widget": "number", "label": "MTU интерфейса данных", "name": "netDataMtu", "min": 1500, "step": 1, "max": 2000}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tabs": [
|
||||
{
|
||||
"name": "monitoring",
|
||||
"desc": "Мониторинг"
|
||||
},
|
||||
{
|
||||
"name": "setup",
|
||||
"desc": "Настройки",
|
||||
"widgets": [
|
||||
{"group": "html", "name": "h3", "payload": "Настройки передатчика"},
|
||||
{"group": "rxtx", "name": "rx.en"},
|
||||
{"group": "rxtx", "name": "rx.isTestInputData"},
|
||||
{"group": "html", "name": "h3", "payload": "Параметры передачи"},
|
||||
{"group": "rxtx", "name": "rx.freqKhz"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"desc": "Администрирование"
|
||||
}
|
||||
{"name": "monitoring", "desc": "Мониторинг"},
|
||||
{"name": "setup", "desc": "Настройки"},
|
||||
{"name": "admin", "desc": "Администрирование"}
|
||||
]
|
||||
},
|
||||
"scpc": {
|
||||
"modem_name": "RCSM-101",
|
||||
"groupsList": ["rxtx"],
|
||||
"dangerousParamGroups": {
|
||||
"buclnb": "Применение неправильных настроек может вывести из строя оборудование! Продолжить?",
|
||||
"network": "Применение этих настроек может сделать модем недоступным! Продолжить?"
|
||||
},
|
||||
"params": {
|
||||
"rxtx": [
|
||||
{"widget": "h2", "label": "Настройки приема/передачи"},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "select", "label": "Режим работы", "name": "isCinC",
|
||||
"values": [{"label": "SCPC", "value": "false"}, {"label": "CinC", "value": "true"}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "flex-container",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки передатчика"},
|
||||
{"widget": "checkbox", "label": "Включить передатчик", "name": "txEn"},
|
||||
{"widget": "checkbox", "label": "Автоматический запуск передатчика", "name": "txAutoStart"},
|
||||
{
|
||||
"widget": "select", "label": "Режим работы модулятора", "name": "txModulatorIsTest",
|
||||
"values": [{"label": "Нормальный", "value": "false"}, {"label": "Тест (CW)", "value": "true"}]
|
||||
},
|
||||
{
|
||||
"widget": "select", "label": "Входные данные", "name": "txIsTestInput",
|
||||
"values": [{"label": "Ethernet", "value": "false"}, {"label": "Тест", "value": "true"}]
|
||||
},
|
||||
{"widget": "h3", "label": "Параметры передачи"},
|
||||
{"widget": "number", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 900000, "step": 0.01},
|
||||
{"widget": "number", "label": "Символьная скорость, Бод", "name": "txBaudrate", "min": 0, "step": 1},
|
||||
{
|
||||
"widget": "select", "label": "Roll-off", "name": "txRolloff",
|
||||
"values": [{"label": "0.02", "value": "2"}, {"label": "0.05", "value": "5"}, {"label": "0.10", "value": "10"}, {"label": "0.15", "value": "15"}, {"label": "0.20", "value": "20"}, {"label": "0.25", "value": "25"}]
|
||||
},
|
||||
{
|
||||
"widget": "select", "label": "Номер последовательности Голда", "name": "txGoldan",
|
||||
"values": [{"label": "0", "value": "0"}, {"label": "1", "value": "1"}]
|
||||
},
|
||||
{"widget": "number", "label": "Ослабление, дБ", "name": "txAttenuation", "min": 0, "step": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Режим работы DVB-S2"},
|
||||
{"widget": "number", "label": "Период служебных пакетов, сек", "name": "dvbServicePacketPeriod", "min": 0, "step": 1, "max": 60},
|
||||
{
|
||||
"widget": "select", "label": "Режим модуляции", "name": "dvbIsAcm",
|
||||
"values": [{"label": "CCM", "value": "false"}, {"label": "ACM", "value": "true"}]
|
||||
},
|
||||
{
|
||||
"widget": "select", "label": "Размер кадра", "name": "txFrameSizeNormal",
|
||||
"values": [{"label": "normal", "value": "true"}, {"label": "short", "value": "false"}]
|
||||
},
|
||||
{"widget": "modulation-modcod", "label": "Модуляция", "name": "dvbCcm", "v_show": "paramRxtx.dvbIsAcm === false"},
|
||||
{"widget": "modulation-speed", "label": "Скорость кода", "name": "dvbCcm", "v_show": "paramRxtx.dvbIsAcm === false"},
|
||||
{"widget": "watch-expr", "label": "Расчетная скорость, kbit", "expr": "calcInterfaceSpeedKb(paramRxtx.txBaudrate, paramRxtx.dvbCcmModulation, paramRxtx.dvbCcmSpeed)", "v_show": "paramRxtx.dvbIsAcm === false"},
|
||||
{"widget": "watch-expr", "label": "Текущий модкод", "expr": "statTx.modcod", "v_show": "paramRxtx.dvbIsAcm === true"},
|
||||
{"widget": "modulation-modcod", "label": "Модуляция (мин. режим)", "name": "dvbAcmMin", "v_show": "paramRxtx.dvbIsAcm === true"},
|
||||
{"widget": "modulation-speed", "label": "Скорость кода (мин. режим)", "name": "dvbAcmMin", "v_show": "paramRxtx.dvbIsAcm === true"},
|
||||
{"widget": "watch-expr", "label": "Расчетная скорость (мин. режим), kbit", "expr": "calcInterfaceSpeedKb(paramRxtx.txBaudrate, paramRxtx.dvbAcmMinModulation, paramRxtx.dvbAcmMinSpeed)", "v_show": "paramRxtx.dvbIsAcm === true"},
|
||||
{"widget": "modulation-modcod", "label": "Модуляция (макс. режим)", "name": "dvbAcmMax", "v_show": "paramRxtx.dvbIsAcm === true"},
|
||||
{"widget": "modulation-speed", "label": "Скорость кода (макс. режим)", "name": "dvbAcmMax", "v_show": "paramRxtx.dvbIsAcm === true"},
|
||||
{"widget": "watch-expr", "label": "Расчетная скорость (макс. режим), kbit", "expr": "calcInterfaceSpeedKb(paramRxtx.txBaudrate, paramRxtx.dvbAcmMaxModulation, paramRxtx.dvbAcmMaxSpeed)", "v_show": "paramRxtx.dvbIsAcm === true"},
|
||||
{"widget": "number", "label": "Запас ОСШ, дБ", "name": "dvbSnrReserve", "min": 0, "step": 0.01, "max": 10}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Авто-регулировка мощности"},
|
||||
{"widget": "checkbox", "label": "Авто-регулировка мощности", "name": "aupcEn"},
|
||||
{"widget": "number", "label": "Минимальное ослабление, дБ", "name": "aupcMinAttenuation", "min": 0, "step": 0.01, "max": 10},
|
||||
{"widget": "number", "label": "Максимальное ослабление, дБ", "name": "aupcMaxAttenuation", "min": 0, "step": 0.01, "max": 10},
|
||||
{"widget": "number", "label": "Требуемое ОСШ", "name": "aupcRequiredSnr", "min": 0, "step": 0.01, "max": 10}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки приемника"},
|
||||
{
|
||||
"widget": "select", "label": "Режим управления усилением", "name": "rxAgcEn",
|
||||
"values": [{"label": "РРУ", "value": "false"}, {"label": "АРУ", "value": "true"}]
|
||||
},
|
||||
{"widget": "number", "label": "Усиление, дБ", "name": "rxManualGain", "min": -40, "step": 0.01, "max": 40, "v_show": "paramRxtx.rxAgcEn === false"},
|
||||
{"widget": "watch-expr", "label": "Текущее усиление", "expr": "paramRxtx.rxManualGain", "v_show": "paramRxtx.rxAgcEn === true"},
|
||||
{"widget": "checkbox", "label": "Инверсия спектра", "name": "rxSpectrumInversion"},
|
||||
{"widget": "number", "label": "Центральная частота, КГц", "name": "rxCentralFreq", "min": 900000, "step": 0.01},
|
||||
{"widget": "number", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 0, "step": 1},
|
||||
{
|
||||
"widget": "select", "label": "Roll-off", "name": "rxRolloff",
|
||||
"values": [{"label": "0.02", "value": "2"}, {"label": "0.05", "value": "5"}, {"label": "0.10", "value": "10"}, {"label": "0.15", "value": "15"}, {"label": "0.20", "value": "20"}, {"label": "0.25", "value": "25"}]
|
||||
},
|
||||
{
|
||||
"widget": "select", "label": "Номер последовательности Голда", "name": "rxGoldan",
|
||||
"values": [{"label": "0", "value": "0"}, {"label": "1", "value": "1"}]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"cinc": [
|
||||
{"widget": "h2", "label": "Настройки режима CinC", "v_show": "paramRxtx.isCinC"},
|
||||
{
|
||||
"widget": "settings-container", "v_show": "paramRxtx.isCinC",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "select", "label": "Метод расчета задержки", "name": "cincIsPositional",
|
||||
"values": [
|
||||
{"label": "Позиционированием", "value": "true"},
|
||||
{"label": "Окном задержки", "value": "false"}
|
||||
]
|
||||
},
|
||||
{"widget": "number", "label": "Полоса поиска, КГц ±", "name": "cincSearchBandwidth", "min": 0, "step": 1, "max": 100},
|
||||
{"widget": "h2", "label": "Настройки позиционирования", "v_show": "paramCinc.cincIsPositional === true"},
|
||||
{"widget": "number", "label": "Широта станции", "name": "cincPositionStationLatitude", "v_show": "paramCinc.cincIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Долгота станции", "name": "cincPositionStationLongitude", "v_show": "paramCinc.cincIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Подспутниковая точка", "name": "cincPositionSatelliteLongitude", "v_show": "paramCinc.cincIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "h2", "label": "Задержка до спутника", "v_show": "paramCinc.cincIsPositional === false"},
|
||||
{"widget": "number", "label": "от, мс", "name": "cincDelayMin", "v_show": "paramCinc.cincIsPositional === false", "min": 0, "step": 0.1, "max": 400},
|
||||
{"widget": "number", "label": "до, мс", "name": "cincDelayMax", "v_show": "paramCinc.cincIsPositional === false", "min": 0, "step": 0.1, "max": 400}]
|
||||
},
|
||||
{"widget": "submit", "v_show": "paramRxtx.isCinC"}
|
||||
],
|
||||
"buclnb": [
|
||||
{"widget": "h2", "label": "Настройки питания и опорного генератора"},
|
||||
{
|
||||
"widget": "flex-container",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки BUC"},
|
||||
{"widget": "checkbox", "label": "Подача опоры 10МГц", "name": "bucRefClk10M"},
|
||||
{
|
||||
"widget": "select", "label": "Питание BUC", "name": "bucPowering",
|
||||
"values": [
|
||||
{"label": "Выкл", "value": "0"},
|
||||
{"label": "24В", "value": "24"},
|
||||
{"label": "48В", "value": "48"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки LNB"},
|
||||
{"widget": "checkbox", "label": "Подача опоры 10МГц", "name": "lnbRefClk10M"},
|
||||
{
|
||||
"widget": "select", "label": "Питание LNB", "name": "lnbPowering",
|
||||
"values": [
|
||||
{"label": "Выкл", "value": "0"},
|
||||
{"label": "13В", "value": "13"},
|
||||
{"label": "18В", "value": "18"},
|
||||
{"label": "24В", "value": "24"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Сервисные настройки"},
|
||||
{"widget": "checkbox", "label": "Подача опоры 10МГц на 'Выход 10МГц'", "name": "srvRefClk10M"},
|
||||
{"widget": "checkbox", "label": "Автозапуск BUC и LNB при включении", "name": "bucLnbAutoStart"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tcpaccel": [
|
||||
{"widget": "h2", "label": "Настройки TCP-акселерации"},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "checkbox", "label": "Активировать акселерацию", "name": "accelEn"},
|
||||
{"widget": "number", "label": "Максимальное количество соединений", "name": "accelMaxConnections", "min": 0, "step": 1, "max": 4000}
|
||||
]
|
||||
}
|
||||
],
|
||||
"network": [
|
||||
{"widget": "h2", "label": "Настройки сети"},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки интерфейса управления"},
|
||||
{"widget": "ip-address", "label": "Интерфейс управления (/24)", "name": "netManagementIp"},
|
||||
{
|
||||
"widget": "select", "label": "Режим сети", "name": "netIsL2",
|
||||
"values": [{"label": "Маршрутизатор", "value": "false"}, {"label": "Коммутатор", "value": "true"}]
|
||||
},
|
||||
{"widget": "ip-address", "label": "Интерфейс данных (/24)", "name": "netDataIp", "v_show": "paramNetwork.netIsL2 === false"},
|
||||
{"widget": "number", "label": "MTU интерфейса данных", "name": "netDataMtu", "min": 1500, "step": 1, "max": 2000}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tabs": [
|
||||
{
|
||||
"name": "monitoring",
|
||||
"desc": "Мониторинг"
|
||||
},
|
||||
{
|
||||
"name": "setup",
|
||||
"desc": "Настройки"
|
||||
},
|
||||
{
|
||||
"name": "qos",
|
||||
"desc": "QoS"
|
||||
},
|
||||
{
|
||||
"name": "admin",
|
||||
"desc": "Администрирование"
|
||||
}
|
||||
{"name": "monitoring", "desc": "Мониторинг"},
|
||||
{"name": "setup", "desc": "Настройки"},
|
||||
{"name": "qos", "desc": "QoS"},
|
||||
{"name": "admin", "desc": "Администрирование"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@@ -1,22 +1,90 @@
|
||||
import json
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
import sys
|
||||
import os
|
||||
|
||||
with open('render-params.json') as f:
|
||||
GLOBAL_CONFIG = json.load(f)
|
||||
|
||||
|
||||
def extract_param_names(mc):
|
||||
result = []
|
||||
|
||||
def helper_extract(widget):
|
||||
if 'childs' in widget:
|
||||
r = []
|
||||
for child in widget['childs']:
|
||||
r += helper_extract(child)
|
||||
return r
|
||||
elif 'name' in widget:
|
||||
match widget['widget']:
|
||||
case 'select': return [{"name": widget['name'], "initValue": widget['values'][0]['value']}]
|
||||
case 'checkbox': return [{"name": widget['name'], "initValue": 'false'}]
|
||||
case 'number': return [{"name": widget['name'], "initValue": widget['min'] if widget['min'] else '0'}]
|
||||
case 'modulation-modcod': return [{"name": widget['name'] + "Modulation", "initValue": '"QPSK"'}]
|
||||
case 'modulation-speed': return [{"name": widget['name'] + "Speed", "initValue": '"1/4"'}]
|
||||
case 'watch': return []
|
||||
|
||||
return [{"name": widget['name'], "initValue": 'null'}]
|
||||
return []
|
||||
|
||||
for cat in mc['params']:
|
||||
ws = []
|
||||
for w in mc['params'][cat]:
|
||||
ws += helper_extract(w)
|
||||
# ws.sort(key=lambda k: k['name'])
|
||||
result.append({
|
||||
"group": cat,
|
||||
"params": ws
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def add_submit_widgets(params):
|
||||
def find_submit(w):
|
||||
if w['widget'] == 'submit':
|
||||
return True
|
||||
if 'childs' in w:
|
||||
for c in w['childs']:
|
||||
if find_submit(c):
|
||||
return True
|
||||
return False
|
||||
|
||||
for group in params:
|
||||
wid_found = False
|
||||
for wid in params[group]:
|
||||
if find_submit(wid):
|
||||
wid_found = True
|
||||
break
|
||||
if wid_found:
|
||||
continue
|
||||
|
||||
params[group].append({"widget": "submit"})
|
||||
|
||||
|
||||
|
||||
def extract_param_groups(mc):
|
||||
return [k for k in mc['params']]
|
||||
|
||||
|
||||
def build_modem_env(modem):
|
||||
with open('render-params.json') as f:
|
||||
config = json.load(f)
|
||||
if modem not in config['modem_types']:
|
||||
if modem not in GLOBAL_CONFIG['modem_types']:
|
||||
raise RuntimeError(f"Modem '{modem}' is not exist in config!")
|
||||
|
||||
mc = config['modem_types'][modem]
|
||||
mc = GLOBAL_CONFIG['modem_types'][modem]
|
||||
|
||||
add_submit_widgets(mc['params'])
|
||||
|
||||
return {
|
||||
"modem": modem,
|
||||
"modem_name": mc['modem_name'],
|
||||
"header_tabs": mc['tabs'],
|
||||
"js_tabs_array": str([t['name'] for t in mc['tabs']]),
|
||||
"params": {"groupsList": mc["groupsList"]} | config["params"]
|
||||
"tab_names_array": [t['name'] for t in mc['tabs']],
|
||||
"params": mc["params"],
|
||||
"dangerousParamGroups": mc["dangerousParamGroups"] if 'dangerousParamGroups' in mc else {},
|
||||
"paramGroups": extract_param_names(mc),
|
||||
"paramGroupsList": extract_param_groups(mc),
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +100,8 @@ def render_modem(modem):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 2:
|
||||
print(f"Usage: {sys.argv[0]} <scpc|tdma>")
|
||||
|
||||
render_modem(sys.argv[1])
|
||||
for mt in GLOBAL_CONFIG['modem_types']:
|
||||
print(f'Generating {mt} modem...')
|
||||
render_modem(mt)
|
||||
os.system(f'cp -u main-{mt}.html ../static')
|
||||
|
||||
|
62
front-generator/template/common/admin-methods.js.j2
Normal file
62
front-generator/template/common/admin-methods.js.j2
Normal file
@@ -0,0 +1,62 @@
|
||||
async settingsUploadUpdate() {
|
||||
if (!this.uploadFw.filename) {
|
||||
alert('Выберите файл для загрузки');
|
||||
return;
|
||||
}
|
||||
|
||||
async function readFileAsArrayBuffer(fileName) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!fileName) { reject(`Файл не выбран`); return }
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => { resolve(reader.result) }
|
||||
reader.onerror = (e) => { reject(e) }
|
||||
reader.readAsArrayBuffer(fileName)
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
this.submitStatus.firmwareUpload = true
|
||||
this.uploadFw.progress = 0
|
||||
const blob = await readFileAsArrayBuffer(this.uploadFw.filename)
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
await new Promise((resolve) => {
|
||||
xhr.upload.addEventListener("progress", (event) => {
|
||||
if (event.lengthComputable) {
|
||||
this.uploadFw.progress = Math.round((event.loaded / event.total) * 1000) / 10;
|
||||
}
|
||||
});
|
||||
xhr.addEventListener("loadend", () => {
|
||||
this.uploadFw.progress = 100
|
||||
const rep = JSON.parse(xhr.responseText);
|
||||
this.uploadFw.sha256 = rep['sha256']
|
||||
resolve(xhr.readyState === 4 && xhr.status === 200);
|
||||
});
|
||||
xhr.open("PUT", "/api/firmwareUpdate", true);
|
||||
xhr.setRequestHeader("Content-Type", "application/octet-stream");
|
||||
xhr.send(blob);
|
||||
});
|
||||
} catch (e) {
|
||||
alert(`Ошибка загрузки файла: ${e}`);
|
||||
}
|
||||
this.submitStatus.firmwareUpload = false
|
||||
},
|
||||
|
||||
async settingsPerformFirmwareUpgrade() {
|
||||
if (this.submitStatus.firmwareUpgrade) { return }
|
||||
this.submitStatus.firmwareUpgrade = true
|
||||
try {
|
||||
await fetch('/api/doFirmwareUpgrade', { method: 'POST' })
|
||||
} catch (e) {
|
||||
console.log("failed to perform upgrade firmware: ", e)
|
||||
}
|
||||
this.submitStatus.firmwareUpgrade = false
|
||||
},
|
||||
|
||||
doModemReboot() {
|
||||
if (this.submitStatus.modemReboot !== null) {
|
||||
return
|
||||
}
|
||||
this.submitStatus.modemReboot = 30
|
||||
fetch('/api/reboot', { method: 'POST' }).then((r) => {})
|
||||
},
|
34
front-generator/template/common/admin.html.j2
Normal file
34
front-generator/template/common/admin.html.j2
Normal file
@@ -0,0 +1,34 @@
|
||||
{% from 'common/widgets.j2' import build_widget %}
|
||||
<div class="tabs-body-item" v-if="activeTab === 'admin' && settingFetchComplete">
|
||||
{% if 'network' in params %}
|
||||
{% for w in params['network'] %}{{ build_widget('network', w) | indent(12, true) }}{% endfor %}
|
||||
{% endif %}
|
||||
{% raw %}
|
||||
<h2>Система</h2>
|
||||
<div class="settings-set-container">
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Версия ПО</th><td>{{ about.firmwareVersion }}</td></tr>
|
||||
<tr><th>ID модема</th><td>{{ about.modemUid }}</td></tr>
|
||||
<tr><th>Серийный номер</th><td>{{ about.modemSn }}</td></tr>
|
||||
<tr><th>MAC интерфейса управления</th><td>{{ about.macManagement }}</td></tr>
|
||||
<tr><th>MAC интерфейса данных</th><td>{{ about.macData }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div>
|
||||
<button class="dangerous-button" @click="doModemReboot()">Перезагрузить модем <span class="submit-spinner" v-show="submitStatus.modemReboot !== null"></span></button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button>
|
||||
</div>
|
||||
|
||||
<h3>Обновление ПО</h3>
|
||||
<label>
|
||||
<span>Файл {{ this.uploadFw.progress !== null ? `(${this.uploadFw.progress}%)` : '' }}</span>
|
||||
<input type="file" accept="application/zip" @change="(e) => { this.uploadFw.filename = e.target.files[0] }">
|
||||
<span v-if="uploadFw.sha256 !== null">SHA256: {{ uploadFw.sha256 }}</span>
|
||||
</label>
|
||||
<button class="action-button" @click="settingsUploadUpdate()">Загрузить<span class="submit-spinner" v-show="submitStatus.firmwareUpload"></span></button>
|
||||
<button class="dangerous-button" v-show="uploadFw.sha256 !== null" @click="settingsPerformFirmwareUpgrade()">Обновить встроенное ПО <span class="submit-spinner" v-show="submitStatus.firmwareUpgrade"></span></button>
|
||||
</div>{% endraw %}
|
||||
</div>
|
7
front-generator/template/common/all-params-data.js.j2
Normal file
7
front-generator/template/common/all-params-data.js.j2
Normal file
@@ -0,0 +1,7 @@
|
||||
{% for g in paramGroups %}
|
||||
param{{ g['group'] | title }}: {
|
||||
{% for p in g['params'] %}
|
||||
{{ p['name'] }}: {{ p['initValue'] }},
|
||||
{% endfor %}
|
||||
},
|
||||
{% endfor %}
|
29
front-generator/template/common/all-params-methods.js.j2
Normal file
29
front-generator/template/common/all-params-methods.js.j2
Normal file
@@ -0,0 +1,29 @@
|
||||
{% for g in paramGroups %}
|
||||
settingsSubmit{{ g['group'] | title }}() {
|
||||
if (this.submitStatus.{{ g['group'] }}) { return }
|
||||
{% if g['group'] in dangerousParamGroups %}
|
||||
{ if (!confirm("{{ dangerousParamGroups[g['group']] }}")) return }
|
||||
{% endif %}
|
||||
|
||||
let query = {
|
||||
{% for p in g['params'] %}
|
||||
"{{ p['name'] }}": this.param{{ g['group'] | title }}.{{ p['name'] }},
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
this.submitStatus.{{ g['group'] }} = true
|
||||
fetch('/api/set/{{ g["group"] }}', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(query), credentials: 'same-origin' })
|
||||
.then(async (resp) => { let vals = await resp.json(); if (vals['status'] !== 'ok') { throw new Error(vals['error'] ? vals['error'] : "Server returns undefined error") } this.update{{ g['group'] | title }}Settings(vals) })
|
||||
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
|
||||
.finally(() => { this.submitStatus.{{ g['group'] }} = false })
|
||||
},
|
||||
{% endfor %}
|
||||
|
||||
{% for g in paramGroups %}
|
||||
update{{ g['group'] | title }}Settings(vals) {
|
||||
this.submitStatus.{{ g['group'] }} = false
|
||||
{% for p in g['params'] %}
|
||||
this.param{{ g['group'] | title }}.{{ p['name'] }} = vals["settings"]["{{ p['name'] }}"]
|
||||
{% endfor %}
|
||||
},
|
||||
{% endfor %}
|
47
front-generator/template/common/monitoring-data.js.j2
Normal file
47
front-generator/template/common/monitoring-data.js.j2
Normal file
@@ -0,0 +1,47 @@
|
||||
statRx: {
|
||||
// индикаторы
|
||||
state: '?', // общее состояние
|
||||
sym_sync_lock: '?', // захват символьной
|
||||
freq_search_lock: '?', // Захват поиска по частоте
|
||||
afc_lock: '?', // захват ФАПЧ
|
||||
pkt_sync: '?', // захват пакетной синхронизации
|
||||
|
||||
// куча других параметров, идет в том же порядке, что и в таблице
|
||||
snr: '?', rssi: '?',
|
||||
modcod: '?', frameSizeNormal: '?',
|
||||
isPilots: '?',
|
||||
symError: '?',
|
||||
freqErr: '?', freqErrAcc: '?',
|
||||
inputSignalLevel: '?',
|
||||
pllError: '?',
|
||||
speedOnRxKbit: '?',
|
||||
speedOnIifKbit: '?',
|
||||
|
||||
// статистика пакетов
|
||||
packetsOk: '?', packetsBad: '?', packetsDummy: '?',
|
||||
},
|
||||
statTx: {
|
||||
// состояние
|
||||
state: '?',
|
||||
|
||||
// прочие поля
|
||||
{% if modem == 'scpc' %}
|
||||
snr: '?', modcod: '?', frameSizeNormal: '?', isPilots: '?', speedOnTxKbit: '?', speedOnIifKbit: '?',
|
||||
{% else %}
|
||||
modcod: '?', speedOnTxKbit: '?', speedOnIifKbit: '?', centerFreq: '?', symSpeed: '?',
|
||||
{% endif %}
|
||||
},
|
||||
{% if modem == 'scpc' %}
|
||||
statCinc: {
|
||||
occ: '?',
|
||||
correlator: null,
|
||||
correlatorFails: '?',
|
||||
freqErr: '?', freqErrAcc: '?',
|
||||
channelDelay: '?'
|
||||
},
|
||||
{% endif %}
|
||||
statDevice: { // температурные датчики
|
||||
adrv: 0, zynq: 0, fpga: 0
|
||||
},
|
||||
statOs: {uptime: '?', load1: '?', load5: '?', load15: '?', totalram: '?', freeram: '?'},
|
||||
|
103
front-generator/template/common/monitoring-methods.js.j2
Normal file
103
front-generator/template/common/monitoring-methods.js.j2
Normal file
@@ -0,0 +1,103 @@
|
||||
updateStatistics(vals) {
|
||||
function modcodToStr(modcod) {
|
||||
// модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
|
||||
const modcods = [
|
||||
"DUMMY",
|
||||
"QPSK 1/4", "QPSK 1/3", "QPSK 2/5", "QPSK 1/2", "QPSK 3/5", "QPSK 2/3", "QPSK 3/4", "QPSK 4/5", "QPSK 5/6", "QPSK 8/9", "QPSK 9/10",
|
||||
"8PSK 3/5", "8PSK 2/3", "8PSK 3/4", "8PSK 5/6", "8PSK 8/9", "8PSK 9/10",
|
||||
"16APSK 2/3", "16APSK 3/4", "16APSK 4/5", "16APSK 5/6", "16APSK 8/9", "16APSK 9/10",
|
||||
"32APSK 3/4", "32APSK 4/5", "32APSK 5/6", "32APSK 8/9", "32APSK 9/10",
|
||||
]
|
||||
if (typeof modcod != "number" || modcod < 0 || modcod >= modcod.length) {
|
||||
return "?";
|
||||
}
|
||||
return modcods[modcod]
|
||||
}
|
||||
|
||||
this.lastUpdateTime = new Date();
|
||||
this.initState = vals["mainState"]["initState"]
|
||||
{% if modem == 'scpc' %}
|
||||
this.isCinC = vals["mainState"]["isCinC"]
|
||||
{% endif %}
|
||||
|
||||
this.statRx.state = vals["mainState"]["rx.state"]
|
||||
this.statRx.sym_sync_lock = vals["mainState"]["rx.sym_sync_lock"]
|
||||
this.statRx.freq_search_lock = vals["mainState"]["rx.freq_search_lock"]
|
||||
this.statRx.afc_lock = vals["mainState"]["rx.afc_lock"]
|
||||
this.statRx.pkt_sync = vals["mainState"]["rx.pkt_sync"]
|
||||
this.statRx.snr = vals["mainState"]["rx.snr"]
|
||||
this.statRx.rssi = vals["mainState"]["rx.rssi"]
|
||||
this.statRx.modcod = modcodToStr(vals["mainState"]["rx.modcod"])
|
||||
this.statRx.frameSizeNormal = vals["mainState"]["rx.frameSizeNormal"]
|
||||
this.statRx.isPilots = vals["mainState"]["rx.isPilots"]
|
||||
this.statRx.symError = vals["mainState"]["rx.symError"]
|
||||
this.statRx.freqErr = vals["mainState"]["rx.freqErr"]
|
||||
this.statRx.freqErrAcc = vals["mainState"]["rx.freqErrAcc"]
|
||||
this.statRx.inputSignalLevel = vals["mainState"]["rx.inputSignalLevel"]
|
||||
this.statRx.pllError = vals["mainState"]["rx.pllError"]
|
||||
this.statRx.speedOnRxKbit = vals["mainState"]["rx.speedOnRxKbit"]
|
||||
this.statRx.speedOnIifKbit = vals["mainState"]["rx.speedOnIifKbit"]
|
||||
this.statRx.packetsOk = vals["mainState"]["rx.packetsOk"]
|
||||
this.statRx.packetsBad = vals["mainState"]["rx.packetsBad"]
|
||||
this.statRx.packetsDummy = vals["mainState"]["rx.packetsDummy"]
|
||||
|
||||
{% if modem == 'scpc' %}
|
||||
this.statTx.state = vals["mainState"]["tx.state"]
|
||||
this.statTx.snr = vals["mainState"]["tx.snr"]
|
||||
this.statTx.modcod = modcodToStr(vals["mainState"]["tx.modcod"])
|
||||
this.statTx.frameSizeNormal = vals["mainState"]["tx.frameSizeNormal"]
|
||||
this.statTx.isPilots = vals["mainState"]["tx.isPilots"]
|
||||
this.statTx.speedOnTxKbit = vals["mainState"]["tx.speedOnTxKbit"]
|
||||
this.statTx.speedOnIifKbit = vals["mainState"]["tx.speedOnIifKbit"]
|
||||
|
||||
this.statCinc.occ = vals["mainState"]["cinc.occ"]
|
||||
this.statCinc.correlator = vals["mainState"]["cinc.correlator"]
|
||||
this.statCinc.correlatorFails = vals["mainState"]["cinc.correlatorFails"]
|
||||
this.statCinc.freqErr = vals["mainState"]["cinc.freqErr"]
|
||||
this.statCinc.freqErrAcc = vals["mainState"]["cinc.freqErrAcc"]
|
||||
this.statCinc.channelDelay = vals["mainState"]["cinc.channelDelay"]
|
||||
{% else %}
|
||||
this.statTx.state = vals["mainState"]["tx.state"]
|
||||
this.statTx.modcod = modcodToStr(vals["mainState"]["tx.modcod"])
|
||||
this.statTx.speedOnTxKbit = vals["mainState"]["tx.speedOnTxKbit"]
|
||||
this.statTx.speedOnIifKbit = vals["mainState"]["tx.speedOnIifKbit"]
|
||||
this.statTx.centerFreq = vals["mainState"]["tx.centerFreq"]
|
||||
this.statTx.symSpeed = vals["mainState"]["tx.symSpeed"]
|
||||
{% endif %}
|
||||
|
||||
this.statDevice.adrv = vals["mainState"]["device.adrv"]
|
||||
this.statDevice.zynq = vals["mainState"]["device.zynq"]
|
||||
this.statDevice.fpga = vals["mainState"]["device.fpga"]
|
||||
|
||||
this.testState = vals["mainState"]["testState"]
|
||||
|
||||
// аптайм приходит в секундах, надо преобразовать его в человеко-читаемый вид
|
||||
let uptime = vals["sysinfo"]["uptime"]
|
||||
if (uptime) {
|
||||
let secs = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
let mins = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
let hours = uptime % 24
|
||||
uptime = Math.floor( uptime / 24)
|
||||
let res = `${hours}:${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
|
||||
if (uptime > 0) { res = `${uptime} дней, ` + res }
|
||||
this.statOs.uptime = res
|
||||
} else {
|
||||
this.statOs.uptime = '?'
|
||||
}
|
||||
this.statOs.load1 = vals["sysinfo"]["load1min"]
|
||||
this.statOs.load5 = vals["sysinfo"]["load5min"]
|
||||
this.statOs.load15 = vals["sysinfo"]["load15min"]
|
||||
this.statOs.totalram = vals["sysinfo"]["totalram"]
|
||||
this.statOs.freeram = vals["sysinfo"]["freeram"]
|
||||
},
|
||||
|
||||
resetPacketsStatistics() {
|
||||
fetch('/api/resetPacketStatistics', {
|
||||
method: 'POST', credentials: 'same-origin'
|
||||
}).then(() => {
|
||||
this.statRx.packetsOk = 0
|
||||
this.statRx.packetsBad = 0
|
||||
this.statRx.packetsDummy = 0
|
||||
})
|
||||
},
|
||||
|
84
front-generator/template/common/monitoring.html.j2
Normal file
84
front-generator/template/common/monitoring.html.j2
Normal file
@@ -0,0 +1,84 @@
|
||||
{% raw %}
|
||||
<div class="tabs-body-item tabs-item-flex-container" v-if="activeTab === 'monitoring'">
|
||||
<div class="settings-set-container">
|
||||
<h2>Статистика приема</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Прием</th><td><span :class="{ indicator_bad: statRx.state === false, indicator_good: statRx.state === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>Захват символьной</th><td><span :class="{ indicator_bad: statRx.sym_sync_lock === false, indicator_good: statRx.sym_sync_lock === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>Захват ФАПЧ</th><td><span :class="{ indicator_bad: statRx.afc_lock === false, indicator_good: statRx.afc_lock === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>Захват поиска по частоте</th><td><span :class="{ indicator_bad: statRx.freq_search_lock === false, indicator_good: statRx.freq_search_lock === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>Захват пакетной синхр.</th><td><span :class="{ indicator_bad: statRx.pkt_sync === false, indicator_good: statRx.pkt_sync === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>SNR/RSSI</th><td>{{ statRx.snr }} / {{ statRx.rssi }}</td></tr>
|
||||
<tr><th>Modcod</th><td>{{ statRx.modcod }}</td></tr>
|
||||
<tr><th>Размер кадра</th><td>{{ statRx.frameSizeNormal ? 'normal' : 'short' }}</td></tr>
|
||||
<tr><th>Пилот-символы</th><td>{{ statRx.isPilots ? 'pilots' : 'no pilots' }}</td></tr>
|
||||
<tr><th>Символьная ошибка</th><td>{{ statRx.symError }}</td></tr>
|
||||
<tr><th>Грубая/точная част. ошибка, Гц</th><td>{{ statRx.freqErr }} / {{ statRx.freqErrAcc }}</td></tr>
|
||||
<tr><th>Ур. входного сигнала</th><td>{{ statRx.inputSignalLevel }}</td></tr>
|
||||
<tr><th>Ошибка ФАПЧ</th><td>{{ statRx.pllError }}</td></tr>
|
||||
<tr><th>Инф. скорость на приеме</th><td>{{ statRx.speedOnRxKbit }} kbit/s</td></tr>
|
||||
<tr><th>Инф. скорость на интерфейсе</th><td>{{ statRx.speedOnIifKbit }} kbit/s</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p> Статистика пакетов </p>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Качественных пакетов</th><td>{{ statRx.packetsOk }}</td></tr>
|
||||
<tr><th>Поврежденных пакетов</th><td>{{ statRx.packetsBad }}</td></tr>
|
||||
<tr><th>DUMMY</th><td>{{ statRx.packetsDummy }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<button class="action-button" @click="resetPacketsStatistics()"> Сброс статистики </button>
|
||||
</div>
|
||||
<div class="settings-set-container">
|
||||
<h2>Статистика передачи</h2>{% endraw %}{% if modem == 'scpc' %}{% raw %}
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Передача</th><td><span :class="{ indicator_bad: statTx.state === false, indicator_good: statTx.state === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>ОСШ дальнего приема</th><td>{{ statTx.snr }}</td></tr>
|
||||
<tr><th>Modcod</th><td>{{ statTx.modcod }}</td></tr>
|
||||
<tr><th>Размер кадра</th><td>{{ statTx.frameSizeNormal ? 'normal' : 'short' }}</td></tr>
|
||||
<tr><th>Пилот-символы</th><td>{{ statTx.isPilots ? 'pilots' : 'no pilots' }}</td></tr>
|
||||
<tr><th>Инф. скорость на передаче</th><td>{{ statTx.speedOnTxKbit }} kbit/s</td></tr>
|
||||
<tr><th>Инф. скорость на интерфейсе</th><td>{{ statTx.speedOnIifKbit }} kbit/s</td></tr>
|
||||
</tbody>
|
||||
</table>{% endraw %}{% else %}{% raw %}
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Передача</th><td><span :class="{ indicator_bad: statTx.state === false, indicator_good: statTx.state === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>Modcod</th><td>{{ statTx.modcod }}</td></tr>
|
||||
<tr><th>Инф. скорость на передаче</th><td>{{ statTx.speedOnTxKbit }} kbit/s</td></tr>
|
||||
<tr><th>Инф. скорость на интерфейсе</th><td>{{ statTx.speedOnIifKbit }} kbit/s</td></tr>
|
||||
<tr><th>Центральная частота</th><td>{{ statTx.centerFreq }} kHz</td></tr>
|
||||
<tr><th>Символьная скорость</th><td>{{ statTx.symSpeed }} ksymb</td></tr>
|
||||
</tbody>
|
||||
</table>{% endraw %}{% endif %}{% raw %}
|
||||
</div>{% endraw %}{% if modem == 'scpc' %}{% raw %}
|
||||
<div class="settings-set-container" v-if="paramRxtx.isCinC === true">
|
||||
<h2>Статистика режима CinC</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>ОСС</th><td>{{ statCinc.occ }}</td></tr>
|
||||
<tr><th>Захват коррелятора</th><td><span :class="{ indicator_bad: statCinc.correlator === false, indicator_good: statCinc.correlator === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>Кол-во срывов коррелятора</th><td>{{ statCinc.correlatorFails }}</td></tr>
|
||||
<tr><th>Грубая/точная част. ошибка, Гц</th><td>{{ statCinc.freqErr }} / {{ statCinc.freqErrAcc }}</td></tr>
|
||||
<tr><th>Задержка в канале, мс</th><td>{{ statCinc.channelDelay }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>{% endraw %}{% endif %}{% raw %}
|
||||
<div class="settings-set-container">
|
||||
<h2>Состояние устройства</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Температура ADRV</th><td>{{ statDevice.adrv }} °C</td></tr>
|
||||
<tr><th>Температура ZYNQ</th><td>{{ statDevice.zynq }} °C</td></tr>
|
||||
<tr><th>Температура FPGA</th><td>{{ statDevice.fpga }} °C</td></tr>
|
||||
<tr><th>Время работы устройства</th><td>{{ statOs.uptime }}</td></tr>
|
||||
<tr><th>Средняя загрузка ЦП (1/5/15 мин.)</th><td>{{ statOs.load1 }}% {{ statOs.load5 }}% {{ statOs.load15 }}%</td></tr>
|
||||
<tr><th>ОЗУ всего/свободно</th><td>{{ statOs.totalram }}MB/{{ statOs.freeram }}MB</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endraw %}
|
8
front-generator/template/common/qos-data.js.j2
Normal file
8
front-generator/template/common/qos-data.js.j2
Normal file
@@ -0,0 +1,8 @@
|
||||
submitStatusQos: false,
|
||||
paramQos: {
|
||||
en: false,
|
||||
rt1: [],
|
||||
rt2: [],
|
||||
rt3: [],
|
||||
cd: [],
|
||||
},
|
222
front-generator/template/common/qos-methods.js.j2
Normal file
222
front-generator/template/common/qos-methods.js.j2
Normal file
@@ -0,0 +1,222 @@
|
||||
settingsSubmitQoS() {
|
||||
if (this.submitStatusQos) { return }
|
||||
this.submitStatusQos = true
|
||||
function _translateQosClass(trafficClass, qc) {
|
||||
let res = {
|
||||
cir: qc['cir'],
|
||||
description: qc['description'],
|
||||
filters: []
|
||||
}
|
||||
if (trafficClass === 'cd') {
|
||||
res.pir = qc.pir
|
||||
}
|
||||
if (!qc.isEnabled) {
|
||||
res.disabled = true
|
||||
}
|
||||
for (const fi in qc.filters) {
|
||||
let filter = {}
|
||||
if (qc['filters'][fi].vlan !== "") { filter['vlan'] = qc['filters'][fi].vlan }
|
||||
if (qc['filters'][fi].proto.length > 0) {
|
||||
let tmp = "";
|
||||
for (let pid = 0; pid < qc['filters'][fi].proto.length; pid++) {
|
||||
if (pid !== 0) { tmp += ',' }
|
||||
tmp += qc['filters'][fi].proto[pid]
|
||||
}
|
||||
filter['proto'] = tmp
|
||||
}
|
||||
if (qc['filters'][fi].sport !== "") { filter['sport'] = qc['filters'][fi].sport }
|
||||
if (qc['filters'][fi].dport !== "") { filter['dport'] = qc['filters'][fi].dport }
|
||||
if (qc['filters'][fi].ip_src !== "") { filter['ip_src'] = qc['filters'][fi].ip_src }
|
||||
if (qc['filters'][fi].ip_dest !== "") { filter['ip_dest'] = qc['filters'][fi].ip_dest }
|
||||
if (qc['filters'][fi].dscp !== "") { filter['dscp'] = qc['filters'][fi].dscp }
|
||||
|
||||
if (Object.keys(filter).length === 0) { continue }
|
||||
if (!qc.filters[fi].isEnabled) { filter['disabled'] = true }
|
||||
|
||||
res.filters.push(filter)
|
||||
}
|
||||
if (res.filters.length === 0) {
|
||||
// автоматическое выключение класса, если правил нет
|
||||
res.disabled = true
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
let query = {
|
||||
"en": this.paramQos.en,
|
||||
"rt1": [],
|
||||
"rt2": [],
|
||||
"rt3": [],
|
||||
"cd": []
|
||||
}
|
||||
for (let i = 0; i < this.paramQos.rt1.length; i++) { query.rt1.push(_translateQosClass('rt', this.paramQos.rt1[i])) }
|
||||
for (let i = 0; i < this.paramQos.rt2.length; i++) { query.rt2.push(_translateQosClass('rt', this.paramQos.rt2[i])) }
|
||||
for (let i = 0; i < this.paramQos.rt3.length; i++) { query.rt3.push(_translateQosClass('rt', this.paramQos.rt3[i])) }
|
||||
for (let i = 0; i < this.paramQos.cd.length; i++) { query.cd.push(_translateQosClass('rt', this.paramQos.cd[i])) }
|
||||
|
||||
//console.log(query)
|
||||
fetch('/api/set/qos', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(query), credentials: 'same-origin'
|
||||
}).then(async (resp) => {
|
||||
this.submitStatusQos = false
|
||||
if (resp['error']) { throw new Error(resp['error']) }
|
||||
this.updateQosSettings(await resp.json())
|
||||
}).catch((reason) => {
|
||||
this.submitStatusQos = false
|
||||
alert(`Ошибка при применении настроек: ${reason}`)
|
||||
})
|
||||
},
|
||||
|
||||
updateQosSettings(vals) {
|
||||
this.submitStatusQos = false
|
||||
this.paramQos.en = vals["settings"]["qos.enabled"]
|
||||
|
||||
const qosProfile = vals["settings"]["qos.profile"]
|
||||
if (qosProfile !== null && qosProfile !== undefined) {
|
||||
this.paramQos.rt1 = [] // .splice(0, this.paramQos.rt1.length)
|
||||
this.paramQos.rt2 = [] // .splice(0, this.paramQos.rt2.length)
|
||||
this.paramQos.rt3 = [] // .splice(0, this.paramQos.rt3.length)
|
||||
this.paramQos.cd = [] // .splice(0, this.paramQos.cd.length)
|
||||
|
||||
for (let trafficClass in qosProfile) {
|
||||
if (['rt1', 'rt2', 'rt3', 'cd'].indexOf(trafficClass) < 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (Array.isArray(qosProfile[trafficClass])) {
|
||||
for (let i = 0; i < qosProfile[trafficClass].length; i++) {
|
||||
const qc = qosProfile[trafficClass][i]
|
||||
let result = {
|
||||
isEnabled: !qc.hasOwnProperty('disabled'),
|
||||
cir: qc['cir'],
|
||||
pir: 0,
|
||||
description: qc['description'],
|
||||
filters: []
|
||||
}
|
||||
if (trafficClass === 'cd') {
|
||||
if (qc['pir']) {
|
||||
result.pir = qc['pir']
|
||||
}
|
||||
}
|
||||
for (let fi = 0; fi < qc['filters'].length; fi++) {
|
||||
result.filters.push({
|
||||
isEnabled: !qc['filters'][fi].hasOwnProperty('disabled'),
|
||||
vlan: qc['filters'][fi].hasOwnProperty('vlan') ? qc['filters'][fi]['vlan'] : '',
|
||||
proto: qc['filters'][fi].hasOwnProperty('proto') ? qc['filters'][fi]['proto'].split(',') : [],
|
||||
sport: qc['filters'][fi].hasOwnProperty('sport') ? qc['filters'][fi]['sport'] : '',
|
||||
dport: qc['filters'][fi].hasOwnProperty('dport') ? qc['filters'][fi]['dport'] : '',
|
||||
ip_src: qc['filters'][fi].hasOwnProperty('ip_src') ? qc['filters'][fi]['ip_src'] : '',
|
||||
ip_dest: qc['filters'][fi].hasOwnProperty('ip_dest') ? qc['filters'][fi]['ip_dest'] : '',
|
||||
dscp: qc['filters'][fi].hasOwnProperty('dscp') ? qc['filters'][fi]['dscp'] : ''
|
||||
})
|
||||
}
|
||||
switch (trafficClass) {
|
||||
case 'rt1': this.paramQos.rt1.push(result); break
|
||||
case 'rt2': this.paramQos.rt2.push(result); break
|
||||
case 'rt3': this.paramQos.rt3.push(result); break
|
||||
case 'cd': this.paramQos.cd.push(result); break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
qosAddClass(name) {
|
||||
let res = {
|
||||
isEnabled: true,
|
||||
cir: 0,
|
||||
pir: 0,
|
||||
description: "",
|
||||
filters: []
|
||||
}
|
||||
switch (name) {
|
||||
case 'rt1': this.paramQos.rt1.push(res); break
|
||||
case 'rt2': this.paramQos.rt2.push(res); break
|
||||
case 'rt3': this.paramQos.rt3.push(res); break
|
||||
case 'cd': this.paramQos.cd.push(res); break
|
||||
}
|
||||
},
|
||||
|
||||
qosClassAddRule(name, index) {
|
||||
let rule = {
|
||||
isEnabled: true,
|
||||
vlan: "",
|
||||
proto: [],
|
||||
sport: "",
|
||||
dport: "",
|
||||
ip_src: "",
|
||||
ip_dest: "",
|
||||
dscp: ""
|
||||
}
|
||||
switch (name) {
|
||||
case 'rt1': this.paramQos.rt1[index].filters.push(rule); break
|
||||
case 'rt2': this.paramQos.rt2[index].filters.push(rule); break
|
||||
case 'rt3': this.paramQos.rt3[index].filters.push(rule); break
|
||||
case 'cd': this.paramQos.cd[index].filters.push(rule); break
|
||||
}
|
||||
},
|
||||
|
||||
qosDelClass(name, index) {
|
||||
switch (name) {
|
||||
case 'rt1': this.paramQos.rt1.splice(index, 1); break
|
||||
case 'rt2': this.paramQos.rt2.splice(index, 1); break
|
||||
case 'rt3': this.paramQos.rt3.splice(index, 1); break
|
||||
case 'cd': this.paramQos.cd.splice(index, 1); break
|
||||
}
|
||||
},
|
||||
|
||||
qosDelFilter(name, index, filterIndex) {
|
||||
switch (name) {
|
||||
case 'rt1': this.paramQos.rt1[index].filters.splice(filterIndex, 1); break
|
||||
case 'rt2': this.paramQos.rt2[index].filters.splice(filterIndex, 1); break
|
||||
case 'rt3': this.paramQos.rt3[index].filters.splice(filterIndex, 1); break
|
||||
case 'cd': this.paramQos.cd[index].filters.splice(filterIndex, 1); break
|
||||
}
|
||||
},
|
||||
|
||||
qosGenerateRuleDescription(filter) {
|
||||
// попытка 1: просто отобразить все фильтры
|
||||
let result = ""
|
||||
let isFirst = true;
|
||||
for (const key in filter) {
|
||||
if (key === "isEnabled" || !filter[key] || (key === "proto" && filter['proto'].length === 0)) {
|
||||
continue
|
||||
}
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
result += '; '
|
||||
}
|
||||
result += `${key}: ${filter[key]}`
|
||||
}
|
||||
if (result === "") {
|
||||
return "пустой"
|
||||
}
|
||||
|
||||
const maxResultLen = 60
|
||||
|
||||
if (result.length > maxResultLen) {
|
||||
// попытка 2, отобразить что вообще в этом фильтре использовалось
|
||||
result = ""
|
||||
isFirst = true;
|
||||
for (const key in filter) {
|
||||
if (key === "isEnabled" || !filter[key] || (key === "proto" && filter['proto'].length === 0)) {
|
||||
continue
|
||||
}
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
result += ', '
|
||||
}
|
||||
result += `${key}`
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
},
|
||||
|
107
front-generator/template/common/qos.html.j2
Normal file
107
front-generator/template/common/qos.html.j2
Normal file
@@ -0,0 +1,107 @@
|
||||
{% from 'common/widgets.j2' import build_widget %}
|
||||
{% raw %}
|
||||
<div class="tabs-body-item" v-if="activeTab === 'qos' && settingFetchComplete">
|
||||
<h2>Настройки QoS</h2>
|
||||
<div class="settings-set-container">
|
||||
<label>
|
||||
<span>Активировать QoS</span>
|
||||
<span class="toggle-input"><input type="checkbox" v-model="paramQos.en" /><span class="slider"></span></span>
|
||||
</label>
|
||||
</div>
|
||||
<div v-for="classesGroup in ['rt1', 'rt2', 'rt3', 'cd']">
|
||||
<h3>Классы {{ classesGroup.toUpperCase() }} <button class="action-button" @click="qosAddClass(classesGroup)"> + </button></h3>
|
||||
<details v-for="(qosClass, index) in paramQos[classesGroup]" :key="index" class="settings-set-container">
|
||||
<summary>
|
||||
<span v-if="classesGroup === 'cd'">#{{ index }} CIR={{ qosClass.cir }}кбит, PIR={{ qosClass.pir }}кбит {{ qosClass.description }}</span>
|
||||
<span v-if="classesGroup !== 'cd'">#{{ index }} CBR={{ qosClass.cir }}кбит {{ qosClass.description }}</span>
|
||||
<span class="summary-actions">
|
||||
<label>
|
||||
<span class="toggle-input">
|
||||
<input type="checkbox" v-model="qosClass.isEnabled" />
|
||||
<span class="slider"></span>
|
||||
</span>
|
||||
</label>
|
||||
</span>
|
||||
</summary>
|
||||
<label>
|
||||
<span v-if="classesGroup === 'cd'">CIR</span> <span v-if="classesGroup !== 'cd'">CBR</span>
|
||||
<input v-model="qosClass.cir" type="number"/>
|
||||
</label>
|
||||
<label v-if="classesGroup === 'cd'">
|
||||
<span>PIR</span>
|
||||
<input v-model="qosClass.pir" type="number"/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Описание</span>
|
||||
<input v-model="qosClass.description"/>
|
||||
</label>
|
||||
|
||||
<h3>Фильтры ({{ qosClass.filters.length }})</h3>
|
||||
<div>
|
||||
<button class="action-button" @click="qosClassAddRule(classesGroup, index)">Добавить правило</button>
|
||||
</div>
|
||||
<details v-for="(filter, filterIndex) in qosClass.filters" :key="filterIndex" class="settings-set-container">
|
||||
<summary>
|
||||
<span>#{{ filterIndex }} {{ qosGenerateRuleDescription(filter) }}</span>
|
||||
<span class="summary-actions">
|
||||
<label>
|
||||
<span class="toggle-input">
|
||||
<input type="checkbox" v-model="filter.isEnabled" />
|
||||
<span class="slider"></span>
|
||||
</span>
|
||||
</label>
|
||||
<button class="dangerous-button" @click="qosDelFilter(classesGroup, index, filterIndex)">Del</button>
|
||||
</span>
|
||||
</summary>
|
||||
<label>
|
||||
<span>VLAN ID</span>
|
||||
<!-- singleVlanExpr: (([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4}))-->
|
||||
<!-- expr: ^(((single,)+single)|single)$-->
|
||||
<input v-model="filter.vlan" type="text" pattern="^((((([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4})),)+(([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4})))|(([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4})))$">
|
||||
</label>
|
||||
<div>
|
||||
<span>Протокол L3</span>
|
||||
<label class="l3-proto-label"><span>AH:</span><input type="checkbox" value="ah" v-model="filter.proto"></label>
|
||||
<label class="l3-proto-label"><span>COMP:</span><input type="checkbox" value="comp" v-model="filter.proto"></label>
|
||||
<label class="l3-proto-label"><span>DCCP:</span><input type="checkbox" value="dccp" v-model="filter.proto"></label>
|
||||
<label class="l3-proto-label"><span>ESP:</span><input type="checkbox" value="esp" v-model="filter.proto"></label>
|
||||
<label class="l3-proto-label"><span>ICMP:</span><input type="checkbox" value="icmp" v-model="filter.proto"></label>
|
||||
<!-- <label class="l3-proto-label"><span>ICMPV6:</span><input type="checkbox" value="icmpv6" v-model="filter.proto"></label>-->
|
||||
<label class="l3-proto-label"><span>SCTP:</span><input type="checkbox" value="sctp" v-model="filter.proto"></label>
|
||||
<label class="l3-proto-label"><span>TCP:</span><input type="checkbox" value="tcp" v-model="filter.proto"></label>
|
||||
<label class="l3-proto-label"><span>UDP:</span><input type="checkbox" value="udp" v-model="filter.proto"></label>
|
||||
<label class="l3-proto-label"><span>UDPLITE:</span><input type="checkbox" value="udplite" v-model="filter.proto"></label>
|
||||
</div>
|
||||
<label>
|
||||
<span>Порт источника</span>
|
||||
<input v-model="filter.sport" type="text" pattern="^((((([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})),)+(([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})))|(([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})))$">
|
||||
</label>
|
||||
<label>
|
||||
<span>Порт назначения</span>
|
||||
<input v-model="filter.dport" type="text" pattern="^((((([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})),)+(([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})))|(([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})))$">
|
||||
</label>
|
||||
<label>
|
||||
<span>IP источника</span>
|
||||
<input v-model="filter.ip_src" type="text">
|
||||
</label>
|
||||
<label>
|
||||
<span>IP назначения</span>
|
||||
<input v-model="filter.ip_dest" type="text">
|
||||
</label>
|
||||
<label>
|
||||
<span>Метка IP.DSCP</span>
|
||||
<input v-model="filter.dscp" type="text">
|
||||
</label>
|
||||
</details>
|
||||
|
||||
<div>
|
||||
<button class="dangerous-button" @click="qosDelClass(classesGroup, index)">Удалить класс QoS</button>
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitQoS()">Применить <span class="submit-spinner" v-show="submitStatusQos"></span></button>
|
||||
|
||||
{% endraw %}{% if 'tcpaccel' in params %}
|
||||
{% for w in params['tcpaccel'] %}{{ build_widget('tcpaccel', w) | indent(12, true) }}{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
8
front-generator/template/common/setup-methods.js.j2
Normal file
8
front-generator/template/common/setup-methods.js.j2
Normal file
@@ -0,0 +1,8 @@
|
||||
{% if 'rxtx' in params and modem == 'scpc' %}
|
||||
calcInterfaceSpeedKb(baud, modulation, speed) {
|
||||
const mMod = Math.max(2, ['', '', 'qpsk', '8psk', '16apsk', '32apsk'].indexOf(modulation))
|
||||
const speedVals = {'1/4': 0.25, '1/3': 0.333, '2/5': 0.4, '1/2': 0.5, '3/5': 0.6, '2/3': 0.666, '3/4': 0.75, '4/5': 0.8, '5/6': 0.833, '8/9': 0.888, '9/10': 0.9}
|
||||
const mSpeed = speed in speedVals ? speedVals[speed] : 1
|
||||
return ((baud * mMod * mSpeed) / 1024).toLocaleString()
|
||||
},
|
||||
{% endif %}
|
8
front-generator/template/common/setup.html.j2
Normal file
8
front-generator/template/common/setup.html.j2
Normal file
@@ -0,0 +1,8 @@
|
||||
{% from 'common/widgets.j2' import build_widget %}
|
||||
<div class="tabs-body-item" v-if="activeTab === 'setup' && settingFetchComplete">
|
||||
{% for cat in ['rxtx', 'cinc', 'buclnb'] %}
|
||||
{% if cat in params %}
|
||||
{% for w in params[cat] %}{{ build_widget(cat, w) | indent(12, true) }}{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
69
front-generator/template/common/widgets.j2
Normal file
69
front-generator/template/common/widgets.j2
Normal file
@@ -0,0 +1,69 @@
|
||||
{% macro build_widget_checkbox(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
<span>{{ widget.label }}</span>
|
||||
<span class="toggle-input"><input type="checkbox" v-model="param{{ param_group | title }}.{{ widget.name }}" /><span class="slider"></span></span>
|
||||
</label>{% endmacro %}
|
||||
|
||||
{# https://ru.stackoverflow.com/questions/1241064 #}
|
||||
{% macro build_widget_number(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}><span>{{ widget.label }}</span><input type="number" v-model="param{{ param_group | title }}.{{ widget.name }}"{% if widget['min'] %} min="{{ widget['min'] }}"{% endif %}{% if widget['max'] %} max="{{ widget['max'] }}"{% endif %}{% if widget['step'] %} step="{{ widget['step'] }}"{% endif %}/></label>{% endmacro %}
|
||||
|
||||
{% macro build_widget_select(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
<span>{{ widget.label }}</span>
|
||||
<select v-model="param{{ param_group | title }}.{{ widget.name }}">
|
||||
{% for opt in widget['values'] %} <option :value="{{ opt.value }}">{{ opt.label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</label>{% endmacro %}
|
||||
|
||||
{% macro build_widget_watch(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}><span>{{ widget.label }}</span><input type="text" readonly v-model="{{ widget.model }}"/></label>{% endmacro %}
|
||||
|
||||
{% macro build_widget_watch_expr(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
<span>{{ widget.label }}</span><span>{{ '{{ ' ~ widget.expr ~ ' }}' }}</span>
|
||||
</label>{% endmacro %}
|
||||
|
||||
|
||||
{% macro build_widget_modulation_modcod(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
<span>{{ widget.label }}</span>
|
||||
<select v-model="param{{ param_group | title }}.{{ widget.name }}Modulation" @change="param{{ param_group | title }}.{{ widget.name }}Speed = correctModcodSpeed(param{{ param_group | title }}.{{ widget.name }}Modulation, param{{ param_group | title }}.{{ widget.name }}Speed)">
|
||||
<option :value="'qpsk'">QPSK</option>
|
||||
<option :value="'8psk'">8PSK</option>
|
||||
<option :value="'16apsk'">16APSK</option>
|
||||
<option :value="'32apsk'">32APSK</option>
|
||||
</select>
|
||||
</label>{% endmacro %}
|
||||
|
||||
{% macro build_widget_modulation_speed(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
<span>{{ widget.label }}</span>
|
||||
<select v-model="param{{ param_group | title }}.{{ widget.name }}Speed">
|
||||
<option v-for="speed in getAvailableModcods(param{{ param_group | title }}.{{ widget.name }}Modulation)" v-bind:value="speed">{{ '{{' }} speed {{ '}}' }}</option>
|
||||
</select>
|
||||
</label>{% endmacro %}
|
||||
|
||||
{% macro build_widget_flex_container(param_group, widget) %}<div class="tabs-item-flex-container"{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
{% for w in widget.childs %}{{ build_widget(param_group, w) | indent(4, true) }}{% endfor %}
|
||||
</div>{% endmacro %}
|
||||
|
||||
{% macro build_widget_settings_container(param_group, widget) %}<div class="settings-set-container"{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
{% for w in widget.childs %}{{ build_widget(param_group, w) | indent(4, true) }}{% endfor %}
|
||||
</div>{% endmacro %}
|
||||
|
||||
{% macro build_widget_ip_address(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
<span>{{ widget.label }}</span>
|
||||
<input v-model="param{{ param_group | title }}.{{ widget.name }}" required type="text" pattern="^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$">
|
||||
</label>{% endmacro %}
|
||||
|
||||
{% macro build_widget(param_group, widget) %}{% if widget.widget == 'flex-container' %}{{ build_widget_flex_container(param_group, widget) }}
|
||||
{% elif widget.widget == 'settings-container' %}{{ build_widget_settings_container(param_group, widget) }}
|
||||
{% elif widget.widget == 'h2' %}<h2{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>{{ widget.label }}</h2>
|
||||
{% elif widget.widget == 'h3' %}<h3{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>{{ widget.label }}</h3>
|
||||
{% elif widget.widget == 'submit' %}<button class="action-button" @click="settingsSubmit{{ param_group | title }}()"{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>Сохранить <span class="submit-spinner" v-show="submitStatus.{{ param_group }}"></span></button>
|
||||
{% elif widget.widget == 'checkbox' %}{{ build_widget_checkbox(param_group, widget) }}
|
||||
{% elif widget.widget == 'number' %}{{ build_widget_number(param_group, widget) }}
|
||||
{% elif widget.widget == 'watch' %}{{ build_widget_watch(param_group, widget) }}
|
||||
{% elif widget.widget == 'watch-expr' %}{{ build_widget_watch_expr(param_group, widget) }}
|
||||
{% elif widget.widget == 'select' %}{{ build_widget_select(param_group, widget) }}
|
||||
{% elif widget.widget == 'modulation-modcod' %}{{ build_widget_modulation_modcod(param_group, widget) }}
|
||||
{% elif widget.widget == 'modulation-speed' %}{{ build_widget_modulation_speed(param_group, widget) }}
|
||||
{% elif widget.widget == 'ip-address' %}{{ build_widget_ip_address(param_group, widget) }}
|
||||
{% else %}<p>Widget '{{ widget.widget }}' not defined!</p><p>{{ widget }}</p>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
@@ -1,139 +0,0 @@
|
||||
{% raw %}// для обновления высоты хидера
|
||||
function updateHeaderHeight() { const header = document.querySelector('header'); document.body.style.setProperty('--header-height', `${header.offsetHeight}px`); }
|
||||
window.addEventListener('load', updateHeaderHeight); window.addEventListener('resize', updateHeaderHeight);
|
||||
|
||||
function getCurrentTab() {
|
||||
const sl = window.location.hash.slice(1)
|
||||
if (availableTabs.indexOf(sl) >= 0) {
|
||||
return sl
|
||||
}
|
||||
return defaultTab
|
||||
}
|
||||
|
||||
function modcodToStr(modcod) {
|
||||
// модкоды из раздела 5.5.2.2 https://www.etsi.org/deliver/etsi_en/302300_302399/302307/01.01.02_60/en_302307v010102p.pdf
|
||||
|
||||
// NOTE модкоды со скоростью хода 3/5 не работают
|
||||
const modcods = [
|
||||
"DUMMY",
|
||||
"QPSK 1/4",
|
||||
"QPSK 1/3",
|
||||
"QPSK 2/5",
|
||||
"QPSK 1/2",
|
||||
"QPSK 3/5", // отключено
|
||||
"QPSK 2/3",
|
||||
"QPSK 3/4",
|
||||
"QPSK 4/5",
|
||||
"QPSK 5/6",
|
||||
"QPSK 8/9",
|
||||
"QPSK 9/10",
|
||||
|
||||
"8PSK 3/5", // отключено
|
||||
"8PSK 2/3",
|
||||
"8PSK 3/4",
|
||||
"8PSK 5/6",
|
||||
"8PSK 8/9",
|
||||
"8PSK 9/10",
|
||||
|
||||
"16APSK 2/3",
|
||||
"16APSK 3/4",
|
||||
"16APSK 4/5",
|
||||
"16APSK 5/6",
|
||||
"16APSK 8/9",
|
||||
"16APSK 9/10",
|
||||
|
||||
"32APSK 3/4",
|
||||
"32APSK 4/5",
|
||||
"32APSK 5/6",
|
||||
"32APSK 8/9",
|
||||
"32APSK 9/10",
|
||||
]
|
||||
if (typeof modcod != "number" || modcod < 0 || modcod >= modcod.length) {
|
||||
return "?";
|
||||
}
|
||||
return modcods[modcod]
|
||||
}
|
||||
|
||||
function toModcod(modulation, speed) {
|
||||
switch (modulation.toLowerCase()) {
|
||||
case 'qpsk':
|
||||
switch (speed) {
|
||||
case '1/4': return 1
|
||||
case '1/3': return 2
|
||||
case '2/5': return 3
|
||||
case '1/2': return 4
|
||||
case '3/5': return 5 // отключено
|
||||
case '2/3': return 6
|
||||
case '3/4': return 7
|
||||
case '4/5': return 8
|
||||
case '5/6': return 9
|
||||
case '8/9': return 10
|
||||
case '9/10': return 11
|
||||
default: return 1 // минимальная скорость
|
||||
}
|
||||
case '8psk':
|
||||
switch (speed) {
|
||||
case '3/5': return 12 // отключено
|
||||
case '2/3': return 13
|
||||
case '3/4': return 14
|
||||
case '5/6': return 15
|
||||
case '8/9': return 16
|
||||
case '9/10': return 17
|
||||
default: return 13 // минимальная скорость
|
||||
}
|
||||
case '16apsk':
|
||||
switch (speed) {
|
||||
case '2/3': return 18
|
||||
case '3/4': return 19
|
||||
case '4/5': return 20
|
||||
case '5/6': return 21
|
||||
case '8/9': return 22
|
||||
case '9/10': return 23
|
||||
default: return 18 // минимальная скорость
|
||||
}
|
||||
case '32apsk':
|
||||
switch (speed) {
|
||||
case '3/4': return 24
|
||||
case '4/5': return 25
|
||||
case '5/6': return 26
|
||||
case '8/9': return 27
|
||||
case '9/10': return 28
|
||||
default: return 24
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function extractModulationAndSpeedFromModcod(modcod) {
|
||||
switch (modcod) {
|
||||
case 1: return { modulation: 'qpsk', speed: '1/4' }
|
||||
case 2: return { modulation: 'qpsk', speed: '1/3' }
|
||||
case 3: return { modulation: 'qpsk', speed: '2/5' }
|
||||
case 4: return { modulation: 'qpsk', speed: '1/2' }
|
||||
case 5: return { modulation: 'qpsk', speed: '3/5' }
|
||||
case 6: return { modulation: 'qpsk', speed: '2/3' }
|
||||
case 7: return { modulation: 'qpsk', speed: '3/4' }
|
||||
case 8: return { modulation: 'qpsk', speed: '4/5' }
|
||||
case 9: return { modulation: 'qpsk', speed: '5/6' }
|
||||
case 10: return { modulation: 'qpsk', speed: '8/9' }
|
||||
case 11: return { modulation: 'qpsk', speed: '9/10' }
|
||||
case 12: return { modulation: '8psk', speed: '3/5' }
|
||||
case 13: return { modulation: '8psk', speed: '2/3' }
|
||||
case 14: return { modulation: '8psk', speed: '3/4' }
|
||||
case 15: return { modulation: '8psk', speed: '5/6' }
|
||||
case 16: return { modulation: '8psk', speed: '8/9' }
|
||||
case 17: return { modulation: '8psk', speed: '9/10' }
|
||||
case 18: return { modulation: '16apsk', speed: '2/3' }
|
||||
case 19: return { modulation: '16apsk', speed: '3/4' }
|
||||
case 20: return { modulation: '16apsk', speed: '4/5' }
|
||||
case 21: return { modulation: '16apsk', speed: '5/6' }
|
||||
case 22: return { modulation: '16apsk', speed: '8/9' }
|
||||
case 23: return { modulation: '16apsk', speed: '9/10' }
|
||||
case 24: return { modulation: '32apsk', speed: '3/4' }
|
||||
case 25: return { modulation: '32apsk', speed: '4/5' }
|
||||
case 26: return { modulation: '32apsk', speed: '5/6' }
|
||||
case 27: return { modulation: '32apsk', speed: '8/9' }
|
||||
case 28: return { modulation: '32apsk', speed: '9/10' }
|
||||
}
|
||||
return { modulation: 'qpsk', speed: '1/4' }
|
||||
}
|
||||
{% endraw %}
|
File diff suppressed because it is too large
Load Diff
@@ -1,181 +0,0 @@
|
||||
isCinC: false,
|
||||
|
||||
// false - означает что статистика не отправляется, true - отправляется
|
||||
submitStatus: {
|
||||
{% for pg in params.groupsList %}
|
||||
{{ pg }}: false,
|
||||
{% endfor %}
|
||||
firmwareUpload: false,
|
||||
firmwareUpgrade: false,
|
||||
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
|
||||
modemReboot: null
|
||||
},
|
||||
|
||||
stat: {
|
||||
|
||||
}
|
||||
|
||||
stat_rx: {
|
||||
// индикаторы
|
||||
state: '?', // общее состояние
|
||||
sym_sync_lock: '?', // захват символьной
|
||||
freq_search_lock: '?', // Захват поиска по частоте
|
||||
afc_lock: '?', // захват ФАПЧ
|
||||
pkt_sync: '?', // захват пакетной синхронизации
|
||||
|
||||
// куча других параметров, идет в том же порядке, что и в таблице
|
||||
snr: '?', rssi: '?',
|
||||
modcod: '?', frameSizeNormal: '?',
|
||||
isPilots: '?',
|
||||
symError: '?',
|
||||
freqErr: '?', freqErrAcc: '?',
|
||||
inputSignalLevel: '?',
|
||||
pllError: '?',
|
||||
speedOnRxKbit: '?',
|
||||
speedOnIifKbit: '?',
|
||||
|
||||
// статистика пакетов
|
||||
packetsOk: '?', packetsBad: '?', packetsDummy: '?',
|
||||
},
|
||||
stat_tx: {
|
||||
// состояние
|
||||
state: '?',
|
||||
|
||||
// прочие поля
|
||||
snr: '?', modcod: '?', frameSizeNormal: '?', isPilots: '?', speedOnTxKbit: '?', speedOnIifKbit: '?',
|
||||
},
|
||||
stat_cinc: {
|
||||
occ: '?',
|
||||
correlator: null,
|
||||
correlatorFails: '?',
|
||||
freqErr: '?', freqErrAcc: '?',
|
||||
channelDelay: '?'
|
||||
},
|
||||
stat_device: { // температурные датчики
|
||||
adrv: 0, zynq: 0, fpga: 0
|
||||
},
|
||||
|
||||
param: {
|
||||
general: {
|
||||
isCinC: Boolean,
|
||||
txEn: Boolean, // включен/выключен
|
||||
modulatorMode: 'normal', // режим работы модулятора
|
||||
autoStartTx: Boolean, // было "режим работы передатчика"
|
||||
isTestInputData: Boolean, // входные данные: eth или test
|
||||
},
|
||||
tx: {
|
||||
attenuation: Number, // ослабление
|
||||
rolloff: Number,
|
||||
cymRate: Number,
|
||||
centerFreq: Number,
|
||||
},
|
||||
dvbs2: {
|
||||
mode: null, // ccm/acm
|
||||
frameSizeNormal: null, // 'normal' / 'short'
|
||||
// isPilots: false,
|
||||
|
||||
// CCM
|
||||
ccm_modulation: null,
|
||||
ccm_speed: null,
|
||||
|
||||
// ACM
|
||||
acm_maxModulation: null,
|
||||
acm_maxSpeed: null,
|
||||
acm_minModulation: null,
|
||||
acm_minSpeed: null,
|
||||
|
||||
snrReserve: null,
|
||||
servicePacketPeriod: null,
|
||||
},
|
||||
// авто-регулировка мощности
|
||||
acm: {
|
||||
en: false,
|
||||
maxAttenuation: null,
|
||||
minAttenuation: null,
|
||||
requiredSnr: null,
|
||||
},
|
||||
rx: {
|
||||
gainMode: null, // 'auto'/'manual' режим управления усилением
|
||||
manualGain: 0, // усиление, только для ручного режима
|
||||
spectrumInversion: false,
|
||||
rolloff: 0,
|
||||
cymRate: 100000,
|
||||
centerFreq: 1200000.0,
|
||||
},
|
||||
|
||||
cinc: {
|
||||
mode: null, // 'positional' | 'delay'
|
||||
searchBandwidth: 0, // полоса поиска в кГц
|
||||
position: {
|
||||
station: {
|
||||
latitude: 0,
|
||||
longitude: 0
|
||||
},
|
||||
satelliteLongitude: 0,
|
||||
},
|
||||
delayMin: 0,
|
||||
delayMax: 0
|
||||
},
|
||||
|
||||
buc: {
|
||||
refClk10M: false, // подача опоры 10MHz
|
||||
powering: 0 // 0, 24, 48
|
||||
},
|
||||
lnb: {
|
||||
refClk10M: false, // подача опоры 10MHz
|
||||
powering: 0 // 0, 13, 18, 24
|
||||
},
|
||||
serviceSettings: {
|
||||
refClk10M: false, // подача опоры 10MHz
|
||||
autoStart: false
|
||||
},
|
||||
|
||||
network: {
|
||||
managementIp: '', // 0.0.0.0/24
|
||||
managementGateway: '',
|
||||
mode: String, // l2 | l3
|
||||
dataIp: '', //
|
||||
dataMtu: 1500
|
||||
},
|
||||
debugSend: {
|
||||
en: false,
|
||||
receiverIp: '0.0.0.0', // 0.0.0.0
|
||||
portCinC: 0,
|
||||
portData: 0,
|
||||
timeout: 0
|
||||
},
|
||||
|
||||
qos: {
|
||||
en: false,
|
||||
rt1: [],
|
||||
rt2: [],
|
||||
rt3: [],
|
||||
cd: [],
|
||||
},
|
||||
|
||||
tcpAccel: {
|
||||
en: false,
|
||||
maxConnections: 128
|
||||
},
|
||||
},
|
||||
|
||||
uploadFw: {
|
||||
progress: null,
|
||||
filename: null,
|
||||
sha256: null
|
||||
},
|
||||
|
||||
// эти "настройки" - read only
|
||||
about: {
|
||||
firmwareVersion: '?',
|
||||
modemUid: '?',
|
||||
modemSn: '?',
|
||||
macManagement: '?',
|
||||
macData: '?',
|
||||
},
|
||||
|
||||
testState: false,
|
||||
initState: '',
|
||||
lastUpdateTime: new Date(),
|
||||
activeTab: getCurrentTab(),
|
||||
settingFetchComplete: false,
|
106
src/auth/jwt.cpp
106
src/auth/jwt.cpp
@@ -1,8 +1,15 @@
|
||||
#include "jwt.h"
|
||||
#include <random>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
static int64_t milliseconds() {
|
||||
timeval tv{};
|
||||
gettimeofday(&tv,nullptr);
|
||||
return ((tv.tv_sec * 1000000l) + tv.tv_usec) / 1000;
|
||||
}
|
||||
|
||||
std::string http::auth::jwt::secretKey;
|
||||
|
||||
void http::auth::jwt::generateSecretKey() {
|
||||
@@ -16,37 +23,45 @@ void http::auth::jwt::generateSecretKey() {
|
||||
}
|
||||
}
|
||||
|
||||
// payload, signature
|
||||
static std::pair<std::string, std::string> parseJwtFromCookie(const std::string& input) {
|
||||
std::string val1, val2;
|
||||
size_t dotPos = input.find('.');
|
||||
|
||||
// Если точка найдена
|
||||
if (dotPos != std::string::npos) {
|
||||
val1 = input.substr(0, dotPos);
|
||||
|
||||
// Если в val1 есть еще точки, нужно найти последнюю точку
|
||||
size_t lastDotPos = val1.find_last_of('.');
|
||||
if (lastDotPos != std::string::npos) {
|
||||
val1 = val1.substr(0, lastDotPos + 1);
|
||||
}
|
||||
|
||||
val2 = input.substr(dotPos + 1);
|
||||
} else {
|
||||
// Точка не найдена, val1 - вся строка
|
||||
val1 = input;
|
||||
}
|
||||
|
||||
return std::make_pair(http::utils::b64Decode(val1), val2);
|
||||
}
|
||||
|
||||
http::auth::jwt::Jwt http::auth::jwt::Jwt::fromCookies(const std::string &cookie) {
|
||||
auto pc = utils::parseCookies(cookie);
|
||||
Jwt t;
|
||||
if (pc.find("auth") != pc.end()) {
|
||||
auto tmp = parseJwtFromCookie(pc.at("auth"));
|
||||
t.payload = tmp.first;
|
||||
t.signature = tmp.second;
|
||||
const auto auth = pc.at("auth");
|
||||
std::string::size_type firstDot = std::string::npos;
|
||||
std::string::size_type secondDot = std::string::npos;
|
||||
for (std::string::size_type i = 0; i < auth.size(); i++) {
|
||||
if (auth[i] == '.') {
|
||||
if (firstDot == std::string::npos) { firstDot = i; }
|
||||
else if (secondDot == std::string::npos) { secondDot = i; }
|
||||
else {
|
||||
// так быть не должно
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (firstDot == std::string::npos || secondDot == std::string::npos || secondDot - firstDot == 0) {
|
||||
// так тоже быть не должно
|
||||
return t;
|
||||
}
|
||||
|
||||
try {
|
||||
t.payload = auth.substr(0, firstDot);
|
||||
t.signature = auth.substr(secondDot + 1);
|
||||
t.lastUpdate = std::stol(auth.substr(firstDot + 1, secondDot - firstDot - 1));
|
||||
|
||||
// теперь проверим, что сигнатура верная, только тогда декодируем строку юзера
|
||||
auto realSignature = utils::sha256(t.payload + std::to_string(t.lastUpdate) + secretKey);
|
||||
if (t.signature != realSignature) {
|
||||
t.payload.clear();
|
||||
} else {
|
||||
t.payload = utils::b64Decode(t.payload);
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
t.payload.clear();
|
||||
t.lastUpdate = 0;
|
||||
t.signature.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
@@ -55,6 +70,7 @@ http::auth::jwt::Jwt http::auth::jwt::Jwt::fromCookies(const std::string &cookie
|
||||
http::auth::jwt::Jwt http::auth::jwt::Jwt::fromUser(const std::string &user) {
|
||||
Jwt t;
|
||||
t.payload = user;
|
||||
t.lastUpdate = milliseconds();
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -63,18 +79,40 @@ bool http::auth::jwt::Jwt::isValid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto realSignature = utils::sha256(this->payload + secretKey);
|
||||
return signature == realSignature;
|
||||
// проверка сигнатуры не нужна, она была на стадии парсинга куки
|
||||
// auto realSignature = utils::sha256(utils::b64Encode(this->payload) + std::to_string(this->lastUpdate) + secretKey);
|
||||
// if (signature != realSignature) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
const auto currTime = milliseconds();
|
||||
|
||||
return currTime <= lastUpdate + SESSION_LIVE_MS && currTime >= lastUpdate;
|
||||
}
|
||||
|
||||
std::string http::auth::jwt::Jwt::getUsername() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
std::string http::auth::jwt::Jwt::asCookie() {
|
||||
signature = utils::sha256(this->payload + secretKey);
|
||||
auto val = utils::b64Encode(payload) + "." + signature;
|
||||
return "auth=" + val + ";Path=/; Max-Age=86400; HttpOnly; SameSite=Lax";
|
||||
std::string http::auth::jwt::Jwt::asCookie(bool isSecure) {
|
||||
this->lastUpdate = milliseconds();
|
||||
const auto uTime = std::to_string(this->lastUpdate);
|
||||
const auto encodedPayload = utils::b64Encode(payload);
|
||||
signature = utils::sha256(encodedPayload + uTime + secretKey);
|
||||
const auto val = encodedPayload + "." + uTime + "." + signature;
|
||||
std::string cookie = "auth=";
|
||||
cookie += val;
|
||||
cookie += ";Path=/; Max-Age=";
|
||||
cookie += std::to_string(SESSION_LIVE_MS / 1000);
|
||||
if (isSecure) {
|
||||
cookie += "; Secure";
|
||||
}
|
||||
cookie += "; HttpOnly; SameSite=Lax";
|
||||
return cookie;
|
||||
}
|
||||
|
||||
bool http::auth::jwt::Jwt::needUpdate() const {
|
||||
return milliseconds() >= lastUpdate + SESSION_UPDATE_THRESHOLD;
|
||||
}
|
||||
|
||||
http::auth::jwt::Jwt::~Jwt() = default;
|
||||
|
@@ -6,7 +6,10 @@
|
||||
namespace http::auth::jwt {
|
||||
extern std::string secretKey;
|
||||
|
||||
constexpr const char* EMPTY_AUTH_COOKIE = "auth=;Path=/; Max-Age=86400; HttpOnly; SameSite=Lax";;
|
||||
constexpr const char* EMPTY_AUTH_COOKIE = "auth=;Path=/; Max-Age=86400; HttpOnly; SameSite=Lax";
|
||||
|
||||
constexpr int64_t SESSION_LIVE_MS = 24 * 60 * 60 * 1000; // 24 часа
|
||||
constexpr int64_t SESSION_UPDATE_THRESHOLD = 10 * 60 * 1000; // 10 минут
|
||||
|
||||
void generateSecretKey();
|
||||
|
||||
@@ -17,6 +20,7 @@ namespace http::auth::jwt {
|
||||
*/
|
||||
class Jwt {
|
||||
std::string payload;
|
||||
int64_t lastUpdate = 0;
|
||||
std::string signature;
|
||||
public:
|
||||
static Jwt fromCookies(const std::string& cookie);
|
||||
@@ -26,7 +30,9 @@ namespace http::auth::jwt {
|
||||
|
||||
std::string getUsername();
|
||||
|
||||
std::string asCookie();
|
||||
std::string asCookie(bool isSecure = false);
|
||||
|
||||
bool needUpdate() const;
|
||||
|
||||
~Jwt();
|
||||
};
|
||||
|
@@ -44,12 +44,12 @@ http::auth::User::~User() = default;
|
||||
|
||||
http::auth::AuthProvider::AuthProvider() = default;
|
||||
|
||||
std::shared_ptr<http::auth::User> http::auth::AuthProvider::doAuth(const std::string &username, const std::string &password, server::Reply &rep) {
|
||||
std::shared_ptr<http::auth::User> http::auth::AuthProvider::doAuth(const std::string &username, const std::string &password, const server::Request &req, server::Reply &rep) {
|
||||
for (const auto& u: users) {
|
||||
if (u->username == username) {
|
||||
if (u->checkPassword(password)) {
|
||||
auto t = jwt::Jwt::fromUser(u->username);
|
||||
rep.headers.push_back({.name = "Set-Cookie", .value = t.asCookie()});
|
||||
rep.headers.push_back({.name = "Set-Cookie", .value = t.asCookie(req.isSecure)});
|
||||
return u;
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(warning) << "http::auth::AuthProvider::doAuth(): Failed to login " << username << ", password: " << password << " (incorrect password)";
|
||||
@@ -60,13 +60,17 @@ std::shared_ptr<http::auth::User> http::auth::AuthProvider::doAuth(const std::st
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<http::auth::User> http::auth::AuthProvider::getSession(const server::Request &req) {
|
||||
std::shared_ptr<http::auth::User> http::auth::AuthProvider::getSession(const server::Request &req, server::Reply &rep) {
|
||||
auto t = jwt::Jwt::fromCookies(req.getHeaderValue("cookie"));
|
||||
if (t.isValid()) {
|
||||
const auto name = t.getUsername();
|
||||
// токен валидный, ищем юзера
|
||||
for (auto& u: users) {
|
||||
if (u->username == name) {
|
||||
// на всякий случай тут проверяем, что токен пора обновлять
|
||||
if (t.needUpdate()) {
|
||||
rep.headers.push_back({.name = "Set-Cookie", .value = t.asCookie(req.isSecure)});
|
||||
}
|
||||
return u;
|
||||
}
|
||||
}
|
||||
@@ -84,7 +88,7 @@ http::auth::AuthRequiredResource::AuthRequiredResource(const std::string &path,
|
||||
BasicResource(path), provider_(provider), generator_(std::move(generator)), perms(perms) {}
|
||||
|
||||
void http::auth::AuthRequiredResource::handle(const server::Request &req, server::Reply &rep) {
|
||||
if (auto user = this->provider_.getSession(req)) {
|
||||
if (auto user = this->provider_.getSession(req, rep)) {
|
||||
if (user->checkPremisions(this->perms)) {
|
||||
this->generator_(req, rep);
|
||||
return;
|
||||
|
@@ -70,20 +70,23 @@ namespace http::auth {
|
||||
* @note Класс устанавливает заголовок 'Set-Cookie' в ответе, и этот заголовок должен дойти до пользователя!
|
||||
*/
|
||||
class AuthProvider {
|
||||
void updateSessionHook();
|
||||
|
||||
public:
|
||||
AuthProvider();
|
||||
|
||||
/**
|
||||
* Авторизовать пользователя.
|
||||
*
|
||||
* @param req
|
||||
* @param rep
|
||||
* @return true, в случае успешной авторизации
|
||||
*/
|
||||
std::shared_ptr<http::auth::User> doAuth(const std::string &username, const std::string &password, server::Reply &rep);
|
||||
std::shared_ptr<http::auth::User> doAuth(const std::string &username, const std::string &password, const server::Request &req, server::Reply &rep);
|
||||
|
||||
std::vector<std::shared_ptr<User>> users;
|
||||
|
||||
std::shared_ptr<User> getSession(const server::Request &req);
|
||||
std::shared_ptr<User> getSession(const server::Request &req, server::Reply &rep);
|
||||
|
||||
~AuthProvider();
|
||||
};
|
||||
|
@@ -113,7 +113,20 @@ std::map<std::string, std::string> http::utils::parseCookies(const std::string&
|
||||
if (equalPos == std::string::npos) {
|
||||
continue; // Неверный формат Cookie
|
||||
}
|
||||
std::string name = cookie.substr(0, equalPos);
|
||||
size_t startIndex = 0;
|
||||
while (startIndex < cookie.size()) {
|
||||
if (cookie[startIndex] == '=') {
|
||||
// некорректная кука, состоит только из пробелов, так что на этом обработку и закончим
|
||||
return cookies;
|
||||
}
|
||||
|
||||
if (cookie[startIndex] == ' ') {
|
||||
startIndex++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string name = cookie.substr(startIndex, equalPos - startIndex);
|
||||
std::string value = cookie.substr(equalPos + 1);
|
||||
|
||||
// Удаляем пробелы с начала и конца значения Cookie
|
||||
|
121
src/main.cpp
121
src/main.cpp
@@ -28,25 +28,6 @@ constexpr const char* REBOOT_COMMAND = "web-action reboot";
|
||||
constexpr const char* UPGRADE_COMMAND = "web-action upgrade";
|
||||
|
||||
|
||||
static std::vector<char> loadFile(const std::string& path) {
|
||||
std::ifstream is(path, std::ios::in | std::ios::binary);
|
||||
if (!is) {
|
||||
throw std::runtime_error("File not found");
|
||||
}
|
||||
|
||||
std::vector<char> content;
|
||||
for (;;) {
|
||||
char buf[512];
|
||||
auto len = is.read(buf, sizeof(buf)).gcount();
|
||||
if (len <= 0) {
|
||||
break;
|
||||
}
|
||||
content.insert(content.end(), buf, buf + len);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
namespace mime_types = http::server::mime_types;
|
||||
|
||||
void init_logging() {
|
||||
@@ -114,6 +95,7 @@ public:
|
||||
#error "Modem type not defined!"
|
||||
#endif
|
||||
static constexpr const char* LOGIN_HTML = "/login.html";
|
||||
static constexpr const char* DEV_HTML = "/dev.html";
|
||||
|
||||
// картинки, их даже можно кешировать
|
||||
static constexpr const char* FAVICON_ICO = "/favicon.ico";
|
||||
@@ -131,17 +113,22 @@ public:
|
||||
auth.users.emplace_back(std::make_shared<http::auth::User>("admin", "", http::auth::User::SUPERUSER));
|
||||
|
||||
sf->registerFile(staticFilesPath + "/favicon.png", FAVICON_ICO, mime_types::image_png, true);
|
||||
#ifdef USE_DEBUG
|
||||
sf->registerFile(staticFilesPath + VUE_JS, VUE_JS, mime_types::javascript, true);
|
||||
#else
|
||||
sf->registerFile(staticFilesPath + "/js/vue.prod.js", VUE_JS, mime_types::javascript, true);
|
||||
#endif
|
||||
sf->registerFile(staticFilesPath + STYLE_CSS, STYLE_CSS, mime_types::text_css, true);
|
||||
sf->registerFile(staticFilesPath + FIELDS_CSS, FIELDS_CSS, mime_types::text_css, true);
|
||||
sf->registerFile(staticFilesPath + INDEX_HTML, INDEX_HTML, mime_types::text_html, false);
|
||||
sf->registerFile(staticFilesPath + DEV_HTML, DEV_HTML, mime_types::text_html, false);
|
||||
sf->registerFile(staticFilesPath + LOGIN_HTML, LOGIN_HTML, mime_types::text_html, true);
|
||||
sf->registerFile(staticFilesPath + INTERNET_JPG, INTERNET_JPG, mime_types::image_jpeg, true);
|
||||
}
|
||||
|
||||
void registerResources(http::server::Server& s) {
|
||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/", [this](const auto& req, auto& rep) {
|
||||
auto user = auth.getSession(req);
|
||||
auto user = auth.getSession(req, rep);
|
||||
if (user == nullptr) {
|
||||
http::server::httpRedirect(rep, "/login");
|
||||
} else {
|
||||
@@ -151,7 +138,7 @@ public:
|
||||
|
||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/login", [this](const auto& req, auto& rep) {
|
||||
if (req.method == "GET") {
|
||||
auto user = auth.getSession(req);
|
||||
auto user = auth.getSession(req, rep);
|
||||
if (user == nullptr) {
|
||||
sf->serve(LOGIN_HTML, rep);
|
||||
} else {
|
||||
@@ -166,7 +153,7 @@ public:
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(is, pt);
|
||||
|
||||
auto u = auth.doAuth(pt.get<std::string>("username"), pt.get<std::string>("password"), rep);
|
||||
auto u = auth.doAuth(pt.get<std::string>("username"), pt.get<std::string>("password"), req, rep);
|
||||
if (u == nullptr) {
|
||||
throw std::runtime_error("invalid session");
|
||||
}
|
||||
@@ -195,14 +182,15 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>(FIELDS_CSS, [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(FIELDS_CSS, rep); }));
|
||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>(VUE_JS, [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(VUE_JS, rep); }));
|
||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>(INTERNET_JPG, [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(INTERNET_JPG, rep); }));
|
||||
s.resources.emplace_back(std::make_unique<http::resource::GenericResource>("/dev", [this](const auto& req, auto& rep) { boost::ignore_unused(req); sf->serve(DEV_HTML, rep); }));
|
||||
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/get/statistics", this->auth, http::auth::User::WATCH_STATISTICS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "GET") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
std::string result = R"({"mainState":)";
|
||||
result += api->loadTerminalState();
|
||||
@@ -215,10 +203,10 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/get/settings", this->auth, http::auth::User::WATCH_SETTINGS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "GET") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
std::string result = R"({"settings":)";
|
||||
result += api->loadSettings();
|
||||
@@ -229,10 +217,10 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/get/aboutFirmware", this->auth, 0, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "GET") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
const auto result = api->loadFirmwareVersion();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
@@ -241,11 +229,11 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/resetPacketStatistics", this->auth, http::auth::User::RESET_PACKET_STATISTICS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
api->resetPacketStatistics();
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
const std::string result = R"({"status":"ok")";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
@@ -254,10 +242,10 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/qos", this->auth, http::auth::User::SETUP_QOS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
|
||||
try {
|
||||
@@ -274,18 +262,18 @@ public:
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/qos): Can't set QoS settings: " << e.what();
|
||||
const std::string result = R"({"status":"error"})";
|
||||
const std::string result = R"({"status": "error", "error": )" + api_driver::buildEscapedString(e.what()) + "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}
|
||||
}));
|
||||
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/bucLnb", this->auth, http::auth::User::SUPERUSER, [this](const auto& req, auto& rep) {
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/buclnb", this->auth, http::auth::User::SUPERUSER, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
|
||||
try {
|
||||
@@ -301,8 +289,8 @@ public:
|
||||
result += "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/bucLnb): Can't set settings: " << e.what();
|
||||
const std::string result = R"({"status":"error"})";
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/buclnb): Can't set BUC LNB settings: " << e.what();
|
||||
const std::string result = R"({"status": "error", "error": )" + api_driver::buildEscapedString(e.what()) + "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}
|
||||
}));
|
||||
@@ -310,10 +298,10 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/cinc", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
|
||||
try {
|
||||
@@ -330,7 +318,7 @@ public:
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/cinc): Can't set CinC settings: " << e.what();
|
||||
const std::string result = R"({"status":"error"})";
|
||||
const std::string result = R"({"status": "error", "error": )" + api_driver::buildEscapedString(e.what()) + "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}
|
||||
}));
|
||||
@@ -338,10 +326,10 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/rxtx", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
|
||||
try {
|
||||
@@ -358,7 +346,7 @@ public:
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/rxtx): Can't set RX/TX settings: " << e.what();
|
||||
const std::string result = R"({"status":"error"})";
|
||||
const std::string result = R"({"status": "error", "error": )" + api_driver::buildEscapedString(e.what()) + "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}
|
||||
}));
|
||||
@@ -366,10 +354,10 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/network", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
|
||||
try {
|
||||
@@ -385,36 +373,8 @@ public:
|
||||
result += "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/rxtx): Can't set RX/TX settings: " << e.what();
|
||||
const std::string result = R"({"status":"error"})";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}
|
||||
}));
|
||||
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/debugSend", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
|
||||
try {
|
||||
std::stringstream ss;
|
||||
ss.str(std::string(req.payload.begin(), req.payload.end()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(ss, pt);
|
||||
|
||||
api->setDebugSendSettings(pt);
|
||||
|
||||
std::string result = R"({"status":"ok","settings":)";
|
||||
result += api->loadSettings();
|
||||
result += "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/rxtx): Can't set RX/TX settings: " << e.what();
|
||||
const std::string result = R"({"status":"error"})";
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/network): Can't set network settings: " << e.what();
|
||||
const std::string result = R"({"status": "error", "error": )" + api_driver::buildEscapedString(e.what()) + "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}
|
||||
}));
|
||||
@@ -422,9 +382,9 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/reboot", this->auth, 0, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
const std::string result = R"({"status":"ok"})";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
@@ -434,9 +394,9 @@ public:
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/resetSettings", this->auth, http::auth::User::SUPERUSER, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
const std::string result = R"({"status":"ok"})";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
@@ -452,7 +412,6 @@ public:
|
||||
onUploadFirmware(req);
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
std::string result = R"({"status":"ok","fwsize":)";
|
||||
result += std::to_string(req.payload.size());
|
||||
@@ -478,16 +437,16 @@ public:
|
||||
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/dev", this->auth, http::auth::User::SUPERUSER, [this](const auto& req, auto& rep) {
|
||||
boost::ignore_unused(req);
|
||||
sf->serve(INTERNET_JPG, rep);
|
||||
sf->serve(DEV_HTML, rep);
|
||||
}));
|
||||
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/dev/fetchParams", this->auth, http::auth::User::SUPERUSER, [this](const auto& req, auto& rep) {
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
std::string result = R"({"status":"ok","fwsize":)";
|
||||
result += std::to_string(req.payload.size());
|
||||
result += R"(,"sha256":")";
|
||||
result += "\"}";
|
||||
}));
|
||||
// s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/dev/fetchParams", this->auth, http::auth::User::SUPERUSER, [this](const auto& req, auto& rep) {
|
||||
// rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
// std::string result = R"({"status":"ok","fwsize":)";
|
||||
// result += std::to_string(req.payload.size());
|
||||
// result += R"(,"sha256":")";
|
||||
// result += "\"}";
|
||||
// }));
|
||||
}
|
||||
|
||||
~ServerResources() = default;
|
||||
@@ -537,9 +496,9 @@ int main(int argc, char *argv[]) {
|
||||
s->run();
|
||||
|
||||
} else if (strcmp(argv[1], "ssl") == 0) {
|
||||
const auto cert = loadFile("cert.pem");
|
||||
const auto key = loadFile("key.pem");
|
||||
const auto dh = loadFile("dh.pem");
|
||||
std::vector<char> cert; http::resource::loadFile("cert.pem", cert);
|
||||
std::vector<char> key; http::resource::loadFile("key.pem", key);
|
||||
std::vector<char> dh; http::resource::loadFile("dh.pem", dh);
|
||||
|
||||
auto ctx = std::make_shared<ssl::context>(ssl::context::tlsv12);
|
||||
|
||||
|
@@ -6,10 +6,14 @@
|
||||
|
||||
|
||||
namespace http::server {
|
||||
const char* SERVER_HEADER_VALUE = "TerminalWebServer v0.1";
|
||||
const char* SERVER_HEADER_VALUE = "TerminalWebServer"
|
||||
#ifdef PROJECT_GIT_REVISION
|
||||
" " PROJECT_GIT_REVISION
|
||||
#endif
|
||||
;
|
||||
|
||||
Connection::Connection(boost::asio::ip::tcp::socket socket, ConnectionManager &manager, request_handler handler)
|
||||
: socket_(std::move(socket)), connection_manager_(manager), request_handler_(std::move(handler)), request_(), reply_() {
|
||||
: socket_(std::move(socket)), connection_manager_(manager), request_handler_(std::move(handler)), request_(false), reply_() {
|
||||
}
|
||||
|
||||
void Connection::start() {
|
||||
@@ -51,7 +55,7 @@ namespace http::server {
|
||||
void Connection::doWrite() {
|
||||
reply_.headers.push_back({.name = "Server", .value = SERVER_HEADER_VALUE});
|
||||
reply_.headers.push_back({.name = "Content-Length", .value = std::to_string(reply_.content.size())});
|
||||
if (request_.http_version_major == 1) {
|
||||
if (request_.httpVersionMajor == 1) {
|
||||
reply_.headers.push_back({.name = "Connection", .value = "keep-alive"});
|
||||
}
|
||||
|
||||
@@ -71,7 +75,7 @@ namespace http::server {
|
||||
}
|
||||
|
||||
SslConnection::SslConnection(boost::asio::ip::tcp::socket socket, ConnectionManager &manager, request_handler handler, const std::shared_ptr<boost::asio::ssl::context>& ctx):
|
||||
stream_(std::move(socket), *ctx), connection_manager_(manager), request_handler_(std::move(handler)), request_(), reply_() {
|
||||
stream_(std::move(socket), *ctx), connection_manager_(manager), request_handler_(std::move(handler)), request_(true), reply_() {
|
||||
}
|
||||
|
||||
void SslConnection::start() {
|
||||
@@ -125,7 +129,7 @@ namespace http::server {
|
||||
void SslConnection::doWrite() {
|
||||
reply_.headers.push_back({.name = "Server", .value = SERVER_HEADER_VALUE});
|
||||
reply_.headers.push_back({.name = "Content-Length", .value = std::to_string(reply_.content.size())});
|
||||
if (request_.http_version_major == 1) {
|
||||
if (request_.httpVersionMajor == 1) {
|
||||
reply_.headers.push_back({.name = "Connection", .value = "keep-alive"});
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ namespace http::server {
|
||||
/// A request received from a client.
|
||||
class Request {
|
||||
public:
|
||||
Request();
|
||||
Request(bool secure);
|
||||
|
||||
void reset();
|
||||
std::string getHeaderValue(const std::string& headerName) const;
|
||||
@@ -29,9 +29,10 @@ namespace http::server {
|
||||
std::string method;
|
||||
std::string queryUri;
|
||||
std::unique_ptr<Url> url;
|
||||
bool is_keep_alive{};
|
||||
int http_version_major{};
|
||||
int http_version_minor{};
|
||||
bool isKeepAlive{};
|
||||
const bool isSecure;
|
||||
int httpVersionMajor{};
|
||||
int httpVersionMinor{};
|
||||
std::vector<header> headers;
|
||||
std::vector<char> payload;
|
||||
|
||||
|
@@ -51,7 +51,7 @@ namespace http::server {
|
||||
|
||||
Url::~Url() = default;
|
||||
|
||||
Request::Request() = default;
|
||||
Request::Request(bool secure): isSecure(secure) {}
|
||||
|
||||
void Request::reset() {
|
||||
method = "";
|
||||
@@ -59,9 +59,9 @@ namespace http::server {
|
||||
if (url != nullptr) {
|
||||
url.reset(nullptr);
|
||||
}
|
||||
is_keep_alive = false;
|
||||
http_version_major = 0;
|
||||
http_version_minor = 0;
|
||||
isKeepAlive = false;
|
||||
httpVersionMajor = 0;
|
||||
httpVersionMinor = 0;
|
||||
headers.clear();
|
||||
payload.clear();
|
||||
}
|
||||
@@ -151,8 +151,8 @@ namespace http::server {
|
||||
}
|
||||
case http_version_slash:
|
||||
if (input == '/') {
|
||||
req.http_version_major = 0;
|
||||
req.http_version_minor = 0;
|
||||
req.httpVersionMajor = 0;
|
||||
req.httpVersionMinor = 0;
|
||||
state_ = http_version_major_start;
|
||||
return indeterminate;
|
||||
} else {
|
||||
@@ -160,7 +160,7 @@ namespace http::server {
|
||||
}
|
||||
case http_version_major_start:
|
||||
if (is_digit(input)) {
|
||||
req.http_version_major = req.http_version_major * 10 + input - '0';
|
||||
req.httpVersionMajor = req.httpVersionMajor * 10 + input - '0';
|
||||
state_ = http_version_major;
|
||||
return indeterminate;
|
||||
} else {
|
||||
@@ -171,14 +171,14 @@ namespace http::server {
|
||||
state_ = http_version_minor_start;
|
||||
return indeterminate;
|
||||
} else if (is_digit(input)) {
|
||||
req.http_version_major = req.http_version_major * 10 + input - '0';
|
||||
req.httpVersionMajor = req.httpVersionMajor * 10 + input - '0';
|
||||
return indeterminate;
|
||||
} else {
|
||||
return bad;
|
||||
}
|
||||
case http_version_minor_start:
|
||||
if (is_digit(input)) {
|
||||
req.http_version_minor = req.http_version_minor * 10 + input - '0';
|
||||
req.httpVersionMinor = req.httpVersionMinor * 10 + input - '0';
|
||||
state_ = http_version_minor;
|
||||
return indeterminate;
|
||||
} else {
|
||||
@@ -189,7 +189,7 @@ namespace http::server {
|
||||
state_ = expecting_newline_1;
|
||||
return indeterminate;
|
||||
} else if (is_digit(input)) {
|
||||
req.http_version_minor = req.http_version_minor * 10 + input - '0';
|
||||
req.httpVersionMinor = req.httpVersionMinor * 10 + input - '0';
|
||||
return indeterminate;
|
||||
} else {
|
||||
return bad;
|
||||
|
@@ -3,10 +3,10 @@
|
||||
#include <fstream>
|
||||
#include <utility>
|
||||
|
||||
static void loadFile(const std::string& path, std::vector<char>& content) {
|
||||
void http::resource::loadFile(const std::string& path, std::vector<char>& content) {
|
||||
std::ifstream is(path, std::ios::in | std::ios::binary);
|
||||
if (!is) {
|
||||
throw std::runtime_error("File not found");
|
||||
throw std::runtime_error("File not found " + path);
|
||||
}
|
||||
|
||||
content.clear();
|
||||
|
@@ -62,6 +62,8 @@ namespace http::resource {
|
||||
|
||||
~GenericResource() override;
|
||||
};
|
||||
|
||||
void loadFile(const std::string& path, std::vector<char>& content);
|
||||
}
|
||||
|
||||
#endif //RESOURCE_H
|
||||
|
@@ -16,48 +16,48 @@ typedef boost::property_tree::ptree::path_type json_path;
|
||||
|
||||
static constexpr const char* DEFAULT_QOS_CLASSES = R"({"rt1":[],"rt2":[],"rt3":[],"cd":[]})";
|
||||
|
||||
static int calculateSubnetMask(const std::string& subnet_mask) {
|
||||
int mask = 0;
|
||||
std::istringstream iss(subnet_mask);
|
||||
std::string octet;
|
||||
while (std::getline(iss, octet, '.')) {
|
||||
int octet_value = std::stoi(octet);
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
if (octet_value & (1 << i)) {
|
||||
mask++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
// static int calculateSubnetMask(const std::string& subnet_mask) {
|
||||
// int mask = 0;
|
||||
// std::istringstream iss(subnet_mask);
|
||||
// std::string octet;
|
||||
// while (std::getline(iss, octet, '.')) {
|
||||
// int octet_value = std::stoi(octet);
|
||||
// for (int i = 7; i >= 0; i--) {
|
||||
// if (octet_value & (1 << i)) {
|
||||
// mask++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return mask;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Преобразует строку вида `1.2.3.4/24` в пару строк вида `1.2.3.4` `255.255.255.0`
|
||||
*/
|
||||
std::pair<std::string, std::string> splitIpAndMask(const std::string& input) {
|
||||
auto pos = input.find('/');
|
||||
if (pos == std::string::npos) {
|
||||
// Обработка ошибки: нет символа '/'
|
||||
throw std::runtime_error("address not contains mask");
|
||||
}
|
||||
std::string ip = input.substr(0, pos);
|
||||
const unsigned int mask_int = std::stoul(input.substr(pos + 1));
|
||||
|
||||
if (mask_int > 32) {
|
||||
throw std::runtime_error("invalid mask");
|
||||
}
|
||||
|
||||
std::string mask_binary = std::string(mask_int, '1') + std::string(32 - mask_int, '0');
|
||||
std::string mask_str;
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
std::string octet = mask_binary.substr(i * 8u, 8);
|
||||
int octet_value = std::stoi(octet, nullptr, 2);
|
||||
mask_str += std::to_string(octet_value) + (i < 3 ? "." : "");
|
||||
}
|
||||
|
||||
return std::make_pair(ip, mask_str);
|
||||
}
|
||||
// std::pair<std::string, std::string> splitIpAndMask(const std::string& input) {
|
||||
// auto pos = input.find('/');
|
||||
// if (pos == std::string::npos) {
|
||||
// // Обработка ошибки: нет символа '/'
|
||||
// throw std::runtime_error("address not contains mask");
|
||||
// }
|
||||
// std::string ip = input.substr(0, pos);
|
||||
// const unsigned int mask_int = std::stoul(input.substr(pos + 1));
|
||||
//
|
||||
// if (mask_int > 32) {
|
||||
// throw std::runtime_error("invalid mask");
|
||||
// }
|
||||
//
|
||||
// std::string mask_binary = std::string(mask_int, '1') + std::string(32 - mask_int, '0');
|
||||
// std::string mask_str;
|
||||
//
|
||||
// for (unsigned int i = 0; i < 4; ++i) {
|
||||
// std::string octet = mask_binary.substr(i * 8u, 8);
|
||||
// int octet_value = std::stoi(octet, nullptr, 2);
|
||||
// mask_str += std::to_string(octet_value) + (i < 3 ? "." : "");
|
||||
// }
|
||||
//
|
||||
// return std::make_pair(ip, mask_str);
|
||||
// }
|
||||
|
||||
static inline void rtrim(std::string &s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||
@@ -67,7 +67,8 @@ static inline void rtrim(std::string &s) {
|
||||
|
||||
class TerminalNetworkSettings {
|
||||
public:
|
||||
std::string managementIp, managementGateway, mode, dataIp;
|
||||
std::string managementIp, managementGateway, dataIp;
|
||||
bool isL2 = true;
|
||||
unsigned int dataMtu = 1500;
|
||||
|
||||
TerminalNetworkSettings() = default;
|
||||
@@ -77,10 +78,10 @@ public:
|
||||
TerminalNetworkSettings& operator= (const TerminalNetworkSettings& src) = default;
|
||||
|
||||
void loadDefaults() {
|
||||
managementIp = "0.0.0.0/0";
|
||||
managementIp = "0.0.0.0";
|
||||
managementGateway = "";
|
||||
mode = "l2";
|
||||
dataIp = "0.0.0.0/0";
|
||||
isL2 = true;
|
||||
dataIp = "0.0.0.0";
|
||||
dataMtu = 1500;
|
||||
}
|
||||
};
|
||||
@@ -193,21 +194,22 @@ private:
|
||||
|
||||
void updateNetworkSettings() {
|
||||
TerminalNetworkSettings s;
|
||||
std::string tmp;
|
||||
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(addr)", CP_GetNetwork(sid, "addr", &tmp));
|
||||
s.managementIp = tmp + "/";
|
||||
tmp.clear(); logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(mask)", CP_GetNetwork(sid, "mask", &tmp));
|
||||
s.managementIp += std::to_string(calculateSubnetMask(tmp));
|
||||
tmp.clear(); logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(gateway)", CP_GetNetwork(sid, "gateway", &s.managementGateway)); s.managementGateway = tmp;
|
||||
tmp.clear(); logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(mode)", CP_GetNetwork(sid, "mode", &tmp));
|
||||
if (tmp == "tun") {
|
||||
s.mode = "l3";
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(addr)", CP_GetNetwork(sid, "addr", &s.managementIp));
|
||||
// s.managementIp = tmp + "/";
|
||||
// tmp.clear(); logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(mask)", CP_GetNetwork(sid, "mask", &tmp));
|
||||
// s.managementIp += std::to_string(calculateSubnetMask(tmp));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(gateway)", CP_GetNetwork(sid, "gateway", &s.managementGateway));
|
||||
std::string nm; logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(mode)", CP_GetNetwork(sid, "mode", &nm));
|
||||
if (nm == "tun") {
|
||||
s.isL2 = false;
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateNetworkSettings()->CP_GetNetwork(addr_data)", CP_GetNetwork(sid, "addr_data", &s.dataIp));
|
||||
s.dataIp += "/24";
|
||||
// s.dataIp += "/24";
|
||||
} else {
|
||||
s.mode = "l2";
|
||||
s.dataIp = "0.0.0.0/24";
|
||||
s.isL2 = true;
|
||||
// s.dataIp = "0.0.0.0/24";
|
||||
s.dataIp = "0.0.0.0";
|
||||
}
|
||||
s.dataMtu = 1500;
|
||||
|
||||
@@ -467,6 +469,15 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isTest() {
|
||||
std::shared_lock lock(this->settingsMutex);
|
||||
return !modSettings.is_carrier
|
||||
#ifdef MODEM_IS_SCPC
|
||||
|| this->modSettings.is_test_data
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
void getNetworkSettings(TerminalNetworkSettings& dest) {
|
||||
std::shared_lock lock(this->networkSettingsMutex);
|
||||
dest = this->networkSettings;
|
||||
@@ -564,41 +575,40 @@ public:
|
||||
}
|
||||
|
||||
void setNetworkSettings(TerminalNetworkSettings& s, bool readback = true) {
|
||||
const auto mang = splitIpAndMask(s.managementIp);
|
||||
std::pair<std::string, std::string> data;
|
||||
bool isL2;
|
||||
if (s.mode == "l2") { isL2 = true; }
|
||||
else if (s.mode == "l3") { isL2 = false; data = splitIpAndMask(s.dataIp); }
|
||||
else { throw std::runtime_error("invalid mode"); }
|
||||
// const auto mang = splitIpAndMask();
|
||||
// std::pair<std::string, std::string> data;
|
||||
// if (!s.isL2) {
|
||||
// data = splitIpAndMask(s.dataIp);
|
||||
// }
|
||||
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(mode)", CP_SetNetwork(sid, "mode", isL2 ? "tap" : "tun"));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(addr)", CP_SetNetwork(sid, "addr", mang.first.c_str()));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(mask)", CP_SetNetwork(sid, "mask", mang.second.c_str()));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(gateway)", CP_SetNetwork(sid, "gateway", s.managementGateway.c_str()));
|
||||
if (!isL2) {
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(data_addr)", CP_SetNetwork(sid, "data_addr", data.first.c_str()));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(mode)", CP_SetNetwork(sid, "mode", s.isL2 ? "tap" : "tun"));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(addr)", CP_SetNetwork(sid, "addr", s.managementIp.c_str()));
|
||||
if (!s.isL2) {
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(addr_data)", CP_SetNetwork(sid, "data_addr", s.dataIp.c_str()));
|
||||
// TODO маска не устанавливается, потому что в API этого нет
|
||||
}
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(mask)", CP_SetNetwork(sid, "mask", "255.255.255.0"));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetNetwork(gateway)", CP_SetNetwork(sid, "gateway", s.managementGateway.c_str()));
|
||||
|
||||
// TODO MTU не устанавливается, потому что в API этого нет
|
||||
|
||||
if (readback) {
|
||||
std::string tmp;
|
||||
s.loadDefaults();
|
||||
s.managementIp.clear();
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_GetNetwork(addr)", CP_GetNetwork(sid, "addr", &s.managementIp));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_GetNetwork(mask)", CP_GetNetwork(sid, "mask", &tmp));
|
||||
s.managementIp += "/";
|
||||
s.managementIp += std::to_string(calculateSubnetMask(tmp));
|
||||
// logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_GetNetwork(mask)", CP_GetNetwork(sid, "mask", &tmp));
|
||||
// s.managementIp += "/";
|
||||
// s.managementIp += std::to_string(calculateSubnetMask(tmp));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_GetNetwork(gateway)", CP_GetNetwork(sid, "gateway", &s.managementGateway));
|
||||
tmp.clear(); logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_GetNetwork(mode)", CP_GetNetwork(sid, "mode", &tmp));
|
||||
if (tmp == "tun") {
|
||||
s.mode = "l3";
|
||||
std::string nm; logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_GetNetwork(mode)", CP_GetNetwork(sid, "mode", &nm));
|
||||
if (nm == "tun") {
|
||||
s.isL2 = false;
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_GetNetwork(addr_data)", CP_GetNetwork(sid, "addr_data", &s.dataIp));
|
||||
} else {
|
||||
s.mode = "l2";
|
||||
s.dataIp = "0.0.0.0/24";
|
||||
s.isL2 = true;
|
||||
s.dataIp = "0.0.0.0";
|
||||
}
|
||||
s.dataMtu = 1500;
|
||||
{
|
||||
@@ -651,7 +661,7 @@ static const char* boolAsStr(bool value) {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
|
||||
static std::string buildEscapedString(const std::string& source) {
|
||||
std::string api_driver::buildEscapedString(const std::string& source) {
|
||||
std::string str(source);
|
||||
size_t start_pos = 0;
|
||||
while((start_pos = str.find('\"', start_pos)) != std::string::npos) {
|
||||
@@ -661,7 +671,7 @@ static std::string buildEscapedString(const std::string& source) {
|
||||
return "\"" + str + "\"";
|
||||
}
|
||||
|
||||
void writeDouble(std::ostream& out, double value, int prec = 2) {
|
||||
static void writeDouble(std::ostream& out, double value, int prec = 2) {
|
||||
if (std::isnan(value) || std::isinf(value)) {
|
||||
out << "\"nan\"";
|
||||
} else {
|
||||
@@ -689,6 +699,7 @@ std::string api_driver::ApiDriver::loadTerminalState() const {
|
||||
std::stringstream result;
|
||||
|
||||
result << "{\n\"initState\":" << buildEscapedString(daemon->getDeviceInitState());
|
||||
result << ",\n\"testState\":" << boolAsStr(daemon->isTest());
|
||||
|
||||
modulator_state modulator{};
|
||||
demodulator_state demodulator{};
|
||||
@@ -799,6 +810,59 @@ void api_driver::ApiDriver::resetPacketStatistics() const {
|
||||
this->daemon->resetPacketStatistics();
|
||||
}
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
struct ModcodDef_t {const char* modulation; const char* speed;};
|
||||
const static ModcodDef_t ModcodDefs[] = {
|
||||
{.modulation = "dummy", .speed = "0"},
|
||||
{.modulation = "qpsk", .speed = "1/4"},
|
||||
{.modulation = "qpsk", .speed = "1/3"},
|
||||
{.modulation = "qpsk", .speed = "2/5"},
|
||||
{.modulation = "qpsk", .speed = "1/2"},
|
||||
{.modulation = "qpsk", .speed = "3/5"},
|
||||
{.modulation = "qpsk", .speed = "2/3"},
|
||||
{.modulation = "qpsk", .speed = "3/4"},
|
||||
{.modulation = "qpsk", .speed = "4/5"},
|
||||
{.modulation = "qpsk", .speed = "5/6"},
|
||||
{.modulation = "qpsk", .speed = "8/9"},
|
||||
{.modulation = "qpsk", .speed = "9/10"},
|
||||
{.modulation = "8psk", .speed = "3/5"},
|
||||
{.modulation = "8psk", .speed = "2/3"},
|
||||
{.modulation = "8psk", .speed = "3/4"},
|
||||
{.modulation = "8psk", .speed = "5/6"},
|
||||
{.modulation = "8psk", .speed = "8/9"},
|
||||
{.modulation = "8psk", .speed = "9/10"},
|
||||
{.modulation = "16apsk", .speed = "2/3"},
|
||||
{.modulation = "16apsk", .speed = "3/4"},
|
||||
{.modulation = "16apsk", .speed = "4/5"},
|
||||
{.modulation = "16apsk", .speed = "5/6"},
|
||||
{.modulation = "16apsk", .speed = "8/9"},
|
||||
{.modulation = "16apsk", .speed = "9/10"},
|
||||
{.modulation = "32apsk", .speed = "3/4"},
|
||||
{.modulation = "32apsk", .speed = "4/5"},
|
||||
{.modulation = "32apsk", .speed = "5/6"},
|
||||
{.modulation = "32apsk", .speed = "8/9"},
|
||||
{.modulation = "32apsk", .speed = "9/10"},
|
||||
};
|
||||
|
||||
static const char* extractModcodModulation(uint32_t modcod, bool defaultQpsk1_4 = true) {
|
||||
modcod >>= 2;
|
||||
const auto* d = defaultQpsk1_4 ? ModcodDefs : ModcodDefs + 1;
|
||||
if (modcod < (sizeof(ModcodDefs) / sizeof(ModcodDef_t))) {
|
||||
d = ModcodDefs + modcod;
|
||||
}
|
||||
return d->modulation;
|
||||
}
|
||||
|
||||
static const char* extractModcodSpeed(uint32_t modcod, bool defaultQpsk1_4 = true) {
|
||||
modcod >>= 2;
|
||||
const auto* d = defaultQpsk1_4 ? ModcodDefs : ModcodDefs + 1;
|
||||
if (modcod < (sizeof(ModcodDefs) / sizeof(ModcodDef_t))) {
|
||||
d = ModcodDefs + modcod;
|
||||
}
|
||||
return d->speed;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string api_driver::ApiDriver::loadSettings() const {
|
||||
if (daemon == nullptr) {
|
||||
return R"({"error": "api daemon not started!"})";
|
||||
@@ -818,91 +882,93 @@ std::string api_driver::ApiDriver::loadSettings() const {
|
||||
daemon->getNetworkSettings(network);
|
||||
|
||||
std::stringstream result;
|
||||
result << "{\n\"txAutoStart\":" << boolAsStr(modSettings.is_save_current_state);
|
||||
result << ",\"txEn\":" << boolAsStr(modSettings.tx_is_on);
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << "{\n\"general.isCinC\":" << boolAsStr(modSettings.is_cinc);
|
||||
result << ",\"general.txEn\":" << boolAsStr(modSettings.tx_is_on);
|
||||
result << ",\"general.modulatorMode\":" << (modSettings.is_carrier ? "\"normal\"" : "\"test\"");
|
||||
result << ",\"general.autoStartTx\":" << boolAsStr(modSettings.is_save_current_state);
|
||||
result << ",\"general.isTestInputData\":" << boolAsStr(modSettings.is_test_data);
|
||||
result << ",\n\"tx.attenuation\":"; writeDouble(result, modSettings.attenuation);
|
||||
result << ",\"tx.rolloff\":" << static_cast<int>(modSettings.rollof * 100);
|
||||
result << ",\"tx.cymRate\":" << modSettings.baudrate;
|
||||
result << ",\"tx.centerFreq\":"; writeDouble(result, modSettings.central_freq_in_kGz, 3);
|
||||
result << ",\"dvbs2.frameSizeNormal\":" << boolAsStr(!(modSettings.modcod_tx & 2));
|
||||
result << ",\"dvbs2.ccm_modcod\":" << (modSettings.modcod_tx >> 2);
|
||||
result << ",\"txIsTestInput\":" << boolAsStr(modSettings.is_test_data);
|
||||
#endif
|
||||
result << ",\"txModulatorIsTest\":" << boolAsStr(!modSettings.is_carrier);
|
||||
result << ",\"txCentralFreq\":"; writeDouble(result, modSettings.central_freq_in_kGz);
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << ",\"txBaudrate\":" << modSettings.baudrate;
|
||||
result << ",\"txRolloff\":" << static_cast<int>(modSettings.rollof);
|
||||
result << ",\"txGoldan\":" << static_cast<int>(modSettings.gold_seq_is_active);
|
||||
#endif
|
||||
result << ",\"txAttenuation\":"; writeDouble(result, modSettings.attenuation);
|
||||
|
||||
// result << ",\"dvbs2.isPilots\":" << "null";
|
||||
result << ",\n\"dvbs2.isAcm\":" << boolAsStr(acmSettings.enable);
|
||||
result << ",\"dvbs2.acm_maxModcod\":" << (acmSettings.max_modcod >> 2);
|
||||
result << ",\"dvbs2.acm_minModcod\":" << (acmSettings.min_modcod >> 2);
|
||||
result << ",\"dvbs2.snrReserve\":"; writeDouble(result, acmSettings.snr_treashold_acm);
|
||||
result << ",\"dvbs2.servicePacketPeriod\":" << acmSettings.period_pack;
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << ",\n\"isCinC\":" << boolAsStr(modSettings.is_cinc);
|
||||
result << ",\n\"dvbServicePacketPeriod\":" << acmSettings.period_pack_acm;
|
||||
result << ",\"dvbIsAcm\":" << boolAsStr(acmSettings.enable_acm);
|
||||
result << ",\"txFrameSizeNormal\":" << boolAsStr((modSettings.modcod_tx & 2) == 0);
|
||||
|
||||
result << ",\n\"acm.en\":" << boolAsStr(acmSettings.enable_auto_atten);
|
||||
result << ",\"acm.maxAttenuation\":"; writeDouble(result, acmSettings.max_attenuation);
|
||||
result << ",\"acm.minAttenuation\":"; writeDouble(result, acmSettings.min_attenuation);
|
||||
result << ",\"acm.requiredSnr\":"; writeDouble(result, acmSettings.snr_treashold);
|
||||
result << R"(,"dvbCcmModulation":")" << extractModcodModulation(modSettings.modcod_tx) << "\"";
|
||||
result << R"(,"dvbCcmSpeed":")" << extractModcodSpeed(modSettings.modcod_tx) << "\"";
|
||||
result << R"(,"dvbAcmMinModulation":")" << extractModcodModulation(acmSettings.min_modcod_acm) << "\"";
|
||||
result << R"(,"dvbAcmMinSpeed":")" << extractModcodSpeed(acmSettings.min_modcod_acm) << "\"";
|
||||
result << R"(,"dvbAcmMaxModulation":")" << extractModcodModulation(acmSettings.max_modcod_acm) << "\"";
|
||||
result << R"(,"dvbAcmMaxSpeed":")" << extractModcodSpeed(acmSettings.max_modcod_acm) << "\"";
|
||||
result << ",\"dvbSnrReserve\":"; writeDouble(result, acmSettings.snr_threashold_acm);
|
||||
|
||||
result << ",\n\"rx.gainMode\":" << (demodSettings.is_aru_on ? "\"auto\"" : "\"manual\"");
|
||||
result << ",\"rx.manualGain\":"; writeDouble(result, demodSettings.gain);
|
||||
result << ",\"rx.spectrumInversion\":" << boolAsStr(demodSettings.is_rvt_iq);
|
||||
result << ",\"rx.rolloff\":" << static_cast<int>(demodSettings.rollof * 100);
|
||||
result << ",\"rx.cymRate\":" << demodSettings.baudrate;
|
||||
result << ",\"rx.centerFreq\":"; writeDouble(result, demodSettings.central_freq_in_kGz);
|
||||
result << ",\n\"aupcEn\":" << boolAsStr(acmSettings.enable_aupc);
|
||||
result << ",\"aupcMinAttenuation\":"; writeDouble(result, acmSettings.min_attenuation_aupc);
|
||||
result << ",\"aupcMaxAttenuation\":"; writeDouble(result, acmSettings.max_attenuation_aupc);
|
||||
result << ",\"aupcRequiredSnr\":"; writeDouble(result, acmSettings.snr_threashold_aupc);
|
||||
|
||||
result << ",\n\"cinc.mode\":" << (dpdiSettings.is_delay_window ? "\"delay\"" : "\"positional\"");
|
||||
result << ",\"cinc.searchBandwidth\":" << dpdiSettings.freq_offset; // полоса поиска в кГц
|
||||
result << ",\"cinc.position.station.latitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.latitude_station_grad, dpdiSettings.latitude_station_minute), 6);
|
||||
result << ",\"cinc.position.station.longitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_station_grad, dpdiSettings.longitude_station_minute), 6);
|
||||
result << ",\"cinc.position.satelliteLongitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_sattelite_grad, dpdiSettings.longitude_sattelite_minute), 6);
|
||||
result << ",\"cinc.delayMin\":" << dpdiSettings.min_delay;
|
||||
result << ",\"cinc.delayMax\":" << dpdiSettings.max_delay;
|
||||
#else
|
||||
result << "{\n\"tx.txEn\":" << boolAsStr(modSettings.tx_is_on);
|
||||
result << ",\"tx.isTestInputData\":" << boolAsStr(modSettings.is_test_data);
|
||||
result << ",\"tx.cymRate\":" << modSettings.baudrate;
|
||||
result << ",\"tx.centerFreq\":"; writeDouble(result, modSettings.central_freq_in_kGz, 3);
|
||||
result << ",\"tx.attenuation\":"; writeDouble(result, modSettings.attenuation);
|
||||
|
||||
result << ",\n\"rx.gainMode\":" << (demodSettings.is_aru_on ? "\"auto\"" : "\"manual\"");
|
||||
result << ",\"rx.manualGain\":"; writeDouble(result, demodSettings.gain);
|
||||
result << ",\"rx.spectrumInversion\":" << boolAsStr(demodSettings.is_rvt_iq);
|
||||
result << ",\"rx.rolloff\":" << static_cast<int>(demodSettings.rollof * 100);
|
||||
result << ",\"rx.cymRate\":" << demodSettings.baudrate;
|
||||
result << ",\"rx.centerFreq\":"; writeDouble(result, demodSettings.central_freq_in_kGz);
|
||||
result << ",\n\"cincIsPositional\":" << boolAsStr(!dpdiSettings.is_delay_window);
|
||||
result << ",\"cincSearchBandwidth\":" << dpdiSettings.freq_offset; // полоса поиска в кГц
|
||||
result << ",\"cincPositionStationLatitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.latitude_station_grad, dpdiSettings.latitude_station_minute), 6);
|
||||
result << ",\"cincPositionStationLongitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_station_grad, dpdiSettings.longitude_station_minute), 6);
|
||||
result << ",\"cincPositionSatelliteLongitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_sattelite_grad, dpdiSettings.longitude_sattelite_minute), 6);
|
||||
result << ",\"cincDelayMin\":" << dpdiSettings.min_delay;
|
||||
result << ",\"cincDelayMax\":" << dpdiSettings.max_delay;
|
||||
#endif
|
||||
|
||||
result << ",\n\"buc.refClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_buc);
|
||||
result << ",\n\"rxAgcEn\":" << boolAsStr(demodSettings.is_aru_on);
|
||||
result << ",\"rxSpectrumInversion\":" << boolAsStr(demodSettings.is_rvt_iq);
|
||||
result << ",\"rxManualGain\":"; writeDouble(result, demodSettings.gain);
|
||||
result << ",\"rxCentralFreq\":"; writeDouble(result, demodSettings.central_freq_in_kGz);
|
||||
result << ",\"rxBaudrate\":" << demodSettings.baudrate;
|
||||
result << ",\"rxRolloff\":" << static_cast<int>(demodSettings.rollof);
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << ",\"rxGoldan\":" << static_cast<int>(demodSettings.gold_seq_is_active);
|
||||
#endif
|
||||
|
||||
// BUC LNB
|
||||
result << ",\n\"bucRefClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_buc);
|
||||
switch (bucLnb.buc) {
|
||||
case voltage_buc::_24V: result << ",\"buc.powering\":24"; break;
|
||||
case voltage_buc::_48V: result << ",\"buc.powering\":48"; break;
|
||||
case voltage_buc::_24V: result << ",\"bucPowering\":24"; break;
|
||||
#ifdef MODEM_IS_SCPC
|
||||
case voltage_buc::_48V: result << ",\"bucPowering\":48"; break;
|
||||
#endif
|
||||
case voltage_buc::DISABLE:
|
||||
default: result << ",\"buc.powering\":0";
|
||||
default: result << ",\"bucPowering\":0";
|
||||
}
|
||||
|
||||
result << ",\n\"lnb.refClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_lnb);
|
||||
result << ",\"lnbRefClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_lnb);
|
||||
switch (bucLnb.lnb) {
|
||||
case voltage_lnb::_13V: result << ",\"lnb.powering\":13"; break;
|
||||
case voltage_lnb::_18V: result << ",\"lnb.powering\":18"; break;
|
||||
case voltage_lnb::_24V: result << ",\"lnb.powering\":24"; break;
|
||||
case voltage_lnb::_13V: result << ",\"lnbPowering\":13"; break;
|
||||
case voltage_lnb::_18V: result << ",\"lnbPowering\":18"; break;
|
||||
case voltage_lnb::_24V: result << ",\"lnbPowering\":24"; break;
|
||||
case voltage_lnb::DISABLE:
|
||||
default: result << ",\"lnb.powering\":0";
|
||||
default: result << ",\"lnbPowering\":0";
|
||||
}
|
||||
|
||||
result << ",\n\"serviceSettings.refClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_output);
|
||||
result << ",\"serviceSettings.autoStart\":" << boolAsStr(bucLnb.is_save_current_state);
|
||||
result << ",\"srvRefClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_output);
|
||||
result << ",\"bucLnbAutoStart\":" << boolAsStr(bucLnb.is_save_current_state);
|
||||
|
||||
// QoS
|
||||
bool qosEnabled = false; std::string qosClasses;
|
||||
daemon->getQosSettings(qosEnabled, qosClasses);
|
||||
result << ",\n\"qos.enabled\":" << boolAsStr(qosEnabled);
|
||||
result << ",\"qos.profile\":" << qosClasses;
|
||||
result << ",\n\"qosEnabled\":" << boolAsStr(qosEnabled);
|
||||
result << ",\"qosProfile\":" << qosClasses;
|
||||
|
||||
// сеть
|
||||
result << ",\"network.managementIp\":\n" << buildEscapedString(network.managementIp);
|
||||
result << ",\"network.managementGateway\":\n" << buildEscapedString(network.managementGateway);
|
||||
result << ",\"network.mode\":\n" << buildEscapedString(network.mode);
|
||||
result << ",\"network.dataIp\":\n" << buildEscapedString(network.dataIp);
|
||||
result << ",\"network.dataMtu\":\n" << network.dataMtu;
|
||||
result << ",\"netManagementIp\":\n" << buildEscapedString(network.managementIp);
|
||||
result << ",\"netIsL2\":\n" << boolAsStr(network.isL2);
|
||||
result << ",\"netManagementGateway\":\n" << buildEscapedString(network.managementGateway);
|
||||
result << ",\"netDataIp\":\n" << buildEscapedString(network.dataIp);
|
||||
result << ",\"netDataMtu\":\n" << network.dataMtu;
|
||||
|
||||
result << "}";
|
||||
return result.str();
|
||||
@@ -924,64 +990,81 @@ std::string api_driver::ApiDriver::loadFirmwareVersion() const {
|
||||
return result.str();
|
||||
}
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
static uint32_t buildModcodFromPt(const boost::property_tree::ptree& pt, const std::string& name, bool isShortFrame) {
|
||||
uint32_t modcod = 0;
|
||||
const auto mod = pt.get<std::string>(name + "Modulation");
|
||||
const auto speed = pt.get<std::string>(name + "Speed");
|
||||
uint32_t _index = 0;
|
||||
for (const auto& m: ModcodDefs) {
|
||||
if (mod == m.modulation) {
|
||||
if (modcod == 0) modcod = _index;
|
||||
if (speed == m.speed) {
|
||||
modcod = _index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_index++;
|
||||
}
|
||||
return (modcod << 2) | (isShortFrame ? 2 : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void api_driver::ApiDriver::setRxTxSettings(boost::property_tree::ptree &pt) {
|
||||
modulator_settings mod{};
|
||||
demodulator_settings demod{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
ACM_parameters_serv_ acm{};
|
||||
daemon->getSettings(&mod, &demod, &acm, nullptr, nullptr);
|
||||
#else
|
||||
daemon->getSettings(&mod, &demod, nullptr);
|
||||
#endif
|
||||
|
||||
// для модулятора
|
||||
#ifdef MODEM_IS_SCPC
|
||||
mod.is_cinc = pt.get<bool>(json_path("general.isCinC", '/'));
|
||||
mod.tx_is_on = pt.get<bool>(json_path("general.txEn", '/'));
|
||||
auto tmp = pt.get<std::string>(json_path("general.modulatorMode", '/'));
|
||||
if (tmp == "normal") { mod.is_carrier = true; }
|
||||
else if (tmp == "test") { mod.is_carrier = false; }
|
||||
else { throw std::runtime_error("api_driver::ApiDriver::setRxTxSettings(): Wrong carrier mode: " + tmp); }
|
||||
mod.is_save_current_state = pt.get<bool>(json_path("general.autoStartTx", '/'));
|
||||
mod.is_test_data = pt.get<bool>(json_path("general.isTestInputData", '/'));
|
||||
mod.attenuation = pt.get<double>(json_path("tx.attenuation", '/'));
|
||||
mod.rollof = pt.get<double>(json_path("tx.rolloff", '/')) / 100.0;
|
||||
mod.baudrate = pt.get<uint32_t>(json_path("tx.cymRate", '/'));
|
||||
mod.central_freq_in_kGz = pt.get<double>(json_path("tx.centerFreq", '/'));
|
||||
mod.is_cinc = pt.get<bool>("isCinC");
|
||||
#endif
|
||||
mod.tx_is_on = pt.get<bool>("txEn");
|
||||
#ifdef MODEM_IS_SCPC
|
||||
mod.is_save_current_state = pt.get<bool>("txAutoStart");
|
||||
mod.is_test_data = pt.get<bool>("txIsTestInput");
|
||||
#endif
|
||||
mod.is_carrier = !pt.get<bool>("txModulatorIsTest");
|
||||
mod.central_freq_in_kGz = pt.get<double>("txCentralFreq");
|
||||
#ifdef MODEM_IS_SCPC
|
||||
mod.baudrate = pt.get<uint32_t>("txBaudrate");
|
||||
mod.rollof = pt.get<unsigned int>("txRolloff");
|
||||
mod.gold_seq_is_active = pt.get<bool>("txGoldan");
|
||||
#endif
|
||||
mod.attenuation = pt.get<double>("txAttenuation");
|
||||
|
||||
const bool acmIsShortFrame = !pt.get<bool>(json_path("dvbs2.frameSizeNormal", '/'));
|
||||
mod.modcod_tx = (pt.get<uint32_t>(json_path("dvbs2.ccm_modcod", '/')) << 2) | (acmIsShortFrame ? 2 : 0);
|
||||
#else
|
||||
mod.tx_is_on = pt.get<bool>(json_path("tx.txEn", '/'));
|
||||
mod.is_test_data = pt.get<bool>(json_path("tx.isTestInputData", '/'));
|
||||
mod.central_freq_in_kGz = pt.get<double>(json_path("tx.centerFreq", '/'));
|
||||
mod.baudrate = pt.get<uint32_t>(json_path("tx.cymRate", '/'));
|
||||
mod.attenuation = pt.get<double>(json_path("tx.attenuation", '/'));
|
||||
#ifdef MODEM_IS_SCPC
|
||||
const bool acmIsShortFrame = !pt.get<bool>("txFrameSizeNormal");
|
||||
mod.modcod_tx = buildModcodFromPt(pt, "dvbCcm", acmIsShortFrame);
|
||||
#endif
|
||||
|
||||
// демодулятор
|
||||
demod.is_aru_on = pt.get<bool>("rxAgcEn");
|
||||
demod.gain = pt.get<double>("rxManualGain");
|
||||
demod.is_rvt_iq = pt.get<bool>("rxSpectrumInversion");
|
||||
demod.central_freq_in_kGz = pt.get<double>("rxCentralFreq");
|
||||
demod.baudrate = pt.get<uint32_t>("rxBaudrate");
|
||||
demod.rollof = pt.get<unsigned int>("rxRolloff");
|
||||
#ifdef MODEM_IS_SCPC
|
||||
tmp = pt.get<std::string>(json_path("rx.gainMode", '/'));
|
||||
#else
|
||||
auto tmp = pt.get<std::string>(json_path("rx.gainMode", '/'));
|
||||
demod.gold_seq_is_active = pt.get<bool>("rxGoldan");
|
||||
#endif
|
||||
if (tmp == "auto") { demod.is_aru_on = true; }
|
||||
else if (tmp == "manual") { demod.is_aru_on = false; }
|
||||
else { throw std::runtime_error("api_driver::ApiDriver::setRxTxSettings(): Wrong gain mode: " + tmp); }
|
||||
demod.gain = pt.get<double>(json_path("rx.manualGain", '/'));
|
||||
demod.baudrate = pt.get<uint32_t>(json_path("rx.cymRate", '/'));
|
||||
demod.is_rvt_iq = pt.get<bool>(json_path("rx.spectrumInversion", '/'));
|
||||
demod.rollof = pt.get<double>(json_path("rx.rolloff", '/')) / 100.0;
|
||||
demod.central_freq_in_kGz = pt.get<double>(json_path("rx.centerFreq", '/'));
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
// ACM
|
||||
acm.enable = pt.get<bool>(json_path("dvbs2.isAcm", '/'));
|
||||
acm.max_modcod = (pt.get<uint32_t>(json_path("dvbs2.acm_maxModcod", '/')) << 2) | (acmIsShortFrame ? 2 : 0);
|
||||
acm.min_modcod = (pt.get<uint32_t>(json_path("dvbs2.acm_minModcod", '/')) << 2) | (acmIsShortFrame ? 2 : 0);
|
||||
acm.snr_treashold_acm = pt.get<double>(json_path("dvbs2.snrReserve", '/')); // запас ОСШ
|
||||
acm.period_pack = pt.get<uint32_t>(json_path("dvbs2.servicePacketPeriod", '/'));
|
||||
acm.enable_auto_atten = pt.get<bool>(json_path("acm.en", '/'));
|
||||
acm.max_attenuation = pt.get<double>(json_path("acm.maxAttenuation", '/'));
|
||||
acm.min_attenuation = pt.get<double>(json_path("acm.minAttenuation", '/'));
|
||||
acm.snr_treashold = pt.get<double>(json_path("acm.requiredSnr", '/')); // требуемый ОСШ
|
||||
acm.period_pack_acm = pt.get<uint32_t>("dvbServicePacketPeriod");
|
||||
acm.enable_acm = pt.get<bool>("dvbIsAcm");
|
||||
acm.min_modcod_acm = buildModcodFromPt(pt, "dvbAcmMin", acmIsShortFrame);
|
||||
acm.max_modcod_acm = buildModcodFromPt(pt, "dvbAcmMax", acmIsShortFrame);
|
||||
acm.snr_threashold_acm = pt.get<double>("dvbSnrReserve"); // запас ОСШ
|
||||
acm.enable_aupc = pt.get<bool>(json_path("aupcEn", '/'));
|
||||
acm.min_attenuation_aupc = pt.get<int>("aupcMinAttenuation");
|
||||
acm.max_attenuation_aupc = pt.get<int>("aupcMaxAttenuation");
|
||||
acm.snr_threashold_aupc= pt.get<double>("aupcRequiredSnr");
|
||||
|
||||
daemon->setSettingsRxTx(mod, demod, acm);
|
||||
#else
|
||||
@@ -993,30 +1076,23 @@ void api_driver::ApiDriver::setRxTxSettings(boost::property_tree::ptree &pt) {
|
||||
void api_driver::ApiDriver::setCincSettings(boost::property_tree::ptree &pt) {
|
||||
DPDI_parmeters s{};
|
||||
|
||||
//result << ",\n\"cinc.mode\":" << (dpdiSettings.is_delay_window ? "\"delay\"" : "\"positional\"");
|
||||
auto tmp = pt.get<std::string>(json_path("cinc.mode", '/'));
|
||||
if (tmp == "delay") { s.is_delay_window = true; }
|
||||
else if (tmp == "positional") { s.is_delay_window = false; }
|
||||
else {
|
||||
throw std::runtime_error("Wrong CinC mode: " + tmp);
|
||||
}
|
||||
s.is_delay_window = !pt.get<bool>("cincIsPositional");
|
||||
s.freq_offset = pt.get<uint32_t>("cincSearchBandwidth");
|
||||
|
||||
auto ctmp = translateCoordinates(pt.get<double>(json_path("cinc.position.station.latitude", '/')));
|
||||
auto ctmp = translateCoordinates(pt.get<double>("cincPositionStationLatitude"));
|
||||
s.latitude_station_grad = std::get<0>(ctmp);
|
||||
s.latitude_station_minute = std::get<1>(ctmp);
|
||||
|
||||
ctmp = translateCoordinates(pt.get<double>(json_path("cinc.position.station.longitude", '/')));
|
||||
ctmp = translateCoordinates(pt.get<double>("cincPositionStationLongitude"));
|
||||
s.longitude_station_grad = std::get<0>(ctmp);
|
||||
s.longitude_station_minute = std::get<1>(ctmp);
|
||||
|
||||
ctmp = translateCoordinates(pt.get<double>(json_path("cinc.position.satelliteLongitude", '/')));
|
||||
ctmp = translateCoordinates(pt.get<double>("cincPositionSatelliteLongitude"));
|
||||
s.longitude_sattelite_grad = std::get<0>(ctmp);
|
||||
s.longitude_sattelite_minute = std::get<1>(ctmp);
|
||||
|
||||
s.max_delay = pt.get<uint32_t>(json_path("cinc.delayMax", '/'));
|
||||
s.min_delay = pt.get<uint32_t>(json_path("cinc.delayMin", '/'));
|
||||
|
||||
s.freq_offset = pt.get<uint32_t>(json_path("cinc.searchBandwidth", '/'));
|
||||
s.min_delay = pt.get<uint32_t>("cincDelayMin");
|
||||
s.max_delay = pt.get<uint32_t>("cincDelayMax");
|
||||
|
||||
this->daemon->setSettingsCinc(s);
|
||||
}
|
||||
@@ -1024,19 +1100,13 @@ void api_driver::ApiDriver::setCincSettings(boost::property_tree::ptree &pt) {
|
||||
|
||||
void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) {
|
||||
buc_lnb_settings s{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
daemon->getSettings(nullptr, nullptr, nullptr, nullptr, &s);
|
||||
#else
|
||||
daemon->getSettings(nullptr, nullptr, &s);
|
||||
#endif
|
||||
|
||||
auto tmp = pt.get<int>(json_path("lnb.powering", '/'));
|
||||
switch (tmp) {
|
||||
case 13: s.lnb = voltage_lnb::_13V; break;
|
||||
case 18: s.lnb = voltage_lnb::_18V; break;
|
||||
case 24: s.lnb = voltage_lnb::_24V; break;
|
||||
case 0:
|
||||
default:
|
||||
s.lnb = voltage_lnb::DISABLE;
|
||||
}
|
||||
s.is_ref_10MHz_lnb = pt.get<bool>(json_path("lnb.refClk10M", '/'));
|
||||
|
||||
tmp = pt.get<int>(json_path("buc.powering", '/'));
|
||||
auto tmp = pt.get<int>("bucPowering");
|
||||
switch (tmp) {
|
||||
case 24: s.buc = voltage_buc::_24V; break;
|
||||
#ifdef MODEM_IS_SCPC
|
||||
@@ -1046,11 +1116,21 @@ void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) {
|
||||
default:
|
||||
s.lnb = voltage_lnb::DISABLE;
|
||||
}
|
||||
s.is_ref_10MHz_buc = pt.get<bool>("bucRefClk10M");
|
||||
|
||||
s.is_ref_10MHz_buc = pt.get<bool>(json_path("buc.refClk10M", '/'));
|
||||
tmp = pt.get<int>("lnbPowering");
|
||||
switch (tmp) {
|
||||
case 13: s.lnb = voltage_lnb::_13V; break;
|
||||
case 18: s.lnb = voltage_lnb::_18V; break;
|
||||
case 24: s.lnb = voltage_lnb::_24V; break;
|
||||
case 0:
|
||||
default:
|
||||
s.lnb = voltage_lnb::DISABLE;
|
||||
}
|
||||
s.is_ref_10MHz_lnb = pt.get<bool>("lnbRefClk10M");
|
||||
|
||||
s.is_ref_10MHz_output = pt.get<bool>(json_path("serviceSettings.refClk10M", '/'));
|
||||
s.is_save_current_state = pt.get<bool>(json_path("serviceSettings.autoStart", '/'));
|
||||
s.is_ref_10MHz_output = pt.get<bool>("srvRefClk10M");
|
||||
s.is_save_current_state = pt.get<bool>("bucLnbAutoStart");
|
||||
|
||||
this->daemon->setSettingsBucLnb(s);
|
||||
}
|
||||
@@ -1067,19 +1147,17 @@ void api_driver::ApiDriver::setQosSettings(boost::property_tree::ptree &pt) {
|
||||
|
||||
void api_driver::ApiDriver::setNetworkSettings(boost::property_tree::ptree &pt) {
|
||||
TerminalNetworkSettings s;
|
||||
s.managementIp = pt.get<std::string>(json_path("network.managementIp", '/'));
|
||||
s.managementGateway = pt.get<std::string>(json_path("network.managementGateway", '/'));
|
||||
s.mode = pt.get<std::string>(json_path("network.mode", '/'));
|
||||
s.dataIp = pt.get<std::string>(json_path("network.dataIp", '/'));
|
||||
s.dataMtu = pt.get<unsigned int>(json_path("network.dataMtu", '/'));
|
||||
daemon->getNetworkSettings(s);
|
||||
|
||||
s.managementIp = pt.get<std::string>("netManagementIp");
|
||||
// s.managementGateway = pt.get<std::string>(json_path("network.managementGateway", '/'));
|
||||
s.isL2 = pt.get<bool>("netIsL2");
|
||||
s.dataIp = pt.get<std::string>("netDataIp");
|
||||
s.dataMtu = pt.get<unsigned int>("netDataMtu");
|
||||
|
||||
daemon->setNetworkSettings(s);
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::setDebugSendSettings(boost::property_tree::ptree &pt) {
|
||||
boost::ignore_unused(pt);
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::resetDefaultSettings() {
|
||||
daemon->resetDefaultSettings();
|
||||
}
|
||||
@@ -1098,35 +1176,34 @@ std::string api_driver::ApiDriver::loadSysInfo() {
|
||||
struct sysinfo info{};
|
||||
sysinfo(&info);
|
||||
|
||||
struct sysinfo {
|
||||
long uptime; /* Seconds since boot */
|
||||
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
|
||||
unsigned long totalram; /* Total usable main memory size */
|
||||
unsigned long freeram; /* Available memory size */
|
||||
unsigned long sharedram; /* Amount of shared memory */
|
||||
unsigned long bufferram; /* Memory used by buffers */
|
||||
unsigned long totalswap; /* Total swap space size */
|
||||
unsigned long freeswap; /* Swap space still available */
|
||||
unsigned short procs; /* Number of current processes */
|
||||
unsigned long totalhigh; /* Total high memory size */
|
||||
unsigned long freehigh; /* Available high memory size */
|
||||
unsigned int mem_unit; /* Memory unit size in bytes */
|
||||
};
|
||||
// struct sysinfo {
|
||||
// long uptime; /* Seconds since boot */
|
||||
// unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
|
||||
// unsigned long totalram; /* Total usable main memory size */
|
||||
// unsigned long freeram; /* Available memory size */
|
||||
// unsigned long sharedram; /* Amount of shared memory */
|
||||
// unsigned long bufferram; /* Memory used by buffers */
|
||||
// unsigned long totalswap; /* Total swap space size */
|
||||
// unsigned long freeswap; /* Swap space still available */
|
||||
// unsigned short procs; /* Number of current processes */
|
||||
// unsigned long totalhigh; /* Total high memory size */
|
||||
// unsigned long freehigh; /* Available high memory size */
|
||||
// unsigned int mem_unit; /* Memory unit size in bytes */
|
||||
// };
|
||||
|
||||
const double f_load = 100.0 / ((1 << SI_LOAD_SHIFT) * get_nprocs());
|
||||
|
||||
result << "{\n\"uptime\":" << info.uptime;
|
||||
result << ",\"load1min\":" << info.loads[0];
|
||||
result << ",\"load5min\":" << info.loads[1];
|
||||
result << ",\"load15min\":" << info.loads[2];
|
||||
result << ",\"totalram\":" << info.totalram;
|
||||
result << ",\"freeram\":" << info.freeram;
|
||||
result << ",\"sharedram\":" << info.sharedram;
|
||||
result << ",\"bufferram\":" << info.bufferram;
|
||||
result << ",\"totalswap\":" << info.totalswap;
|
||||
result << ",\"freeswap\":" << info.freeswap;
|
||||
result << ",\"load1min\":"; writeDouble(result, f_load * static_cast<double>(info.loads[0]), 2);
|
||||
result << ",\"load5min\":"; writeDouble(result, f_load * static_cast<double>(info.loads[1]), 2);
|
||||
result << ",\"load15min\":"; writeDouble(result, f_load * static_cast<double>(info.loads[2]), 2);
|
||||
result << ",\"totalram\":" << ((info.totalram * info.mem_unit) >> 20); // Mb
|
||||
result << ",\"freeram\":" << ((info.freeram * info.mem_unit) >> 20); // Mb
|
||||
// result << ",\"sharedram\":" << ((info.sharedram * info.mem_unit) >> 20); // Mb
|
||||
// result << ",\"bufferram\":" << ((info.bufferram * info.mem_unit) >> 20); // Mb
|
||||
// result << ",\"totalswap\":" << info.totalswap * info.mem_unit;
|
||||
// result << ",\"freeswap\":" << info.freeswap * info.mem_unit;
|
||||
result << ",\"procs\":" << static_cast<long>(info.procs);
|
||||
result << ",\"totalhigh\":" << info.totalhigh;
|
||||
result << ",\"freehigh\":" << info.freehigh;
|
||||
result << ",\"mem_unit\":" << info.mem_unit;
|
||||
result << "\n}";
|
||||
return result.str();
|
||||
}
|
||||
|
@@ -64,8 +64,6 @@ namespace api_driver {
|
||||
|
||||
void setNetworkSettings(boost::property_tree::ptree & pt);
|
||||
|
||||
void setDebugSendSettings(boost::property_tree::ptree & pt);
|
||||
|
||||
void resetDefaultSettings();
|
||||
|
||||
void executeInApi(const std::function<void(TSID sid)>& callback);
|
||||
@@ -77,6 +75,13 @@ namespace api_driver {
|
||||
private:
|
||||
std::unique_ptr<TerminalApiDaemon> daemon;
|
||||
};
|
||||
|
||||
/**
|
||||
* Функция для создания экранированной строки (для json)
|
||||
* @param source исходная строка (например, {123"})
|
||||
* @return {"123\""}
|
||||
*/
|
||||
std::string buildEscapedString(const std::string& source);
|
||||
}
|
||||
|
||||
#endif //TERMINAL_API_DRIVER_H
|
||||
|
@@ -2,9 +2,103 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RSCM-101</title>
|
||||
<link rel="stylesheet" type="text/css" href="/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="/fields.css">
|
||||
<style>
|
||||
header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 10;
|
||||
background: var(--bg-selected);
|
||||
}
|
||||
|
||||
body { /* значение по-умолчанию */ --header-height: 60px; }
|
||||
|
||||
#content {
|
||||
padding-top: var(--header-height);
|
||||
}
|
||||
|
||||
.l3-proto-label {
|
||||
margin: 0 0 0 0.5em;
|
||||
}
|
||||
.l3-proto-label > * {
|
||||
display: inline-block;
|
||||
}
|
||||
.l3-proto-label input[type=checkbox] {
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" hidden>
|
||||
<header>
|
||||
<span class="nav-bar-element">Прием: <span :class="{ indicator_bad: stat_rx.state === false, indicator_good: stat_rx.state === true, indicator: true }"></span></span>
|
||||
<span :class="{ value_bad: initState !== 'Успешная инициализация системы' }">{{ initState }}</span>
|
||||
<div class="tabs-header">
|
||||
<span style="font-weight:bold">RSCM-101</span>
|
||||
<a href="#monitoring" class="tabs-btn" @click="activeTab = 'monitoring'" :class="{ active: activeTab === 'monitoring' }">Мониторинг</a>
|
||||
<a href="#setup" class="tabs-btn" @click="activeTab = 'setup'" :class="{ active: activeTab === 'setup' }">Настройки</a>
|
||||
<a href="#qos" class="tabs-btn" @click="activeTab = 'qos'" :class="{ active: activeTab === 'qos' }">QoS</a>
|
||||
<a href="#admin" class="tabs-btn" @click="activeTab = 'admin'" :class="{ active: activeTab === 'admin' }">Администрирование</a>
|
||||
<a href="/logout" class="tabs-btn">Выход</a>
|
||||
</div>
|
||||
</header>
|
||||
<div id="content">
|
||||
<p>Прием: <span :class="{ indicator_bad: stat_rx.state === false, indicator_good: stat_rx.state === true, indicator: true }"></span></p>
|
||||
<p>Скорость: <span>{{ stat_rx.speedOnRxKbit }}</span></p>
|
||||
|
||||
<h2>Настройки</h2>
|
||||
<div class="settings-set-container">
|
||||
<label>
|
||||
<span>Режим работы</span>
|
||||
<select v-model="param.general.isCinC">
|
||||
<option :value="false">SCPC</option>
|
||||
<option :value="true">CinC</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Полоса поиска, кгц ±</span>
|
||||
<input v-model="param.num" type="number" min="0" max="100" step="1"/>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/vue.js"></script>
|
||||
<script>
|
||||
const app = Vue.createApp({
|
||||
data() {
|
||||
return {
|
||||
stat_rx: {
|
||||
state: false,
|
||||
},
|
||||
param: {
|
||||
general: {
|
||||
isCinC: true,
|
||||
isTestInputData: false,
|
||||
modulatorMode: 'test'
|
||||
},
|
||||
num: 1
|
||||
},
|
||||
|
||||
initState: '?',
|
||||
activeTab: 'setup'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
document.getElementById("app").removeAttribute("hidden")
|
||||
}
|
||||
});
|
||||
app.mount('#app')
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -134,9 +134,10 @@ select * {
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
.settings-set-container tr > * {
|
||||
border-bottom: solid 1px var(--text-color2);
|
||||
.settings-set-container th, .settings-set-container td {
|
||||
border-bottom: solid 1px var(--bg-element);
|
||||
}
|
||||
.settings-set-container table { border-collapse: collapse; }
|
||||
|
||||
.settings-set-container tr:hover {
|
||||
background: var(--bg-selected);
|
||||
|
29805
static/js/vue.js
29805
static/js/vue.js
File diff suppressed because it is too large
Load Diff
9
static/js/vue.prod.js
Normal file
9
static/js/vue.prod.js
Normal file
File diff suppressed because one or more lines are too long
@@ -111,7 +111,8 @@
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(requestData)
|
||||
body: JSON.stringify(requestData),
|
||||
credentials: 'same-origin'
|
||||
}).then(response => {
|
||||
// Обработка ответа сервера
|
||||
response.json().then((value) => {
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user