Compare commits
30 Commits
3e38e77069
...
master
Author | SHA1 | Date | |
---|---|---|---|
483c174cd5 | |||
eb1e4609bb | |||
00a9692b3d | |||
89004bcf31 | |||
b580ac6b37 | |||
7cd096a269 | |||
beca00ff70 | |||
ed6694b99d | |||
305a8c54fa | |||
297e681b75 | |||
32720ca365 | |||
33bbdafc3d | |||
bfcdc88da9 | |||
760a6858ee | |||
e9ff1d099a | |||
11e4561551 | |||
081ef1b84f | |||
bb90a3fec2 | |||
9fbe88b64d | |||
996e711436 | |||
57ba61da41 | |||
b9a25e8734 | |||
1e185a987d | |||
4c555d5400 | |||
38a00173a2 | |||
e5e6878351 | |||
55fc322c13 | |||
f30e1adb49 | |||
50f82483fd | |||
c2dd4b13e8 |
@@ -8,9 +8,9 @@ test for build:
|
||||
- cpp-test-universal
|
||||
only:
|
||||
- master
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
script:
|
||||
- git submodule init
|
||||
- git submodule update
|
||||
- cmake -DCMAKE_BUILD_TYPE=Debug -DMODEM_TYPE=TDMA -B cmake-build-debug-tdma
|
||||
- cmake -DCMAKE_BUILD_TYPE=Debug -DMODEM_TYPE=SCPC -B cmake-build-debug-scpc
|
||||
- cmake -DCMAKE_BUILD_TYPE=Debug -DMODEM_TYPE=SHPS -B cmake-build-debug-shps
|
||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,3 +1,9 @@
|
||||
[submodule "dependencies/control_system_client"]
|
||||
path = dependencies/control_system_client
|
||||
url = http://gitlab.devrss.vg/mf-tdma/protocol_processing/control_system_client.git
|
||||
[submodule "dependencies/control_system_client_tdma"]
|
||||
path = dependencies/control_system_client_tdma
|
||||
url = http://gitlab.devrss.vg/mf-tdma/protocol_processing/control_system_client.git
|
||||
[submodule "dependencies/control_system_client_shps"]
|
||||
path = dependencies/control_system_client_shps
|
||||
url = http://gitlab.devrss.vg/mf-tdma/protocol_processing/control_system_client.git
|
||||
|
@@ -18,12 +18,15 @@ endif()
|
||||
if("${MODEM_TYPE}" STREQUAL "SCPC")
|
||||
add_definitions(-DMODEM_IS_SCPC)
|
||||
message(STATUS "Selected SCPC modem")
|
||||
add_subdirectory(dependencies/control_system_client) # подключение правильного control system client SCPC, ветка main
|
||||
elseif ("${MODEM_TYPE}" STREQUAL "TDMA")
|
||||
add_definitions(-DMODEM_IS_TDMA)
|
||||
message(STATUS "Selected TDMA modem")
|
||||
add_subdirectory(dependencies/control_system_client_tdma) # подключение правильного control system client TDMA, ветка terminal-tdma
|
||||
elseif ("${MODEM_TYPE}" STREQUAL "SHPS")
|
||||
add_definitions(-DMODEM_IS_SHPS)
|
||||
message(STATUS "Selected TDMA modem")
|
||||
message(STATUS "Selected SHPS modem")
|
||||
add_subdirectory(dependencies/control_system_client_shps) # подключение правильного control system client SHPS, ветка shps
|
||||
else()
|
||||
message(FATAL_ERROR "You must set `MODEM_TYPE` \"SCPC\" or \"TDMA\" or \"SHPS\"!")
|
||||
endif()
|
||||
@@ -52,7 +55,6 @@ add_compile_options(-Wall -Wextra -Wsign-conversion -DPROJECT_GIT_REVISION="${PR
|
||||
# максимальный размер тела запроса 200mb
|
||||
add_definitions(-DHTTP_MAX_PAYLOAD=200000000)
|
||||
|
||||
add_subdirectory(dependencies/control_system_client)
|
||||
|
||||
include_directories(src/)
|
||||
|
||||
@@ -63,6 +65,7 @@ add_executable(terminal-web-server
|
||||
src/api-driver/proxy.cpp
|
||||
src/api-driver/structs.h
|
||||
src/api-driver/structs.cpp
|
||||
src/common/nlohmann/json.hpp
|
||||
src/server/mime_types.hpp
|
||||
src/server/mime_types.cpp
|
||||
src/server/request_parser.hpp
|
||||
|
1
dependencies/control_system_client_shps
vendored
Submodule
1
dependencies/control_system_client_shps
vendored
Submodule
Submodule dependencies/control_system_client_shps added at 6fb944f930
1
dependencies/control_system_client_tdma
vendored
Submodule
1
dependencies/control_system_client_tdma
vendored
Submodule
Submodule dependencies/control_system_client_tdma added at 4eefdaf82e
33
devtool.py
33
devtool.py
@@ -44,6 +44,25 @@ def cp_get_dma_debug(base_url, param_name):
|
||||
return res.content.decode('utf-8')
|
||||
|
||||
|
||||
def cp_set_network(base_url, param_name, value):
|
||||
session = do_login(base_url)
|
||||
res = session.post(f"{base_url}/dev/cpapicall", params={
|
||||
"f": "SetDmaDebug",
|
||||
"param": param_name,
|
||||
"value": value
|
||||
})
|
||||
return res.content.decode('utf-8')
|
||||
|
||||
|
||||
def cp_get_network(base_url, param_name):
|
||||
session = do_login(base_url)
|
||||
res = session.post(f"{base_url}/dev/cpapicall", params={
|
||||
"f": "GetDmaDebug",
|
||||
"param": param_name
|
||||
})
|
||||
return res.content.decode('utf-8')
|
||||
|
||||
|
||||
def set_logging(base_url, value):
|
||||
print(cp_set_dma_debug(base_url, "log_bool", value))
|
||||
|
||||
@@ -53,6 +72,8 @@ if __name__ == '__main__':
|
||||
print(f"Usage: {sys.argv[0]} http(s)://terminal-url logging on|off")
|
||||
print(f" set_dma_debug <param_name> <value>")
|
||||
print(f" get_dma_debug <param_name>")
|
||||
print(f" set_network <param_name> <value>")
|
||||
print(f" get_network <param_name>")
|
||||
exit(1)
|
||||
|
||||
if sys.argv[2] == "logging":
|
||||
@@ -67,7 +88,17 @@ if __name__ == '__main__':
|
||||
print(cp_set_dma_debug(sys.argv[1], sys.argv[3], sys.argv[4]))
|
||||
elif sys.argv[2] == "get_dma_debug":
|
||||
if len(sys.argv) != 4:
|
||||
print("Wrong set dma debug usage!")
|
||||
print("Wrong get dma debug usage!")
|
||||
else:
|
||||
print(cp_get_dma_debug(sys.argv[1], sys.argv[3]))
|
||||
elif sys.argv[2] == "set_network":
|
||||
if len(sys.argv) != 5:
|
||||
print("Wrong set network usage!")
|
||||
else:
|
||||
print(cp_set_dma_debug(sys.argv[1], sys.argv[3], sys.argv[4]))
|
||||
elif sys.argv[2] == "get_network":
|
||||
if len(sys.argv) != 4:
|
||||
print("Wrong get dma debug usage!")
|
||||
else:
|
||||
print(cp_get_dma_debug(sys.argv[1], sys.argv[3]))
|
||||
else:
|
||||
|
@@ -22,7 +22,8 @@
|
||||
"values": [{"label": "Нормальный", "value": "false"}, {"label": "Тест (CW)", "value": "true"}]
|
||||
},
|
||||
{"widget": "number-int", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 900000, "step": 0.01, "v_show": "paramRxtx.txModulatorIsTest"},
|
||||
{"widget": "number", "label": "Ослабление, дБ", "name": "txAttenuation", "max": 0, "min": -90, "step": 1}
|
||||
{"widget": "number", "label": "Ослабление, дБ", "name": "txAttenuation", "max": 0, "min": -90, "step": 1},
|
||||
{"widget": "number", "label": "Ограничение ослабления", "name": "txAttenuationLimit", "max": 0, "min": -40, "step": 0.25}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -42,7 +43,7 @@
|
||||
{"widget": "number-int", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 200000, "max": 54000000, "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"}]
|
||||
"values": [{"label": "0.02", "value": "20"}, {"label": "0.05", "value": "50"}, {"label": "0.10", "value": "100"}, {"label": "0.15", "value": "150"}, {"label": "0.20", "value": "200"}, {"label": "0.25", "value": "250"}]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -65,7 +66,8 @@
|
||||
{"label": "Выкл", "value": "0"},
|
||||
{"label": "24В", "value": "24"}
|
||||
]
|
||||
}
|
||||
},
|
||||
{"widget": "number-int", "label": "Частота LO, кГц", "name": "bucLoKhz", "min": 0, "max": 40000000, "step": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -81,7 +83,8 @@
|
||||
{"label": "18В", "value": "18"},
|
||||
{"label": "24В", "value": "24"}
|
||||
]
|
||||
}
|
||||
},
|
||||
{"widget": "number-int", "label": "Частота LO, кГц", "name": "lnbLoKhz", "min": 0, "max": 40000000, "step": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -101,17 +104,17 @@
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "select", "label": "Метод расчета задержки", "name": "dpdiIsPositional",
|
||||
"widget": "select", "label": "Метод расчета задержки", "name": "isPositional",
|
||||
"values": [
|
||||
{"label": "Позиционированием", "value": "true"},
|
||||
{"label": "Окном задержки", "value": "false"}
|
||||
]
|
||||
},
|
||||
{"widget": "h2", "label": "Настройки позиционирования", "v_show": "paramDpdi.dpdiIsPositional === true"},
|
||||
{"widget": "number", "label": "Широта станции", "name": "dpdiPositionStationLatitude", "v_show": "paramDpdi.dpdiIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Долгота станции", "name": "dpdiPositionStationLongitude", "v_show": "paramDpdi.dpdiIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Подспутниковая точка", "name": "dpdiPositionSatelliteLongitude", "v_show": "paramDpdi.dpdiIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Задержка до спутника, мс", "name": "dpdiDelay", "v_show": "paramDpdi.dpdiIsPositional === false", "min": 0, "step": 0.1, "max": 400}]
|
||||
{"widget": "h2", "label": "Настройки позиционирования", "v_show": "paramDpdi.isPositional === true"},
|
||||
{"widget": "number", "label": "Широта станции", "name": "positionStationLatitude", "v_show": "paramDpdi.isPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Долгота станции", "name": "positionStationLongitude", "v_show": "paramDpdi.isPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Подспутниковая точка", "name": "positionSatelliteLongitude", "v_show": "paramDpdi.isPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Задержка до спутника, мс", "name": "delay", "v_show": "paramDpdi.isPositional === false", "min": 0, "step": 0.1, "max": 400}]
|
||||
},
|
||||
{"widget": "submit"}
|
||||
],
|
||||
@@ -120,10 +123,9 @@
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "text", "label": "Пароль для входа в сеть ЦЗС", "name": "netCesPassword"},
|
||||
{"widget": "h3", "label": "Настройки интерфейса управления"},
|
||||
{"widget": "ip-address", "label": "IP Интерфейса управления (/24)", "name": "netManagementIp"},
|
||||
{"widget": "text", "label": "Имя веб-сервера", "name": "netServerName"}
|
||||
{"widget": "ip-address-mask", "label": "Интерфейс управления (a.d.d.r/mask)", "name": "managementIp"},
|
||||
{"widget": "text", "label": "Имя веб-сервера", "name": "serverName"}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -170,11 +172,11 @@
|
||||
"values": [{"label": "Ethernet", "value": "false"}, {"label": "Тест", "value": "true"}]
|
||||
},
|
||||
{"widget": "h3", "label": "Параметры передачи"},
|
||||
{"widget": "number-int", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 950000, "max": 6000000, "step": 0.01},
|
||||
{"widget": "number-int", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 100000, "max": 6000000, "step": 0.01},
|
||||
{"widget": "number-int", "label": "Символьная скорость, Бод", "name": "txBaudrate", "min": 200000, "max": 54000000},
|
||||
{
|
||||
"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"}]
|
||||
"values": [{"label": "0.02", "value": "20"}, {"label": "0.05", "value": "50"}, {"label": "0.10", "value": "100"}, {"label": "0.15", "value": "150"}, {"label": "0.20", "value": "200"}, {"label": "0.25", "value": "250"}]
|
||||
},
|
||||
{
|
||||
"widget": "select", "label": "Номер последовательности Голда", "name": "txGoldan",
|
||||
@@ -217,7 +219,7 @@
|
||||
{"widget": "checkbox", "label": "Авто-регулировка мощности", "name": "aupcEn"},
|
||||
{"widget": "number", "label": "Минимальное ослабление, дБ", "name": "aupcMinAttenuation", "min": 0, "step": 0.1, "max": 10},
|
||||
{"widget": "number", "label": "Максимальное ослабление, дБ", "name": "aupcMaxAttenuation", "min": 0, "step": 0.1, "max": 10},
|
||||
{"widget": "number", "label": "Требуемое ОСШ", "name": "aupcRequiredSnr", "min": 0, "step": 0.01, "max": 10}
|
||||
{"widget": "number", "label": "Требуемое ОСШ", "name": "aupcRequiredSnr", "min": 0, "step": 0.01, "max": 30}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -231,11 +233,11 @@
|
||||
{"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-int", "label": "Центральная частота, КГц", "name": "rxCentralFreq", "min": 950000, "max": 6000000, "step": 0.01},
|
||||
{"widget": "number-int", "label": "Центральная частота, КГц", "name": "rxCentralFreq", "min": 100000, "max": 6000000, "step": 0.01},
|
||||
{"widget": "number-int", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 200000, "max": 54000000},
|
||||
{
|
||||
"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"}]
|
||||
"values": [{"label": "0.02", "value": "20"}, {"label": "0.05", "value": "50"}, {"label": "0.10", "value": "100"}, {"label": "0.15", "value": "150"}, {"label": "0.20", "value": "200"}, {"label": "0.25", "value": "250"}]
|
||||
},
|
||||
{
|
||||
"widget": "select", "label": "Номер последовательности Голда", "name": "rxGoldan",
|
||||
@@ -252,20 +254,20 @@
|
||||
"widget": "settings-container", "v_show": "paramRxtx.isCinC",
|
||||
"childs": [
|
||||
{
|
||||
"widget": "select", "label": "Метод расчета задержки", "name": "dpdiIsPositional",
|
||||
"widget": "select", "label": "Метод расчета задержки", "name": "isPositional",
|
||||
"values": [
|
||||
{"label": "Позиционированием", "value": "true"},
|
||||
{"label": "Окном задержки", "value": "false"}
|
||||
]
|
||||
},
|
||||
{"widget": "number", "label": "Полоса поиска, КГц ±", "name": "dpdiSearchBandwidth", "min": 0, "step": 1, "max": 100},
|
||||
{"widget": "h2", "label": "Настройки позиционирования", "v_show": "paramDpdi.dpdiIsPositional === true"},
|
||||
{"widget": "number", "label": "Широта станции", "name": "dpdiPositionStationLatitude", "v_show": "paramDpdi.dpdiIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Долгота станции", "name": "dpdiPositionStationLongitude", "v_show": "paramDpdi.dpdiIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Подспутниковая точка", "name": "dpdiPositionSatelliteLongitude", "v_show": "paramDpdi.dpdiIsPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "h2", "label": "Задержка до спутника", "v_show": "paramDpdi.dpdiIsPositional === false"},
|
||||
{"widget": "number", "label": "от, мс", "name": "dpdiDelayMin", "v_show": "paramDpdi.dpdiIsPositional === false", "min": 0, "step": 0.1, "max": 400},
|
||||
{"widget": "number", "label": "до, мс", "name": "dpdiDelayMax", "v_show": "paramDpdi.dpdiIsPositional === false", "min": 0, "step": 0.1, "max": 400}]
|
||||
{"widget": "number", "label": "Полоса поиска, КГц ±", "name": "searchBandwidth", "min": 0, "step": 1, "max": 100},
|
||||
{"widget": "h2", "label": "Настройки позиционирования", "v_show": "paramDpdi.isPositional === true"},
|
||||
{"widget": "number", "label": "Широта станции", "name": "positionStationLatitude", "v_show": "paramDpdi.isPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Долгота станции", "name": "positionStationLongitude", "v_show": "paramDpdi.isPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "number", "label": "Подспутниковая точка", "name": "positionSatelliteLongitude", "v_show": "paramDpdi.isPositional === true", "min": -180, "step": 0.000001, "max": 180},
|
||||
{"widget": "h2", "label": "Задержка до спутника", "v_show": "paramDpdi.isPositional === false"},
|
||||
{"widget": "number", "label": "от, мс", "name": "delayMin", "v_show": "paramDpdi.isPositional === false", "min": 0, "step": 0.1, "max": 400},
|
||||
{"widget": "number", "label": "до, мс", "name": "delayMax", "v_show": "paramDpdi.isPositional === false", "min": 0, "step": 0.1, "max": 400}]
|
||||
},
|
||||
{"widget": "submit", "v_show": "paramRxtx.isCinC"}
|
||||
],
|
||||
@@ -316,30 +318,20 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"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": "ip-address-mask", "label": "Интерфейс управления (a.d.d.r/mask)", "name": "managementIp"},
|
||||
{
|
||||
"widget": "select", "label": "Режим сети", "name": "netIsL2",
|
||||
"widget": "select", "label": "Режим сети", "name": "isL2",
|
||||
"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},
|
||||
{"widget": "text", "label": "Имя веб-сервера", "name": "netServerName"}
|
||||
{"widget": "ip-address", "label": "Интерфейс данных (/24)", "name": "dataIp", "v_show": "paramNetwork.isL2 === false"},
|
||||
{"widget": "number", "label": "MTU интерфейса данных", "name": "dataMtu", "min": 1500, "step": 1, "max": 2000},
|
||||
{"widget": "text", "label": "Имя веб-сервера", "name": "serverName"}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -373,23 +365,30 @@
|
||||
"widget": "select", "label": "Режим работы модулятора", "name": "txModulatorIsTest",
|
||||
"values": [{"label": "Нормальный", "value": "false"}, {"label": "Тест (CW)", "value": "true"}]
|
||||
},
|
||||
{"widget": "number", "label": "Ослабление, дБ", "name": "txAttenuation", "max": 0, "min": -40, "step": 0.25},
|
||||
{
|
||||
"widget": "select", "label": "Входные данные", "name": "txIsTestInput",
|
||||
"values": [{"label": "Ethernet", "value": "false"}, {"label": "Тест", "value": "true"}]
|
||||
},
|
||||
{"widget": "h3", "label": "Параметры передачи"},
|
||||
{"widget": "number", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 950000, "max": 6000000, "step": 0.01},
|
||||
{"widget": "number", "label": "Символьная скорость, Бод", "name": "txBaudrate", "min": 200000, "max": 54000000},
|
||||
{"widget": "number-int", "label": "Центральная частота, КГц", "name": "txCentralFreq", "min": 70000, "max": 6000000, "step": 100},
|
||||
{"widget": "number-int", "label": "Символьная скорость, Бод", "name": "txBaudrate", "min": 128000, "max": 30000000},
|
||||
{
|
||||
"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"}]
|
||||
"values": [{"label": "0.02", "value": "20"}, {"label": "0.05", "value": "50"}, {"label": "0.10", "value": "100"}, {"label": "0.15", "value": "150"}, {"label": "0.20", "value": "200"}, {"label": "0.25", "value": "250"}, {"label": "0.30", "value": "300"}, {"label": "0.35", "value": "350"}]
|
||||
},
|
||||
{"widget": "number", "label": "Коэф. расширения", "name": "txSpreadCoef", "max": 1024, "min": 8, "step": 2},
|
||||
{"widget": "number", "label": "Кол-во пакетов на преамбулу", "name": "txFieldsDataPreamble", "max": 255, "min": 1, "step": 1}
|
||||
]
|
||||
},
|
||||
{"widget": "number", "label": "Коэф. расширения", "name": "txSpreadCoef", "max": 1000, "min": -1000, "step": 0.01},
|
||||
{
|
||||
"widget": "select", "label": "Номер последовательности Голда", "name": "txGoldan",
|
||||
"values": [{"label": "0", "value": "0"}, {"label": "1", "value": "1"}]
|
||||
},
|
||||
{"widget": "number", "label": "Ослабление, дБ", "name": "txAttenuation", "max": 0, "min": -40, "step": 0.25}
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Авто-регулировка мощности"},
|
||||
{"widget": "checkbox", "label": "Авто-регулировка мощности", "name": "aupcEn"},
|
||||
{"widget": "number", "label": "Минимальное ослабление, дБ", "name": "aupcMinAttenuation", "min": 0, "step": 0.1, "max": 10},
|
||||
{"widget": "number", "label": "Максимальное ослабление, дБ", "name": "aupcMaxAttenuation", "min": 0, "step": 0.1, "max": 10},
|
||||
{"widget": "number", "label": "Требуемое ОСШ", "name": "aupcRequiredSnr", "min": 0, "step": 0.01, "max": 30}
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -403,17 +402,15 @@
|
||||
{"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": 950000, "max": 6000000, "step": 0.01},
|
||||
{"widget": "number", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 200000, "max": 54000000},
|
||||
{"widget": "number-int", "label": "Центральная частота, КГц", "name": "rxCentralFreq", "min": 70000, "max": 6000000, "step": 100},
|
||||
{"widget": "number-int", "label": "Символьная скорость, Бод", "name": "rxBaudrate", "min": 128000, "max": 30000000},
|
||||
{
|
||||
"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"}]
|
||||
"values": [{"label": "0.02", "value": "20"}, {"label": "0.05", "value": "50"}, {"label": "0.10", "value": "100"}, {"label": "0.15", "value": "150"}, {"label": "0.20", "value": "200"}, {"label": "0.25", "value": "250"}, {"label": "0.30", "value": "300"}, {"label": "0.35", "value": "350"}]
|
||||
},
|
||||
{"widget": "number", "label": "Коэф. расширения", "name": "rxSpreadCoef", "max": 1000, "min": -1000, "step": 0.01},
|
||||
{
|
||||
"widget": "select", "label": "Номер последовательности Голда", "name": "rxGoldan",
|
||||
"values": [{"label": "0", "value": "0"}, {"label": "1", "value": "1"}]
|
||||
}
|
||||
{"widget": "number", "label": "Коэф. расширения", "name": "rxSpreadCoef", "max": 1024, "min": 8, "step": 2},
|
||||
{"widget": "number", "label": "Порог коррелятора", "name": "rxFftShift", "max": 10, "min": 1, "step": 0.125},
|
||||
{"widget": "number", "label": "Кол-во пакетов на преамбулу", "name": "rxFieldsDataPreamble", "max": 255, "min": 1, "step": 1}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -465,6 +462,23 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"network": [
|
||||
{"widget": "h2", "label": "Настройки сети"},
|
||||
{
|
||||
"widget": "settings-container",
|
||||
"childs": [
|
||||
{"widget": "h3", "label": "Настройки интерфейса управления"},
|
||||
{"widget": "ip-address-mask", "label": "Интерфейс управления (a.d.d.r/mask)", "name": "managementIp"},
|
||||
{
|
||||
"widget": "select", "label": "Режим сети", "name": "isL2",
|
||||
"values": [{"label": "Маршрутизатор", "value": "false"}, {"label": "Коммутатор", "value": "true"}]
|
||||
},
|
||||
{"widget": "ip-address", "label": "Интерфейс данных (/24)", "name": "dataIp", "v_show": "paramNetwork.isL2 === false"},
|
||||
{"widget": "number", "label": "MTU интерфейса данных", "name": "dataMtu", "min": 1500, "step": 1, "max": 2000},
|
||||
{"widget": "text", "label": "Имя веб-сервера", "name": "serverName"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"tabs": [
|
||||
|
@@ -63,6 +63,22 @@
|
||||
}
|
||||
this.submitStatus.firmwareUpgradeOta = false
|
||||
},
|
||||
async settingsPerformSetCesPassword() {
|
||||
if (this.submitStatus.cesPassword) { return }
|
||||
this.submitStatus.cesPassword = true
|
||||
try {
|
||||
await fetch('/api/set/cesPassword', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({'password': this.cesPasswordValue})
|
||||
})
|
||||
} catch (e) {
|
||||
console.log("failed to perform set CES password: ", e)
|
||||
}
|
||||
this.submitStatus.cesPassword = false
|
||||
},
|
||||
{% endif %}
|
||||
|
||||
doModemReboot() {
|
||||
@@ -72,3 +88,130 @@
|
||||
this.submitStatus.modemReboot = 30
|
||||
fetch('/api/reboot', { method: 'POST' }).then((r) => {})
|
||||
},
|
||||
async restoreAllSettings() {
|
||||
// Порядок применения настроек
|
||||
const settingsApplyOrder = ['qos', 'tcpaccel', 'dpdi', 'rxtx', 'buclnb', 'network'];
|
||||
|
||||
// 1. Чтение JSON-файла, выбранного пользователем
|
||||
const fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = '.json';
|
||||
|
||||
const filePromise = new Promise((resolve, reject) => {
|
||||
fileInput.onchange = e => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) {
|
||||
reject(new Error('Файл не выбран'));
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = event => {
|
||||
try {
|
||||
const jsonData = JSON.parse(event.target.result);
|
||||
resolve(jsonData);
|
||||
} catch (error) {
|
||||
reject(new Error('Ошибка парсинга JSON'));
|
||||
}
|
||||
};
|
||||
reader.onerror = () => reject(new Error('Ошибка чтения файла'));
|
||||
reader.readAsText(file);
|
||||
};
|
||||
fileInput.click();
|
||||
});
|
||||
|
||||
try {
|
||||
const settingsToApply = await filePromise;
|
||||
const errors = [];
|
||||
|
||||
// 2. Перебор групп параметров в заданном порядке
|
||||
for (const groupName of settingsApplyOrder) {
|
||||
if (!settingsToApply.hasOwnProperty(groupName)) {
|
||||
continue; // Пропускаем группы, которых нет в файле
|
||||
}
|
||||
|
||||
const groupSettings = settingsToApply[groupName];
|
||||
if (typeof groupSettings !== 'object' || groupSettings === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2.1. POST-запрос для применения группы параметров
|
||||
const postResponse = await fetch(`/api/set/${groupName}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(groupSettings)
|
||||
});
|
||||
|
||||
if (!postResponse.ok) {
|
||||
throw new Error(`HTTP error ${postResponse.status}`);
|
||||
}
|
||||
|
||||
const postResult = await postResponse.json();
|
||||
if (postResult.status !== 'ok') {
|
||||
throw new Error(`API error: ${postResult.message || 'unknown error'}`);
|
||||
}
|
||||
|
||||
// 2.2. Проверка примененных параметров
|
||||
const getResponse = await fetch('/api/get/settings', { method: 'GET' });
|
||||
if (!getResponse.ok) {
|
||||
throw new Error(`HTTP error ${getResponse.status}`);
|
||||
}
|
||||
|
||||
const fetchSettingsResult = await getResponse.json();
|
||||
if (fetchSettingsResult.status !== 'ok') {
|
||||
throw new Error('Не удалось получить текущие настройки');
|
||||
}
|
||||
|
||||
// Проверка соответствия параметров
|
||||
const appliedGroup = fetchSettingsResult.settings[groupName] || {};
|
||||
const failedSettings = [];
|
||||
|
||||
for (const [key, value] of Object.entries(groupSettings)) {
|
||||
if (appliedGroup[key] !== value) {
|
||||
failedSettings.push(`${key} (ожидалось: ${value}, получено: ${appliedGroup[key]})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (failedSettings.length > 0) {
|
||||
throw new Error(`Не совпадают параметры: ${failedSettings.join(', ')}`);
|
||||
}
|
||||
|
||||
} catch (groupError) {
|
||||
errors.push(`Группа ${groupName}: ${groupError.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Показ ошибок, если они есть
|
||||
if (errors.length > 0) {
|
||||
const errorMessage = errors.join('\n\n') +
|
||||
'\n\nНекоторые настройки могли примениться некорректно.\nСтраница будет перезагружена.';
|
||||
alert(errorMessage);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
alert(`Ошибка при восстановлении настроек: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Перезагрузка страницы
|
||||
location.reload();
|
||||
},
|
||||
async dumpAllSettings() {
|
||||
function downloadAsFile(data, filename) {
|
||||
let a = document.createElement("a");
|
||||
let file = new Blob([data], {type: 'application/json'});
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = filename;
|
||||
a.click();
|
||||
}
|
||||
const response = await fetch('/api/get/settings', { method: 'GET' })
|
||||
if (response.ok) {
|
||||
const jres = await response.json()
|
||||
if (jres["status"] === "ok") {
|
||||
downloadAsFile(JSON.stringify(jres["settings"], null, 4), "backup-" + this.about.firmwareVersion + "-" + this.about.modemSn + ".json")
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -21,7 +21,18 @@
|
||||
<div>
|
||||
<button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="action-button" @click="dumpAllSettings()">Сохранить бекап конфигурации</button>
|
||||
<button class="dangerous-button" @click="restoreAllSettings()">Восстановить бекап конфигурации</button>
|
||||
</div>{% endraw %}{% if modem == 'tdma' %}
|
||||
|
||||
<h2>Вход в сеть ЦЗС</h2>
|
||||
<div class="settings-set-container statistics-container">
|
||||
<label>
|
||||
<span>Хеш-строка пароля (выдается оператором NMS)</span>
|
||||
<input v-model="cesPasswordValue" type="text">
|
||||
</label>
|
||||
<button class="action-button" @click="settingsPerformSetCesPassword()">Установить пароль<span class="submit-spinner" v-show="submitStatus.cesPassword"></span></button>
|
||||
</div>{% endif %}{% raw %}
|
||||
|
||||
<h2>Обновление ПО</h2>
|
||||
<div class="settings-set-container statistics-container">
|
||||
|
@@ -24,7 +24,7 @@
|
||||
update{{ g['group'] | title }}Settings(vals) {
|
||||
this.submitStatus.{{ g['group'] }} = false
|
||||
{% for p in g['params'] %}
|
||||
{{ build_setter_js(g['group'], p, "vals[\"settings\"][\"" ~ p['name'] ~ "\"]") }}
|
||||
{{ build_setter_js(g['group'], p, "vals[\"settings\"][\"" ~ g['group'] ~ "\"][\"" ~ p['name'] ~ "\"]") }}
|
||||
{% endfor %}
|
||||
},
|
||||
{% endfor %}
|
@@ -18,69 +18,68 @@
|
||||
}
|
||||
|
||||
this.lastUpdateTime = new Date();
|
||||
this.initState = vals["mainState"]["initState"]
|
||||
this.initState = vals["state"]["initState"]
|
||||
this.testState = vals["state"]["testState"]
|
||||
{% if modem == 'scpc' %}
|
||||
this.isCinC = vals["mainState"]["isCinC"]
|
||||
this.isCinC = vals["state"]["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"]
|
||||
this.statRx.state = vals["state"]["rx"]["state"]
|
||||
this.statRx.sym_sync_lock = vals["state"]["rx"]["sym_sync_lock"]
|
||||
this.statRx.freq_search_lock = vals["state"]["rx"]["freq_search_lock"]
|
||||
this.statRx.afc_lock = vals["state"]["rx"]["afc_lock"]
|
||||
this.statRx.pkt_sync = vals["state"]["rx"]["pkt_sync"]
|
||||
this.statRx.snr = Math.round(vals["state"]["rx"]["snr"] * 10) / 10
|
||||
this.statRx.rssi = Math.round(vals["state"]["rx"]["rssi"] * 10) / 10
|
||||
this.statRx.modcod = modcodToStr(vals["state"]["rx"]["modcod"])
|
||||
this.statRx.frameSizeNormal = vals["state"]["rx"]["frameSizeNormal"]
|
||||
this.statRx.isPilots = vals["state"]["rx"]["isPilots"]
|
||||
this.statRx.symError = vals["state"]["rx"]["symError"]
|
||||
this.statRx.freqErr = Math.round(vals["state"]["rx"]["freqErr"] * 100) / 100
|
||||
this.statRx.freqErrAcc = Math.round(vals["state"]["rx"]["freqErrAcc"] * 100) / 100
|
||||
this.statRx.inputSignalLevel = vals["state"]["rx"]["inputSignalLevel"]
|
||||
this.statRx.pllError = Math.round(vals["state"]["rx"]["pllError"] * 100) / 100
|
||||
this.statRx.speedOnRxKbit = Math.round(vals["state"]["rx"]["speedOnRxKbit"] * 100) / 100
|
||||
this.statRx.speedOnIifKbit = Math.round(vals["state"]["rx"]["speedOnIifKbit"] * 100) / 100
|
||||
this.statRx.packetsOk = vals["state"]["rx"]["packetsOk"]
|
||||
this.statRx.packetsBad = vals["state"]["rx"]["packetsBad"]
|
||||
this.statRx.packetsDummy = vals["state"]["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.statTx.state = vals["state"]["tx"]["state"]
|
||||
this.statTx.snr = Math.round(vals["state"]["tx"]["snr"] * 100) / 100
|
||||
this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
|
||||
this.statTx.frameSizeNormal = vals["state"]["tx"]["frameSizeNormal"]
|
||||
this.statTx.isPilots = vals["state"]["tx"]["isPilots"]
|
||||
this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
|
||||
this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
|
||||
|
||||
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"]
|
||||
this.statCinc.occ = vals["state"]["cinc"]["occ"]
|
||||
this.statCinc.correlator = vals["state"]["cinc"]["correlator"]
|
||||
this.statCinc.correlatorFails = vals["state"]["cinc"]["correlatorFails"]
|
||||
this.statCinc.freqErr = Math.round(vals["state"]["cinc"]["freqErr"] * 100) / 100
|
||||
this.statCinc.freqErrAcc = Math.round(vals["state"]["cinc"]["freqErrAcc"] * 100) / 100
|
||||
this.statCinc.channelDelay = vals["state"]["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"]
|
||||
this.statTx.state = vals["state"]["tx"]["state"]
|
||||
this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
|
||||
this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
|
||||
this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
|
||||
this.statTx.centerFreq = vals["state"]["tx"]["centerFreq"]
|
||||
this.statTx.symSpeed = vals["state"]["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.statDevice.adrv = vals["state"]["device"]["adrv"]
|
||||
this.statDevice.zynq = vals["state"]["device"]["zynq"]
|
||||
this.statDevice.fpga = vals["state"]["device"]["fpga"]
|
||||
{% if modem == 'tdma' %}
|
||||
this.statDevice.upgradeStatus = vals["mainState"]["device.upgradeStatus"]
|
||||
this.statDevice.upgradePercent = vals["mainState"]["device.upgradePercent"]
|
||||
this.statDevice.upgradeImage = vals["mainState"]["device.upgradeImage"]
|
||||
this.statDevice.upgradeStatus = vals["state"]["device"]["upgradeStatus"]
|
||||
this.statDevice.upgradePercent = vals["state"]["device"]["upgradePercent"]
|
||||
this.statDevice.upgradeImage = vals["state"]["device"]["upgradeImage"]
|
||||
{% endif %}
|
||||
|
||||
this.testState = vals["mainState"]["testState"]
|
||||
|
||||
// аптайм приходит в секундах, надо преобразовать его в человеко-читаемый вид
|
||||
let uptime = vals["sysinfo"]["uptime"]
|
||||
let uptime = vals["state"]["device"]["uptime"]
|
||||
if (uptime) {
|
||||
let secs = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
let mins = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
@@ -92,11 +91,11 @@
|
||||
} 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"]
|
||||
this.statOs.load1 = Math.round(vals["state"]["device"]["load1min"] * 100) / 100
|
||||
this.statOs.load5 = Math.round(vals["state"]["device"]["load5min"] * 100) / 100
|
||||
this.statOs.load15 = Math.round(vals["state"]["device"]["load15min"] * 100) / 100
|
||||
this.statOs.totalram = vals["state"]["device"]["totalram"]
|
||||
this.statOs.freeram = vals["state"]["device"]["freeram"]
|
||||
},
|
||||
|
||||
resetPacketsStatistics() {
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<div class="settings-set-container statistics-container">
|
||||
<h2>Статистика приема</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
<tbody>{% endraw %}{% if modem != 'shps' %}{% raw %}
|
||||
<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>
|
||||
@@ -22,7 +22,17 @@
|
||||
<tr><td colspan="2" style="padding-top: 1em; text-align: center">Статистика пакетов</td></tr>
|
||||
<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>
|
||||
<tr><th>DUMMY</th><td>{{ statRx.packetsDummy }}</td></tr>{% endraw %}{% else %}{% raw %}
|
||||
<tr><th>Прием</th><td><span :class="{ indicator_bad: statRx.state === false, indicator_good: statRx.state === true, indicator: true }"></span></td></tr>
|
||||
<tr><th>ОСШ/RSSI</th><td>{{ statRx.snr }} / {{ statRx.rssi }}</td></tr>
|
||||
<tr><th>Частотная ошибка, Гц</th><td>{{ 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 }} кбит/с</td></tr>
|
||||
<tr><th>Инф. скорость на интерфейсе</th><td>{{ statRx.speedOnIifKbit }} кбит/с</td></tr>
|
||||
<tr><td colspan="2" style="padding-top: 1em; text-align: center">Статистика пакетов</td></tr>
|
||||
<tr><th>Качественных пакетов</th><td>{{ statRx.packetsOk }}</td></tr>
|
||||
<tr><th>Поврежденных пакетов</th><td>{{ statRx.packetsBad }}</td></tr>{% endraw %}{% endif %}{% raw %}
|
||||
</tbody>
|
||||
</table>
|
||||
<button class="action-button" @click="resetPacketsStatistics()"> Сброс статистики </button>
|
||||
@@ -39,7 +49,7 @@
|
||||
<tr><th>Инф. скорость на передаче</th><td>{{ statTx.speedOnTxKbit }} кбит/с</td></tr>
|
||||
<tr><th>Инф. скорость на интерфейсе</th><td>{{ statTx.speedOnIifKbit }} кбит/с</td></tr>
|
||||
</tbody>
|
||||
</table>{% endraw %}{% else %}{% raw %}
|
||||
</table>{% endraw %}{% elif modem == 'tdma' %}{% raw %}
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th>Передача</th><td><span :class="{ indicator_bad: statTx.state === false, indicator_good: statTx.state === true, indicator: true }"></span></td></tr>
|
||||
@@ -49,6 +59,15 @@
|
||||
<tr><th>Центральная частота</th><td>{{ statTx.centerFreq }} кГц</td></tr>
|
||||
<tr><th>Символьная скорость</th><td>{{ statTx.symSpeed }} ksymb</td></tr>
|
||||
</tbody>
|
||||
</table>{% endraw %}{% elif modem == 'shps' %}{% 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.speedOnTxKbit }} кбит/с</td></tr>
|
||||
<tr><th>Инф. скорость на интерфейсе</th><td>{{ statTx.speedOnIifKbit }} кбит/с</td></tr>
|
||||
<tr><th>Центральная частота</th><td>{{ statTx.centerFreq }} кГц</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 statistics-container" v-if="paramRxtx.isCinC === true">
|
||||
|
@@ -44,15 +44,17 @@
|
||||
}
|
||||
let query = {
|
||||
"en": this.paramQos.en,
|
||||
"profile": {
|
||||
"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])) }
|
||||
}
|
||||
for (let i = 0; i < this.paramQos.rt1.length; i++) { query.profile.rt1.push(_translateQosClass('rt', this.paramQos.rt1[i])) }
|
||||
for (let i = 0; i < this.paramQos.rt2.length; i++) { query.profile.rt2.push(_translateQosClass('rt', this.paramQos.rt2[i])) }
|
||||
for (let i = 0; i < this.paramQos.rt3.length; i++) { query.profile.rt3.push(_translateQosClass('rt', this.paramQos.rt3[i])) }
|
||||
for (let i = 0; i < this.paramQos.cd.length; i++) { query.profile.cd.push(_translateQosClass('rt', this.paramQos.cd[i])) }
|
||||
|
||||
//console.log(query)
|
||||
fetch('/api/set/qos', {
|
||||
@@ -73,9 +75,9 @@
|
||||
|
||||
updateQosSettings(vals) {
|
||||
this.submitStatusQos = false
|
||||
this.paramQos.en = vals["settings"]["qosEnabled"]
|
||||
this.paramQos.en = vals["settings"]["qos"]["en"]
|
||||
|
||||
const qosProfile = vals["settings"]["qosProfile"]
|
||||
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)
|
||||
|
@@ -58,6 +58,10 @@
|
||||
<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_ip_address_mask(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]?)\/([0-9]|[1-2][0-9]|3[0-2])$">
|
||||
</label>{% endmacro %}
|
||||
|
||||
{% macro build_widget_text(param_group, widget) %}<label{% if widget.v_show %} v-show="{{ widget.v_show }}"{% endif %}>
|
||||
<span>{{ widget.label }}</span>
|
||||
@@ -78,22 +82,23 @@
|
||||
{% 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) }}
|
||||
{% elif widget.widget == 'ip-address-mask' %}{{ build_widget_ip_address_mask(param_group, widget) }}
|
||||
{% elif widget.widget == 'text' %}{{ build_widget_text(param_group, widget) }}
|
||||
{% else %}<p>Widget '{{ widget.widget }}' not defined!</p><p>{{ widget }}</p>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro build_getter_js(param_group, widget) %}{% if widget.widget in ['flex-container', 'settings-container', 'h2', 'h3', 'submit', 'watch', 'watch-expr'] %}null{%
|
||||
elif widget.widget in ['checkbox', 'number', 'select', 'ip-address', 'modulation-modcod', 'modulation-speed', 'text'] %}this.param{{ param_group | title }}.{{ widget.name }}{%
|
||||
elif widget.widget in ['checkbox', 'number', 'select', 'ip-address', 'ip-address-mask', 'modulation-modcod', 'modulation-speed', 'text'] %}this.param{{ param_group | title }}.{{ widget.name }}{%
|
||||
elif widget.widget == 'number-int' %}parseFloat(this.param{{ param_group | title }}.{{ widget.name }}.replace(/[^0-9,.]/g, '').replace(',', '.')){%
|
||||
else %}<p>Widget '{{ widget.widget }}' not defined!</p><p>{{ widget }}</p>{% endif %}{% endmacro %}
|
||||
|
||||
{% macro build_setter_js(param_group, widget, expr) %}{% if widget.widget in ['flex-container', 'settings-container', 'h2', 'h3', 'submit', 'watch', 'watch-expr'] %}null{%
|
||||
elif widget.widget in ['checkbox', 'number', 'select', 'ip-address', 'modulation-modcod', 'modulation-speed', 'text'] %}this.param{{ param_group | title }}.{{ widget.name }} = {{ expr }}{%
|
||||
elif widget.widget in ['checkbox', 'number', 'select', 'ip-address', 'ip-address-mask', 'modulation-modcod', 'modulation-speed', 'text'] %}this.param{{ param_group | title }}.{{ widget.name }} = {{ expr }}{%
|
||||
elif widget.widget == 'number-int' %}this.param{{ param_group | title }}.{{ widget.name }} = this.inputFormatNumber({{ expr }}, {{ js_build_number_number_validator(widget) }}){%
|
||||
else %}<p>Widget '{{ widget.widget }}' not defined!</p><p>{{ widget }}</p>{% endif %}{% endmacro %}
|
||||
|
||||
{% macro build_setter(param_group, widget, expr) %}{% if widget.widget in ['flex-container', 'settings-container', 'h2', 'h3', 'submit', 'watch', 'watch-expr'] %}null{%
|
||||
elif widget.widget in ['checkbox', 'number', 'select', 'ip-address', 'modulation-modcod', 'modulation-speed', 'text'] %}param{{ param_group | title }}.{{ widget.name }} = {{ expr }}{%
|
||||
elif widget.widget in ['checkbox', 'number', 'select', 'ip-address', 'ip-address-mask', 'modulation-modcod', 'modulation-speed', 'text'] %}param{{ param_group | title }}.{{ widget.name }} = {{ expr }}{%
|
||||
elif widget.widget == 'number-int' %}param{{ param_group | title }}.{{ widget.name }} = inputFormatNumber({{ expr }}, {{ js_build_number_number_validator(widget) }}){%
|
||||
else %}<p>Widget '{{ widget.widget }}' not defined!</p><p>{{ widget }}</p>{% endif %}{% endmacro %}
|
||||
|
@@ -99,10 +99,14 @@
|
||||
firmwareUpgrade: false,
|
||||
{% if modem == 'tdma' %}
|
||||
firmwareUpgradeOta: false,
|
||||
cesPassword: false,
|
||||
{% endif %}
|
||||
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
|
||||
modemReboot: null
|
||||
},
|
||||
{% if modem == 'tdma' %}
|
||||
cesPasswordValue: '',
|
||||
{% endif %}
|
||||
|
||||
// ========== include from 'common/all-params-data.js.j2'
|
||||
{% include 'common/all-params-data.js.j2' %}
|
||||
@@ -235,11 +239,11 @@
|
||||
try {
|
||||
const fr = await fetch("/api/get/aboutFirmware")
|
||||
const d = await fr.json()
|
||||
this.about.firmwareVersion = d["fw.version"]
|
||||
this.about.modemUid = d["fw.modemId"]
|
||||
this.about.modemSn = d["fw.modemSn"]
|
||||
this.about.macManagement = d["fw.macMang"]
|
||||
this.about.macData = d["fw.macData"]
|
||||
this.about.firmwareVersion = d["firmware"]["version"]
|
||||
this.about.modemUid = d["firmware"]["modemId"]
|
||||
this.about.modemSn = d["firmware"]["modemSn"]
|
||||
this.about.macManagement = d["firmware"]["macMang"]
|
||||
this.about.macData = d["firmware"]["macData"]
|
||||
} catch (e) {
|
||||
console.log('Ошибка загрузки версии ПО', e)
|
||||
}
|
||||
|
@@ -1,10 +1,50 @@
|
||||
//
|
||||
// Created by vlad on 03.04.2025.
|
||||
//
|
||||
|
||||
#include "daemon.h"
|
||||
#include <utility>
|
||||
|
||||
#include <boost/thread/pthread/thread_data.hpp>
|
||||
#include "terminal_api_driver.h"
|
||||
|
||||
// минимальный порог для сна в цикле событий демона
|
||||
static constexpr int64_t SLEEP_THRESHOLD = 10;
|
||||
|
||||
int64_t api_driver::TimeNow() {
|
||||
return std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
|
||||
|
||||
namespace api_driver {
|
||||
/**
|
||||
* Обертка для объектов, доступных для обновления
|
||||
* NOTE: перед вызовом функций, требующих `TSID`, необходимо захватить мютекс API.
|
||||
*/
|
||||
class CpUpdatebleObject {
|
||||
public:
|
||||
int64_t lastUpdate = 0;
|
||||
int64_t updatePeriodMs = -1;
|
||||
|
||||
/**
|
||||
* Функция для обновления (загрузки) объекта из CP API.
|
||||
*/
|
||||
std::function<void ()> updateCallback;
|
||||
|
||||
explicit CpUpdatebleObject(std::function<void ()> callback, int64_t period = -1): updatePeriodMs(period), updateCallback(std::move(callback)) {}
|
||||
|
||||
bool checkNeedUpdate(int64_t now) const {
|
||||
if (updatePeriodMs < 0) return false;
|
||||
// тут нет смысла спать меньше чем на 20мс, поэтому можно разрешить чтение на некоторое время раньше
|
||||
return now - lastUpdate >= (updatePeriodMs - 20);
|
||||
}
|
||||
|
||||
int64_t getNextUpdate(int64_t now) const {
|
||||
if (checkNeedUpdate(now)) {
|
||||
return 0;
|
||||
}
|
||||
auto next = now - lastUpdate;
|
||||
return next < 0 ? 0 : next;
|
||||
}
|
||||
|
||||
~CpUpdatebleObject() = default;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void api_driver::TerminalApiDaemon::connectToApi() {
|
||||
@@ -12,7 +52,7 @@ void api_driver::TerminalApiDaemon::connectToApi() {
|
||||
std::lock_guard _lock(this->stateMutex);
|
||||
this->state.fInitState = "Not connected to API";
|
||||
}
|
||||
#if defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA)
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
{
|
||||
std::lock_guard _lock(this->settingsMutex);
|
||||
this->settingsNetwork.loadDefaults();
|
||||
@@ -54,89 +94,97 @@ void api_driver::TerminalApiDaemon::run() {
|
||||
this->connectToApi();
|
||||
|
||||
struct {
|
||||
obj::CpUpdatebleObject* u;
|
||||
std::function<void ()> c;
|
||||
CpUpdatebleObject uo;
|
||||
std::string updaterName;
|
||||
} updaters[] = {
|
||||
#if API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
// обновление логов
|
||||
{.u = &statsLogs, .c = [this]() {
|
||||
try {
|
||||
{
|
||||
std::lock_guard _alock(this->cpApiMutex);
|
||||
{.uo = CpUpdatebleObject([this]() {
|
||||
this->statsLogs.updateCallback(cp);
|
||||
}
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon->statsLogs.putItem(): success write statistics state to log!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon->statsLogs.putItem() failed to log: " << e.what();
|
||||
}
|
||||
}},
|
||||
}), .updaterName = "updateDebugMetrics"},
|
||||
#endif
|
||||
// обновление статистики
|
||||
{.u = state, .c = [this]() {
|
||||
try {
|
||||
std::lock_guard _alock(this->cpApiMutex);
|
||||
std::lock_guard _slock(this->stateMutex);
|
||||
state.updateCallback(cp);
|
||||
stateDev.updateCallback(cp);
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateState(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateState(): " << e.what();
|
||||
{.uo = CpUpdatebleObject([this]() {
|
||||
|
||||
obj::TerminalState tmp;
|
||||
{
|
||||
std::shared_lock _slock1(this->settingsMutex);
|
||||
tmp = state;
|
||||
}
|
||||
}},
|
||||
|
||||
tmp.updateCallback(cp);
|
||||
std::lock_guard _slock2(this->settingsMutex);
|
||||
state = tmp;
|
||||
}, CACHE_STATISTICS_UPDATE_MS), .updaterName = "updateStatistics"},
|
||||
{.uo = CpUpdatebleObject([this]() {
|
||||
obj::TerminalDeviceState tmp(stateDev);
|
||||
tmp.updateCallback(cp);
|
||||
std::lock_guard _slock2(this->settingsMutex);
|
||||
stateDev = tmp;
|
||||
}, CACHE_STATISTICS_UPDATE_MS), .updaterName = "updateDeviceState"},
|
||||
// обновление кеша настроек
|
||||
{.lastUpdate = 0, .periodMs = CACHE_SETTINGS_UPDATE_MS, .c = [this]() {
|
||||
try {
|
||||
this->updateSettings();
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateSettings(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateSettings(): " << e.what();
|
||||
{.uo = CpUpdatebleObject([this]() {
|
||||
obj::TerminalRxTxSettings rxtx;
|
||||
rxtx.updateCallback(cp);
|
||||
std::lock_guard _slock2(this->settingsMutex);
|
||||
settingsRxTx = rxtx;
|
||||
}, CACHE_SETTINGS_UPDATE_MS), .updaterName = "updateRxTxSettings"},
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
{.uo = CpUpdatebleObject([this]() {
|
||||
obj::TerminalNetworkSettings net;
|
||||
{
|
||||
std::shared_lock _slock1(this->settingsMutex);
|
||||
net = settingsNetwork;
|
||||
}
|
||||
}},
|
||||
// обновление кеша настроек сети (делается отдельно)
|
||||
{.lastUpdate = 0, .periodMs = CACHE_SETTINGS_UPDATE_MS, .c = [this]() {
|
||||
try {
|
||||
this->updateNetworkSettings();
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateNetworkSettings(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateNetworkSettings(): " << e.what();
|
||||
}
|
||||
}},
|
||||
|
||||
net.updateCallback(cp);
|
||||
std::lock_guard _slock2(this->settingsMutex);
|
||||
settingsNetwork = net;
|
||||
}, CACHE_SETTINGS_UPDATE_MS), .updaterName = "updateNetworkSettings"},
|
||||
#endif
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
// обновление кеша QoS
|
||||
{.lastUpdate = 0, .periodMs = CACHE_QOS_UPDATE_MS, .c = [this]() {
|
||||
try {
|
||||
this->updateQos();
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateQos(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateQos(): " << e.what();
|
||||
}
|
||||
}}
|
||||
{.uo = CpUpdatebleObject([this]() {
|
||||
obj::TerminalQosSettings qos;
|
||||
qos.updateCallback(cp);
|
||||
std::lock_guard _slock(this->settingsMutex);
|
||||
settingsQos = qos;
|
||||
}, CACHE_SETTINGS_UPDATE_MS), .updaterName = "updateQosSettings"},
|
||||
#endif
|
||||
};
|
||||
|
||||
while (true) {
|
||||
if (this->lastCpError == ERROR || this->lastCpError == TIMEOUT) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::run(): close current daemon session caused error " << this->lastCpError;
|
||||
CP_Logout(this->sid);
|
||||
if (this->cp.lastCpError == ERROR || this->cp.lastCpError == TIMEOUT) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::run(): close current daemon session caused error " << this->cp.lastCpError;
|
||||
cp.disconnect();
|
||||
this->connectToApi();
|
||||
}
|
||||
#ifdef MODEM_IS_SCPC
|
||||
updaters[0].periodMs = this->statsLogs.logEn ? this->statsLogs.logPeriodMs.load() : -1;
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
updaters[0].uo.updatePeriodMs = this->statsLogs.logEn ? this->statsLogs.logPeriodMs.load() : -1;
|
||||
#endif
|
||||
int64_t sleepTime = 60000; // минута по-умолчанию
|
||||
auto now = TIME_NOW();
|
||||
auto now = TimeNow();
|
||||
for (auto& u: updaters) {
|
||||
if (u.checkNeedUpdate(now)) {
|
||||
auto targetTime = u.lastUpdate + u.periodMs;
|
||||
if (u.uo.checkNeedUpdate(now)) {
|
||||
auto targetTime = u.uo.lastUpdate + u.uo.updatePeriodMs;
|
||||
if (targetTime + SLEEP_THRESHOLD <= now && targetTime - SLEEP_THRESHOLD >= now) {
|
||||
u.lastUpdate = targetTime;
|
||||
u.uo.lastUpdate = targetTime;
|
||||
} else {
|
||||
u.lastUpdate = now;
|
||||
u.uo.lastUpdate = now;
|
||||
}
|
||||
|
||||
u.callback();
|
||||
now = TIME_NOW();
|
||||
try {
|
||||
std::lock_guard _lock(this->cpApiMutex);
|
||||
u.uo.updateCallback();
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::run()->" << u.updaterName << "(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::run()->" << u.updaterName << "(): error " << e.what();
|
||||
}
|
||||
if (u.periodMs >= 0) {
|
||||
sleepTime = std::min(sleepTime, u.getNextUpdate(now));
|
||||
|
||||
now = TimeNow();
|
||||
}
|
||||
if (u.uo.updatePeriodMs >= 0) {
|
||||
sleepTime = std::min(sleepTime, u.uo.getNextUpdate(now));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,46 +197,80 @@ void api_driver::TerminalApiDaemon::run() {
|
||||
api_driver::TerminalApiDaemon::TerminalApiDaemon(): daemon([this]() { this->run(); }) {}
|
||||
|
||||
void api_driver::TerminalApiDaemon::getState(obj::TerminalState &dest) {
|
||||
std::shared_lock _lock(state);
|
||||
std::shared_lock _lock(stateMutex);
|
||||
dest = state;
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::getDeviceState(obj::TerminalDeviceState &dest) {
|
||||
std::shared_lock _lock(state);
|
||||
std::shared_lock _lock(stateMutex);
|
||||
dest = stateDev;
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::getSettingsRxTx(obj::TerminalRxTxSettings &dest) {
|
||||
api_driver::obj::TerminalRxTxSettings api_driver::TerminalApiDaemon::getSettingsRxTx() {
|
||||
obj::TerminalRxTxSettings s;
|
||||
{
|
||||
std::shared_lock _olock(this->settingsMutex);
|
||||
s = settingsRxTx;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::getNetworkSettings(obj::TerminalNetworkSettings &dest) {
|
||||
void api_driver::TerminalApiDaemon::setSettingsRxTx(obj::TerminalRxTxSettings &s) {
|
||||
std::lock_guard _olock(settingsMutex);
|
||||
settingsRxTx = s;
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::getQosSettings(bool &isEnabled, std::string &json) {
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
api_driver::obj::TerminalNetworkSettings api_driver::TerminalApiDaemon::getNetworkSettings() {
|
||||
obj::TerminalNetworkSettings s;
|
||||
{
|
||||
std::shared_lock _olock(this->settingsMutex);
|
||||
s = settingsNetwork;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::setSettingsRxTx(obj::TerminalRxTxSettings &s, bool readback) {
|
||||
void api_driver::TerminalApiDaemon::setNetworkSettings(obj::TerminalNetworkSettings &s) {
|
||||
std::lock_guard _olock(settingsMutex);
|
||||
settingsNetwork = s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
api_driver::obj::TerminalQosSettings api_driver::TerminalApiDaemon::getQosSettings() {
|
||||
obj::TerminalQosSettings s;
|
||||
{
|
||||
std::shared_lock _olock(this->settingsMutex);
|
||||
s = settingsQos;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::setSettingsDpdi(DPDI_parmeters &s, bool readback) {
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::setSettingsBucLnb(buc_lnb_settings &bucLnb, bool readback) {
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::setQosSettings(bool enabled, const std::string &str, bool readback) {
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::setNetworkSettings(obj::TerminalNetworkSettings &s, bool readback) {
|
||||
void api_driver::TerminalApiDaemon::setQosSettings(obj::TerminalQosSettings &s) {
|
||||
std::lock_guard _olock(settingsMutex);
|
||||
settingsQos = s;
|
||||
}
|
||||
#endif
|
||||
|
||||
api_driver::obj::TerminalFirmwareVersion api_driver::TerminalApiDaemon::getFirmware() {
|
||||
obj::TerminalFirmwareVersion res;
|
||||
{
|
||||
std::shared_lock _olock(firmwareMutex);
|
||||
res = firmware;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::resetPacketStatistics() {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
cp.getDmaDebug("reset_cnt_rx");
|
||||
}
|
||||
|
||||
void api_driver::TerminalApiDaemon::resetDefaultSettings() {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
cp.setDmaDebug("begin_save_config", "");
|
||||
cp.setDmaDebug("default_params", "");
|
||||
cp.setDmaDebug("save_config", "");
|
||||
}
|
||||
|
||||
api_driver::TerminalApiDaemon::~TerminalApiDaemon() {
|
||||
@@ -199,274 +281,3 @@ api_driver::TerminalApiDaemon::~TerminalApiDaemon() {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::~TerminalApiDaemon(): " << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* Этот демон нужен для того, чтобы получать статистику из API, а так же корректно сохранять настройки
|
||||
*/
|
||||
class api_driver::TerminalApiDaemon {
|
||||
void updateState() {
|
||||
obj::TerminalDeviceState s;
|
||||
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
try {
|
||||
s.updateCallback(cp);
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard lock2(this->stateMutex);
|
||||
this->state = s;
|
||||
#ifdef MODEM_IS_TDMA
|
||||
this->state.fInitState = tmpDevState;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void updateSettings() {
|
||||
modulator_settings mod{};
|
||||
// uint32_t modulatorModcod;
|
||||
// CP_GetModulatorParams(sid, "modcod", &modulatorModcod);
|
||||
demodulator_settings demod{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
ACM_parameters_serv_ acm{};
|
||||
#endif
|
||||
DPDI_parmeters dpdi{};
|
||||
buc_lnb_settings bucLnb{};
|
||||
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateSettings()->CP_GetModulatorSettings()", CP_GetModulatorSettings(sid, mod));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateSettings()->CP_GetDemodulatorSettings()", CP_GetDemodulatorSettings(sid, demod));
|
||||
#ifdef MODEM_IS_SCPC
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateSettings()->CP_GetAcmParams()", CP_GetAcmParams(sid, &acm));
|
||||
#endif
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateSettings()->CP_GetDpdiParams()", CP_GetDpdiParams(sid, &dpdi));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateSettings()->CP_GetBUC_LNB_settings()", CP_GetBUC_LNB_settings(sid, bucLnb));
|
||||
|
||||
{
|
||||
std::lock_guard lock2(this->settingsMutex);
|
||||
this->modSettings = mod;
|
||||
this->demodSettings = demod;
|
||||
#ifdef MODEM_IS_SCPC
|
||||
this->acmSettings = acm;
|
||||
#endif
|
||||
this->dpdiSettings = dpdi;
|
||||
this->bucLnbSettings = bucLnb;
|
||||
}
|
||||
}
|
||||
|
||||
void updateNetworkSettings() {
|
||||
obj::TerminalNetworkSettings s;
|
||||
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
unsafeLoadNetworkSettings(s);
|
||||
|
||||
{
|
||||
std::lock_guard lock2(this->networkSettingsMutex);
|
||||
this->networkSettings = s;
|
||||
}
|
||||
}
|
||||
|
||||
void updateQos() {
|
||||
bool tmp1; std::string tmp2;
|
||||
std::scoped_lock lock{this->cpApiMutex};
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateQos()->CP_GetQoSSettings()", CP_GetQoSSettings(this->sid, tmp2, tmp1));
|
||||
{
|
||||
std::lock_guard lock2(this->qosSettingsMutex);
|
||||
this->qosEnabled = tmp1;
|
||||
this->qosClassesJson = tmp2.empty() ? DEFAULT_QOS_CLASSES : tmp2;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Получение статистики, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
|
||||
*/
|
||||
TerminalDeviceState getState() {
|
||||
TerminalDeviceState s;
|
||||
{
|
||||
std::shared_lock lock(this->stateMutex);
|
||||
s = this->state;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
/**
|
||||
* Получение настроек, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
|
||||
*/
|
||||
void getSettings(
|
||||
modulator_settings* mod, demodulator_settings* demod,
|
||||
#ifdef MODEM_IS_SCPC
|
||||
ACM_parameters_serv_* acm,
|
||||
#endif
|
||||
DPDI_parmeters* dpdi, buc_lnb_settings* bucLnb) {
|
||||
if (mod || demod ||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
acm ||
|
||||
#endif
|
||||
dpdi || bucLnb) {
|
||||
std::shared_lock lock(this->settingsMutex);
|
||||
if (mod) { *mod = this->modSettings; }
|
||||
if (demod) { *demod = this->demodSettings; }
|
||||
#ifdef MODEM_IS_SCPC
|
||||
if (acm) { *acm = this->acmSettings; }
|
||||
#endif
|
||||
if (dpdi) { *dpdi = this->dpdiSettings; }
|
||||
if (bucLnb) { *bucLnb = this->bucLnbSettings; }
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
bool getIsCinC() {
|
||||
std::shared_lock lock(this->settingsMutex);
|
||||
return modSettings.is_cinc;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool isTest() {
|
||||
std::shared_lock lock(this->settingsMutex);
|
||||
return modSettings.tx_is_on && (!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;
|
||||
}
|
||||
|
||||
void getQosSettings(bool& isEnabled, std::string& json) {
|
||||
std::shared_lock lock(this->qosSettingsMutex);
|
||||
isEnabled = this->qosEnabled;
|
||||
json = this->qosClassesJson;
|
||||
}
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
void setSettingsRxTx(modulator_settings& mod, demodulator_settings& demod, ACM_parameters_serv_& acm, bool readback = true) {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetModulatorSettings()", CP_SetModulatorSettings(this->sid, mod));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetDemodulatorSettings()", CP_SetDemodulatorSettings(this->sid, demod));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetAcmParams()", CP_SetAcmParams(this->sid, acm));
|
||||
if (readback) {
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_GetModulatorSettings()", CP_GetModulatorSettings(this->sid, mod));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_GetDemodulatorSettings()", CP_GetDemodulatorSettings(this->sid, demod));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_GetAcmParams()", CP_GetAcmParams(this->sid, &acm));
|
||||
{
|
||||
std::lock_guard lock2{this->settingsMutex};
|
||||
this->modSettings = mod;
|
||||
this->demodSettings = demod;
|
||||
this->acmSettings = acm;
|
||||
}
|
||||
}
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", ""));
|
||||
}
|
||||
#else
|
||||
void setSettingsRxTx(modulator_settings& mod, demodulator_settings& demod, bool readback = true) {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetModulatorSettings()", CP_SetModulatorSettings(this->sid, mod));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetDemodulatorSettings()", CP_SetDemodulatorSettings(this->sid, demod));
|
||||
if (readback) {
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_GetModulatorSettings()", CP_GetModulatorSettings(this->sid, mod));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_GetDemodulatorSettings()", CP_GetDemodulatorSettings(this->sid, demod));
|
||||
{
|
||||
std::lock_guard lock2{this->settingsMutex};
|
||||
this->modSettings = mod;
|
||||
this->demodSettings = demod;
|
||||
}
|
||||
}
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsRxTx()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", ""));
|
||||
}
|
||||
#endif
|
||||
|
||||
void setSettingsDpdi(DPDI_parmeters& s, bool readback = true) {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsDpdi()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsDpdi()->CP_SetDpdiParams()", CP_SetDpdiParams(sid, s));
|
||||
if (readback) {
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsDpdi()->CP_GetDpdiParams()", CP_GetDpdiParams(this->sid, &s));
|
||||
{
|
||||
std::lock_guard lock2{this->settingsMutex};
|
||||
this->dpdiSettings = s;
|
||||
}
|
||||
}
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsDpdi()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", ""));
|
||||
}
|
||||
|
||||
void setSettingsBucLnb(buc_lnb_settings& bucLnb, bool readback = true) {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsBucLnb()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsBucLnb()->CP_SetBUC_LNB_settings()", CP_SetBUC_LNB_settings(this->sid, bucLnb));
|
||||
if (readback) {
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsBucLnb()->CP_GetBUC_LNB_settings()", CP_GetBUC_LNB_settings(this->sid, bucLnb));
|
||||
{
|
||||
std::lock_guard lock2{this->settingsMutex};
|
||||
this->bucLnbSettings = bucLnb;
|
||||
}
|
||||
}
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setSettingsBucLnb()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", ""));
|
||||
}
|
||||
|
||||
void setQosSettings(bool enabled, const std::string& str, bool readback = true) {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetQoSSettings()", CP_SetQoSSettings(this->sid, str, enabled));
|
||||
if (readback) {
|
||||
bool tmp1; std::string tmp2;
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_GetQoSSettings()", CP_GetQoSSettings(this->sid, tmp2, tmp1));
|
||||
{
|
||||
std::lock_guard lock2(this->qosSettingsMutex);
|
||||
this->qosEnabled = tmp1;
|
||||
this->qosClassesJson = tmp2.empty() ? DEFAULT_QOS_CLASSES : tmp2;
|
||||
}
|
||||
}
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setQosSettings()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", ""));
|
||||
}
|
||||
|
||||
void setNetworkSettings(TerminalNetworkSettings& s, bool readback = true) {
|
||||
// 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", ""));
|
||||
unsafStoreNetworkSettings(s);
|
||||
|
||||
if (readback) {
|
||||
unsafeLoadNetworkSettings(s);
|
||||
{
|
||||
std::lock_guard lock2(this->networkSettingsMutex);
|
||||
this->networkSettings = s;
|
||||
}
|
||||
}
|
||||
logCpApiError("api_driver::TerminalApiDaemon::setNetworkSettings()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", ""));
|
||||
}
|
||||
|
||||
TerminalFirmwareVersion getFirmware() {
|
||||
std::shared_lock lock(this->firmwareMutex);
|
||||
return firmware;
|
||||
}
|
||||
|
||||
void resetPacketStatistics() {
|
||||
std::string tmp;
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::resetPacketStatistics()->CP_GetDmaDebug(reset_cnt_rx)", CP_GetDmaDebug(sid, "reset_cnt_rx", &tmp));
|
||||
}
|
||||
|
||||
void resetDefaultSettings() {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
logCpApiError("api_driver::TerminalApiDaemon::resetDefaultSettings()->CP_SetDmaDebug(begin_save_config)", CP_SetDmaDebug(sid, "begin_save_config", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::resetDefaultSettings()->CP_SetDmaDebug(default_params)", CP_SetDmaDebug(sid, "default_params", ""));
|
||||
logCpApiError("api_driver::TerminalApiDaemon::resetDefaultSettings()->CP_SetDmaDebug(save_config)", CP_SetDmaDebug(sid, "save_config", ""));
|
||||
}
|
||||
|
||||
};
|
||||
|
@@ -1,16 +1,15 @@
|
||||
#ifndef DAEMON_H
|
||||
#define DAEMON_H
|
||||
|
||||
#include <boost/thread/detail/thread.hpp>
|
||||
#ifndef API_DRIVER_DAEMON_H
|
||||
#define API_DRIVER_DAEMON_H
|
||||
|
||||
#include "proxy.h"
|
||||
#include "api-driver/structs.h"
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
namespace api_driver {
|
||||
int64_t TimeNow();
|
||||
|
||||
class TerminalApiDaemon {
|
||||
std::mutex cpApiMutex;
|
||||
boost::thread daemon;
|
||||
proxy::CpProxy cp;
|
||||
|
||||
void connectToApi();
|
||||
|
||||
@@ -22,10 +21,10 @@ namespace api_driver {
|
||||
|
||||
std::shared_mutex settingsMutex;
|
||||
obj::TerminalRxTxSettings settingsRxTx;
|
||||
#if API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
obj::TerminalNetworkSettings settingsNetwork;
|
||||
#endif
|
||||
#if API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
obj::TerminalQosSettings settingsQos;
|
||||
#endif
|
||||
|
||||
@@ -33,38 +32,38 @@ namespace api_driver {
|
||||
obj::TerminalFirmwareVersion firmware;
|
||||
|
||||
public:
|
||||
#if API_OBJECT_STATISTICS_ENABLE
|
||||
std::mutex cpApiMutex;
|
||||
proxy::CpProxy cp;
|
||||
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
obj::StatisticsLogger statsLogs;
|
||||
#endif
|
||||
|
||||
explicit TerminalApiDaemon();
|
||||
|
||||
std::string getDeviceInitState();
|
||||
|
||||
/**
|
||||
* Получение статистики, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
|
||||
*/
|
||||
void getState(obj::TerminalState &dest);
|
||||
|
||||
void getDeviceState(obj::TerminalDeviceState &dest);
|
||||
|
||||
// /**
|
||||
// * Получение настроек, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
|
||||
// * Установка настроек просто копирует настройки и устанавливает их текущими
|
||||
// */
|
||||
void getSettingsRxTx(obj::TerminalRxTxSettings& dest);
|
||||
obj::TerminalRxTxSettings getSettingsRxTx();
|
||||
void setSettingsRxTx(obj::TerminalRxTxSettings &s);
|
||||
|
||||
void getNetworkSettings(obj::TerminalNetworkSettings& dest);
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
obj::TerminalNetworkSettings getNetworkSettings();
|
||||
void setNetworkSettings(obj::TerminalNetworkSettings &s);
|
||||
#endif
|
||||
|
||||
void getQosSettings(bool& isEnabled, std::string& json);
|
||||
|
||||
void setSettingsRxTx(obj::TerminalRxTxSettings& s, bool readback = true);
|
||||
|
||||
void setSettingsDpdi(DPDI_parmeters& s, bool readback = true);
|
||||
|
||||
void setSettingsBucLnb(buc_lnb_settings& bucLnb, bool readback = true);
|
||||
|
||||
void setQosSettings(bool enabled, const std::string& str, bool readback = true);
|
||||
|
||||
void setNetworkSettings(obj::TerminalNetworkSettings& s, bool readback = true);
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
obj::TerminalQosSettings getQosSettings();
|
||||
void setQosSettings(obj::TerminalQosSettings &s);
|
||||
#endif
|
||||
|
||||
obj::TerminalFirmwareVersion getFirmware();
|
||||
|
||||
@@ -77,4 +76,4 @@ namespace api_driver {
|
||||
}
|
||||
|
||||
|
||||
#endif //DAEMON_H
|
||||
#endif //API_DRIVER_DAEMON_H
|
||||
|
@@ -1,10 +1,137 @@
|
||||
#include "proxy.h"
|
||||
#include "sstream"
|
||||
|
||||
//#define CPAPI_PROXY_CALL(proxy, func, ...) do { auto _res = func(proxy.sid, __VA_ARGS__); if (_res != OK) { BOOST_LOG_TRIVIAL(error) << "CP API error in " #func "(" #__VA_ARGS__ "): " << _res; } } while (0)
|
||||
// void foo() {
|
||||
// api_driver::proxy::CpProxy proxy;
|
||||
// std::string tmp;
|
||||
// CPAPI_PROXY_CALL(proxy, CP_GetDmaDebug, "fuck", &tmp);
|
||||
// }
|
||||
#define CPAPI_PROXY_CALL_HELPER(callfrom, func, funcArgs, throwArgs) do { lastCpError = func funcArgs; if (lastCpError != OK) { \
|
||||
std::stringstream err; err << callfrom ": CP Api error " #func "("; err << throwArgs; err << "): " << lastCpError;\
|
||||
throw std::runtime_error(err.str());\
|
||||
} } while (0)
|
||||
|
||||
|
||||
api_driver::proxy::CpProxy::CpProxy() = default;
|
||||
|
||||
api_driver::proxy::CpProxy::CpProxy(TSID s): sid(s) {}
|
||||
|
||||
void api_driver::proxy::CpProxy::connect() {
|
||||
unsigned int access{};
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::connect", CP_Login, ("admin", "pass", &sid, &access), R"("admin", "pass", &sid, &access)");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::disconnect() {
|
||||
if (sid != 0) {
|
||||
lastCpError = CP_Logout(sid);
|
||||
sid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::string api_driver::proxy::CpProxy::getDmaDebug(const std::string &arg) {
|
||||
std::string result;
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getDmaDebug", CP_GetDmaDebug, (sid, arg.c_str(), &result), arg);
|
||||
return result;
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setDmaDebug(const std::string &arg, const std::string &value) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setDmaDebug", CP_SetDmaDebug, (sid, arg.c_str(), value), arg << ", \"" << value << "\"");
|
||||
}
|
||||
|
||||
std::string api_driver::proxy::CpProxy::getNetwork(const std::string ¶m) {
|
||||
std::string result;
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getNetwork", CP_GetNetwork, (sid, param.c_str(), &result), param);
|
||||
return result;
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setNetwork(const std::string ¶m, const std::string &value) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setNetwork", CP_SetNetwork, (sid, param.c_str(), value.c_str()), param << ", \"" << value << "\"");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::getModState(modulator_state &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getModState", CP_GetModulatorState, (sid, dest), "");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::getModSettings(modulator_settings &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getModSettings", CP_GetModulatorSettings, (sid, dest), "");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setModSettings(modulator_settings &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setModSettings", CP_SetModulatorSettings, (sid, dest), "struct {...}");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::getDemodState(demodulator_state &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getDemodState", CP_GetDemodulatorState, (sid, dest), "");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::getDemodSettings(demodulator_settings &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getDemodSettings", CP_GetDemodulatorSettings, (sid, dest), "");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setDemodSettings(demodulator_settings &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setDemodSettings", CP_SetDemodulatorSettings, (sid, dest), "struct {...}");
|
||||
}
|
||||
|
||||
#ifdef API_STRUCT_ACM_ENABLE
|
||||
void api_driver::proxy::CpProxy::getAcmSettings(ACM_parameters_serv_ &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getAcmSettings", CP_GetAcmParams, (sid, &dest), "");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setAcmSettings(ACM_parameters_serv_ &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setAcmSettings", CP_SetAcmParams, (sid, dest), "struct {...}");
|
||||
}
|
||||
#endif
|
||||
|
||||
void api_driver::proxy::CpProxy::getDeviceState(device_state &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getDeviceState", CP_GetDeviceState, (sid, dest), "");
|
||||
}
|
||||
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
std::tuple<std::string, bool> api_driver::proxy::CpProxy::getQosSettings() {
|
||||
std::string rules;
|
||||
bool en;
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getQosSettings", CP_GetQoSSettings, (sid, rules, en), "");
|
||||
return {rules, en};
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setQosSettings(const std::string &rules, bool enable) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setQosSettings", CP_SetQoSSettings, (sid, rules, enable), "`" << rules << "`, " << (enable ? "true" : "false"));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
void api_driver::proxy::CpProxy::getDpdiSettings(DPDI_parmeters &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getDpdiSettings", CP_GetDpdiParams, (sid, &dest), "");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setDpdiSettings(DPDI_parmeters &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setDpdiSettings", CP_SetDpdiParams, (sid, dest), "struct {...}");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
void api_driver::proxy::CpProxy::getBuclnbSettings(buc_lnb_settings &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getBuclnbSettings", CP_GetBUC_LNB_settings, (sid, dest), "");
|
||||
}
|
||||
|
||||
void api_driver::proxy::CpProxy::setBuclnbSettings(buc_lnb_settings &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::setBuclnbSettings", CP_SetBUC_LNB_settings, (sid, dest), "struct {...}");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
void api_driver::proxy::CpProxy::getCincState(CinC_state &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getCincState", CP_GetCinCState, (sid, dest), "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
void api_driver::proxy::CpProxy::getDebugMetrics(debug_metrics &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getDebugMetrics", CP_GetDebugMetrics, (sid, dest), "");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MODEM_IS_TDMA
|
||||
void api_driver::proxy::CpProxy::getUpdateStatus(progress_msg &dest) {
|
||||
CPAPI_PROXY_CALL_HELPER("CpProxy::getUpdateStatus", CP_GetUpdateStatus, (sid, dest), "");
|
||||
}
|
||||
#endif
|
||||
|
||||
api_driver::proxy::CpProxy::~CpProxy() {
|
||||
disconnect();
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, CP_Result result);
|
||||
|
||||
|
||||
namespace api_driver::proxy {
|
||||
class CpProxy {
|
||||
public:
|
||||
@@ -28,6 +27,7 @@ namespace api_driver::proxy {
|
||||
void disconnect();
|
||||
|
||||
std::string getDmaDebug(const std::string& arg);
|
||||
void setDmaDebug(const std::string& arg, const std::string& value);
|
||||
|
||||
std::string getNetwork(const std::string& param);
|
||||
void setNetwork(const std::string& param, const std::string& value);
|
||||
@@ -40,16 +40,40 @@ namespace api_driver::proxy {
|
||||
void getDemodSettings(demodulator_settings& dest);
|
||||
void setDemodSettings(demodulator_settings& dest);
|
||||
|
||||
#ifdef API_STRUCT_ACM_ENABLE
|
||||
void getAcmSettings(ACM_parameters_serv_& dest);
|
||||
void setAcmSettings(ACM_parameters_serv_& dest);
|
||||
#endif
|
||||
|
||||
void getDeviceState(device_state& dest);
|
||||
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
std::tuple<std::string, bool> getQosSettings();
|
||||
void setQosSettings(const std::string& rules, bool enable);
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
void getDpdiSettings(DPDI_parmeters& dest);
|
||||
void setDpdiSettings(DPDI_parmeters& dest);
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
void getBuclnbSettings(buc_lnb_settings& dest);
|
||||
void setBuclnbSettings(buc_lnb_settings& dest);
|
||||
#endif
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
void getCincState(CinC_state& dest);
|
||||
#endif
|
||||
|
||||
#if API_OBJECT_STATISTICS_ENABLE
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
void getDebugMetrics(debug_metrics& dest);
|
||||
#endif
|
||||
|
||||
#ifdef MODEM_IS_TDMA
|
||||
void getUpdateStatus(progress_msg& dest);
|
||||
#endif
|
||||
|
||||
~CpProxy();
|
||||
};
|
||||
}
|
||||
|
@@ -1,8 +1,30 @@
|
||||
#ifndef API_DRIVER_STRICTS_ENABLE_H
|
||||
#define API_DRIVER_STRICTS_ENABLE_H
|
||||
|
||||
#define API_OBJECT_STATISTICS_ENABLE defined(MODEM_IS_SCPC)
|
||||
#define API_OBJECT_NETWORK_SETTINGS_ENABLE defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA)
|
||||
#define API_OBJECT_QOS_SETTINGS_ENABLE defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA)
|
||||
|
||||
#if defined(MODEM_IS_SCPC)
|
||||
#define API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
#endif
|
||||
|
||||
#if defined(MODEM_IS_SCPC) || defined(MODEM_IS_SHPS)
|
||||
#define API_STRUCT_ACM_ENABLE
|
||||
#endif
|
||||
|
||||
#if defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA) || defined(MODEM_IS_SHPS)
|
||||
#define API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
#endif
|
||||
|
||||
#if defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA)
|
||||
#define API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
#endif
|
||||
|
||||
#if defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA)
|
||||
#define API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
#endif
|
||||
|
||||
#if defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA) || defined(MODEM_IS_SHPS)
|
||||
#define API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
#endif
|
||||
|
||||
|
||||
#endif //API_DRIVER_STRICTS_ENABLE_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -7,36 +7,12 @@
|
||||
#include <fstream>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/property_tree/ptree_fwd.hpp>
|
||||
|
||||
#include "common/nlohmann/json.hpp"
|
||||
|
||||
|
||||
namespace api_driver::obj {
|
||||
/**
|
||||
* Обертка для объектов, доступных для обновления
|
||||
* NOTE: перед вызовом функций, требующих `TSID`, необходимо захватить мютекс API.
|
||||
*/
|
||||
class CpUpdatebleObject {
|
||||
public:
|
||||
int64_t lastUpdate = 0;
|
||||
int64_t updatePeriodMs = -1;
|
||||
|
||||
/**
|
||||
* Функция для обновления (загрузки) объекта из CP API.
|
||||
*/
|
||||
virtual void updateCallback(proxy::CpProxy& cp) = 0;
|
||||
|
||||
bool checkNeedUpdate(int64_t now) const;
|
||||
|
||||
int64_t getNextUpdate(int64_t now) const;
|
||||
|
||||
virtual ~CpUpdatebleObject();
|
||||
};
|
||||
|
||||
|
||||
#if API_OBJECT_STATISTICS_ENABLE
|
||||
class StatisticsLogger: public CpUpdatebleObject {
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
class StatisticsLogger {
|
||||
public:
|
||||
StatisticsLogger();
|
||||
|
||||
@@ -52,10 +28,10 @@ namespace api_driver::obj {
|
||||
*
|
||||
* @return {"en": bool, "logPeriodMs": int, "maxAgeMs": int}
|
||||
*/
|
||||
std::string getSettings();
|
||||
void setSettings(boost::property_tree::ptree &pt);
|
||||
nlohmann::json getSettings();
|
||||
void setSettings(const nlohmann::json& data);
|
||||
|
||||
void updateCallback(proxy::CpProxy& cp) override;
|
||||
void updateCallback(proxy::CpProxy& cp);
|
||||
/**
|
||||
* Записать значение в "базу данных". Метку при этом вставлять не нужно, она будет вставлена автоматически.
|
||||
* @param item
|
||||
@@ -69,7 +45,7 @@ namespace api_driver::obj {
|
||||
// logs.clear();
|
||||
// }
|
||||
|
||||
~StatisticsLogger() override;
|
||||
~StatisticsLogger();
|
||||
private:
|
||||
// std::pmr::deque<LogItem> logs;
|
||||
std::fstream logFile{};
|
||||
@@ -81,14 +57,14 @@ namespace api_driver::obj {
|
||||
static constexpr const char* DEFAULT_SERVER_NAME = "RSCM-101";
|
||||
#elif defined(MODEM_IS_TDMA)
|
||||
static constexpr const char* DEFAULT_SERVER_NAME = "TDMA Abonent";
|
||||
#elif defined(MODEM_IS_SHPC)
|
||||
#elif defined(MODEM_IS_SHPS)
|
||||
static constexpr const char* DEFAULT_SERVER_NAME = "SHPS Terminal";
|
||||
#else
|
||||
#error "Selected modem type not supported!"
|
||||
#endif
|
||||
|
||||
#if API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
class TerminalNetworkSettings: public CpUpdatebleObject {
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
class TerminalNetworkSettings {
|
||||
public:
|
||||
std::string managementIp, managementGateway, dataIp, serverName;
|
||||
bool isL2 = true;
|
||||
@@ -100,20 +76,20 @@ namespace api_driver::obj {
|
||||
|
||||
void loadDefaults();
|
||||
|
||||
void updateCallback(proxy::CpProxy& cp) override;
|
||||
void updateFromPt(boost::property_tree::ptree &pt);
|
||||
void updateCallback(proxy::CpProxy& cp);
|
||||
void updateFromJson(const nlohmann::json& data);
|
||||
void store(proxy::CpProxy& cp);
|
||||
std::string asJson();
|
||||
nlohmann::json asJson();
|
||||
|
||||
~TerminalNetworkSettings() override;
|
||||
~TerminalNetworkSettings();
|
||||
};
|
||||
#endif
|
||||
|
||||
#if API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
class TerminalQosSettings: public CpUpdatebleObject {
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
class TerminalQosSettings {
|
||||
public:
|
||||
static constexpr const char* DEFAULT_QOS_CLASSES = R"({"rt1":[],"rt2":[],"rt3":[],"cd":[]})";
|
||||
std::string qosSettingsJson;
|
||||
nlohmann::json qosSettingsJson;
|
||||
bool qosEnabled = false;
|
||||
|
||||
TerminalQosSettings();
|
||||
@@ -122,12 +98,12 @@ namespace api_driver::obj {
|
||||
|
||||
void loadDefaults();
|
||||
|
||||
void updateCallback(proxy::CpProxy& cp) override;
|
||||
void updateFromPt(boost::property_tree::ptree &pt);
|
||||
void updateCallback(proxy::CpProxy& cp);
|
||||
void updateFromJson(const nlohmann::json& data);
|
||||
void store(proxy::CpProxy& cp);
|
||||
std::string asJson();
|
||||
nlohmann::json asJson();
|
||||
|
||||
~TerminalQosSettings() override;
|
||||
~TerminalQosSettings();
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -137,24 +113,18 @@ namespace api_driver::obj {
|
||||
|
||||
TerminalFirmwareVersion();
|
||||
TerminalFirmwareVersion(const TerminalFirmwareVersion& src);
|
||||
~TerminalFirmwareVersion();
|
||||
|
||||
// logCpApiError("api_driver::TerminalApiDaemon::connectToApi()->CP_GetNetwork(version)", CP_GetNetwork(sid, "version", &f.version));
|
||||
// logCpApiError("api_driver::TerminalApiDaemon::connectToApi()->CP_GetNetwork(chip_id)", CP_GetNetwork(sid, "chip_id", &f.modemId));
|
||||
// rtrim(f.modemId);
|
||||
// logCpApiError("api_driver::TerminalApiDaemon::connectToApi()->CP_GetNetwork(serial)", CP_GetNetwork(sid, "serial", &f.modemSn));
|
||||
// logCpApiError("api_driver::TerminalApiDaemon::connectToApi()->CP_GetNetwork(mac_eth0)", CP_GetNetwork(sid, "mac_eth0", &f.macMang));
|
||||
// logCpApiError("api_driver::TerminalApiDaemon::connectToApi()->CP_GetNetwork(mac_eth1)", CP_GetNetwork(sid, "mac_eth1", &f.macData));
|
||||
void load(proxy::CpProxy& cp);
|
||||
std::string asJson();
|
||||
|
||||
TerminalFirmwareVersion& operator= (const TerminalFirmwareVersion& src);
|
||||
|
||||
void load(proxy::CpProxy& cp);
|
||||
nlohmann::json asJson();
|
||||
|
||||
~TerminalFirmwareVersion();
|
||||
};
|
||||
|
||||
/**
|
||||
* Обертка состояния терминала, тут состояние девайса, модулятора/демодулятора, состояние автоматического обновления.
|
||||
*/
|
||||
class TerminalState: public CpUpdatebleObject {
|
||||
class TerminalState {
|
||||
public:
|
||||
std::string fInitState{};
|
||||
bool fIsTest = false; // daemon->isTest()
|
||||
@@ -163,62 +133,62 @@ namespace api_driver::obj {
|
||||
bool fIsCinC = false;
|
||||
#endif
|
||||
|
||||
bool fStatRxState;
|
||||
bool fStatRxSymSyncLock;
|
||||
bool fStatRxFreqSearchLock;
|
||||
bool fStatRxAfcLock;
|
||||
bool fStatRxPktSync;
|
||||
bool fRxState{};
|
||||
#ifndef MODEM_IS_SHPS
|
||||
bool fRxSymSyncLock{};
|
||||
bool fRxFreqSearchLock{};
|
||||
bool fRxAfcLock{};
|
||||
bool fRxPktSync{};
|
||||
#endif
|
||||
|
||||
float fStatRxSnr;
|
||||
float fStatRxRssi;
|
||||
uint16_t fStatRxModcod;
|
||||
bool fStatRxFrameSizeNormal;
|
||||
bool fStatRxIsPilots;
|
||||
|
||||
double fStatRxSymError;
|
||||
double fStatRxFreqErr;
|
||||
double fStatRxFreqErrAcc;
|
||||
double fStatRxInputSignalLevel;
|
||||
double fStatRxPllError;
|
||||
double fStatRxSpeedOnRxKbit;
|
||||
double fStatRxSpeedOnIifKbit;
|
||||
uint32_t fStatRxPacketsOk;
|
||||
uint32_t fStatRxPacketsBad;
|
||||
uint32_t fStatRxPacketsDummy;
|
||||
|
||||
bool fStatTxState;
|
||||
uint16_t fStatTxModcod;
|
||||
double fStatTxSpeedOnTxKbit;
|
||||
double fStatTxSpeedOnIifKbit;
|
||||
float fRxSnr{};
|
||||
float fRxRssi{};
|
||||
#ifndef MODEM_IS_SHPS
|
||||
uint16_t fRxModcod{};
|
||||
bool fRxFrameSizeNormal{};
|
||||
bool fRxIsPilots{};
|
||||
double fRxSymError{};
|
||||
double fRxFreqErr{};
|
||||
#endif
|
||||
double fRxFreqErrAcc{};
|
||||
double fRxInputSignalLevel{};
|
||||
double fRxPllError{};
|
||||
double fRxSpeedOnRxKbit{};
|
||||
double fRxSpeedOnIifKbit{};
|
||||
uint32_t fRxPacketsOk{};
|
||||
uint32_t fRxPacketsBad{};
|
||||
#ifndef MODEM_IS_SHPS
|
||||
uint32_t fRxPacketsDummy{};
|
||||
uint16_t fTxModcod{};
|
||||
#endif
|
||||
double fTxSpeedOnTxKbit{};
|
||||
double fTxSpeedOnIifKbit{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
float fStatTxSnr;
|
||||
bool fStatTxFrameSizeNormal;
|
||||
bool fStatTxIsPilots;
|
||||
double fStatCincOcc;
|
||||
bool fStatCincCorrelator;
|
||||
uint32_t fStatCincCorrelatorFails;
|
||||
int32_t fStatCincFreqErr;
|
||||
int32_t fStatCincFreqErrAcc;
|
||||
float fStatCincChannelDelay;
|
||||
#endif
|
||||
#ifdef MODEM_IS_TDMA
|
||||
fStatTxCenterFreq;
|
||||
fStatTxSymSpeed;
|
||||
float fTxSnr{};
|
||||
bool fTxFrameSizeNormal{};
|
||||
bool fTxIsPilots{};
|
||||
double fCincOcc{};
|
||||
bool fCincCorrelator{};
|
||||
uint32_t fCincCorrelatorFails{};
|
||||
int32_t fCincFreqErr{};
|
||||
int32_t fCincFreqErrAcc{};
|
||||
float fCincChannelDelay{};
|
||||
#endif
|
||||
double fTxCenterFreq;
|
||||
double fTxSymSpeed;
|
||||
|
||||
TerminalState();
|
||||
|
||||
/**
|
||||
* Обновление основной части статистики, то есть RX/TX и sysinfo
|
||||
*/
|
||||
void updateCallback(proxy::CpProxy& cp) override;
|
||||
void updateCallback(proxy::CpProxy& cp);
|
||||
nlohmann::json asJson();
|
||||
|
||||
void updateFromPt(boost::property_tree::ptree &pt);
|
||||
void store(TSID sid, CP_Result& lastCpError);
|
||||
std::string asJson();
|
||||
|
||||
~TerminalState() override;
|
||||
~TerminalState();
|
||||
};
|
||||
|
||||
class TerminalDeviceState: public CpUpdatebleObject {
|
||||
class TerminalDeviceState {
|
||||
public:
|
||||
time_t fOsUptime{};
|
||||
double fOsLoad1{};
|
||||
@@ -241,23 +211,49 @@ namespace api_driver::obj {
|
||||
TerminalDeviceState(const TerminalDeviceState& src);
|
||||
TerminalDeviceState& operator= (const TerminalDeviceState& src);
|
||||
|
||||
void updateCallback(proxy::CpProxy& cp) override;
|
||||
std::string asJson() const;
|
||||
void updateCallback(proxy::CpProxy& cp);
|
||||
nlohmann::json asJson() const;
|
||||
|
||||
~TerminalDeviceState() override;
|
||||
~TerminalDeviceState();
|
||||
};
|
||||
|
||||
class TerminalRxTxSettings: public CpUpdatebleObject {
|
||||
class TerminalRxTxSettings {
|
||||
modulator_settings mod{};
|
||||
demodulator_settings dem{};
|
||||
#ifdef API_STRUCT_ACM_ENABLE
|
||||
ACM_parameters_serv_ acm{};
|
||||
#endif
|
||||
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
DPDI_parmeters dpdi{};
|
||||
#endif
|
||||
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
buc_lnb_settings buclnb{};
|
||||
#endif
|
||||
public:
|
||||
|
||||
// TODO описать все параметры для всех терминалов
|
||||
TerminalRxTxSettings();
|
||||
TerminalRxTxSettings(const TerminalRxTxSettings& src);
|
||||
TerminalRxTxSettings& operator= (const TerminalRxTxSettings& src);
|
||||
|
||||
void updateCallback(proxy::CpProxy& cp) override;
|
||||
void updateFromPt(boost::property_tree::ptree &pt);
|
||||
void store(proxy::CpProxy& cp);
|
||||
std::string asJson();
|
||||
void updateCallback(proxy::CpProxy& cp);
|
||||
|
||||
~TerminalRxTxSettings() override;
|
||||
void updateMainSettings(const nlohmann::json& data);
|
||||
void storeMainSettings(proxy::CpProxy& cp);
|
||||
|
||||
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
void updateDpdiSettings(const nlohmann::json& data);
|
||||
void storeDpdiSettings(proxy::CpProxy& cp);
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
void updateBuclnbSettings(const nlohmann::json& data);
|
||||
void storeBuclnbSettings(proxy::CpProxy& cp);
|
||||
#endif
|
||||
|
||||
void storeAll(proxy::CpProxy& cp);
|
||||
nlohmann::json asJson() const;
|
||||
|
||||
~TerminalRxTxSettings();
|
||||
};
|
||||
}
|
||||
|
||||
|
24765
src/common/nlohmann/json.hpp
Normal file
24765
src/common/nlohmann/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
368
src/main.cpp
368
src/main.cpp
@@ -11,7 +11,6 @@
|
||||
#include <boost/log/utility/setup/formatter_parser.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
@@ -21,6 +20,7 @@
|
||||
#include "auth/resources.h"
|
||||
#include "auth/jwt.h"
|
||||
#include "auth/utils.h"
|
||||
#include "common/nlohmann/json.hpp"
|
||||
|
||||
|
||||
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
|
||||
@@ -76,25 +76,25 @@ class ServerResources {
|
||||
}
|
||||
|
||||
void doTerminalUpgrade() const {
|
||||
api->executeInApi([](TSID sid) {
|
||||
CP_SetDmaDebug(sid, "begin_save_config", "");
|
||||
api->executeInApi([](api_driver::proxy::CpProxy& cp) {
|
||||
cp.setDmaDebug("begin_save_config", "");
|
||||
std::string cmd(UPGRADE_COMMAND);
|
||||
cmd += " ";
|
||||
cmd += FIRMWARE_LOCATION;
|
||||
system(cmd.c_str());
|
||||
CP_SetDmaDebug(sid, "save_config", "");
|
||||
cp.setDmaDebug("save_config", "");
|
||||
});
|
||||
}
|
||||
|
||||
#ifdef MODEM_IS_TDMA
|
||||
void doTerminalUpgradeOta() const {
|
||||
api->executeInApi([&](TSID sid) {
|
||||
CP_SetDmaDebug(sid, "begin_save_config", "");
|
||||
api->executeInApi([&](auto& cp) {
|
||||
cp.setDmaDebug("begin_save_config", "");
|
||||
std::string cmd(UPGRADE_COMMAND);
|
||||
cmd += " ";
|
||||
cmd += api->getOtaFileLocation();
|
||||
system(cmd.c_str());
|
||||
CP_SetDmaDebug(sid, "save_config", "");
|
||||
cp.setDmaDebug("save_config", "");
|
||||
});
|
||||
}
|
||||
#endif
|
||||
@@ -104,6 +104,8 @@ public:
|
||||
static constexpr const char* INDEX_HTML = "/main-tdma.html";
|
||||
#elif defined(MODEM_IS_SCPC)
|
||||
static constexpr const char* INDEX_HTML = "/main-scpc.html";
|
||||
#elif defined(MODEM_IS_SHPS)
|
||||
static constexpr const char* INDEX_HTML = "/main-shps.html";
|
||||
#else
|
||||
#error "Modem type not defined!"
|
||||
#endif
|
||||
@@ -177,11 +179,9 @@ public:
|
||||
rep.headers.clear();
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
try {
|
||||
std::istringstream is(std::string(req.payload.data(), req.payload.size()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(is, pt);
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
|
||||
auto u = auth.doAuth(pt.get<std::string>("username"), pt.get<std::string>("password"), req, rep);
|
||||
auto u = auth.doAuth(reqJson["username"], reqJson["password"], req, rep);
|
||||
if (u == nullptr) {
|
||||
throw std::runtime_error("invalid session");
|
||||
}
|
||||
@@ -219,14 +219,21 @@ public:
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
std::string result = R"({"mainState":)";
|
||||
result += api->loadTerminalState();
|
||||
result += R"(,"sysinfo":)";
|
||||
result += api->loadSysInfo();
|
||||
result += "}";
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["state"] = api->loadTerminalState();
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/get/statistics): Can't get terminal state: " << e.what();
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
|
||||
@@ -235,12 +242,22 @@ public:
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
std::string result = R"({"settings":)";
|
||||
result += api->loadSettings();
|
||||
result += "}";
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["settings"] = api->loadSettings();
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/get/settings): Can't get object: " << e.what();
|
||||
resultJson.clear();
|
||||
rep.status = http::server::internal_server_error;
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
|
||||
@@ -252,7 +269,20 @@ public:
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
const auto result = api->loadFirmwareVersion();
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["firmware"] = api->loadFirmwareVersion();
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/get/aboutFirmware): Can't get object: " << e.what();
|
||||
resultJson.clear();
|
||||
rep.status = http::server::internal_server_error;
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
|
||||
@@ -269,6 +299,7 @@ public:
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
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);
|
||||
@@ -277,26 +308,26 @@ public:
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
std::stringstream ss;
|
||||
ss.str(std::string(req.payload.begin(), req.payload.end()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(ss, pt);
|
||||
|
||||
api->setQosSettings(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());
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
api->setQosSettings(reqJson);
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["settings"] = api->loadSettings();
|
||||
} 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", "error": )" + api_driver::buildEscapedString(e.what()) + "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
}));
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/buclnb", 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);
|
||||
@@ -306,25 +337,26 @@ public:
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
std::stringstream ss;
|
||||
ss.str(std::string(req.payload.begin(), req.payload.end()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(ss, pt);
|
||||
|
||||
api->setBucLnbSettings(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());
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
api->setBucLnbSettings(reqJson);
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["settings"] = api->loadSettings();
|
||||
} catch (std::exception& e) {
|
||||
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());
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
}));
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/dpdi", 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);
|
||||
@@ -333,25 +365,24 @@ public:
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
std::stringstream ss;
|
||||
ss.str(std::string(req.payload.begin(), req.payload.end()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(ss, pt);
|
||||
|
||||
api->setDpdiSettings(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());
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
api->setDpdiSettings(reqJson);
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["settings"] = api->loadSettings();
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/dpdi): Can't set DPDI 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());
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
#endif
|
||||
|
||||
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") {
|
||||
@@ -361,26 +392,25 @@ public:
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
std::stringstream ss;
|
||||
ss.str(std::string(req.payload.begin(), req.payload.end()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(ss, pt);
|
||||
|
||||
api->setRxTxSettings(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());
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
api->setRxTxSettings(reqJson);
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["settings"] = api->loadSettings();
|
||||
} 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", "error": )" + api_driver::buildEscapedString(e.what()) + "}";
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
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);
|
||||
@@ -389,25 +419,54 @@ public:
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
std::stringstream ss;
|
||||
ss.str(std::string(req.payload.begin(), req.payload.end()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(ss, pt);
|
||||
|
||||
api->setNetworkSettings(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());
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
api->setNetworkSettings(reqJson);
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["settings"] = api->loadSettings();
|
||||
} catch (std::exception& e) {
|
||||
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());
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
#ifdef MODEM_IS_TDMA
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/cesPassword", this->auth, http::auth::User::EDIT_SETTINGS, [this](const http::server::Request& req, auto& rep) {
|
||||
if (req.method != "POST") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
auto password = reqJson["password"].get<std::string>();
|
||||
|
||||
this->api->executeInApi([&password](auto& cp) {
|
||||
cp.setNetwork("ces_password", password);
|
||||
});
|
||||
resultJson["status"] = "ok";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/cesPassword): Can't set CES password: " << e.what();
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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") {
|
||||
@@ -458,6 +517,12 @@ public:
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
this->upgradeOrRebootRunning = true;
|
||||
#ifdef MODEM_IS_TDMA
|
||||
if (req.url->params.find("ota") != req.url->params.end()) {
|
||||
@@ -468,10 +533,15 @@ public:
|
||||
#else
|
||||
doTerminalUpgrade();
|
||||
#endif
|
||||
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();
|
||||
resultJson["status"] = "ok";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/doFirmwareUpgrade): Error: " << e.what();
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
|
||||
@@ -490,59 +560,103 @@ public:
|
||||
return;
|
||||
}
|
||||
const auto func = req.url->params["f"];
|
||||
std::string result = R"({"status":"ok"})";
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
resultJson["status"] = "error";
|
||||
if (func == "SetDmaDebug") {
|
||||
if (req.url->params.find("param") == req.url->params.end()) { http::server::stockReply(http::server::bad_request, rep); return; }
|
||||
if (req.url->params.find("value") == req.url->params.end()) { http::server::stockReply(http::server::bad_request, rep); return; }
|
||||
this->api->executeInApi([&](auto sid) {
|
||||
CP_SetDmaDebug(sid, req.url->params["param"].c_str(), req.url->params["value"]);
|
||||
if (req.url->params.find("param") == req.url->params.end()) {
|
||||
rep.status = http::server::bad_request;
|
||||
resultJson["error"] = "missing required adgument: `param`";
|
||||
} else if (req.url->params.find("value") == req.url->params.end()) {
|
||||
rep.status = http::server::bad_request;
|
||||
resultJson["error"] = "missing required adgument: `value`";
|
||||
} else {
|
||||
this->api->executeInApi([&](auto& cp) {
|
||||
cp.setDmaDebug(req.url->params["param"], req.url->params["value"]);
|
||||
});
|
||||
}
|
||||
} else if (func == "GetDmaDebug") {
|
||||
if (req.url->params.find("param") == req.url->params.end()) { http::server::stockReply(http::server::bad_request, rep); return; }
|
||||
this->api->executeInApi([&](auto sid) {
|
||||
std::string tmp{};
|
||||
CP_GetDmaDebug(sid, req.url->params["param"].c_str(), &tmp);
|
||||
result = R"({"status":"ok","result":)";
|
||||
result += api_driver::buildEscapedString(tmp);
|
||||
result += "}";
|
||||
if (req.url->params.find("param") == req.url->params.end()) {
|
||||
rep.status = http::server::bad_request;
|
||||
resultJson["error"] = "missing required adgument: `param`";
|
||||
} else {
|
||||
this->api->executeInApi([&](auto& cp) {
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["result"] = cp.getDmaDebug(req.url->params["param"]);
|
||||
});
|
||||
}
|
||||
} else if (func == "SetNetwork") {
|
||||
if (req.url->params.find("param") == req.url->params.end()) {
|
||||
rep.status = http::server::bad_request;
|
||||
resultJson["error"] = "missing required adgument: `param`";
|
||||
} else if (req.url->params.find("value") == req.url->params.end()) {
|
||||
rep.status = http::server::bad_request;
|
||||
resultJson["error"] = "missing required adgument: `value`";
|
||||
} else {
|
||||
http::server::stockReply(http::server::not_implemented, rep);
|
||||
return;
|
||||
this->api->executeInApi([&](auto& cp) {
|
||||
cp.setNetwork(req.url->params["param"], req.url->params["value"]);
|
||||
});
|
||||
}
|
||||
} else if (func == "GetNetwork") {
|
||||
if (req.url->params.find("param") == req.url->params.end()) {
|
||||
rep.status = http::server::bad_request;
|
||||
resultJson["error"] = "missing required adgument: `param`";
|
||||
} else {
|
||||
this->api->executeInApi([&](auto& cp) {
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["result"] = cp.getNetwork(req.url->params["param"]);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
resultJson["error"] = "function not supported";
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/qos): Can't set QoS settings: " << e.what();
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
#ifdef MODEM_IS_SCPC
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/dev/settings", this->auth, http::auth::User::DEVELOPER, [this](const auto& req, auto& rep) {
|
||||
std::string result;
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::text_plain)});
|
||||
nlohmann::json resultJson;
|
||||
|
||||
try {
|
||||
if (req.method == "GET") {
|
||||
result = R"({"status":"ok","logstat":)";
|
||||
result += this->api->getLoggingStatisticsSettings();
|
||||
result += "}";
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["logstat"] = api->getLoggingStatisticsSettings();
|
||||
} else if (req.method == "POST") {
|
||||
std::stringstream ss;
|
||||
ss.str(std::string(req.payload.begin(), req.payload.end()));
|
||||
boost::property_tree::ptree pt;
|
||||
read_json(ss, pt);
|
||||
auto reqJson = nlohmann::json::parse(std::string(req.payload.begin(), req.payload.end()));
|
||||
api->setLoggingStatisticsSettings(reqJson);
|
||||
|
||||
api->setLoggingStatisticsSettings(pt);
|
||||
|
||||
result = R"({"status":"ok","logstat":)";
|
||||
result += this->api->getLoggingStatisticsSettings();
|
||||
result += "}";
|
||||
resultJson["status"] = "ok";
|
||||
resultJson["logstat"] = api->getLoggingStatisticsSettings();
|
||||
} else {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
return;
|
||||
rep.status = http::server::bad_request;
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = "unsupported request type";
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/qos): Can't set QoS settings: " << e.what();
|
||||
resultJson.clear();
|
||||
resultJson["status"] = "error";
|
||||
resultJson["error"] = e.what();
|
||||
}
|
||||
|
||||
rep.status = http::server::ok;
|
||||
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
|
||||
auto result = resultJson.dump();
|
||||
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
|
||||
}));
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/dev/logs.csv", this->auth, http::auth::User::DEVELOPER, [this](const auto& req, auto& rep) {
|
||||
if (req.method != "GET") {
|
||||
http::server::stockReply(http::server::bad_request, rep);
|
||||
|
@@ -1,7 +1,6 @@
|
||||
#include "terminal_api_driver.h"
|
||||
|
||||
#include <cmath>
|
||||
#include "terminal_api/ControlProtoCInterface.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <shared_mutex>
|
||||
@@ -9,215 +8,11 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#define TIME_NOW() std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count()
|
||||
#include "common/nlohmann/json.hpp"
|
||||
#include "api-driver/daemon.h"
|
||||
|
||||
typedef boost::property_tree::ptree::path_type json_path;
|
||||
|
||||
// пороговое значение сна
|
||||
static constexpr int64_t SLEEP_THRESHOLD = 10;
|
||||
|
||||
static inline void rtrim(std::string &s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||
return !std::isspace(ch);
|
||||
}).base(), s.end());
|
||||
}
|
||||
static inline const char* boolAsStr(bool value) {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
|
||||
class TerminalNetworkSettings {
|
||||
public:
|
||||
std::string managementIp, managementGateway, dataIp, serverName;
|
||||
bool isL2 = true;
|
||||
unsigned int dataMtu = 1500;
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
static constexpr const char* DEFAULT_SERVER_NAME = "RCSM-101";
|
||||
#endif
|
||||
#ifdef MODEM_IS_TDMA
|
||||
static constexpr const char* DEFAULT_SERVER_NAME = "RCSM-101 TDMA";
|
||||
#endif
|
||||
|
||||
TerminalNetworkSettings() = default;
|
||||
TerminalNetworkSettings(const TerminalNetworkSettings& src) = default;
|
||||
~TerminalNetworkSettings() = default;
|
||||
|
||||
TerminalNetworkSettings& operator= (const TerminalNetworkSettings& src) = default;
|
||||
|
||||
void loadDefaults() {
|
||||
managementIp = "0.0.0.0";
|
||||
managementGateway = "";
|
||||
isL2 = true;
|
||||
dataIp = "0.0.0.0";
|
||||
dataMtu = 1500;
|
||||
serverName = DEFAULT_SERVER_NAME;
|
||||
}
|
||||
};
|
||||
|
||||
class TerminalDeviceState {
|
||||
public:
|
||||
double adrv_temp{}, pl_temp{}, zynq_temp{};
|
||||
|
||||
#ifdef MODEM_IS_TDMA
|
||||
DOWNLOAD_STATUS otaStatus{}; // Downloading Status
|
||||
unsigned int otaPercent{}; // % downloaded data
|
||||
std::string otaImage{}; // Name of downloading image file
|
||||
#endif
|
||||
|
||||
modulator_state mod{};
|
||||
demodulator_state demod{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
debug_metrics debug{};
|
||||
CinC_state cinc{};
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
class TerminalFirmwareVersion {
|
||||
public:
|
||||
std::string version, modemId, modemSn, macMang, macData;
|
||||
|
||||
TerminalFirmwareVersion() = default;
|
||||
TerminalFirmwareVersion(const TerminalFirmwareVersion& src) = default;
|
||||
~TerminalFirmwareVersion() = default;
|
||||
|
||||
TerminalFirmwareVersion& operator= (const TerminalFirmwareVersion& src) = default;
|
||||
};
|
||||
|
||||
static std::ostream& operator<<(std::ostream& out, CP_Result result) {
|
||||
switch (result) {
|
||||
case OK: out << "OK"; break;
|
||||
case TIMEOUT: out << "TIMEOUT"; break;
|
||||
case ERROR: out << "ERROR"; break;
|
||||
case ABORT: out << "ABORT"; break;
|
||||
case BUSY: out << "BUSY"; break;
|
||||
default:
|
||||
out << static_cast<int>(result);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string makeTimepointFromMillis(int64_t unix_time_ms) {
|
||||
// Преобразуем миллисекунды в микросекунды для std::chrono
|
||||
auto time_point = std::chrono::time_point<std::chrono::system_clock,
|
||||
std::chrono::microseconds>(std::chrono::microseconds(unix_time_ms * 1000));
|
||||
|
||||
auto tp = std::chrono::system_clock::to_time_t(time_point);
|
||||
tm* t = std::localtime(&tp);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << std::put_time(t, "%Y-%m-%d %H:%M:%S");
|
||||
auto ms = (unix_time_ms % 1000);
|
||||
ss << '.' << std::setw(3) << std::setfill('0') << ms;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
class api_driver::StatisticsLogger {
|
||||
public:
|
||||
StatisticsLogger(): timeStart(TIME_NOW()) {}
|
||||
|
||||
int64_t timeStart;
|
||||
|
||||
bool logEn = false;
|
||||
std::atomic<int> logPeriodMs = 1000;
|
||||
std::atomic<int> maxAgeMs = 10000;
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {"en": bool, "logPeriodMs": int, ""}
|
||||
*/
|
||||
std::string getSettings() {
|
||||
std::lock_guard _lock(mutex);
|
||||
std::stringstream res;
|
||||
res << "{\"en\":" << boolAsStr(this->logEn);
|
||||
res << ",\"logPeriodMs\":" << logPeriodMs;
|
||||
res << ",\"maxAgeMs\":" << maxAgeMs;
|
||||
res << '}';
|
||||
return res.str();
|
||||
}
|
||||
void setSettings(boost::property_tree::ptree &pt) {
|
||||
const bool newEn = pt.get<bool>("en");
|
||||
const int newInterval = pt.get<int>("logPeriodMs");
|
||||
const int newMaxAgeMs = pt.get<int>("maxAgeMs");
|
||||
|
||||
std::lock_guard _lock(this->mutex);
|
||||
this->logPeriodMs = newInterval;
|
||||
this->maxAgeMs = newMaxAgeMs;
|
||||
|
||||
if (newEn != this->logEn) {
|
||||
if (newEn) {
|
||||
this->logFile.open("/tmp/weblog-statistics.csv", std::ios::out);
|
||||
if (this->logFile.is_open()) {
|
||||
const auto* header = "timestamp\tcnt ok\tcnt bad\tfine freq dem\tcrs freq dem\tcrs freq compensator\tcrs time est\tfine time est\tmax level corr\tcurrent delay\tSNR\tcurrent modcod\tfine freq compensator\tind freq grb\tind freq tochn\tind filt adapt\tfilter corr cinc\tcorr cnt\tRSS\tcor erl\tcor lat\tgc gain\tpower pl rx\n";
|
||||
this->logFile.write(header, static_cast<std::streamsize>(strlen(header)));
|
||||
this->logEn = true;
|
||||
this->timeStart = TIME_NOW();
|
||||
}
|
||||
} else {
|
||||
if (this->logFile.is_open()) {
|
||||
this->logFile.close();
|
||||
}
|
||||
this->logEn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Записать значение в "базу данных". Метку при этом вставлять не нужно, она будет вставлена автоматически.
|
||||
* @param item
|
||||
*/
|
||||
void putItem(const debug_metrics& item) {
|
||||
std::lock_guard _lock(this->mutex);
|
||||
if (!logEn) return;
|
||||
if (this->logFile.is_open()) {
|
||||
std::stringstream res;
|
||||
res << makeTimepointFromMillis(TIME_NOW()) << '\t';
|
||||
res << item.cnt_ok << '\t';
|
||||
res << item.cnt_bad << '\t';
|
||||
res << item.fine_freq_dem << '\t';
|
||||
res << item.crs_freq_dem << '\t';
|
||||
res << item.crs_freq_compensator << '\t';
|
||||
res << item.crs_time_est << '\t';
|
||||
res << item.fine_time_est << '\t';
|
||||
res << item.max_level_corr << '\t';
|
||||
res << item.current_delay << '\t';
|
||||
res << item.SNR << '\t';
|
||||
res << item.current_modcod << '\t';
|
||||
res << item.fine_freq_compensator << '\t';
|
||||
res << item.ind_freq_grb << '\t';
|
||||
res << item.ind_freq_tochn << '\t';
|
||||
res << item.ind_filt_adapt << '\t';
|
||||
res << item.filter_corr_cinc << '\t';
|
||||
res << item.corr_cnt << '\t';
|
||||
res << item.RSS << '\t';
|
||||
res << item.cor_erl << '\t';
|
||||
res << item.cor_lat << '\t';
|
||||
res << item.gc_gain << '\t';
|
||||
res << item.power_pl_rx << '\n';
|
||||
|
||||
const auto out = res.str();
|
||||
this->logFile.write(out.c_str(), static_cast<std::streamsize>(out.length()));
|
||||
this->logFile.flush();
|
||||
}
|
||||
}
|
||||
|
||||
// void collectExpiredItems();
|
||||
|
||||
// void resetLogs() {
|
||||
// std::lock_guard _lock(mutex);
|
||||
// logs.clear();
|
||||
// }
|
||||
|
||||
~StatisticsLogger() = default;
|
||||
private:
|
||||
// std::pmr::deque<LogItem> logs;
|
||||
std::fstream logFile{};
|
||||
std::shared_mutex mutex;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
api_driver::ApiDriver::ApiDriver() = default;
|
||||
|
||||
@@ -241,18 +36,6 @@ std::string api_driver::buildEscapedString(const std::string& source) {
|
||||
return "\"" + str.substr(start_pos, end_pos - start_pos + 1) + "\"";
|
||||
}
|
||||
|
||||
static void writeDouble(std::ostream& out, double value, int prec = 2) {
|
||||
if (std::isnan(value) || std::isinf(value)) {
|
||||
out << "\"nan\"";
|
||||
} else {
|
||||
out << std::fixed << std::setprecision(prec) << value;
|
||||
}
|
||||
}
|
||||
|
||||
double translateCoordinates(uint8_t deg, uint8_t min) {
|
||||
return static_cast<double>(deg) + static_cast<double>(min) / 60;
|
||||
}
|
||||
|
||||
std::tuple<uint8_t, uint8_t> translateCoordinates(double abs) {
|
||||
auto deg = static_cast<uint8_t>(abs);
|
||||
double min_double = (abs - deg) * 60;
|
||||
@@ -261,130 +44,19 @@ std::tuple<uint8_t, uint8_t> translateCoordinates(double abs) {
|
||||
}
|
||||
|
||||
|
||||
std::string api_driver::ApiDriver::loadTerminalState() const {
|
||||
nlohmann::json api_driver::ApiDriver::loadTerminalState() const {
|
||||
if (daemon == nullptr) {
|
||||
return R"({"error": "api daemon not started!"})";
|
||||
}
|
||||
std::stringstream result;
|
||||
|
||||
result << "{\n\"initState\":" << buildEscapedString(daemon->getDeviceInitState());
|
||||
result << ",\n\"testState\":" << boolAsStr(daemon->isTest());
|
||||
obj::TerminalState state;
|
||||
daemon->getState(state);
|
||||
obj::TerminalDeviceState devState;
|
||||
daemon->getDeviceState(devState);
|
||||
|
||||
auto state = daemon->getState();
|
||||
#ifdef MODEM_IS_SCPC
|
||||
const bool isCinC = this->daemon->getIsCinC();
|
||||
#endif
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << ",\"isCinC\":" << boolAsStr(isCinC);
|
||||
#endif
|
||||
|
||||
// формируем структуру для TX
|
||||
result << ",\n\"tx.state\":" << boolAsStr(state.mod.is_tx_on);
|
||||
result << ",\"tx.modcod\":" << state.mod.modcod;
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << ",\"tx.snr\":"; writeDouble(result, state.mod.snr_remote);
|
||||
|
||||
if (state.mod.is_short) { result << R"(,"tx.frameSizeNormal":false)"; }
|
||||
else { result << R"(,"tx.frameSizeNormal":true)"; }
|
||||
|
||||
if (state.mod.is_pilots) { result << R"(,"tx.isPilots":true)"; }
|
||||
else { result << R"(,"tx.isPilots":false)"; }
|
||||
#else
|
||||
{
|
||||
modulator_settings modSet{};
|
||||
daemon->getSettings(&modSet, nullptr, nullptr, nullptr);
|
||||
result << ",\"tx.centerFreq\":"; writeDouble(result, modSet.central_freq_in_kGz);
|
||||
result << ",\"tx.symSpeed\":"; writeDouble(result, (static_cast<double>(modSet.baudrate) / 1000.0));
|
||||
}
|
||||
#endif
|
||||
result << ",\"tx.speedOnTxKbit\":"; writeDouble(result, static_cast<double>(state.mod.speed_in_bytes_tx) / 128.0);
|
||||
result << ",\"tx.speedOnIifKbit\":"; writeDouble(result, (static_cast<double>(state.mod.speed_in_bytes_tx_iface) / 128.0));
|
||||
|
||||
// формируем структуру для RX
|
||||
result << ",\n\"rx.state\":" << boolAsStr(state.demod.locks.sym_sync_lock && state.demod.locks.freq_lock && state.demod.locks.afc_lock && state.demod.locks.pkt_sync);
|
||||
result << ",\"rx.sym_sync_lock\":" << boolAsStr(state.demod.locks.sym_sync_lock);
|
||||
result << ",\"rx.freq_search_lock\":" << boolAsStr(state.demod.locks.freq_lock);
|
||||
result << ",\"rx.afc_lock\":" << boolAsStr(state.demod.locks.afc_lock);
|
||||
result << ",\"rx.pkt_sync\":" << boolAsStr(state.demod.locks.pkt_sync);
|
||||
|
||||
result << ",\"rx.snr\":"; writeDouble(result, state.demod.snr);
|
||||
result << ",\"rx.rssi\":"; writeDouble(result, state.demod.rssi);
|
||||
result << ",\"rx.modcod\":" << state.demod.modcod;
|
||||
|
||||
if (state.demod.is_short) {
|
||||
result << R"(,"rx.frameSizeNormal":false)";
|
||||
} else {
|
||||
result << R"(,"rx.frameSizeNormal":true)";
|
||||
}
|
||||
|
||||
if (state.demod.is_pilots) {
|
||||
result << R"(,"rx.isPilots":true)";
|
||||
} else {
|
||||
result << R"(,"rx.isPilots":false)";
|
||||
}
|
||||
|
||||
result << ",\n\"rx.symError\":"; writeDouble(result, state.demod.sym_err);
|
||||
result << ",\"rx.freqErr\":"; writeDouble(result, state.demod.crs_freq_err);
|
||||
result << ",\"rx.freqErrAcc\":"; writeDouble(result, state.demod.fine_freq_err);
|
||||
result << ",\"rx.inputSignalLevel\":"; writeDouble(result, state.demod.if_overload);
|
||||
result << ",\"rx.pllError\":"; writeDouble(result, state.demod.afc_err);
|
||||
result << ",\"rx.speedOnRxKbit\":"; writeDouble(result, static_cast<double>(state.demod.speed_in_bytes_rx) / 128.0);
|
||||
result << ",\"rx.speedOnIifKbit\":"; writeDouble(result, static_cast<double>(state.demod.speed_in_bytes_rx_iface) / 128.0);
|
||||
result << ",\"rx.packetsOk\":" << state.demod.packet_ok_cnt;
|
||||
result << ",\"rx.packetsBad\":" << state.demod.packet_bad_cnt;
|
||||
result << ",\"rx.packetsDummy\":" << state.demod.dummy_cnt;
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
// формируем структуру для CinC
|
||||
if (isCinC) {
|
||||
if (state.mod.is_tx_on) {
|
||||
if (state.cinc.carrier_lock) {
|
||||
result << R"(,"cinc.correlator":true)";
|
||||
} else {
|
||||
result << R"(,"cinc.correlator":false)";
|
||||
}
|
||||
} else {
|
||||
result << R"(,"cinc.correlator":null)";
|
||||
}
|
||||
|
||||
result << ",\n\"cinc.occ\":"; writeDouble(result, state.cinc.ratio_signal_signal, 3);
|
||||
result << ",\"cinc.correlatorFails\":" << state.cinc.cnt_bad_lock;
|
||||
result << ",\"cinc.freqErr\":" << state.cinc.freq_error_offset;
|
||||
result << ",\"cinc.freqErrAcc\":" << state.cinc.freq_fine_estimate;
|
||||
result << ",\"cinc.channelDelay\":" << state.cinc.delay_dpdi;
|
||||
} else {
|
||||
result << R"(,"cinc.correlator":null)";
|
||||
}
|
||||
#endif
|
||||
|
||||
// структура температур девайса
|
||||
result << ",\n\"device.adrv\":"; writeDouble(result, state.adrv_temp, 1);
|
||||
result << ",\"device.fpga\":"; writeDouble(result, state.pl_temp, 1);
|
||||
result << ",\"device.zynq\":"; writeDouble(result, state.zynq_temp, 1);
|
||||
#ifdef MODEM_IS_TDMA
|
||||
if (state.otaImage.empty()) {
|
||||
result << R"(,
|
||||
"device.upgradeStatus":"Нет обновлений","device.upgradePercent":0,"device.upgradeImage":"")";
|
||||
} else {
|
||||
switch (state.otaStatus) {
|
||||
case NORM_RX_OBJECT_NEW_API: result << ",\n" R"("device.upgradeStatus": "Начало загрузки")"; break;
|
||||
case NORM_RX_OBJECT_INFO_API: result << ",\n" R"("device.upgradeStatus": "Получено имя образа")"; break;
|
||||
case NORM_RX_OBJECT_UPDATED_API: result << ",\n" R"("device.upgradeStatus": "Загружается")"; break;
|
||||
case NORM_RX_OBJECT_COMPLETED_API: result << ",\n" R"("device.upgradeStatus": "Загрузка завершена")"; break;
|
||||
case NORM_RX_OBJECT_ABORTED_API: result << ",\n" R"("device.upgradeStatus": "Загрузка прервана")"; break;
|
||||
default: result << ",\n" R"("device.upgradeStatus": "?")";
|
||||
|
||||
}
|
||||
result << ",\"device.upgradePercent\":" << state.otaPercent;
|
||||
result << ",\"device.upgradeImage\":" << buildEscapedString(state.otaImage);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
result << "}";
|
||||
|
||||
return result.str();
|
||||
auto res = state.asJson();
|
||||
res["device"] = devState.asJson();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,387 +64,114 @@ 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 {
|
||||
nlohmann::json api_driver::ApiDriver::loadSettings() const {
|
||||
if (daemon == nullptr) {
|
||||
return R"({"error": "api daemon not started!"})";
|
||||
}
|
||||
|
||||
modulator_settings modSettings{};
|
||||
demodulator_settings demodSettings{};
|
||||
buc_lnb_settings bucLnb{};
|
||||
TerminalNetworkSettings network;
|
||||
DPDI_parmeters dpdiSettings{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
ACM_parameters_serv_ acmSettings{};
|
||||
daemon->getSettings(&modSettings, &demodSettings, &acmSettings, &dpdiSettings, &bucLnb);
|
||||
#else
|
||||
daemon->getSettings(&modSettings, &demodSettings, &dpdiSettings, &bucLnb);
|
||||
nlohmann::json res = daemon->getSettingsRxTx().asJson();
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
res["qos"] = (daemon->getQosSettings().asJson());
|
||||
#endif
|
||||
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 << ",\"txIsTestInput\":" << boolAsStr(modSettings.is_test_data);
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
res["network"] = (daemon->getNetworkSettings().asJson());
|
||||
#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);
|
||||
|
||||
#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 << ",\"txIsPilots\":" << boolAsStr((modSettings.modcod_tx & 1) != 0);
|
||||
|
||||
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\"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);
|
||||
#endif
|
||||
|
||||
result << ",\n\"dpdiIsPositional\":" << boolAsStr(!dpdiSettings.is_delay_window);
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << ",\"dpdiSearchBandwidth\":" << dpdiSettings.freq_offset; // полоса поиска в кГц
|
||||
#endif
|
||||
result << ",\"dpdiPositionStationLatitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.latitude_station_grad, dpdiSettings.latitude_station_minute), 6);
|
||||
result << ",\"dpdiPositionStationLongitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_station_grad, dpdiSettings.longitude_station_minute), 6);
|
||||
result << ",\"dpdiPositionSatelliteLongitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_sattelite_grad, dpdiSettings.longitude_sattelite_minute), 6);
|
||||
#ifdef MODEM_IS_SCPC
|
||||
result << ",\"dpdiDelayMin\":" << dpdiSettings.min_delay;
|
||||
result << ",\"dpdiDelayMax\":" << dpdiSettings.max_delay;
|
||||
#else
|
||||
result << ",\"dpdiDelay\":" << dpdiSettings.max_delay;
|
||||
#endif
|
||||
|
||||
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 << ",\"bucPowering\":24"; break;
|
||||
#ifdef MODEM_IS_SCPC
|
||||
case voltage_buc::_48V: result << ",\"bucPowering\":48"; break;
|
||||
#endif
|
||||
case voltage_buc::DISABLE:
|
||||
default: result << ",\"bucPowering\":0";
|
||||
return res;
|
||||
}
|
||||
|
||||
result << ",\"lnbRefClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_lnb);
|
||||
switch (bucLnb.lnb) {
|
||||
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 << ",\"lnbPowering\":0";
|
||||
}
|
||||
|
||||
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\"qosEnabled\":" << boolAsStr(qosEnabled);
|
||||
result << ",\"qosProfile\":" << qosClasses;
|
||||
|
||||
// сеть
|
||||
result << "\n,\"netManagementIp\":" << buildEscapedString(network.managementIp);
|
||||
result << ",\"netIsL2\":" << boolAsStr(network.isL2);
|
||||
result << ",\"netManagementGateway\":" << buildEscapedString(network.managementGateway);
|
||||
result << ",\"netDataIp\":" << buildEscapedString(network.dataIp);
|
||||
result << ",\"netDataMtu\":" << network.dataMtu;
|
||||
result << ",\"netServerName\":" << buildEscapedString(network.serverName);
|
||||
|
||||
result << "}";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
std::string api_driver::ApiDriver::loadFirmwareVersion() const {
|
||||
nlohmann::json api_driver::ApiDriver::loadFirmwareVersion() const {
|
||||
if (daemon == nullptr) {
|
||||
return R"({"error": "api daemon not started!"})";
|
||||
}
|
||||
|
||||
std::stringstream result;
|
||||
auto firmware = daemon->getFirmware();
|
||||
result << "{\n\"fw.version\":" << buildEscapedString(firmware.version);
|
||||
result << ",\"fw.modemId\":" << buildEscapedString(firmware.modemId);
|
||||
result << ",\"fw.modemSn\":" << buildEscapedString(firmware.modemSn);
|
||||
result << ",\"fw.macMang\":" << buildEscapedString(firmware.macMang);
|
||||
result << ",\"fw.macData\":" << buildEscapedString(firmware.macData);
|
||||
result << "\n}";
|
||||
return result.str();
|
||||
return daemon->getFirmware().asJson();
|
||||
}
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
static uint32_t buildModcodFromPt(const boost::property_tree::ptree& pt, const std::string& name, bool isShortFrame, bool isPilots = false) {
|
||||
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;
|
||||
void api_driver::ApiDriver::setRxTxSettings(const nlohmann::json& data) {
|
||||
auto rxtx = daemon->getSettingsRxTx();
|
||||
rxtx.updateMainSettings(data);
|
||||
|
||||
std::lock_guard _lapi(this->daemon->cpApiMutex);
|
||||
this->daemon->cp.setDmaDebug("begin_save_config", "");
|
||||
rxtx.storeMainSettings(this->daemon->cp);
|
||||
this->daemon->cp.setDmaDebug("save_config", "");
|
||||
rxtx.updateCallback(this->daemon->cp);
|
||||
{
|
||||
daemon->setSettingsRxTx(rxtx);
|
||||
}
|
||||
}
|
||||
_index++;
|
||||
|
||||
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
void api_driver::ApiDriver::setDpdiSettings(const nlohmann::json& data) {
|
||||
auto rxtx = daemon->getSettingsRxTx();
|
||||
rxtx.updateDpdiSettings(data);
|
||||
|
||||
std::lock_guard _lapi(this->daemon->cpApiMutex);
|
||||
this->daemon->cp.setDmaDebug("begin_save_config", "");
|
||||
rxtx.storeDpdiSettings(this->daemon->cp);
|
||||
this->daemon->cp.setDmaDebug("save_config", "");
|
||||
rxtx.updateCallback(this->daemon->cp);
|
||||
{
|
||||
daemon->setSettingsRxTx(rxtx);
|
||||
}
|
||||
return (modcod << 2)| (isShortFrame ? 2 : 0) | (isPilots ? 1 : 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, nullptr);
|
||||
#endif
|
||||
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
void api_driver::ApiDriver::setBucLnbSettings(const nlohmann::json& data) {
|
||||
auto rxtx = daemon->getSettingsRxTx();
|
||||
rxtx.updateBuclnbSettings(data);
|
||||
|
||||
// для модулятора
|
||||
#ifdef MODEM_IS_SCPC
|
||||
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<unsigned int>("txGoldan");
|
||||
#endif
|
||||
mod.attenuation = pt.get<double>("txAttenuation");
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
const bool acmIsShortFrame = !pt.get<bool>("txFrameSizeNormal");
|
||||
const bool acmIsPilots = pt.get<bool>("txIsPilots");
|
||||
mod.modcod_tx = buildModcodFromPt(pt, "dvbCcm", acmIsShortFrame, acmIsPilots);
|
||||
#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
|
||||
demod.gold_seq_is_active = pt.get<unsigned int>("rxGoldan");
|
||||
#endif
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
// ACM
|
||||
acm.period_pack_acm = pt.get<uint32_t>("dvbServicePacketPeriod");
|
||||
acm.enable_acm = pt.get<bool>("dvbIsAcm");
|
||||
#ifdef MODEM_IS_SCPC
|
||||
acm.min_modcod_acm = buildModcodFromPt(pt, "dvbAcmMin", acmIsShortFrame, acmIsPilots);
|
||||
acm.max_modcod_acm = buildModcodFromPt(pt, "dvbAcmMax", acmIsShortFrame, acmIsPilots);
|
||||
#else
|
||||
acm.min_modcod_acm = buildModcodFromPt(pt, "dvbAcmMin", acmIsShortFrame);
|
||||
acm.max_modcod_acm = buildModcodFromPt(pt, "dvbAcmMax", acmIsShortFrame);
|
||||
#endif
|
||||
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
|
||||
daemon->setSettingsRxTx(mod, demod);
|
||||
#endif
|
||||
std::lock_guard _lapi(this->daemon->cpApiMutex);
|
||||
this->daemon->cp.setDmaDebug("begin_save_config", "");
|
||||
rxtx.storeBuclnbSettings(this->daemon->cp);
|
||||
this->daemon->cp.setDmaDebug("save_config", "");
|
||||
rxtx.updateCallback(this->daemon->cp);
|
||||
{
|
||||
daemon->setSettingsRxTx(rxtx);
|
||||
}
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::setDpdiSettings(boost::property_tree::ptree &pt) {
|
||||
DPDI_parmeters s{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
this->daemon->getSettings(nullptr, nullptr, nullptr, &s, nullptr);
|
||||
#else
|
||||
this->daemon->getSettings(nullptr, nullptr, &s, nullptr);
|
||||
#endif
|
||||
|
||||
s.is_delay_window = !pt.get<bool>("dpdiIsPositional");
|
||||
#ifdef MODEM_IS_SCPC
|
||||
s.freq_offset = pt.get<uint32_t>("dpdiSearchBandwidth");
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
void api_driver::ApiDriver::setQosSettings(const nlohmann::json& data) {
|
||||
auto qos = daemon->getQosSettings();
|
||||
qos.updateFromJson(data);
|
||||
|
||||
std::lock_guard _lapi(this->daemon->cpApiMutex);
|
||||
this->daemon->cp.setDmaDebug("begin_save_config", "");
|
||||
qos.store(this->daemon->cp);
|
||||
this->daemon->cp.setDmaDebug("save_config", "");
|
||||
qos.updateCallback(this->daemon->cp);
|
||||
{
|
||||
daemon->setQosSettings(qos);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
auto ctmp = translateCoordinates(pt.get<double>("dpdiPositionStationLatitude"));
|
||||
s.latitude_station_grad = std::get<0>(ctmp);
|
||||
s.latitude_station_minute = std::get<1>(ctmp);
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
void api_driver::ApiDriver::setNetworkSettings(const nlohmann::json& data) {
|
||||
auto net = daemon->getNetworkSettings();
|
||||
net.updateFromJson(data);
|
||||
|
||||
ctmp = translateCoordinates(pt.get<double>("dpdiPositionStationLongitude"));
|
||||
s.longitude_station_grad = std::get<0>(ctmp);
|
||||
s.longitude_station_minute = std::get<1>(ctmp);
|
||||
|
||||
ctmp = translateCoordinates(pt.get<double>("dpdiPositionSatelliteLongitude"));
|
||||
s.longitude_sattelite_grad = std::get<0>(ctmp);
|
||||
s.longitude_sattelite_minute = std::get<1>(ctmp);
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
s.min_delay = pt.get<uint32_t>("dpdiDelayMin");
|
||||
s.max_delay = pt.get<uint32_t>("dpdiDelayMax");
|
||||
#else
|
||||
s.min_delay = 0;
|
||||
s.max_delay = pt.get<uint32_t>("dpdiDelay");
|
||||
std::lock_guard _lapi(this->daemon->cpApiMutex);
|
||||
this->daemon->cp.setDmaDebug("begin_save_config", "");
|
||||
net.store(this->daemon->cp);
|
||||
this->daemon->cp.setDmaDebug("save_config", "");
|
||||
net.updateCallback(this->daemon->cp);
|
||||
{
|
||||
daemon->setNetworkSettings(net);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
this->daemon->setSettingsDpdi(s);
|
||||
}
|
||||
|
||||
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, nullptr, &s);
|
||||
#endif
|
||||
|
||||
auto tmp = pt.get<int>("bucPowering");
|
||||
switch (tmp) {
|
||||
case 24: s.buc = voltage_buc::_24V; break;
|
||||
#ifdef MODEM_IS_SCPC
|
||||
case 48: s.buc = voltage_buc::_48V; break;
|
||||
#endif
|
||||
case 0:
|
||||
default:
|
||||
s.buc = voltage_buc::DISABLE;
|
||||
}
|
||||
s.is_ref_10MHz_buc = pt.get<bool>("bucRefClk10M");
|
||||
|
||||
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>("srvRefClk10M");
|
||||
s.is_save_current_state = pt.get<bool>("bucLnbAutoStart");
|
||||
|
||||
this->daemon->setSettingsBucLnb(s);
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::setQosSettings(boost::property_tree::ptree &pt) {
|
||||
bool enabled = pt.get<bool>("en");
|
||||
pt.erase("en");
|
||||
|
||||
std::ostringstream oss;
|
||||
write_json(oss, pt);
|
||||
|
||||
this->daemon->setQosSettings(enabled, oss.str());
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::setNetworkSettings(boost::property_tree::ptree &pt) {
|
||||
TerminalNetworkSettings s;
|
||||
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");
|
||||
s.serverName = pt.get<std::string>("netServerName");
|
||||
|
||||
daemon->setNetworkSettings(s);
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::resetDefaultSettings() {
|
||||
daemon->resetDefaultSettings();
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::executeInApi(const std::function<void(TSID sid)>& callback) {
|
||||
void api_driver::ApiDriver::executeInApi(const std::function<void(proxy::CpProxy&)>& callback) {
|
||||
try {
|
||||
std::lock_guard lock(this->daemon->cpApiMutex);
|
||||
callback(this->daemon->sid);
|
||||
callback(this->daemon->cp);
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "ApiDriver::executeInApi(): failed to exec with error: " << e.what();
|
||||
}
|
||||
@@ -780,17 +179,19 @@ void api_driver::ApiDriver::executeInApi(const std::function<void(TSID sid)>& ca
|
||||
|
||||
#ifdef MODEM_IS_TDMA
|
||||
std::string api_driver::ApiDriver::getOtaFileLocation() const {
|
||||
return daemon->getState().otaImage;
|
||||
obj::TerminalDeviceState ds;
|
||||
daemon->getDeviceState(ds);
|
||||
return ds.fUpgradeImage;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
std::string api_driver::ApiDriver::getLoggingStatisticsSettings() {
|
||||
nlohmann::json api_driver::ApiDriver::getLoggingStatisticsSettings() {
|
||||
return this->daemon->statsLogs.getSettings();
|
||||
}
|
||||
|
||||
void api_driver::ApiDriver::setLoggingStatisticsSettings(boost::property_tree::ptree &pt) {
|
||||
this->daemon->statsLogs.setSettings(pt);
|
||||
void api_driver::ApiDriver::setLoggingStatisticsSettings(const nlohmann::json& data) {
|
||||
this->daemon->statsLogs.setSettings(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -1,11 +1,12 @@
|
||||
#ifndef TERMINAL_API_DRIVER_H
|
||||
#define TERMINAL_API_DRIVER_H
|
||||
|
||||
#include "api-driver/stricts-enable.h"
|
||||
#include "api-driver/proxy.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <terminal_api/ControlProtoCInterface.h>
|
||||
|
||||
#include "common/nlohmann/json.hpp"
|
||||
|
||||
namespace api_driver {
|
||||
constexpr int CACHE_STATISTICS_UPDATE_MS = 500; ///< время обновления кеша статистики модулятора/демодулятора
|
||||
@@ -13,7 +14,6 @@ namespace api_driver {
|
||||
constexpr int CACHE_SETTINGS_UPDATE_MS = 5000;
|
||||
constexpr int CACHE_QOS_UPDATE_MS = 5000;
|
||||
|
||||
class StatisticsLogger;
|
||||
class TerminalApiDaemon;
|
||||
|
||||
/**
|
||||
@@ -30,50 +30,56 @@ namespace api_driver {
|
||||
|
||||
/**
|
||||
* Запросить общее состояние терминала
|
||||
* @return {"txState":false,"rxState":false,"rx.sym_sync_lock":false,"rx.freq_search_lock":false,"rx.afc_lock":false,"rx.pkt_sync":false}
|
||||
*/
|
||||
std::string loadTerminalState() const;
|
||||
nlohmann::json loadTerminalState() const;
|
||||
|
||||
/**
|
||||
* Сбросить статистику пакетов
|
||||
*/
|
||||
void resetPacketStatistics() const;
|
||||
|
||||
std::string loadSettings() const;
|
||||
nlohmann::json loadSettings() const;
|
||||
|
||||
std::string loadFirmwareVersion() const;
|
||||
nlohmann::json loadFirmwareVersion() const;
|
||||
|
||||
/**
|
||||
* Установить настройки RX/TX, readback можно получить используя loadTerminalState
|
||||
*/
|
||||
void setRxTxSettings(boost::property_tree::ptree &pt);
|
||||
|
||||
void setRxTxSettings(const nlohmann::json& data);
|
||||
|
||||
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
|
||||
/**
|
||||
* Установить настройки DPDI, readback можно получить используя loadTerminalState.
|
||||
* @note Для TDMA и SCPC модемов эти настройки доступны
|
||||
*/
|
||||
void setDpdiSettings(boost::property_tree::ptree &pt);
|
||||
void setDpdiSettings(const nlohmann::json& data);
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
|
||||
/**
|
||||
* Установить настройки BUC и LNB, readback можно получить используя loadTerminalState.
|
||||
*/
|
||||
void setBucLnbSettings(boost::property_tree::ptree &pt);
|
||||
void setBucLnbSettings(const nlohmann::json& data);
|
||||
#endif
|
||||
|
||||
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
/**
|
||||
* Установить настройки QoS, readback можно получить используя loadTerminalState.
|
||||
*/
|
||||
void setQosSettings(boost::property_tree::ptree &pt);
|
||||
void setQosSettings(const nlohmann::json& data);
|
||||
#endif
|
||||
|
||||
void setNetworkSettings(boost::property_tree::ptree &pt);
|
||||
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
void setNetworkSettings(const nlohmann::json& data);
|
||||
#endif
|
||||
|
||||
void resetDefaultSettings();
|
||||
|
||||
void executeInApi(const std::function<void(TSID sid)> &callback);
|
||||
void executeInApi(const std::function<void(proxy::CpProxy&)> &callback);
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
std::string getLoggingStatisticsSettings();
|
||||
void setLoggingStatisticsSettings(boost::property_tree::ptree &pt);
|
||||
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
|
||||
nlohmann::json getLoggingStatisticsSettings();
|
||||
void setLoggingStatisticsSettings(const nlohmann::json& data);
|
||||
|
||||
/**
|
||||
* Получить статистику в формате json. Выход будет дописан в вектор
|
||||
@@ -90,8 +96,6 @@ namespace api_driver {
|
||||
std::string getOtaFileLocation() const;
|
||||
#endif
|
||||
|
||||
static std::string loadSysInfo();
|
||||
|
||||
~ApiDriver();
|
||||
|
||||
private:
|
||||
|
@@ -160,7 +160,7 @@
|
||||
<h3>Параметры передачи</h3>
|
||||
<label>
|
||||
<span>Центральная частота, КГц</span>
|
||||
<input type="text" v-model.lazy="paramRxtx.txCentralFreq" @change="e => paramRxtx.txCentralFreq = inputFormatNumber(inputFormatNumber(e.target.value, {min:950000,max:6000000,step:0.01}), {min:950000,max:6000000,step:0.01})"/>
|
||||
<input type="text" v-model.lazy="paramRxtx.txCentralFreq" @change="e => paramRxtx.txCentralFreq = inputFormatNumber(inputFormatNumber(e.target.value, {min:100000,max:6000000,step:0.01}), {min:100000,max:6000000,step:0.01})"/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Символьная скорость, Бод</span>
|
||||
@@ -169,12 +169,12 @@
|
||||
<label>
|
||||
<span>Roll-off</span>
|
||||
<select v-model="paramRxtx.txRolloff">
|
||||
<option :value="2">0.02</option>
|
||||
<option :value="5">0.05</option>
|
||||
<option :value="10">0.10</option>
|
||||
<option :value="15">0.15</option>
|
||||
<option :value="20">0.20</option>
|
||||
<option :value="25">0.25</option>
|
||||
<option :value="20">0.02</option>
|
||||
<option :value="50">0.05</option>
|
||||
<option :value="100">0.10</option>
|
||||
<option :value="150">0.15</option>
|
||||
<option :value="200">0.20</option>
|
||||
<option :value="250">0.25</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
@@ -274,7 +274,7 @@
|
||||
</label>
|
||||
<label><span>Минимальное ослабление, дБ</span><input type="number" v-model="paramRxtx.aupcMinAttenuation" max="10" step="0.1"/></label>
|
||||
<label><span>Максимальное ослабление, дБ</span><input type="number" v-model="paramRxtx.aupcMaxAttenuation" max="10" step="0.1"/></label>
|
||||
<label><span>Требуемое ОСШ</span><input type="number" v-model="paramRxtx.aupcRequiredSnr" max="10" step="0.01"/></label>
|
||||
<label><span>Требуемое ОСШ</span><input type="number" v-model="paramRxtx.aupcRequiredSnr" max="30" step="0.01"/></label>
|
||||
</div>
|
||||
<div class="settings-set-container">
|
||||
<h3>Настройки приемника</h3>
|
||||
@@ -295,7 +295,7 @@
|
||||
</label>
|
||||
<label>
|
||||
<span>Центральная частота, КГц</span>
|
||||
<input type="text" v-model.lazy="paramRxtx.rxCentralFreq" @change="e => paramRxtx.rxCentralFreq = inputFormatNumber(inputFormatNumber(e.target.value, {min:950000,max:6000000,step:0.01}), {min:950000,max:6000000,step:0.01})"/>
|
||||
<input type="text" v-model.lazy="paramRxtx.rxCentralFreq" @change="e => paramRxtx.rxCentralFreq = inputFormatNumber(inputFormatNumber(e.target.value, {min:100000,max:6000000,step:0.01}), {min:100000,max:6000000,step:0.01})"/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Символьная скорость, Бод</span>
|
||||
@@ -304,12 +304,12 @@
|
||||
<label>
|
||||
<span>Roll-off</span>
|
||||
<select v-model="paramRxtx.rxRolloff">
|
||||
<option :value="2">0.02</option>
|
||||
<option :value="5">0.05</option>
|
||||
<option :value="10">0.10</option>
|
||||
<option :value="15">0.15</option>
|
||||
<option :value="20">0.20</option>
|
||||
<option :value="25">0.25</option>
|
||||
<option :value="20">0.02</option>
|
||||
<option :value="50">0.05</option>
|
||||
<option :value="100">0.10</option>
|
||||
<option :value="150">0.15</option>
|
||||
<option :value="200">0.20</option>
|
||||
<option :value="250">0.25</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
@@ -326,19 +326,19 @@
|
||||
<div class="settings-set-container" v-show="paramRxtx.isCinC">
|
||||
<label>
|
||||
<span>Метод расчета задержки</span>
|
||||
<select v-model="paramDpdi.dpdiIsPositional">
|
||||
<select v-model="paramDpdi.isPositional">
|
||||
<option :value="true">Позиционированием</option>
|
||||
<option :value="false">Окном задержки</option>
|
||||
</select>
|
||||
</label>
|
||||
<label><span>Полоса поиска, КГц ±</span><input type="number" v-model="paramDpdi.dpdiSearchBandwidth" max="100" step="1"/></label>
|
||||
<h2 v-show="paramDpdi.dpdiIsPositional === true">Настройки позиционирования</h2>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === true"><span>Широта станции</span><input type="number" v-model="paramDpdi.dpdiPositionStationLatitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === true"><span>Долгота станции</span><input type="number" v-model="paramDpdi.dpdiPositionStationLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === true"><span>Подспутниковая точка</span><input type="number" v-model="paramDpdi.dpdiPositionSatelliteLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<h2 v-show="paramDpdi.dpdiIsPositional === false">Задержка до спутника</h2>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === false"><span>от, мс</span><input type="number" v-model="paramDpdi.dpdiDelayMin" max="400" step="0.1"/></label>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === false"><span>до, мс</span><input type="number" v-model="paramDpdi.dpdiDelayMax" max="400" step="0.1"/></label>
|
||||
<label><span>Полоса поиска, КГц ±</span><input type="number" v-model="paramDpdi.searchBandwidth" max="100" step="1"/></label>
|
||||
<h2 v-show="paramDpdi.isPositional === true">Настройки позиционирования</h2>
|
||||
<label v-show="paramDpdi.isPositional === true"><span>Широта станции</span><input type="number" v-model="paramDpdi.positionStationLatitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.isPositional === true"><span>Долгота станции</span><input type="number" v-model="paramDpdi.positionStationLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.isPositional === true"><span>Подспутниковая точка</span><input type="number" v-model="paramDpdi.positionSatelliteLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<h2 v-show="paramDpdi.isPositional === false">Задержка до спутника</h2>
|
||||
<label v-show="paramDpdi.isPositional === false"><span>от, мс</span><input type="number" v-model="paramDpdi.delayMin" max="400" step="0.1"/></label>
|
||||
<label v-show="paramDpdi.isPositional === false"><span>до, мс</span><input type="number" v-model="paramDpdi.delayMax" max="400" step="0.1"/></label>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitDpdi()" v-show="paramRxtx.isCinC">Сохранить <span class="submit-spinner" v-show="submitStatus.dpdi"></span></button>
|
||||
<h2>Настройки питания и опорного генератора</h2>
|
||||
@@ -489,38 +489,29 @@
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitQoS()">Применить <span class="submit-spinner" v-show="submitStatusQos"></span></button>
|
||||
|
||||
<h2>Настройки TCP-акселерации</h2>
|
||||
<div class="settings-set-container">
|
||||
<label>
|
||||
<span>Активировать акселерацию</span>
|
||||
<span class="toggle-input"><input type="checkbox" v-model="paramTcpaccel.accelEn" /><span class="slider"></span></span>
|
||||
</label>
|
||||
<label><span>Максимальное количество соединений</span><input type="number" v-model="paramTcpaccel.accelMaxConnections" max="4000" step="1"/></label>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitTcpaccel()">Сохранить <span class="submit-spinner" v-show="submitStatus.tcpaccel"></span></button>
|
||||
</div> <div class="tabs-body-item" v-if="activeTab === 'admin' && settingFetchComplete">
|
||||
<h2>Настройки сети</h2>
|
||||
<div class="settings-set-container">
|
||||
<h3>Настройки интерфейса управления</h3>
|
||||
<label>
|
||||
<span>Интерфейс управления (/24)</span>
|
||||
<input v-model="paramNetwork.netManagementIp" 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]?)$">
|
||||
<span>Интерфейс управления (a.d.d.r/mask)</span>
|
||||
<input v-model="paramNetwork.managementIp" 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]?)\/([0-9]|[1-2][0-9]|3[0-2])$">
|
||||
</label>
|
||||
<label>
|
||||
<span>Режим сети</span>
|
||||
<select v-model="paramNetwork.netIsL2">
|
||||
<select v-model="paramNetwork.isL2">
|
||||
<option :value="false">Маршрутизатор</option>
|
||||
<option :value="true">Коммутатор</option>
|
||||
</select>
|
||||
</label>
|
||||
<label v-show="paramNetwork.netIsL2 === false">
|
||||
<label v-show="paramNetwork.isL2 === false">
|
||||
<span>Интерфейс данных (/24)</span>
|
||||
<input v-model="paramNetwork.netDataIp" 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]?)$">
|
||||
<input v-model="paramNetwork.dataIp" 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>
|
||||
<label><span>MTU интерфейса данных</span><input type="number" v-model="paramNetwork.netDataMtu" min="1500" max="2000" step="1"/></label>
|
||||
<label><span>MTU интерфейса данных</span><input type="number" v-model="paramNetwork.dataMtu" min="1500" max="2000" step="1"/></label>
|
||||
<label>
|
||||
<span>Имя веб-сервера</span>
|
||||
<input v-model="paramNetwork.netServerName" type="text">
|
||||
<input v-model="paramNetwork.serverName" type="text">
|
||||
</label>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitNetwork()">Сохранить <span class="submit-spinner" v-show="submitStatus.network"></span></button>
|
||||
@@ -542,6 +533,8 @@
|
||||
<div>
|
||||
<button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button>
|
||||
</div>
|
||||
<button class="action-button" @click="dumpAllSettings()">Сохранить бекап конфигурации</button>
|
||||
<button class="dangerous-button" @click="restoreAllSettings()">Восстановить бекап конфигурации</button>
|
||||
</div>
|
||||
|
||||
<h2>Обновление ПО</h2>
|
||||
@@ -595,7 +588,6 @@
|
||||
rxtx: false,
|
||||
dpdi: false,
|
||||
buclnb: false,
|
||||
tcpaccel: false,
|
||||
network: false,
|
||||
firmwareUpload: false,
|
||||
firmwareUpgrade: false,
|
||||
@@ -612,7 +604,7 @@
|
||||
txIsTestInput: false,
|
||||
txCentralFreq: 0,
|
||||
txBaudrate: 0,
|
||||
txRolloff: 2,
|
||||
txRolloff: 20,
|
||||
txGoldan: 0,
|
||||
txAttenuation: -40,
|
||||
dvbServicePacketPeriod: 0,
|
||||
@@ -635,17 +627,17 @@
|
||||
rxSpectrumInversion: false,
|
||||
rxCentralFreq: 0,
|
||||
rxBaudrate: 0,
|
||||
rxRolloff: 2,
|
||||
rxRolloff: 20,
|
||||
rxGoldan: 0,
|
||||
},
|
||||
paramDpdi: {
|
||||
dpdiIsPositional: true,
|
||||
dpdiSearchBandwidth: 0,
|
||||
dpdiPositionStationLatitude: -180,
|
||||
dpdiPositionStationLongitude: -180,
|
||||
dpdiPositionSatelliteLongitude: -180,
|
||||
dpdiDelayMin: 0,
|
||||
dpdiDelayMax: 0,
|
||||
isPositional: true,
|
||||
searchBandwidth: 0,
|
||||
positionStationLatitude: -180,
|
||||
positionStationLongitude: -180,
|
||||
positionSatelliteLongitude: -180,
|
||||
delayMin: 0,
|
||||
delayMax: 0,
|
||||
},
|
||||
paramBuclnb: {
|
||||
bucRefClk10M: false,
|
||||
@@ -655,16 +647,12 @@
|
||||
srvRefClk10M: false,
|
||||
bucLnbAutoStart: false,
|
||||
},
|
||||
paramTcpaccel: {
|
||||
accelEn: false,
|
||||
accelMaxConnections: 0,
|
||||
},
|
||||
paramNetwork: {
|
||||
netManagementIp: null,
|
||||
netIsL2: false,
|
||||
netDataIp: null,
|
||||
netDataMtu: 1500,
|
||||
netServerName: null,
|
||||
managementIp: null,
|
||||
isL2: false,
|
||||
dataIp: null,
|
||||
dataMtu: 1500,
|
||||
serverName: null,
|
||||
},
|
||||
// ========== include end from 'common/all-params-data.js.j2'
|
||||
|
||||
@@ -841,13 +829,13 @@
|
||||
if (this.submitStatus.dpdi) { return }
|
||||
|
||||
let query = {
|
||||
"dpdiIsPositional": this.paramDpdi.dpdiIsPositional,
|
||||
"dpdiSearchBandwidth": this.paramDpdi.dpdiSearchBandwidth,
|
||||
"dpdiPositionStationLatitude": this.paramDpdi.dpdiPositionStationLatitude,
|
||||
"dpdiPositionStationLongitude": this.paramDpdi.dpdiPositionStationLongitude,
|
||||
"dpdiPositionSatelliteLongitude": this.paramDpdi.dpdiPositionSatelliteLongitude,
|
||||
"dpdiDelayMin": this.paramDpdi.dpdiDelayMin,
|
||||
"dpdiDelayMax": this.paramDpdi.dpdiDelayMax,
|
||||
"isPositional": this.paramDpdi.isPositional,
|
||||
"searchBandwidth": this.paramDpdi.searchBandwidth,
|
||||
"positionStationLatitude": this.paramDpdi.positionStationLatitude,
|
||||
"positionStationLongitude": this.paramDpdi.positionStationLongitude,
|
||||
"positionSatelliteLongitude": this.paramDpdi.positionSatelliteLongitude,
|
||||
"delayMin": this.paramDpdi.delayMin,
|
||||
"delayMax": this.paramDpdi.delayMax,
|
||||
}
|
||||
|
||||
this.submitStatus.dpdi = true
|
||||
@@ -875,30 +863,16 @@
|
||||
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
|
||||
.finally(() => { this.submitStatus.buclnb = false })
|
||||
},
|
||||
settingsSubmitTcpaccel() {
|
||||
if (this.submitStatus.tcpaccel) { return }
|
||||
|
||||
let query = {
|
||||
"accelEn": this.paramTcpaccel.accelEn,
|
||||
"accelMaxConnections": this.paramTcpaccel.accelMaxConnections,
|
||||
}
|
||||
|
||||
this.submitStatus.tcpaccel = true
|
||||
fetch('/api/set/tcpaccel', {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.updateTcpaccelSettings(vals) })
|
||||
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
|
||||
.finally(() => { this.submitStatus.tcpaccel = false })
|
||||
},
|
||||
settingsSubmitNetwork() {
|
||||
if (this.submitStatus.network) { return }
|
||||
{ if (!confirm("Применение этих настроек может сделать модем недоступным! Продолжить?")) return }
|
||||
|
||||
let query = {
|
||||
"netManagementIp": this.paramNetwork.netManagementIp,
|
||||
"netIsL2": this.paramNetwork.netIsL2,
|
||||
"netDataIp": this.paramNetwork.netDataIp,
|
||||
"netDataMtu": this.paramNetwork.netDataMtu,
|
||||
"netServerName": this.paramNetwork.netServerName,
|
||||
"managementIp": this.paramNetwork.managementIp,
|
||||
"isL2": this.paramNetwork.isL2,
|
||||
"dataIp": this.paramNetwork.dataIp,
|
||||
"dataMtu": this.paramNetwork.dataMtu,
|
||||
"serverName": this.paramNetwork.serverName,
|
||||
}
|
||||
|
||||
this.submitStatus.network = true
|
||||
@@ -910,70 +884,65 @@
|
||||
|
||||
updateRxtxSettings(vals) {
|
||||
this.submitStatus.rxtx = false
|
||||
this.paramRxtx.isCinC = vals["settings"]["isCinC"]
|
||||
this.paramRxtx.txEn = vals["settings"]["txEn"]
|
||||
this.paramRxtx.txAutoStart = vals["settings"]["txAutoStart"]
|
||||
this.paramRxtx.txModulatorIsTest = vals["settings"]["txModulatorIsTest"]
|
||||
this.paramRxtx.txIsTestInput = vals["settings"]["txIsTestInput"]
|
||||
this.paramRxtx.txCentralFreq = this.inputFormatNumber(vals["settings"]["txCentralFreq"], {min:950000,max:6000000,step:0.01})
|
||||
this.paramRxtx.txBaudrate = this.inputFormatNumber(vals["settings"]["txBaudrate"], {min:200000,max:54000000,})
|
||||
this.paramRxtx.txRolloff = vals["settings"]["txRolloff"]
|
||||
this.paramRxtx.txGoldan = vals["settings"]["txGoldan"]
|
||||
this.paramRxtx.txAttenuation = vals["settings"]["txAttenuation"]
|
||||
this.paramRxtx.dvbServicePacketPeriod = vals["settings"]["dvbServicePacketPeriod"]
|
||||
this.paramRxtx.dvbIsAcm = vals["settings"]["dvbIsAcm"]
|
||||
this.paramRxtx.txFrameSizeNormal = vals["settings"]["txFrameSizeNormal"]
|
||||
this.paramRxtx.txIsPilots = vals["settings"]["txIsPilots"]
|
||||
this.paramRxtx.dvbCcmModulation = vals["settings"]["dvbCcmModulation"]
|
||||
this.paramRxtx.dvbCcmSpeed = vals["settings"]["dvbCcmSpeed"]
|
||||
this.paramRxtx.dvbAcmMinModulation = vals["settings"]["dvbAcmMinModulation"]
|
||||
this.paramRxtx.dvbAcmMinSpeed = vals["settings"]["dvbAcmMinSpeed"]
|
||||
this.paramRxtx.dvbAcmMaxModulation = vals["settings"]["dvbAcmMaxModulation"]
|
||||
this.paramRxtx.dvbAcmMaxSpeed = vals["settings"]["dvbAcmMaxSpeed"]
|
||||
this.paramRxtx.dvbSnrReserve = vals["settings"]["dvbSnrReserve"]
|
||||
this.paramRxtx.aupcEn = vals["settings"]["aupcEn"]
|
||||
this.paramRxtx.aupcMinAttenuation = vals["settings"]["aupcMinAttenuation"]
|
||||
this.paramRxtx.aupcMaxAttenuation = vals["settings"]["aupcMaxAttenuation"]
|
||||
this.paramRxtx.aupcRequiredSnr = vals["settings"]["aupcRequiredSnr"]
|
||||
this.paramRxtx.rxAgcEn = vals["settings"]["rxAgcEn"]
|
||||
this.paramRxtx.rxManualGain = vals["settings"]["rxManualGain"]
|
||||
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxSpectrumInversion"]
|
||||
this.paramRxtx.rxCentralFreq = this.inputFormatNumber(vals["settings"]["rxCentralFreq"], {min:950000,max:6000000,step:0.01})
|
||||
this.paramRxtx.rxBaudrate = this.inputFormatNumber(vals["settings"]["rxBaudrate"], {min:200000,max:54000000,})
|
||||
this.paramRxtx.rxRolloff = vals["settings"]["rxRolloff"]
|
||||
this.paramRxtx.rxGoldan = vals["settings"]["rxGoldan"]
|
||||
this.paramRxtx.isCinC = vals["settings"]["rxtx"]["isCinC"]
|
||||
this.paramRxtx.txEn = vals["settings"]["rxtx"]["txEn"]
|
||||
this.paramRxtx.txAutoStart = vals["settings"]["rxtx"]["txAutoStart"]
|
||||
this.paramRxtx.txModulatorIsTest = vals["settings"]["rxtx"]["txModulatorIsTest"]
|
||||
this.paramRxtx.txIsTestInput = vals["settings"]["rxtx"]["txIsTestInput"]
|
||||
this.paramRxtx.txCentralFreq = this.inputFormatNumber(vals["settings"]["rxtx"]["txCentralFreq"], {min:100000,max:6000000,step:0.01})
|
||||
this.paramRxtx.txBaudrate = this.inputFormatNumber(vals["settings"]["rxtx"]["txBaudrate"], {min:200000,max:54000000,})
|
||||
this.paramRxtx.txRolloff = vals["settings"]["rxtx"]["txRolloff"]
|
||||
this.paramRxtx.txGoldan = vals["settings"]["rxtx"]["txGoldan"]
|
||||
this.paramRxtx.txAttenuation = vals["settings"]["rxtx"]["txAttenuation"]
|
||||
this.paramRxtx.dvbServicePacketPeriod = vals["settings"]["rxtx"]["dvbServicePacketPeriod"]
|
||||
this.paramRxtx.dvbIsAcm = vals["settings"]["rxtx"]["dvbIsAcm"]
|
||||
this.paramRxtx.txFrameSizeNormal = vals["settings"]["rxtx"]["txFrameSizeNormal"]
|
||||
this.paramRxtx.txIsPilots = vals["settings"]["rxtx"]["txIsPilots"]
|
||||
this.paramRxtx.dvbCcmModulation = vals["settings"]["rxtx"]["dvbCcmModulation"]
|
||||
this.paramRxtx.dvbCcmSpeed = vals["settings"]["rxtx"]["dvbCcmSpeed"]
|
||||
this.paramRxtx.dvbAcmMinModulation = vals["settings"]["rxtx"]["dvbAcmMinModulation"]
|
||||
this.paramRxtx.dvbAcmMinSpeed = vals["settings"]["rxtx"]["dvbAcmMinSpeed"]
|
||||
this.paramRxtx.dvbAcmMaxModulation = vals["settings"]["rxtx"]["dvbAcmMaxModulation"]
|
||||
this.paramRxtx.dvbAcmMaxSpeed = vals["settings"]["rxtx"]["dvbAcmMaxSpeed"]
|
||||
this.paramRxtx.dvbSnrReserve = vals["settings"]["rxtx"]["dvbSnrReserve"]
|
||||
this.paramRxtx.aupcEn = vals["settings"]["rxtx"]["aupcEn"]
|
||||
this.paramRxtx.aupcMinAttenuation = vals["settings"]["rxtx"]["aupcMinAttenuation"]
|
||||
this.paramRxtx.aupcMaxAttenuation = vals["settings"]["rxtx"]["aupcMaxAttenuation"]
|
||||
this.paramRxtx.aupcRequiredSnr = vals["settings"]["rxtx"]["aupcRequiredSnr"]
|
||||
this.paramRxtx.rxAgcEn = vals["settings"]["rxtx"]["rxAgcEn"]
|
||||
this.paramRxtx.rxManualGain = vals["settings"]["rxtx"]["rxManualGain"]
|
||||
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxtx"]["rxSpectrumInversion"]
|
||||
this.paramRxtx.rxCentralFreq = this.inputFormatNumber(vals["settings"]["rxtx"]["rxCentralFreq"], {min:100000,max:6000000,step:0.01})
|
||||
this.paramRxtx.rxBaudrate = this.inputFormatNumber(vals["settings"]["rxtx"]["rxBaudrate"], {min:200000,max:54000000,})
|
||||
this.paramRxtx.rxRolloff = vals["settings"]["rxtx"]["rxRolloff"]
|
||||
this.paramRxtx.rxGoldan = vals["settings"]["rxtx"]["rxGoldan"]
|
||||
},
|
||||
updateDpdiSettings(vals) {
|
||||
this.submitStatus.dpdi = false
|
||||
this.paramDpdi.dpdiIsPositional = vals["settings"]["dpdiIsPositional"]
|
||||
this.paramDpdi.dpdiSearchBandwidth = vals["settings"]["dpdiSearchBandwidth"]
|
||||
this.paramDpdi.dpdiPositionStationLatitude = vals["settings"]["dpdiPositionStationLatitude"]
|
||||
this.paramDpdi.dpdiPositionStationLongitude = vals["settings"]["dpdiPositionStationLongitude"]
|
||||
this.paramDpdi.dpdiPositionSatelliteLongitude = vals["settings"]["dpdiPositionSatelliteLongitude"]
|
||||
this.paramDpdi.dpdiDelayMin = vals["settings"]["dpdiDelayMin"]
|
||||
this.paramDpdi.dpdiDelayMax = vals["settings"]["dpdiDelayMax"]
|
||||
this.paramDpdi.isPositional = vals["settings"]["dpdi"]["isPositional"]
|
||||
this.paramDpdi.searchBandwidth = vals["settings"]["dpdi"]["searchBandwidth"]
|
||||
this.paramDpdi.positionStationLatitude = vals["settings"]["dpdi"]["positionStationLatitude"]
|
||||
this.paramDpdi.positionStationLongitude = vals["settings"]["dpdi"]["positionStationLongitude"]
|
||||
this.paramDpdi.positionSatelliteLongitude = vals["settings"]["dpdi"]["positionSatelliteLongitude"]
|
||||
this.paramDpdi.delayMin = vals["settings"]["dpdi"]["delayMin"]
|
||||
this.paramDpdi.delayMax = vals["settings"]["dpdi"]["delayMax"]
|
||||
},
|
||||
updateBuclnbSettings(vals) {
|
||||
this.submitStatus.buclnb = false
|
||||
this.paramBuclnb.bucRefClk10M = vals["settings"]["bucRefClk10M"]
|
||||
this.paramBuclnb.bucPowering = vals["settings"]["bucPowering"]
|
||||
this.paramBuclnb.lnbRefClk10M = vals["settings"]["lnbRefClk10M"]
|
||||
this.paramBuclnb.lnbPowering = vals["settings"]["lnbPowering"]
|
||||
this.paramBuclnb.srvRefClk10M = vals["settings"]["srvRefClk10M"]
|
||||
this.paramBuclnb.bucLnbAutoStart = vals["settings"]["bucLnbAutoStart"]
|
||||
},
|
||||
updateTcpaccelSettings(vals) {
|
||||
this.submitStatus.tcpaccel = false
|
||||
this.paramTcpaccel.accelEn = vals["settings"]["accelEn"]
|
||||
this.paramTcpaccel.accelMaxConnections = vals["settings"]["accelMaxConnections"]
|
||||
this.paramBuclnb.bucRefClk10M = vals["settings"]["buclnb"]["bucRefClk10M"]
|
||||
this.paramBuclnb.bucPowering = vals["settings"]["buclnb"]["bucPowering"]
|
||||
this.paramBuclnb.lnbRefClk10M = vals["settings"]["buclnb"]["lnbRefClk10M"]
|
||||
this.paramBuclnb.lnbPowering = vals["settings"]["buclnb"]["lnbPowering"]
|
||||
this.paramBuclnb.srvRefClk10M = vals["settings"]["buclnb"]["srvRefClk10M"]
|
||||
this.paramBuclnb.bucLnbAutoStart = vals["settings"]["buclnb"]["bucLnbAutoStart"]
|
||||
},
|
||||
updateNetworkSettings(vals) {
|
||||
this.submitStatus.network = false
|
||||
this.paramNetwork.netManagementIp = vals["settings"]["netManagementIp"]
|
||||
this.paramNetwork.netIsL2 = vals["settings"]["netIsL2"]
|
||||
this.paramNetwork.netDataIp = vals["settings"]["netDataIp"]
|
||||
this.paramNetwork.netDataMtu = vals["settings"]["netDataMtu"]
|
||||
this.paramNetwork.netServerName = vals["settings"]["netServerName"]
|
||||
this.paramNetwork.managementIp = vals["settings"]["network"]["managementIp"]
|
||||
this.paramNetwork.isL2 = vals["settings"]["network"]["isL2"]
|
||||
this.paramNetwork.dataIp = vals["settings"]["network"]["dataIp"]
|
||||
this.paramNetwork.dataMtu = vals["settings"]["network"]["dataMtu"]
|
||||
this.paramNetwork.serverName = vals["settings"]["network"]["serverName"]
|
||||
},
|
||||
// ========== include end from 'common/all-params-methods.js.j2'
|
||||
|
||||
@@ -998,53 +967,52 @@
|
||||
}
|
||||
|
||||
this.lastUpdateTime = new Date();
|
||||
this.initState = vals["mainState"]["initState"]
|
||||
this.isCinC = vals["mainState"]["isCinC"]
|
||||
this.initState = vals["state"]["initState"]
|
||||
this.testState = vals["state"]["testState"]
|
||||
this.isCinC = vals["state"]["isCinC"]
|
||||
|
||||
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"]
|
||||
this.statRx.state = vals["state"]["rx"]["state"]
|
||||
this.statRx.sym_sync_lock = vals["state"]["rx"]["sym_sync_lock"]
|
||||
this.statRx.freq_search_lock = vals["state"]["rx"]["freq_search_lock"]
|
||||
this.statRx.afc_lock = vals["state"]["rx"]["afc_lock"]
|
||||
this.statRx.pkt_sync = vals["state"]["rx"]["pkt_sync"]
|
||||
this.statRx.snr = Math.round(vals["state"]["rx"]["snr"] * 10) / 10
|
||||
this.statRx.rssi = Math.round(vals["state"]["rx"]["rssi"] * 10) / 10
|
||||
this.statRx.modcod = modcodToStr(vals["state"]["rx"]["modcod"])
|
||||
this.statRx.frameSizeNormal = vals["state"]["rx"]["frameSizeNormal"]
|
||||
this.statRx.isPilots = vals["state"]["rx"]["isPilots"]
|
||||
this.statRx.symError = vals["state"]["rx"]["symError"]
|
||||
this.statRx.freqErr = Math.round(vals["state"]["rx"]["freqErr"] * 100) / 100
|
||||
this.statRx.freqErrAcc = Math.round(vals["state"]["rx"]["freqErrAcc"] * 100) / 100
|
||||
this.statRx.inputSignalLevel = vals["state"]["rx"]["inputSignalLevel"]
|
||||
this.statRx.pllError = Math.round(vals["state"]["rx"]["pllError"] * 100) / 100
|
||||
this.statRx.speedOnRxKbit = Math.round(vals["state"]["rx"]["speedOnRxKbit"] * 100) / 100
|
||||
this.statRx.speedOnIifKbit = Math.round(vals["state"]["rx"]["speedOnIifKbit"] * 100) / 100
|
||||
this.statRx.packetsOk = vals["state"]["rx"]["packetsOk"]
|
||||
this.statRx.packetsBad = vals["state"]["rx"]["packetsBad"]
|
||||
this.statRx.packetsDummy = vals["state"]["rx"]["packetsDummy"]
|
||||
|
||||
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.statTx.state = vals["state"]["tx"]["state"]
|
||||
this.statTx.snr = Math.round(vals["state"]["tx"]["snr"] * 100) / 100
|
||||
this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
|
||||
this.statTx.frameSizeNormal = vals["state"]["tx"]["frameSizeNormal"]
|
||||
this.statTx.isPilots = vals["state"]["tx"]["isPilots"]
|
||||
this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
|
||||
this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
|
||||
|
||||
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"]
|
||||
this.statCinc.occ = vals["state"]["cinc"]["occ"]
|
||||
this.statCinc.correlator = vals["state"]["cinc"]["correlator"]
|
||||
this.statCinc.correlatorFails = vals["state"]["cinc"]["correlatorFails"]
|
||||
this.statCinc.freqErr = Math.round(vals["state"]["cinc"]["freqErr"] * 100) / 100
|
||||
this.statCinc.freqErrAcc = Math.round(vals["state"]["cinc"]["freqErrAcc"] * 100) / 100
|
||||
this.statCinc.channelDelay = vals["state"]["cinc"]["channelDelay"]
|
||||
|
||||
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"]
|
||||
this.statDevice.adrv = vals["state"]["device"]["adrv"]
|
||||
this.statDevice.zynq = vals["state"]["device"]["zynq"]
|
||||
this.statDevice.fpga = vals["state"]["device"]["fpga"]
|
||||
|
||||
// аптайм приходит в секундах, надо преобразовать его в человеко-читаемый вид
|
||||
let uptime = vals["sysinfo"]["uptime"]
|
||||
let uptime = vals["state"]["device"]["uptime"]
|
||||
if (uptime) {
|
||||
let secs = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
let mins = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
@@ -1056,11 +1024,11 @@
|
||||
} 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"]
|
||||
this.statOs.load1 = Math.round(vals["state"]["device"]["load1min"] * 100) / 100
|
||||
this.statOs.load5 = Math.round(vals["state"]["device"]["load5min"] * 100) / 100
|
||||
this.statOs.load15 = Math.round(vals["state"]["device"]["load15min"] * 100) / 100
|
||||
this.statOs.totalram = vals["state"]["device"]["totalram"]
|
||||
this.statOs.freeram = vals["state"]["device"]["freeram"]
|
||||
},
|
||||
|
||||
resetPacketsStatistics() {
|
||||
@@ -1156,15 +1124,17 @@
|
||||
}
|
||||
let query = {
|
||||
"en": this.paramQos.en,
|
||||
"profile": {
|
||||
"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])) }
|
||||
}
|
||||
for (let i = 0; i < this.paramQos.rt1.length; i++) { query.profile.rt1.push(_translateQosClass('rt', this.paramQos.rt1[i])) }
|
||||
for (let i = 0; i < this.paramQos.rt2.length; i++) { query.profile.rt2.push(_translateQosClass('rt', this.paramQos.rt2[i])) }
|
||||
for (let i = 0; i < this.paramQos.rt3.length; i++) { query.profile.rt3.push(_translateQosClass('rt', this.paramQos.rt3[i])) }
|
||||
for (let i = 0; i < this.paramQos.cd.length; i++) { query.profile.cd.push(_translateQosClass('rt', this.paramQos.cd[i])) }
|
||||
|
||||
//console.log(query)
|
||||
fetch('/api/set/qos', {
|
||||
@@ -1185,9 +1155,9 @@
|
||||
|
||||
updateQosSettings(vals) {
|
||||
this.submitStatusQos = false
|
||||
this.paramQos.en = vals["settings"]["qosEnabled"]
|
||||
this.paramQos.en = vals["settings"]["qos"]["en"]
|
||||
|
||||
const qosProfile = vals["settings"]["qosProfile"]
|
||||
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)
|
||||
@@ -1395,6 +1365,133 @@
|
||||
}
|
||||
this.submitStatus.modemReboot = 30
|
||||
fetch('/api/reboot', { method: 'POST' }).then((r) => {})
|
||||
},
|
||||
async restoreAllSettings() {
|
||||
// Порядок применения настроек
|
||||
const settingsApplyOrder = ['qos', 'tcpaccel', 'dpdi', 'rxtx', 'buclnb', 'network'];
|
||||
|
||||
// 1. Чтение JSON-файла, выбранного пользователем
|
||||
const fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = '.json';
|
||||
|
||||
const filePromise = new Promise((resolve, reject) => {
|
||||
fileInput.onchange = e => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) {
|
||||
reject(new Error('Файл не выбран'));
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = event => {
|
||||
try {
|
||||
const jsonData = JSON.parse(event.target.result);
|
||||
resolve(jsonData);
|
||||
} catch (error) {
|
||||
reject(new Error('Ошибка парсинга JSON'));
|
||||
}
|
||||
};
|
||||
reader.onerror = () => reject(new Error('Ошибка чтения файла'));
|
||||
reader.readAsText(file);
|
||||
};
|
||||
fileInput.click();
|
||||
});
|
||||
|
||||
try {
|
||||
const settingsToApply = await filePromise;
|
||||
const errors = [];
|
||||
|
||||
// 2. Перебор групп параметров в заданном порядке
|
||||
for (const groupName of settingsApplyOrder) {
|
||||
if (!settingsToApply.hasOwnProperty(groupName)) {
|
||||
continue; // Пропускаем группы, которых нет в файле
|
||||
}
|
||||
|
||||
const groupSettings = settingsToApply[groupName];
|
||||
if (typeof groupSettings !== 'object' || groupSettings === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2.1. POST-запрос для применения группы параметров
|
||||
const postResponse = await fetch(`/api/set/${groupName}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(groupSettings)
|
||||
});
|
||||
|
||||
if (!postResponse.ok) {
|
||||
throw new Error(`HTTP error ${postResponse.status}`);
|
||||
}
|
||||
|
||||
const postResult = await postResponse.json();
|
||||
if (postResult.status !== 'ok') {
|
||||
throw new Error(`API error: ${postResult.message || 'unknown error'}`);
|
||||
}
|
||||
|
||||
// 2.2. Проверка примененных параметров
|
||||
const getResponse = await fetch('/api/get/settings', { method: 'GET' });
|
||||
if (!getResponse.ok) {
|
||||
throw new Error(`HTTP error ${getResponse.status}`);
|
||||
}
|
||||
|
||||
const fetchSettingsResult = await getResponse.json();
|
||||
if (fetchSettingsResult.status !== 'ok') {
|
||||
throw new Error('Не удалось получить текущие настройки');
|
||||
}
|
||||
|
||||
// Проверка соответствия параметров
|
||||
const appliedGroup = fetchSettingsResult.settings[groupName] || {};
|
||||
const failedSettings = [];
|
||||
|
||||
for (const [key, value] of Object.entries(groupSettings)) {
|
||||
if (appliedGroup[key] !== value) {
|
||||
failedSettings.push(`${key} (ожидалось: ${value}, получено: ${appliedGroup[key]})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (failedSettings.length > 0) {
|
||||
throw new Error(`Не совпадают параметры: ${failedSettings.join(', ')}`);
|
||||
}
|
||||
|
||||
} catch (groupError) {
|
||||
errors.push(`Группа ${groupName}: ${groupError.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Показ ошибок, если они есть
|
||||
if (errors.length > 0) {
|
||||
const errorMessage = errors.join('\n\n') +
|
||||
'\n\nНекоторые настройки могли примениться некорректно.\nСтраница будет перезагружена.';
|
||||
alert(errorMessage);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
alert(`Ошибка при восстановлении настроек: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Перезагрузка страницы
|
||||
location.reload();
|
||||
},
|
||||
async dumpAllSettings() {
|
||||
function downloadAsFile(data, filename) {
|
||||
let a = document.createElement("a");
|
||||
let file = new Blob([data], {type: 'application/json'});
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = filename;
|
||||
a.click();
|
||||
}
|
||||
const response = await fetch('/api/get/settings', { method: 'GET' })
|
||||
if (response.ok) {
|
||||
const jres = await response.json()
|
||||
if (jres["status"] === "ok") {
|
||||
downloadAsFile(JSON.stringify(jres["settings"], null, 4), "backup-" + this.about.firmwareVersion + "-" + this.about.modemSn + ".json")
|
||||
}
|
||||
}
|
||||
}, // ========== include end from 'common/admin-methods.js.j2'
|
||||
|
||||
|
||||
@@ -1406,7 +1503,6 @@
|
||||
this.updateRxtxSettings(vals)
|
||||
this.updateDpdiSettings(vals)
|
||||
this.updateBuclnbSettings(vals)
|
||||
this.updateTcpaccelSettings(vals)
|
||||
this.updateNetworkSettings(vals)
|
||||
this.updateQosSettings(vals)
|
||||
|
||||
@@ -1443,11 +1539,11 @@
|
||||
try {
|
||||
const fr = await fetch("/api/get/aboutFirmware")
|
||||
const d = await fr.json()
|
||||
this.about.firmwareVersion = d["fw.version"]
|
||||
this.about.modemUid = d["fw.modemId"]
|
||||
this.about.modemSn = d["fw.modemSn"]
|
||||
this.about.macManagement = d["fw.macMang"]
|
||||
this.about.macData = d["fw.macData"]
|
||||
this.about.firmwareVersion = d["firmware"]["version"]
|
||||
this.about.modemUid = d["firmware"]["modemId"]
|
||||
this.about.modemSn = d["firmware"]["modemSn"]
|
||||
this.about.macManagement = d["firmware"]["macMang"]
|
||||
this.about.macData = d["firmware"]["macData"]
|
||||
} catch (e) {
|
||||
console.log('Ошибка загрузки версии ПО', e)
|
||||
}
|
||||
|
@@ -58,16 +58,8 @@
|
||||
<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>ОСШ/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.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 }} кбит/с</td></tr>
|
||||
@@ -75,7 +67,6 @@
|
||||
<tr><td colspan="2" style="padding-top: 1em; text-align: center">Статистика пакетов</td></tr>
|
||||
<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>
|
||||
@@ -85,7 +76,6 @@
|
||||
<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 }} кбит/с</td></tr>
|
||||
<tr><th>Инф. скорость на интерфейсе</th><td>{{ statTx.speedOnIifKbit }} кбит/с</td></tr>
|
||||
<tr><th>Центральная частота</th><td>{{ statTx.centerFreq }} кГц</td></tr>
|
||||
@@ -127,6 +117,7 @@
|
||||
<option :value="true">Тест (CW)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label><span>Ослабление, дБ</span><input type="number" v-model="paramRxtx.txAttenuation" min="-40" step="0.25"/></label>
|
||||
<label>
|
||||
<span>Входные данные</span>
|
||||
<select v-model="paramRxtx.txIsTestInput">
|
||||
@@ -135,28 +126,39 @@
|
||||
</select>
|
||||
</label>
|
||||
<h3>Параметры передачи</h3>
|
||||
<label><span>Центральная частота, КГц</span><input type="number" v-model="paramRxtx.txCentralFreq" min="950000" max="6000000" step="0.01"/></label>
|
||||
<label><span>Символьная скорость, Бод</span><input type="number" v-model="paramRxtx.txBaudrate" min="200000" max="54000000"/></label>
|
||||
<label>
|
||||
<span>Центральная частота, КГц</span>
|
||||
<input type="text" v-model.lazy="paramRxtx.txCentralFreq" @change="e => paramRxtx.txCentralFreq = inputFormatNumber(inputFormatNumber(e.target.value, {min:70000,max:6000000,step:100}), {min:70000,max:6000000,step:100})"/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Символьная скорость, Бод</span>
|
||||
<input type="text" v-model.lazy="paramRxtx.txBaudrate" @change="e => paramRxtx.txBaudrate = inputFormatNumber(inputFormatNumber(e.target.value, {min:128000,max:30000000,}), {min:128000,max:30000000,})"/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Roll-off</span>
|
||||
<select v-model="paramRxtx.txRolloff">
|
||||
<option :value="2">0.02</option>
|
||||
<option :value="5">0.05</option>
|
||||
<option :value="10">0.10</option>
|
||||
<option :value="15">0.15</option>
|
||||
<option :value="20">0.20</option>
|
||||
<option :value="25">0.25</option>
|
||||
<option :value="20">0.02</option>
|
||||
<option :value="50">0.05</option>
|
||||
<option :value="100">0.10</option>
|
||||
<option :value="150">0.15</option>
|
||||
<option :value="200">0.20</option>
|
||||
<option :value="250">0.25</option>
|
||||
<option :value="300">0.30</option>
|
||||
<option :value="350">0.35</option>
|
||||
</select>
|
||||
</label>
|
||||
<label><span>Коэф. расширения</span><input type="number" v-model="paramRxtx.txSpreadCoef" min="-1000" max="1000" step="0.01"/></label>
|
||||
<label><span>Коэф. расширения</span><input type="number" v-model="paramRxtx.txSpreadCoef" min="8" max="1024" step="2"/></label>
|
||||
<label><span>Кол-во пакетов на преамбулу</span><input type="number" v-model="paramRxtx.txFieldsDataPreamble" min="1" max="255" step="1"/></label>
|
||||
</div>
|
||||
<div class="settings-set-container">
|
||||
<h3>Авто-регулировка мощности</h3>
|
||||
<label>
|
||||
<span>Номер последовательности Голда</span>
|
||||
<select v-model="paramRxtx.txGoldan">
|
||||
<option :value="0">0</option>
|
||||
<option :value="1">1</option>
|
||||
</select>
|
||||
<span>Авто-регулировка мощности</span>
|
||||
<span class="toggle-input"><input type="checkbox" v-model="paramRxtx.aupcEn" /><span class="slider"></span></span>
|
||||
</label>
|
||||
<label><span>Ослабление, дБ</span><input type="number" v-model="paramRxtx.txAttenuation" min="-40" step="0.25"/></label>
|
||||
<label><span>Минимальное ослабление, дБ</span><input type="number" v-model="paramRxtx.aupcMinAttenuation" max="10" step="0.1"/></label>
|
||||
<label><span>Максимальное ослабление, дБ</span><input type="number" v-model="paramRxtx.aupcMaxAttenuation" max="10" step="0.1"/></label>
|
||||
<label><span>Требуемое ОСШ</span><input type="number" v-model="paramRxtx.aupcRequiredSnr" max="30" step="0.01"/></label>
|
||||
</div>
|
||||
<div class="settings-set-container">
|
||||
<h3>Настройки приемника</h3>
|
||||
@@ -175,27 +177,30 @@
|
||||
<span>Инверсия спектра</span>
|
||||
<span class="toggle-input"><input type="checkbox" v-model="paramRxtx.rxSpectrumInversion" /><span class="slider"></span></span>
|
||||
</label>
|
||||
<label><span>Центральная частота, КГц</span><input type="number" v-model="paramRxtx.rxCentralFreq" min="950000" max="6000000" step="0.01"/></label>
|
||||
<label><span>Символьная скорость, Бод</span><input type="number" v-model="paramRxtx.rxBaudrate" min="200000" max="54000000"/></label>
|
||||
<label>
|
||||
<span>Центральная частота, КГц</span>
|
||||
<input type="text" v-model.lazy="paramRxtx.rxCentralFreq" @change="e => paramRxtx.rxCentralFreq = inputFormatNumber(inputFormatNumber(e.target.value, {min:70000,max:6000000,step:100}), {min:70000,max:6000000,step:100})"/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Символьная скорость, Бод</span>
|
||||
<input type="text" v-model.lazy="paramRxtx.rxBaudrate" @change="e => paramRxtx.rxBaudrate = inputFormatNumber(inputFormatNumber(e.target.value, {min:128000,max:30000000,}), {min:128000,max:30000000,})"/>
|
||||
</label>
|
||||
<label>
|
||||
<span>Roll-off</span>
|
||||
<select v-model="paramRxtx.rxRolloff">
|
||||
<option :value="2">0.02</option>
|
||||
<option :value="5">0.05</option>
|
||||
<option :value="10">0.10</option>
|
||||
<option :value="15">0.15</option>
|
||||
<option :value="20">0.20</option>
|
||||
<option :value="25">0.25</option>
|
||||
</select>
|
||||
</label>
|
||||
<label><span>Коэф. расширения</span><input type="number" v-model="paramRxtx.rxSpreadCoef" min="-1000" max="1000" step="0.01"/></label>
|
||||
<label>
|
||||
<span>Номер последовательности Голда</span>
|
||||
<select v-model="paramRxtx.rxGoldan">
|
||||
<option :value="0">0</option>
|
||||
<option :value="1">1</option>
|
||||
<option :value="20">0.02</option>
|
||||
<option :value="50">0.05</option>
|
||||
<option :value="100">0.10</option>
|
||||
<option :value="150">0.15</option>
|
||||
<option :value="200">0.20</option>
|
||||
<option :value="250">0.25</option>
|
||||
<option :value="300">0.30</option>
|
||||
<option :value="350">0.35</option>
|
||||
</select>
|
||||
</label>
|
||||
<label><span>Коэф. расширения</span><input type="number" v-model="paramRxtx.rxSpreadCoef" min="8" max="1024" step="2"/></label>
|
||||
<label><span>Порог коррелятора</span><input type="number" v-model="paramRxtx.rxFftShift" min="1" max="10" step="0.125"/></label>
|
||||
<label><span>Кол-во пакетов на преамбулу</span><input type="number" v-model="paramRxtx.rxFieldsDataPreamble" min="1" max="255" step="1"/></label>
|
||||
</div>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitRxtx()">Сохранить <span class="submit-spinner" v-show="submitStatus.rxtx"></span></button>
|
||||
@@ -246,6 +251,31 @@
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitBuclnb()">Сохранить <span class="submit-spinner" v-show="submitStatus.buclnb"></span></button>
|
||||
</div> <div class="tabs-body-item" v-if="activeTab === 'admin' && settingFetchComplete">
|
||||
<h2>Настройки сети</h2>
|
||||
<div class="settings-set-container">
|
||||
<h3>Настройки интерфейса управления</h3>
|
||||
<label>
|
||||
<span>Интерфейс управления (a.d.d.r/mask)</span>
|
||||
<input v-model="paramNetwork.managementIp" 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]?)\/([0-9]|[1-2][0-9]|3[0-2])$">
|
||||
</label>
|
||||
<label>
|
||||
<span>Режим сети</span>
|
||||
<select v-model="paramNetwork.isL2">
|
||||
<option :value="false">Маршрутизатор</option>
|
||||
<option :value="true">Коммутатор</option>
|
||||
</select>
|
||||
</label>
|
||||
<label v-show="paramNetwork.isL2 === false">
|
||||
<span>Интерфейс данных (/24)</span>
|
||||
<input v-model="paramNetwork.dataIp" 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>
|
||||
<label><span>MTU интерфейса данных</span><input type="number" v-model="paramNetwork.dataMtu" min="1500" max="2000" step="1"/></label>
|
||||
<label>
|
||||
<span>Имя веб-сервера</span>
|
||||
<input v-model="paramNetwork.serverName" type="text">
|
||||
</label>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitNetwork()">Сохранить <span class="submit-spinner" v-show="submitStatus.network"></span></button>
|
||||
|
||||
<h2>Система</h2>
|
||||
<div class="settings-set-container statistics-container">
|
||||
@@ -264,6 +294,8 @@
|
||||
<div>
|
||||
<button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button>
|
||||
</div>
|
||||
<button class="action-button" @click="dumpAllSettings()">Сохранить бекап конфигурации</button>
|
||||
<button class="dangerous-button" @click="restoreAllSettings()">Восстановить бекап конфигурации</button>
|
||||
</div>
|
||||
|
||||
<h2>Обновление ПО</h2>
|
||||
@@ -316,6 +348,7 @@
|
||||
submitStatus: {
|
||||
rxtx: false,
|
||||
buclnb: false,
|
||||
network: false,
|
||||
firmwareUpload: false,
|
||||
firmwareUpgrade: false,
|
||||
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
|
||||
@@ -327,21 +360,26 @@
|
||||
txEn: false,
|
||||
txAutoStart: false,
|
||||
txModulatorIsTest: false,
|
||||
txIsTestInput: false,
|
||||
txCentralFreq: 950000,
|
||||
txBaudrate: 200000,
|
||||
txRolloff: 2,
|
||||
txSpreadCoef: -1000,
|
||||
txGoldan: 0,
|
||||
txAttenuation: -40,
|
||||
txIsTestInput: false,
|
||||
txCentralFreq: 0,
|
||||
txBaudrate: 0,
|
||||
txRolloff: 20,
|
||||
txSpreadCoef: 8,
|
||||
txFieldsDataPreamble: 1,
|
||||
aupcEn: false,
|
||||
aupcMinAttenuation: 0,
|
||||
aupcMaxAttenuation: 0,
|
||||
aupcRequiredSnr: 0,
|
||||
rxAgcEn: false,
|
||||
rxManualGain: -40,
|
||||
rxSpectrumInversion: false,
|
||||
rxCentralFreq: 950000,
|
||||
rxBaudrate: 200000,
|
||||
rxRolloff: 2,
|
||||
rxSpreadCoef: -1000,
|
||||
rxGoldan: 0,
|
||||
rxCentralFreq: 0,
|
||||
rxBaudrate: 0,
|
||||
rxRolloff: 20,
|
||||
rxSpreadCoef: 8,
|
||||
rxFftShift: 1,
|
||||
rxFieldsDataPreamble: 1,
|
||||
},
|
||||
paramBuclnb: {
|
||||
bucRefClk10M: false,
|
||||
@@ -351,6 +389,13 @@
|
||||
srvRefClk10M: false,
|
||||
bucLnbAutoStart: false,
|
||||
},
|
||||
paramNetwork: {
|
||||
managementIp: null,
|
||||
isL2: false,
|
||||
dataIp: null,
|
||||
dataMtu: 1500,
|
||||
serverName: null,
|
||||
},
|
||||
// ========== include end from 'common/all-params-data.js.j2'
|
||||
|
||||
// ========== include from 'common/monitoring-data.js.j2'
|
||||
@@ -468,21 +513,26 @@
|
||||
"txEn": this.paramRxtx.txEn,
|
||||
"txAutoStart": this.paramRxtx.txAutoStart,
|
||||
"txModulatorIsTest": this.paramRxtx.txModulatorIsTest,
|
||||
"txAttenuation": this.paramRxtx.txAttenuation,
|
||||
"txIsTestInput": this.paramRxtx.txIsTestInput,
|
||||
"txCentralFreq": this.paramRxtx.txCentralFreq,
|
||||
"txBaudrate": this.paramRxtx.txBaudrate,
|
||||
"txCentralFreq": parseFloat(this.paramRxtx.txCentralFreq.replace(/[^0-9,.]/g, '').replace(',', '.')),
|
||||
"txBaudrate": parseFloat(this.paramRxtx.txBaudrate.replace(/[^0-9,.]/g, '').replace(',', '.')),
|
||||
"txRolloff": this.paramRxtx.txRolloff,
|
||||
"txSpreadCoef": this.paramRxtx.txSpreadCoef,
|
||||
"txGoldan": this.paramRxtx.txGoldan,
|
||||
"txAttenuation": this.paramRxtx.txAttenuation,
|
||||
"txFieldsDataPreamble": this.paramRxtx.txFieldsDataPreamble,
|
||||
"aupcEn": this.paramRxtx.aupcEn,
|
||||
"aupcMinAttenuation": this.paramRxtx.aupcMinAttenuation,
|
||||
"aupcMaxAttenuation": this.paramRxtx.aupcMaxAttenuation,
|
||||
"aupcRequiredSnr": this.paramRxtx.aupcRequiredSnr,
|
||||
"rxAgcEn": this.paramRxtx.rxAgcEn,
|
||||
"rxManualGain": this.paramRxtx.rxManualGain,
|
||||
"rxSpectrumInversion": this.paramRxtx.rxSpectrumInversion,
|
||||
"rxCentralFreq": this.paramRxtx.rxCentralFreq,
|
||||
"rxBaudrate": this.paramRxtx.rxBaudrate,
|
||||
"rxCentralFreq": parseFloat(this.paramRxtx.rxCentralFreq.replace(/[^0-9,.]/g, '').replace(',', '.')),
|
||||
"rxBaudrate": parseFloat(this.paramRxtx.rxBaudrate.replace(/[^0-9,.]/g, '').replace(',', '.')),
|
||||
"rxRolloff": this.paramRxtx.rxRolloff,
|
||||
"rxSpreadCoef": this.paramRxtx.rxSpreadCoef,
|
||||
"rxGoldan": this.paramRxtx.rxGoldan,
|
||||
"rxFftShift": this.paramRxtx.rxFftShift,
|
||||
"rxFieldsDataPreamble": this.paramRxtx.rxFieldsDataPreamble,
|
||||
}
|
||||
|
||||
this.submitStatus.rxtx = true
|
||||
@@ -510,36 +560,67 @@
|
||||
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
|
||||
.finally(() => { this.submitStatus.buclnb = false })
|
||||
},
|
||||
settingsSubmitNetwork() {
|
||||
if (this.submitStatus.network) { return }
|
||||
{ if (!confirm("Применение этих настроек может сделать модем недоступным! Продолжить?")) return }
|
||||
|
||||
let query = {
|
||||
"managementIp": this.paramNetwork.managementIp,
|
||||
"isL2": this.paramNetwork.isL2,
|
||||
"dataIp": this.paramNetwork.dataIp,
|
||||
"dataMtu": this.paramNetwork.dataMtu,
|
||||
"serverName": this.paramNetwork.serverName,
|
||||
}
|
||||
|
||||
this.submitStatus.network = true
|
||||
fetch('/api/set/network', {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.updateNetworkSettings(vals) })
|
||||
.catch((reason) => { alert(`Ошибка при применении настроек: ${reason}`) })
|
||||
.finally(() => { this.submitStatus.network = false })
|
||||
},
|
||||
|
||||
updateRxtxSettings(vals) {
|
||||
this.submitStatus.rxtx = false
|
||||
this.paramRxtx.txEn = vals["settings"]["txEn"]
|
||||
this.paramRxtx.txAutoStart = vals["settings"]["txAutoStart"]
|
||||
this.paramRxtx.txModulatorIsTest = vals["settings"]["txModulatorIsTest"]
|
||||
this.paramRxtx.txIsTestInput = vals["settings"]["txIsTestInput"]
|
||||
this.paramRxtx.txCentralFreq = vals["settings"]["txCentralFreq"]
|
||||
this.paramRxtx.txBaudrate = vals["settings"]["txBaudrate"]
|
||||
this.paramRxtx.txRolloff = vals["settings"]["txRolloff"]
|
||||
this.paramRxtx.txSpreadCoef = vals["settings"]["txSpreadCoef"]
|
||||
this.paramRxtx.txGoldan = vals["settings"]["txGoldan"]
|
||||
this.paramRxtx.txAttenuation = vals["settings"]["txAttenuation"]
|
||||
this.paramRxtx.rxAgcEn = vals["settings"]["rxAgcEn"]
|
||||
this.paramRxtx.rxManualGain = vals["settings"]["rxManualGain"]
|
||||
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxSpectrumInversion"]
|
||||
this.paramRxtx.rxCentralFreq = vals["settings"]["rxCentralFreq"]
|
||||
this.paramRxtx.rxBaudrate = vals["settings"]["rxBaudrate"]
|
||||
this.paramRxtx.rxRolloff = vals["settings"]["rxRolloff"]
|
||||
this.paramRxtx.rxSpreadCoef = vals["settings"]["rxSpreadCoef"]
|
||||
this.paramRxtx.rxGoldan = vals["settings"]["rxGoldan"]
|
||||
this.paramRxtx.txEn = vals["settings"]["rxtx"]["txEn"]
|
||||
this.paramRxtx.txAutoStart = vals["settings"]["rxtx"]["txAutoStart"]
|
||||
this.paramRxtx.txModulatorIsTest = vals["settings"]["rxtx"]["txModulatorIsTest"]
|
||||
this.paramRxtx.txAttenuation = vals["settings"]["rxtx"]["txAttenuation"]
|
||||
this.paramRxtx.txIsTestInput = vals["settings"]["rxtx"]["txIsTestInput"]
|
||||
this.paramRxtx.txCentralFreq = this.inputFormatNumber(vals["settings"]["rxtx"]["txCentralFreq"], {min:70000,max:6000000,step:100})
|
||||
this.paramRxtx.txBaudrate = this.inputFormatNumber(vals["settings"]["rxtx"]["txBaudrate"], {min:128000,max:30000000,})
|
||||
this.paramRxtx.txRolloff = vals["settings"]["rxtx"]["txRolloff"]
|
||||
this.paramRxtx.txSpreadCoef = vals["settings"]["rxtx"]["txSpreadCoef"]
|
||||
this.paramRxtx.txFieldsDataPreamble = vals["settings"]["rxtx"]["txFieldsDataPreamble"]
|
||||
this.paramRxtx.aupcEn = vals["settings"]["rxtx"]["aupcEn"]
|
||||
this.paramRxtx.aupcMinAttenuation = vals["settings"]["rxtx"]["aupcMinAttenuation"]
|
||||
this.paramRxtx.aupcMaxAttenuation = vals["settings"]["rxtx"]["aupcMaxAttenuation"]
|
||||
this.paramRxtx.aupcRequiredSnr = vals["settings"]["rxtx"]["aupcRequiredSnr"]
|
||||
this.paramRxtx.rxAgcEn = vals["settings"]["rxtx"]["rxAgcEn"]
|
||||
this.paramRxtx.rxManualGain = vals["settings"]["rxtx"]["rxManualGain"]
|
||||
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxtx"]["rxSpectrumInversion"]
|
||||
this.paramRxtx.rxCentralFreq = this.inputFormatNumber(vals["settings"]["rxtx"]["rxCentralFreq"], {min:70000,max:6000000,step:100})
|
||||
this.paramRxtx.rxBaudrate = this.inputFormatNumber(vals["settings"]["rxtx"]["rxBaudrate"], {min:128000,max:30000000,})
|
||||
this.paramRxtx.rxRolloff = vals["settings"]["rxtx"]["rxRolloff"]
|
||||
this.paramRxtx.rxSpreadCoef = vals["settings"]["rxtx"]["rxSpreadCoef"]
|
||||
this.paramRxtx.rxFftShift = vals["settings"]["rxtx"]["rxFftShift"]
|
||||
this.paramRxtx.rxFieldsDataPreamble = vals["settings"]["rxtx"]["rxFieldsDataPreamble"]
|
||||
},
|
||||
updateBuclnbSettings(vals) {
|
||||
this.submitStatus.buclnb = false
|
||||
this.paramBuclnb.bucRefClk10M = vals["settings"]["bucRefClk10M"]
|
||||
this.paramBuclnb.bucPowering = vals["settings"]["bucPowering"]
|
||||
this.paramBuclnb.lnbRefClk10M = vals["settings"]["lnbRefClk10M"]
|
||||
this.paramBuclnb.lnbPowering = vals["settings"]["lnbPowering"]
|
||||
this.paramBuclnb.srvRefClk10M = vals["settings"]["srvRefClk10M"]
|
||||
this.paramBuclnb.bucLnbAutoStart = vals["settings"]["bucLnbAutoStart"]
|
||||
this.paramBuclnb.bucRefClk10M = vals["settings"]["buclnb"]["bucRefClk10M"]
|
||||
this.paramBuclnb.bucPowering = vals["settings"]["buclnb"]["bucPowering"]
|
||||
this.paramBuclnb.lnbRefClk10M = vals["settings"]["buclnb"]["lnbRefClk10M"]
|
||||
this.paramBuclnb.lnbPowering = vals["settings"]["buclnb"]["lnbPowering"]
|
||||
this.paramBuclnb.srvRefClk10M = vals["settings"]["buclnb"]["srvRefClk10M"]
|
||||
this.paramBuclnb.bucLnbAutoStart = vals["settings"]["buclnb"]["bucLnbAutoStart"]
|
||||
},
|
||||
updateNetworkSettings(vals) {
|
||||
this.submitStatus.network = false
|
||||
this.paramNetwork.managementIp = vals["settings"]["network"]["managementIp"]
|
||||
this.paramNetwork.isL2 = vals["settings"]["network"]["isL2"]
|
||||
this.paramNetwork.dataIp = vals["settings"]["network"]["dataIp"]
|
||||
this.paramNetwork.dataMtu = vals["settings"]["network"]["dataMtu"]
|
||||
this.paramNetwork.serverName = vals["settings"]["network"]["serverName"]
|
||||
},
|
||||
// ========== include end from 'common/all-params-methods.js.j2'
|
||||
|
||||
@@ -564,44 +645,43 @@
|
||||
}
|
||||
|
||||
this.lastUpdateTime = new Date();
|
||||
this.initState = vals["mainState"]["initState"]
|
||||
this.initState = vals["state"]["initState"]
|
||||
this.testState = vals["state"]["testState"]
|
||||
|
||||
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"]
|
||||
this.statRx.state = vals["state"]["rx"]["state"]
|
||||
this.statRx.sym_sync_lock = vals["state"]["rx"]["sym_sync_lock"]
|
||||
this.statRx.freq_search_lock = vals["state"]["rx"]["freq_search_lock"]
|
||||
this.statRx.afc_lock = vals["state"]["rx"]["afc_lock"]
|
||||
this.statRx.pkt_sync = vals["state"]["rx"]["pkt_sync"]
|
||||
this.statRx.snr = Math.round(vals["state"]["rx"]["snr"] * 10) / 10
|
||||
this.statRx.rssi = Math.round(vals["state"]["rx"]["rssi"] * 10) / 10
|
||||
this.statRx.modcod = modcodToStr(vals["state"]["rx"]["modcod"])
|
||||
this.statRx.frameSizeNormal = vals["state"]["rx"]["frameSizeNormal"]
|
||||
this.statRx.isPilots = vals["state"]["rx"]["isPilots"]
|
||||
this.statRx.symError = vals["state"]["rx"]["symError"]
|
||||
this.statRx.freqErr = Math.round(vals["state"]["rx"]["freqErr"] * 100) / 100
|
||||
this.statRx.freqErrAcc = Math.round(vals["state"]["rx"]["freqErrAcc"] * 100) / 100
|
||||
this.statRx.inputSignalLevel = vals["state"]["rx"]["inputSignalLevel"]
|
||||
this.statRx.pllError = Math.round(vals["state"]["rx"]["pllError"] * 100) / 100
|
||||
this.statRx.speedOnRxKbit = Math.round(vals["state"]["rx"]["speedOnRxKbit"] * 100) / 100
|
||||
this.statRx.speedOnIifKbit = Math.round(vals["state"]["rx"]["speedOnIifKbit"] * 100) / 100
|
||||
this.statRx.packetsOk = vals["state"]["rx"]["packetsOk"]
|
||||
this.statRx.packetsBad = vals["state"]["rx"]["packetsBad"]
|
||||
this.statRx.packetsDummy = vals["state"]["rx"]["packetsDummy"]
|
||||
|
||||
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"]
|
||||
this.statTx.state = vals["state"]["tx"]["state"]
|
||||
this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
|
||||
this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
|
||||
this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
|
||||
this.statTx.centerFreq = vals["state"]["tx"]["centerFreq"]
|
||||
this.statTx.symSpeed = vals["state"]["tx"]["symSpeed"]
|
||||
|
||||
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"]
|
||||
this.statDevice.adrv = vals["state"]["device"]["adrv"]
|
||||
this.statDevice.zynq = vals["state"]["device"]["zynq"]
|
||||
this.statDevice.fpga = vals["state"]["device"]["fpga"]
|
||||
|
||||
// аптайм приходит в секундах, надо преобразовать его в человеко-читаемый вид
|
||||
let uptime = vals["sysinfo"]["uptime"]
|
||||
let uptime = vals["state"]["device"]["uptime"]
|
||||
if (uptime) {
|
||||
let secs = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
let mins = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
@@ -613,11 +693,11 @@
|
||||
} 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"]
|
||||
this.statOs.load1 = Math.round(vals["state"]["device"]["load1min"] * 100) / 100
|
||||
this.statOs.load5 = Math.round(vals["state"]["device"]["load5min"] * 100) / 100
|
||||
this.statOs.load15 = Math.round(vals["state"]["device"]["load15min"] * 100) / 100
|
||||
this.statOs.totalram = vals["state"]["device"]["totalram"]
|
||||
this.statOs.freeram = vals["state"]["device"]["freeram"]
|
||||
},
|
||||
|
||||
resetPacketsStatistics() {
|
||||
@@ -696,6 +776,133 @@
|
||||
}
|
||||
this.submitStatus.modemReboot = 30
|
||||
fetch('/api/reboot', { method: 'POST' }).then((r) => {})
|
||||
},
|
||||
async restoreAllSettings() {
|
||||
// Порядок применения настроек
|
||||
const settingsApplyOrder = ['qos', 'tcpaccel', 'dpdi', 'rxtx', 'buclnb', 'network'];
|
||||
|
||||
// 1. Чтение JSON-файла, выбранного пользователем
|
||||
const fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = '.json';
|
||||
|
||||
const filePromise = new Promise((resolve, reject) => {
|
||||
fileInput.onchange = e => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) {
|
||||
reject(new Error('Файл не выбран'));
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = event => {
|
||||
try {
|
||||
const jsonData = JSON.parse(event.target.result);
|
||||
resolve(jsonData);
|
||||
} catch (error) {
|
||||
reject(new Error('Ошибка парсинга JSON'));
|
||||
}
|
||||
};
|
||||
reader.onerror = () => reject(new Error('Ошибка чтения файла'));
|
||||
reader.readAsText(file);
|
||||
};
|
||||
fileInput.click();
|
||||
});
|
||||
|
||||
try {
|
||||
const settingsToApply = await filePromise;
|
||||
const errors = [];
|
||||
|
||||
// 2. Перебор групп параметров в заданном порядке
|
||||
for (const groupName of settingsApplyOrder) {
|
||||
if (!settingsToApply.hasOwnProperty(groupName)) {
|
||||
continue; // Пропускаем группы, которых нет в файле
|
||||
}
|
||||
|
||||
const groupSettings = settingsToApply[groupName];
|
||||
if (typeof groupSettings !== 'object' || groupSettings === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2.1. POST-запрос для применения группы параметров
|
||||
const postResponse = await fetch(`/api/set/${groupName}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(groupSettings)
|
||||
});
|
||||
|
||||
if (!postResponse.ok) {
|
||||
throw new Error(`HTTP error ${postResponse.status}`);
|
||||
}
|
||||
|
||||
const postResult = await postResponse.json();
|
||||
if (postResult.status !== 'ok') {
|
||||
throw new Error(`API error: ${postResult.message || 'unknown error'}`);
|
||||
}
|
||||
|
||||
// 2.2. Проверка примененных параметров
|
||||
const getResponse = await fetch('/api/get/settings', { method: 'GET' });
|
||||
if (!getResponse.ok) {
|
||||
throw new Error(`HTTP error ${getResponse.status}`);
|
||||
}
|
||||
|
||||
const fetchSettingsResult = await getResponse.json();
|
||||
if (fetchSettingsResult.status !== 'ok') {
|
||||
throw new Error('Не удалось получить текущие настройки');
|
||||
}
|
||||
|
||||
// Проверка соответствия параметров
|
||||
const appliedGroup = fetchSettingsResult.settings[groupName] || {};
|
||||
const failedSettings = [];
|
||||
|
||||
for (const [key, value] of Object.entries(groupSettings)) {
|
||||
if (appliedGroup[key] !== value) {
|
||||
failedSettings.push(`${key} (ожидалось: ${value}, получено: ${appliedGroup[key]})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (failedSettings.length > 0) {
|
||||
throw new Error(`Не совпадают параметры: ${failedSettings.join(', ')}`);
|
||||
}
|
||||
|
||||
} catch (groupError) {
|
||||
errors.push(`Группа ${groupName}: ${groupError.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Показ ошибок, если они есть
|
||||
if (errors.length > 0) {
|
||||
const errorMessage = errors.join('\n\n') +
|
||||
'\n\nНекоторые настройки могли примениться некорректно.\nСтраница будет перезагружена.';
|
||||
alert(errorMessage);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
alert(`Ошибка при восстановлении настроек: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Перезагрузка страницы
|
||||
location.reload();
|
||||
},
|
||||
async dumpAllSettings() {
|
||||
function downloadAsFile(data, filename) {
|
||||
let a = document.createElement("a");
|
||||
let file = new Blob([data], {type: 'application/json'});
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = filename;
|
||||
a.click();
|
||||
}
|
||||
const response = await fetch('/api/get/settings', { method: 'GET' })
|
||||
if (response.ok) {
|
||||
const jres = await response.json()
|
||||
if (jres["status"] === "ok") {
|
||||
downloadAsFile(JSON.stringify(jres["settings"], null, 4), "backup-" + this.about.firmwareVersion + "-" + this.about.modemSn + ".json")
|
||||
}
|
||||
}
|
||||
}, // ========== include end from 'common/admin-methods.js.j2'
|
||||
|
||||
|
||||
@@ -706,6 +913,7 @@
|
||||
this.settingFetchComplete = true
|
||||
this.updateRxtxSettings(vals)
|
||||
this.updateBuclnbSettings(vals)
|
||||
this.updateNetworkSettings(vals)
|
||||
|
||||
if ('netServerName' in vals['settings']) {
|
||||
document.getElementsByTagName('title')[0].innerText = vals['settings']['netServerName']
|
||||
@@ -740,11 +948,11 @@
|
||||
try {
|
||||
const fr = await fetch("/api/get/aboutFirmware")
|
||||
const d = await fr.json()
|
||||
this.about.firmwareVersion = d["fw.version"]
|
||||
this.about.modemUid = d["fw.modemId"]
|
||||
this.about.modemSn = d["fw.modemSn"]
|
||||
this.about.macManagement = d["fw.macMang"]
|
||||
this.about.macData = d["fw.macData"]
|
||||
this.about.firmwareVersion = d["firmware"]["version"]
|
||||
this.about.modemUid = d["firmware"]["modemId"]
|
||||
this.about.modemSn = d["firmware"]["modemSn"]
|
||||
this.about.macManagement = d["firmware"]["macMang"]
|
||||
this.about.macData = d["firmware"]["macData"]
|
||||
} catch (e) {
|
||||
console.log('Ошибка загрузки версии ПО', e)
|
||||
}
|
||||
|
@@ -132,6 +132,7 @@
|
||||
<input type="text" v-model.lazy="paramRxtx.txCentralFreq" @change="e => paramRxtx.txCentralFreq = inputFormatNumber(inputFormatNumber(e.target.value, {min:900000,step:0.01}), {min:900000,step:0.01})"/>
|
||||
</label>
|
||||
<label><span>Ослабление, дБ</span><input type="number" v-model="paramRxtx.txAttenuation" min="-90" step="1"/></label>
|
||||
<label><span>Ограничение ослабления</span><input type="number" v-model="paramRxtx.txAttenuationLimit" min="-40" step="0.25"/></label>
|
||||
</div>
|
||||
<div class="settings-set-container">
|
||||
<h3>Настройки приемника</h3>
|
||||
@@ -158,12 +159,12 @@
|
||||
<label>
|
||||
<span>Roll-off</span>
|
||||
<select v-model="paramRxtx.rxRolloff">
|
||||
<option :value="2">0.02</option>
|
||||
<option :value="5">0.05</option>
|
||||
<option :value="10">0.10</option>
|
||||
<option :value="15">0.15</option>
|
||||
<option :value="20">0.20</option>
|
||||
<option :value="25">0.25</option>
|
||||
<option :value="20">0.02</option>
|
||||
<option :value="50">0.05</option>
|
||||
<option :value="100">0.10</option>
|
||||
<option :value="150">0.15</option>
|
||||
<option :value="200">0.20</option>
|
||||
<option :value="250">0.25</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
@@ -173,16 +174,16 @@
|
||||
<div class="settings-set-container">
|
||||
<label>
|
||||
<span>Метод расчета задержки</span>
|
||||
<select v-model="paramDpdi.dpdiIsPositional">
|
||||
<select v-model="paramDpdi.isPositional">
|
||||
<option :value="true">Позиционированием</option>
|
||||
<option :value="false">Окном задержки</option>
|
||||
</select>
|
||||
</label>
|
||||
<h2 v-show="paramDpdi.dpdiIsPositional === true">Настройки позиционирования</h2>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === true"><span>Широта станции</span><input type="number" v-model="paramDpdi.dpdiPositionStationLatitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === true"><span>Долгота станции</span><input type="number" v-model="paramDpdi.dpdiPositionStationLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === true"><span>Подспутниковая точка</span><input type="number" v-model="paramDpdi.dpdiPositionSatelliteLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.dpdiIsPositional === false"><span>Задержка до спутника, мс</span><input type="number" v-model="paramDpdi.dpdiDelay" max="400" step="0.1"/></label>
|
||||
<h2 v-show="paramDpdi.isPositional === true">Настройки позиционирования</h2>
|
||||
<label v-show="paramDpdi.isPositional === true"><span>Широта станции</span><input type="number" v-model="paramDpdi.positionStationLatitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.isPositional === true"><span>Долгота станции</span><input type="number" v-model="paramDpdi.positionStationLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.isPositional === true"><span>Подспутниковая точка</span><input type="number" v-model="paramDpdi.positionSatelliteLongitude" min="-180" max="180" step="1e-06"/></label>
|
||||
<label v-show="paramDpdi.isPositional === false"><span>Задержка до спутника, мс</span><input type="number" v-model="paramDpdi.delay" max="400" step="0.1"/></label>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitDpdi()">Сохранить <span class="submit-spinner" v-show="submitStatus.dpdi"></span></button>
|
||||
<h2>Настройки питания и опорного генератора</h2>
|
||||
@@ -200,6 +201,10 @@
|
||||
<option :value="24">24В</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Частота LO, кГц</span>
|
||||
<input type="text" v-model.lazy="paramBuclnb.bucLoKhz" @change="e => paramBuclnb.bucLoKhz = inputFormatNumber(inputFormatNumber(e.target.value, {max:40000000,step:1}), {max:40000000,step:1})"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="settings-set-container">
|
||||
<h3>Настройки LNB</h3>
|
||||
@@ -216,6 +221,10 @@
|
||||
<option :value="24">24В</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
<span>Частота LO, кГц</span>
|
||||
<input type="text" v-model.lazy="paramBuclnb.lnbLoKhz" @change="e => paramBuclnb.lnbLoKhz = inputFormatNumber(inputFormatNumber(e.target.value, {max:40000000,step:1}), {max:40000000,step:1})"/>
|
||||
</label>
|
||||
</div>
|
||||
<div class="settings-set-container">
|
||||
<h3>Сервисные настройки</h3>
|
||||
@@ -233,18 +242,14 @@
|
||||
</div> <div class="tabs-body-item" v-if="activeTab === 'admin' && settingFetchComplete">
|
||||
<h2>Настройки сети</h2>
|
||||
<div class="settings-set-container">
|
||||
<label>
|
||||
<span>Пароль для входа в сеть ЦЗС</span>
|
||||
<input v-model="paramNetwork.netCesPassword" type="text">
|
||||
</label>
|
||||
<h3>Настройки интерфейса управления</h3>
|
||||
<label>
|
||||
<span>IP Интерфейса управления (/24)</span>
|
||||
<input v-model="paramNetwork.netManagementIp" 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]?)$">
|
||||
<span>Интерфейс управления (a.d.d.r/mask)</span>
|
||||
<input v-model="paramNetwork.managementIp" 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]?)\/([0-9]|[1-2][0-9]|3[0-2])$">
|
||||
</label>
|
||||
<label>
|
||||
<span>Имя веб-сервера</span>
|
||||
<input v-model="paramNetwork.netServerName" type="text">
|
||||
<input v-model="paramNetwork.serverName" type="text">
|
||||
</label>
|
||||
</div>
|
||||
<button class="action-button" @click="settingsSubmitNetwork()">Сохранить <span class="submit-spinner" v-show="submitStatus.network"></span></button>
|
||||
@@ -266,6 +271,16 @@
|
||||
<div>
|
||||
<button class="dangerous-button" onclick="fetch('/api/resetSettings', { method: 'POST' }).then((r) => { window.location.reload(); })">Сбросить модем до заводских настроек</button>
|
||||
</div>
|
||||
<button class="action-button" @click="dumpAllSettings()">Сохранить бекап конфигурации</button>
|
||||
<button class="dangerous-button" @click="restoreAllSettings()">Восстановить бекап конфигурации</button>
|
||||
</div>
|
||||
<h2>Вход в сеть ЦЗС</h2>
|
||||
<div class="settings-set-container statistics-container">
|
||||
<label>
|
||||
<span>Хеш-строка пароля (выдается оператором NMS)</span>
|
||||
<input v-model="cesPasswordValue" type="text">
|
||||
</label>
|
||||
<button class="action-button" @click="settingsPerformSetCesPassword()">Установить пароль<span class="submit-spinner" v-show="submitStatus.cesPassword"></span></button>
|
||||
</div>
|
||||
|
||||
<h2>Обновление ПО</h2>
|
||||
@@ -325,9 +340,11 @@
|
||||
firmwareUpload: false,
|
||||
firmwareUpgrade: false,
|
||||
firmwareUpgradeOta: false,
|
||||
cesPassword: false,
|
||||
// когда модем перезагружается, тут должен быть счетчик. Направление счета - к нулю
|
||||
modemReboot: null
|
||||
},
|
||||
cesPasswordValue: '',
|
||||
|
||||
// ========== include from 'common/all-params-data.js.j2'
|
||||
paramRxtx: {
|
||||
@@ -335,32 +352,34 @@
|
||||
txModulatorIsTest: false,
|
||||
txCentralFreq: 0,
|
||||
txAttenuation: -90,
|
||||
txAttenuationLimit: -40,
|
||||
rxAgcEn: true,
|
||||
rxManualGain: -40,
|
||||
rxSpectrumInversion: false,
|
||||
rxCentralFreq: 0,
|
||||
rxBaudrate: 0,
|
||||
rxRolloff: 2,
|
||||
rxRolloff: 20,
|
||||
},
|
||||
paramBuclnb: {
|
||||
bucRefClk10M: false,
|
||||
bucPowering: 0,
|
||||
bucLoKhz: 0,
|
||||
lnbRefClk10M: false,
|
||||
lnbPowering: 0,
|
||||
lnbLoKhz: 0,
|
||||
srvRefClk10M: false,
|
||||
bucLnbAutoStart: false,
|
||||
},
|
||||
paramDpdi: {
|
||||
dpdiIsPositional: true,
|
||||
dpdiPositionStationLatitude: -180,
|
||||
dpdiPositionStationLongitude: -180,
|
||||
dpdiPositionSatelliteLongitude: -180,
|
||||
dpdiDelay: 0,
|
||||
isPositional: true,
|
||||
positionStationLatitude: -180,
|
||||
positionStationLongitude: -180,
|
||||
positionSatelliteLongitude: -180,
|
||||
delay: 0,
|
||||
},
|
||||
paramNetwork: {
|
||||
netCesPassword: null,
|
||||
netManagementIp: null,
|
||||
netServerName: null,
|
||||
managementIp: null,
|
||||
serverName: null,
|
||||
},
|
||||
// ========== include end from 'common/all-params-data.js.j2'
|
||||
|
||||
@@ -482,6 +501,7 @@
|
||||
"txModulatorIsTest": this.paramRxtx.txModulatorIsTest,
|
||||
"txCentralFreq": parseFloat(this.paramRxtx.txCentralFreq.replace(/[^0-9,.]/g, '').replace(',', '.')),
|
||||
"txAttenuation": this.paramRxtx.txAttenuation,
|
||||
"txAttenuationLimit": this.paramRxtx.txAttenuationLimit,
|
||||
"rxAgcEn": this.paramRxtx.rxAgcEn,
|
||||
"rxManualGain": this.paramRxtx.rxManualGain,
|
||||
"rxSpectrumInversion": this.paramRxtx.rxSpectrumInversion,
|
||||
@@ -503,8 +523,10 @@
|
||||
let query = {
|
||||
"bucRefClk10M": this.paramBuclnb.bucRefClk10M,
|
||||
"bucPowering": this.paramBuclnb.bucPowering,
|
||||
"bucLoKhz": parseFloat(this.paramBuclnb.bucLoKhz.replace(/[^0-9,.]/g, '').replace(',', '.')),
|
||||
"lnbRefClk10M": this.paramBuclnb.lnbRefClk10M,
|
||||
"lnbPowering": this.paramBuclnb.lnbPowering,
|
||||
"lnbLoKhz": parseFloat(this.paramBuclnb.lnbLoKhz.replace(/[^0-9,.]/g, '').replace(',', '.')),
|
||||
"srvRefClk10M": this.paramBuclnb.srvRefClk10M,
|
||||
"bucLnbAutoStart": this.paramBuclnb.bucLnbAutoStart,
|
||||
}
|
||||
@@ -519,11 +541,11 @@
|
||||
if (this.submitStatus.dpdi) { return }
|
||||
|
||||
let query = {
|
||||
"dpdiIsPositional": this.paramDpdi.dpdiIsPositional,
|
||||
"dpdiPositionStationLatitude": this.paramDpdi.dpdiPositionStationLatitude,
|
||||
"dpdiPositionStationLongitude": this.paramDpdi.dpdiPositionStationLongitude,
|
||||
"dpdiPositionSatelliteLongitude": this.paramDpdi.dpdiPositionSatelliteLongitude,
|
||||
"dpdiDelay": this.paramDpdi.dpdiDelay,
|
||||
"isPositional": this.paramDpdi.isPositional,
|
||||
"positionStationLatitude": this.paramDpdi.positionStationLatitude,
|
||||
"positionStationLongitude": this.paramDpdi.positionStationLongitude,
|
||||
"positionSatelliteLongitude": this.paramDpdi.positionSatelliteLongitude,
|
||||
"delay": this.paramDpdi.delay,
|
||||
}
|
||||
|
||||
this.submitStatus.dpdi = true
|
||||
@@ -537,9 +559,8 @@
|
||||
{ if (!confirm("Применение этих настроек может сделать модем недоступным! Продолжить?")) return }
|
||||
|
||||
let query = {
|
||||
"netCesPassword": this.paramNetwork.netCesPassword,
|
||||
"netManagementIp": this.paramNetwork.netManagementIp,
|
||||
"netServerName": this.paramNetwork.netServerName,
|
||||
"managementIp": this.paramNetwork.managementIp,
|
||||
"serverName": this.paramNetwork.serverName,
|
||||
}
|
||||
|
||||
this.submitStatus.network = true
|
||||
@@ -551,39 +572,41 @@
|
||||
|
||||
updateRxtxSettings(vals) {
|
||||
this.submitStatus.rxtx = false
|
||||
this.paramRxtx.txEn = vals["settings"]["txEn"]
|
||||
this.paramRxtx.txModulatorIsTest = vals["settings"]["txModulatorIsTest"]
|
||||
this.paramRxtx.txCentralFreq = this.inputFormatNumber(vals["settings"]["txCentralFreq"], {min:900000,step:0.01})
|
||||
this.paramRxtx.txAttenuation = vals["settings"]["txAttenuation"]
|
||||
this.paramRxtx.rxAgcEn = vals["settings"]["rxAgcEn"]
|
||||
this.paramRxtx.rxManualGain = vals["settings"]["rxManualGain"]
|
||||
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxSpectrumInversion"]
|
||||
this.paramRxtx.rxCentralFreq = this.inputFormatNumber(vals["settings"]["rxCentralFreq"], {min:900000,step:0.01})
|
||||
this.paramRxtx.rxBaudrate = this.inputFormatNumber(vals["settings"]["rxBaudrate"], {min:200000,max:54000000,step:1})
|
||||
this.paramRxtx.rxRolloff = vals["settings"]["rxRolloff"]
|
||||
this.paramRxtx.txEn = vals["settings"]["rxtx"]["txEn"]
|
||||
this.paramRxtx.txModulatorIsTest = vals["settings"]["rxtx"]["txModulatorIsTest"]
|
||||
this.paramRxtx.txCentralFreq = this.inputFormatNumber(vals["settings"]["rxtx"]["txCentralFreq"], {min:900000,step:0.01})
|
||||
this.paramRxtx.txAttenuation = vals["settings"]["rxtx"]["txAttenuation"]
|
||||
this.paramRxtx.txAttenuationLimit = vals["settings"]["rxtx"]["txAttenuationLimit"]
|
||||
this.paramRxtx.rxAgcEn = vals["settings"]["rxtx"]["rxAgcEn"]
|
||||
this.paramRxtx.rxManualGain = vals["settings"]["rxtx"]["rxManualGain"]
|
||||
this.paramRxtx.rxSpectrumInversion = vals["settings"]["rxtx"]["rxSpectrumInversion"]
|
||||
this.paramRxtx.rxCentralFreq = this.inputFormatNumber(vals["settings"]["rxtx"]["rxCentralFreq"], {min:900000,step:0.01})
|
||||
this.paramRxtx.rxBaudrate = this.inputFormatNumber(vals["settings"]["rxtx"]["rxBaudrate"], {min:200000,max:54000000,step:1})
|
||||
this.paramRxtx.rxRolloff = vals["settings"]["rxtx"]["rxRolloff"]
|
||||
},
|
||||
updateBuclnbSettings(vals) {
|
||||
this.submitStatus.buclnb = false
|
||||
this.paramBuclnb.bucRefClk10M = vals["settings"]["bucRefClk10M"]
|
||||
this.paramBuclnb.bucPowering = vals["settings"]["bucPowering"]
|
||||
this.paramBuclnb.lnbRefClk10M = vals["settings"]["lnbRefClk10M"]
|
||||
this.paramBuclnb.lnbPowering = vals["settings"]["lnbPowering"]
|
||||
this.paramBuclnb.srvRefClk10M = vals["settings"]["srvRefClk10M"]
|
||||
this.paramBuclnb.bucLnbAutoStart = vals["settings"]["bucLnbAutoStart"]
|
||||
this.paramBuclnb.bucRefClk10M = vals["settings"]["buclnb"]["bucRefClk10M"]
|
||||
this.paramBuclnb.bucPowering = vals["settings"]["buclnb"]["bucPowering"]
|
||||
this.paramBuclnb.bucLoKhz = this.inputFormatNumber(vals["settings"]["buclnb"]["bucLoKhz"], {max:40000000,step:1})
|
||||
this.paramBuclnb.lnbRefClk10M = vals["settings"]["buclnb"]["lnbRefClk10M"]
|
||||
this.paramBuclnb.lnbPowering = vals["settings"]["buclnb"]["lnbPowering"]
|
||||
this.paramBuclnb.lnbLoKhz = this.inputFormatNumber(vals["settings"]["buclnb"]["lnbLoKhz"], {max:40000000,step:1})
|
||||
this.paramBuclnb.srvRefClk10M = vals["settings"]["buclnb"]["srvRefClk10M"]
|
||||
this.paramBuclnb.bucLnbAutoStart = vals["settings"]["buclnb"]["bucLnbAutoStart"]
|
||||
},
|
||||
updateDpdiSettings(vals) {
|
||||
this.submitStatus.dpdi = false
|
||||
this.paramDpdi.dpdiIsPositional = vals["settings"]["dpdiIsPositional"]
|
||||
this.paramDpdi.dpdiPositionStationLatitude = vals["settings"]["dpdiPositionStationLatitude"]
|
||||
this.paramDpdi.dpdiPositionStationLongitude = vals["settings"]["dpdiPositionStationLongitude"]
|
||||
this.paramDpdi.dpdiPositionSatelliteLongitude = vals["settings"]["dpdiPositionSatelliteLongitude"]
|
||||
this.paramDpdi.dpdiDelay = vals["settings"]["dpdiDelay"]
|
||||
this.paramDpdi.isPositional = vals["settings"]["dpdi"]["isPositional"]
|
||||
this.paramDpdi.positionStationLatitude = vals["settings"]["dpdi"]["positionStationLatitude"]
|
||||
this.paramDpdi.positionStationLongitude = vals["settings"]["dpdi"]["positionStationLongitude"]
|
||||
this.paramDpdi.positionSatelliteLongitude = vals["settings"]["dpdi"]["positionSatelliteLongitude"]
|
||||
this.paramDpdi.delay = vals["settings"]["dpdi"]["delay"]
|
||||
},
|
||||
updateNetworkSettings(vals) {
|
||||
this.submitStatus.network = false
|
||||
this.paramNetwork.netCesPassword = vals["settings"]["netCesPassword"]
|
||||
this.paramNetwork.netManagementIp = vals["settings"]["netManagementIp"]
|
||||
this.paramNetwork.netServerName = vals["settings"]["netServerName"]
|
||||
this.paramNetwork.managementIp = vals["settings"]["network"]["managementIp"]
|
||||
this.paramNetwork.serverName = vals["settings"]["network"]["serverName"]
|
||||
},
|
||||
// ========== include end from 'common/all-params-methods.js.j2'
|
||||
|
||||
@@ -608,47 +631,46 @@
|
||||
}
|
||||
|
||||
this.lastUpdateTime = new Date();
|
||||
this.initState = vals["mainState"]["initState"]
|
||||
this.initState = vals["state"]["initState"]
|
||||
this.testState = vals["state"]["testState"]
|
||||
|
||||
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"]
|
||||
this.statRx.state = vals["state"]["rx"]["state"]
|
||||
this.statRx.sym_sync_lock = vals["state"]["rx"]["sym_sync_lock"]
|
||||
this.statRx.freq_search_lock = vals["state"]["rx"]["freq_search_lock"]
|
||||
this.statRx.afc_lock = vals["state"]["rx"]["afc_lock"]
|
||||
this.statRx.pkt_sync = vals["state"]["rx"]["pkt_sync"]
|
||||
this.statRx.snr = Math.round(vals["state"]["rx"]["snr"] * 10) / 10
|
||||
this.statRx.rssi = Math.round(vals["state"]["rx"]["rssi"] * 10) / 10
|
||||
this.statRx.modcod = modcodToStr(vals["state"]["rx"]["modcod"])
|
||||
this.statRx.frameSizeNormal = vals["state"]["rx"]["frameSizeNormal"]
|
||||
this.statRx.isPilots = vals["state"]["rx"]["isPilots"]
|
||||
this.statRx.symError = vals["state"]["rx"]["symError"]
|
||||
this.statRx.freqErr = Math.round(vals["state"]["rx"]["freqErr"] * 100) / 100
|
||||
this.statRx.freqErrAcc = Math.round(vals["state"]["rx"]["freqErrAcc"] * 100) / 100
|
||||
this.statRx.inputSignalLevel = vals["state"]["rx"]["inputSignalLevel"]
|
||||
this.statRx.pllError = Math.round(vals["state"]["rx"]["pllError"] * 100) / 100
|
||||
this.statRx.speedOnRxKbit = Math.round(vals["state"]["rx"]["speedOnRxKbit"] * 100) / 100
|
||||
this.statRx.speedOnIifKbit = Math.round(vals["state"]["rx"]["speedOnIifKbit"] * 100) / 100
|
||||
this.statRx.packetsOk = vals["state"]["rx"]["packetsOk"]
|
||||
this.statRx.packetsBad = vals["state"]["rx"]["packetsBad"]
|
||||
this.statRx.packetsDummy = vals["state"]["rx"]["packetsDummy"]
|
||||
|
||||
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"]
|
||||
this.statTx.state = vals["state"]["tx"]["state"]
|
||||
this.statTx.modcod = modcodToStr(vals["state"]["tx"]["modcod"])
|
||||
this.statTx.speedOnTxKbit = Math.round(vals["state"]["tx"]["speedOnTxKbit"] * 100) / 100
|
||||
this.statTx.speedOnIifKbit = Math.round(vals["state"]["tx"]["speedOnIifKbit"] * 100) / 100
|
||||
this.statTx.centerFreq = vals["state"]["tx"]["centerFreq"]
|
||||
this.statTx.symSpeed = vals["state"]["tx"]["symSpeed"]
|
||||
|
||||
this.statDevice.adrv = vals["mainState"]["device.adrv"]
|
||||
this.statDevice.zynq = vals["mainState"]["device.zynq"]
|
||||
this.statDevice.fpga = vals["mainState"]["device.fpga"]
|
||||
this.statDevice.upgradeStatus = vals["mainState"]["device.upgradeStatus"]
|
||||
this.statDevice.upgradePercent = vals["mainState"]["device.upgradePercent"]
|
||||
this.statDevice.upgradeImage = vals["mainState"]["device.upgradeImage"]
|
||||
|
||||
this.testState = vals["mainState"]["testState"]
|
||||
this.statDevice.adrv = vals["state"]["device"]["adrv"]
|
||||
this.statDevice.zynq = vals["state"]["device"]["zynq"]
|
||||
this.statDevice.fpga = vals["state"]["device"]["fpga"]
|
||||
this.statDevice.upgradeStatus = vals["state"]["device"]["upgradeStatus"]
|
||||
this.statDevice.upgradePercent = vals["state"]["device"]["upgradePercent"]
|
||||
this.statDevice.upgradeImage = vals["state"]["device"]["upgradeImage"]
|
||||
|
||||
// аптайм приходит в секундах, надо преобразовать его в человеко-читаемый вид
|
||||
let uptime = vals["sysinfo"]["uptime"]
|
||||
let uptime = vals["state"]["device"]["uptime"]
|
||||
if (uptime) {
|
||||
let secs = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
let mins = uptime % 60; uptime = Math.floor(uptime / 60)
|
||||
@@ -660,11 +682,11 @@
|
||||
} 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"]
|
||||
this.statOs.load1 = Math.round(vals["state"]["device"]["load1min"] * 100) / 100
|
||||
this.statOs.load5 = Math.round(vals["state"]["device"]["load5min"] * 100) / 100
|
||||
this.statOs.load15 = Math.round(vals["state"]["device"]["load15min"] * 100) / 100
|
||||
this.statOs.totalram = vals["state"]["device"]["totalram"]
|
||||
this.statOs.freeram = vals["state"]["device"]["freeram"]
|
||||
},
|
||||
|
||||
resetPacketsStatistics() {
|
||||
@@ -746,6 +768,22 @@
|
||||
}
|
||||
this.submitStatus.firmwareUpgradeOta = false
|
||||
},
|
||||
async settingsPerformSetCesPassword() {
|
||||
if (this.submitStatus.cesPassword) { return }
|
||||
this.submitStatus.cesPassword = true
|
||||
try {
|
||||
await fetch('/api/set/cesPassword', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({'password': this.cesPasswordValue})
|
||||
})
|
||||
} catch (e) {
|
||||
console.log("failed to perform set CES password: ", e)
|
||||
}
|
||||
this.submitStatus.cesPassword = false
|
||||
},
|
||||
|
||||
doModemReboot() {
|
||||
if (this.submitStatus.modemReboot !== null) {
|
||||
@@ -753,6 +791,133 @@
|
||||
}
|
||||
this.submitStatus.modemReboot = 30
|
||||
fetch('/api/reboot', { method: 'POST' }).then((r) => {})
|
||||
},
|
||||
async restoreAllSettings() {
|
||||
// Порядок применения настроек
|
||||
const settingsApplyOrder = ['qos', 'tcpaccel', 'dpdi', 'rxtx', 'buclnb', 'network'];
|
||||
|
||||
// 1. Чтение JSON-файла, выбранного пользователем
|
||||
const fileInput = document.createElement('input');
|
||||
fileInput.type = 'file';
|
||||
fileInput.accept = '.json';
|
||||
|
||||
const filePromise = new Promise((resolve, reject) => {
|
||||
fileInput.onchange = e => {
|
||||
const file = e.target.files[0];
|
||||
if (!file) {
|
||||
reject(new Error('Файл не выбран'));
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = event => {
|
||||
try {
|
||||
const jsonData = JSON.parse(event.target.result);
|
||||
resolve(jsonData);
|
||||
} catch (error) {
|
||||
reject(new Error('Ошибка парсинга JSON'));
|
||||
}
|
||||
};
|
||||
reader.onerror = () => reject(new Error('Ошибка чтения файла'));
|
||||
reader.readAsText(file);
|
||||
};
|
||||
fileInput.click();
|
||||
});
|
||||
|
||||
try {
|
||||
const settingsToApply = await filePromise;
|
||||
const errors = [];
|
||||
|
||||
// 2. Перебор групп параметров в заданном порядке
|
||||
for (const groupName of settingsApplyOrder) {
|
||||
if (!settingsToApply.hasOwnProperty(groupName)) {
|
||||
continue; // Пропускаем группы, которых нет в файле
|
||||
}
|
||||
|
||||
const groupSettings = settingsToApply[groupName];
|
||||
if (typeof groupSettings !== 'object' || groupSettings === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// 2.1. POST-запрос для применения группы параметров
|
||||
const postResponse = await fetch(`/api/set/${groupName}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(groupSettings)
|
||||
});
|
||||
|
||||
if (!postResponse.ok) {
|
||||
throw new Error(`HTTP error ${postResponse.status}`);
|
||||
}
|
||||
|
||||
const postResult = await postResponse.json();
|
||||
if (postResult.status !== 'ok') {
|
||||
throw new Error(`API error: ${postResult.message || 'unknown error'}`);
|
||||
}
|
||||
|
||||
// 2.2. Проверка примененных параметров
|
||||
const getResponse = await fetch('/api/get/settings', { method: 'GET' });
|
||||
if (!getResponse.ok) {
|
||||
throw new Error(`HTTP error ${getResponse.status}`);
|
||||
}
|
||||
|
||||
const fetchSettingsResult = await getResponse.json();
|
||||
if (fetchSettingsResult.status !== 'ok') {
|
||||
throw new Error('Не удалось получить текущие настройки');
|
||||
}
|
||||
|
||||
// Проверка соответствия параметров
|
||||
const appliedGroup = fetchSettingsResult.settings[groupName] || {};
|
||||
const failedSettings = [];
|
||||
|
||||
for (const [key, value] of Object.entries(groupSettings)) {
|
||||
if (appliedGroup[key] !== value) {
|
||||
failedSettings.push(`${key} (ожидалось: ${value}, получено: ${appliedGroup[key]})`);
|
||||
}
|
||||
}
|
||||
|
||||
if (failedSettings.length > 0) {
|
||||
throw new Error(`Не совпадают параметры: ${failedSettings.join(', ')}`);
|
||||
}
|
||||
|
||||
} catch (groupError) {
|
||||
errors.push(`Группа ${groupName}: ${groupError.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Показ ошибок, если они есть
|
||||
if (errors.length > 0) {
|
||||
const errorMessage = errors.join('\n\n') +
|
||||
'\n\nНекоторые настройки могли примениться некорректно.\nСтраница будет перезагружена.';
|
||||
alert(errorMessage);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
alert(`Ошибка при восстановлении настроек: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Перезагрузка страницы
|
||||
location.reload();
|
||||
},
|
||||
async dumpAllSettings() {
|
||||
function downloadAsFile(data, filename) {
|
||||
let a = document.createElement("a");
|
||||
let file = new Blob([data], {type: 'application/json'});
|
||||
a.href = URL.createObjectURL(file);
|
||||
a.download = filename;
|
||||
a.click();
|
||||
}
|
||||
const response = await fetch('/api/get/settings', { method: 'GET' })
|
||||
if (response.ok) {
|
||||
const jres = await response.json()
|
||||
if (jres["status"] === "ok") {
|
||||
downloadAsFile(JSON.stringify(jres["settings"], null, 4), "backup-" + this.about.firmwareVersion + "-" + this.about.modemSn + ".json")
|
||||
}
|
||||
}
|
||||
}, // ========== include end from 'common/admin-methods.js.j2'
|
||||
|
||||
|
||||
@@ -799,11 +964,11 @@
|
||||
try {
|
||||
const fr = await fetch("/api/get/aboutFirmware")
|
||||
const d = await fr.json()
|
||||
this.about.firmwareVersion = d["fw.version"]
|
||||
this.about.modemUid = d["fw.modemId"]
|
||||
this.about.modemSn = d["fw.modemSn"]
|
||||
this.about.macManagement = d["fw.macMang"]
|
||||
this.about.macData = d["fw.macData"]
|
||||
this.about.firmwareVersion = d["firmware"]["version"]
|
||||
this.about.modemUid = d["firmware"]["modemId"]
|
||||
this.about.modemSn = d["firmware"]["modemSn"]
|
||||
this.about.macManagement = d["firmware"]["macMang"]
|
||||
this.about.macData = d["firmware"]["macData"]
|
||||
} catch (e) {
|
||||
console.log('Ошибка загрузки версии ПО', e)
|
||||
}
|
||||
|
Reference in New Issue
Block a user