условно компилируемый проект после рефактора, еще нет настроек rxtx

This commit is contained in:
Vladislav Ostapov 2025-06-01 15:49:31 +03:00
parent 3e38e77069
commit c2dd4b13e8
11 changed files with 25182 additions and 1298 deletions

View File

@ -23,7 +23,7 @@ elseif ("${MODEM_TYPE}" STREQUAL "TDMA")
message(STATUS "Selected TDMA modem") message(STATUS "Selected TDMA modem")
elseif ("${MODEM_TYPE}" STREQUAL "SHPS") elseif ("${MODEM_TYPE}" STREQUAL "SHPS")
add_definitions(-DMODEM_IS_SHPS) add_definitions(-DMODEM_IS_SHPS)
message(STATUS "Selected TDMA modem") message(STATUS "Selected SHPS modem")
else() else()
message(FATAL_ERROR "You must set `MODEM_TYPE` \"SCPC\" or \"TDMA\" or \"SHPS\"!") message(FATAL_ERROR "You must set `MODEM_TYPE` \"SCPC\" or \"TDMA\" or \"SHPS\"!")
endif() endif()
@ -63,6 +63,7 @@ add_executable(terminal-web-server
src/api-driver/proxy.cpp src/api-driver/proxy.cpp
src/api-driver/structs.h src/api-driver/structs.h
src/api-driver/structs.cpp src/api-driver/structs.cpp
src/common/nlohmann/json.hpp
src/server/mime_types.hpp src/server/mime_types.hpp
src/server/mime_types.cpp src/server/mime_types.cpp
src/server/request_parser.hpp src/server/request_parser.hpp

View File

@ -1,10 +1,45 @@
//
// Created by vlad on 03.04.2025.
//
#include "daemon.h" #include "daemon.h"
#include <utility>
#include <boost/thread/pthread/thread_data.hpp> #include "terminal_api_driver.h"
// минимальный порог для сна в цикле событий демона
static constexpr int64_t SLEEP_THRESHOLD = 10;
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() { void api_driver::TerminalApiDaemon::connectToApi() {
@ -12,7 +47,7 @@ void api_driver::TerminalApiDaemon::connectToApi() {
std::lock_guard _lock(this->stateMutex); std::lock_guard _lock(this->stateMutex);
this->state.fInitState = "Not connected to API"; 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); std::lock_guard _lock(this->settingsMutex);
this->settingsNetwork.loadDefaults(); this->settingsNetwork.loadDefaults();
@ -54,89 +89,92 @@ void api_driver::TerminalApiDaemon::run() {
this->connectToApi(); this->connectToApi();
struct { struct {
obj::CpUpdatebleObject* u; CpUpdatebleObject uo;
std::function<void ()> c; std::string updaterName;
} updaters[] = { } updaters[] = {
#if API_OBJECT_NETWORK_SETTINGS_ENABLE #ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
// обновление логов // обновление логов
{.u = &statsLogs, .c = [this]() { {.uo = CpUpdatebleObject([this]() {
try { this->statsLogs.updateCallback(cp);
{ }), .updaterName = "updateDebugMetrics"},
std::lock_guard _alock(this->cpApiMutex);
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();
}
}},
#endif #endif
// обновление статистики // обновление статистики
{.u = state, .c = [this]() { {.uo = CpUpdatebleObject([this]() {
try { std::shared_lock _slock1(this->settingsMutex);
std::lock_guard _alock(this->cpApiMutex); obj::TerminalState tmp(state);
std::lock_guard _slock(this->stateMutex); _slock1.release();
state.updateCallback(cp);
stateDev.updateCallback(cp); tmp.updateCallback(cp);
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateState(): success update!"; std::lock_guard _slock2(this->settingsMutex);
} catch (std::exception& e) { state = tmp;
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateState(): " << e.what(); }, 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]() { {.uo = CpUpdatebleObject([this]() {
try { obj::TerminalRxTxSettings rxtx;
this->updateSettings(); rxtx.updateCallback(cp);
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateSettings(): success update!"; std::lock_guard _slock2(this->settingsMutex);
} catch (std::exception& e) { settingsRxTx = rxtx;
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateSettings(): " << e.what(); }, CACHE_SETTINGS_UPDATE_MS), .updaterName = "updateRxTxSettings"},
} #ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
}}, {.uo = CpUpdatebleObject([this]() {
// обновление кеша настроек сети (делается отдельно) std::shared_lock _slock1(this->settingsMutex);
{.lastUpdate = 0, .periodMs = CACHE_SETTINGS_UPDATE_MS, .c = [this]() { obj::TerminalNetworkSettings net(settingsNetwork);
try { _slock1.release();
this->updateNetworkSettings();
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateNetworkSettings(): success update!"; net.updateCallback(cp);
} catch (std::exception& e) { std::lock_guard _slock2(this->settingsMutex);
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateNetworkSettings(): " << e.what(); settingsNetwork = net;
} }, CACHE_SETTINGS_UPDATE_MS), .updaterName = "updateNetworkSettings"},
}}, #endif
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
// обновление кеша QoS // обновление кеша QoS
{.lastUpdate = 0, .periodMs = CACHE_QOS_UPDATE_MS, .c = [this]() { {.uo = CpUpdatebleObject([this]() {
try { obj::TerminalQosSettings qos;
this->updateQos(); qos.updateCallback(cp);
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateQos(): success update!"; std::lock_guard _slock(this->settingsMutex);
} catch (std::exception& e) { settingsQos = qos;
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateQos(): " << e.what(); }, CACHE_SETTINGS_UPDATE_MS), .updaterName = "updateQosSettings"},
} #endif
}}
}; };
while (true) { while (true) {
if (this->lastCpError == ERROR || this->lastCpError == TIMEOUT) { if (this->cp.lastCpError == ERROR || this->cp.lastCpError == TIMEOUT) {
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::run(): close current daemon session caused error " << this->lastCpError; BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::run(): close current daemon session caused error " << this->cp.lastCpError;
CP_Logout(this->sid); cp.disconnect();
this->connectToApi(); this->connectToApi();
} }
#ifdef MODEM_IS_SCPC #ifdef API_OBJECT_DEBUG_METRICS_ENABLE
updaters[0].periodMs = this->statsLogs.logEn ? this->statsLogs.logPeriodMs.load() : -1; updaters[0].uo.updatePeriodMs = this->statsLogs.logEn ? this->statsLogs.logPeriodMs.load() : -1;
#endif #endif
int64_t sleepTime = 60000; // минута по-умолчанию int64_t sleepTime = 60000; // минута по-умолчанию
auto now = TIME_NOW(); auto now = TimeNow();
for (auto& u: updaters) { for (auto& u: updaters) {
if (u.checkNeedUpdate(now)) { if (u.uo.checkNeedUpdate(now)) {
auto targetTime = u.lastUpdate + u.periodMs; auto targetTime = u.uo.lastUpdate + u.uo.updatePeriodMs;
if (targetTime + SLEEP_THRESHOLD <= now && targetTime - SLEEP_THRESHOLD >= now) { if (targetTime + SLEEP_THRESHOLD <= now && targetTime - SLEEP_THRESHOLD >= now) {
u.lastUpdate = targetTime; u.uo.lastUpdate = targetTime;
} else { } else {
u.lastUpdate = now; u.uo.lastUpdate = now;
} }
u.callback(); try {
now = TIME_NOW(); 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();
}
now = TimeNow();
} }
if (u.periodMs >= 0) { if (u.uo.updatePeriodMs >= 0) {
sleepTime = std::min(sleepTime, u.getNextUpdate(now)); sleepTime = std::min(sleepTime, u.uo.getNextUpdate(now));
} }
} }
@ -149,12 +187,12 @@ void api_driver::TerminalApiDaemon::run() {
api_driver::TerminalApiDaemon::TerminalApiDaemon(): daemon([this]() { this->run(); }) {} api_driver::TerminalApiDaemon::TerminalApiDaemon(): daemon([this]() { this->run(); }) {}
void api_driver::TerminalApiDaemon::getState(obj::TerminalState &dest) { void api_driver::TerminalApiDaemon::getState(obj::TerminalState &dest) {
std::shared_lock _lock(state); std::shared_lock _lock(stateMutex);
dest = state; dest = state;
} }
void api_driver::TerminalApiDaemon::getDeviceState(obj::TerminalDeviceState &dest) { void api_driver::TerminalApiDaemon::getDeviceState(obj::TerminalDeviceState &dest) {
std::shared_lock _lock(state); std::shared_lock _lock(stateMutex);
dest = stateDev; dest = stateDev;
} }
@ -199,274 +237,3 @@ api_driver::TerminalApiDaemon::~TerminalApiDaemon() {
BOOST_LOG_TRIVIAL(error) << "api_driver::~TerminalApiDaemon(): " << e.what(); 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", ""));
}
};

View File

@ -1,16 +1,15 @@
#ifndef DAEMON_H #ifndef API_DRIVER_DAEMON_H
#define DAEMON_H #define API_DRIVER_DAEMON_H
#include <boost/thread/detail/thread.hpp>
#include "proxy.h" #include "proxy.h"
#include "api-driver/structs.h" #include "api-driver/structs.h"
#include <boost/thread/thread.hpp>
namespace api_driver { namespace api_driver {
int64_t TimeNow();
class TerminalApiDaemon { class TerminalApiDaemon {
std::mutex cpApiMutex;
boost::thread daemon; boost::thread daemon;
proxy::CpProxy cp;
void connectToApi(); void connectToApi();
@ -22,49 +21,51 @@ namespace api_driver {
std::shared_mutex settingsMutex; std::shared_mutex settingsMutex;
obj::TerminalRxTxSettings settingsRxTx; obj::TerminalRxTxSettings settingsRxTx;
#if API_OBJECT_NETWORK_SETTINGS_ENABLE #ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
obj::TerminalNetworkSettings settingsNetwork; obj::TerminalNetworkSettings settingsNetwork;
#endif #endif
#if API_OBJECT_QOS_SETTINGS_ENABLE #ifdef API_OBJECT_QOS_SETTINGS_ENABLE
obj::TerminalQosSettings settingsQos; obj::TerminalQosSettings settingsQos;
#endif #endif
std::shared_mutex firmwareMutex; std::shared_mutex firmwareMutex;
obj::TerminalFirmwareVersion firmware; obj::TerminalFirmwareVersion firmware;
public: public:
#if API_OBJECT_STATISTICS_ENABLE std::mutex cpApiMutex;
proxy::CpProxy cp;
#ifdef API_OBJECT_DEBUG_METRICS_ENABLE
obj::StatisticsLogger statsLogs; obj::StatisticsLogger statsLogs;
#endif #endif
explicit TerminalApiDaemon(); explicit TerminalApiDaemon();
std::string getDeviceInitState();
/** /**
* Получение статистики, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет. * Получение статистики, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
*/ */
void getState(obj::TerminalState& dest); void getState(obj::TerminalState &dest);
void getDeviceState(obj::TerminalDeviceState& dest);
void getDeviceState(obj::TerminalDeviceState &dest);
// /** // /**
// * Получение настроек, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет. // * Получение настроек, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
// */ // */
void getSettingsRxTx(obj::TerminalRxTxSettings& dest); void getSettingsRxTx(obj::TerminalRxTxSettings &dest);
void getNetworkSettings(obj::TerminalNetworkSettings& dest); void getNetworkSettings(obj::TerminalNetworkSettings &dest);
void getQosSettings(bool& isEnabled, std::string& json); void getQosSettings(bool &isEnabled, std::string &json);
void setSettingsRxTx(obj::TerminalRxTxSettings& s, bool readback = true); void setSettingsRxTx(obj::TerminalRxTxSettings &s, bool readback = true);
void setSettingsDpdi(DPDI_parmeters& s, bool readback = true); void setSettingsDpdi(DPDI_parmeters &s, bool readback = true);
void setSettingsBucLnb(buc_lnb_settings& bucLnb, bool readback = true); void setSettingsBucLnb(buc_lnb_settings &bucLnb, bool readback = true);
void setQosSettings(bool enabled, const std::string& str, bool readback = true); void setQosSettings(bool enabled, const std::string &str, bool readback = true);
void setNetworkSettings(obj::TerminalNetworkSettings& s, bool readback = true); void setNetworkSettings(obj::TerminalNetworkSettings &s, bool readback = true);
obj::TerminalFirmwareVersion getFirmware(); obj::TerminalFirmwareVersion getFirmware();
@ -77,4 +78,4 @@ namespace api_driver {
} }
#endif //DAEMON_H #endif //API_DRIVER_DAEMON_H

View File

@ -28,6 +28,7 @@ namespace api_driver::proxy {
void disconnect(); void disconnect();
std::string getDmaDebug(const std::string& arg); std::string getDmaDebug(const std::string& arg);
void setDmaDebug(const std::string& arg, const std::string& value);
std::string getNetwork(const std::string& param); std::string getNetwork(const std::string& param);
void setNetwork(const std::string& param, const std::string& value); void setNetwork(const std::string& param, const std::string& value);
@ -46,7 +47,7 @@ namespace api_driver::proxy {
void getCincState(CinC_state& dest); void getCincState(CinC_state& dest);
#endif #endif
#if API_OBJECT_STATISTICS_ENABLE #ifdef API_OBJECT_DEBUG_METRICS_ENABLE
void getDebugMetrics(debug_metrics& dest); void getDebugMetrics(debug_metrics& dest);
#endif #endif

View File

@ -1,8 +1,26 @@
#ifndef API_DRIVER_STRICTS_ENABLE_H #ifndef API_DRIVER_STRICTS_ENABLE_H
#define 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) #if defined(MODEM_IS_SCPC)
#define API_OBJECT_QOS_SETTINGS_ENABLE defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA) #define API_OBJECT_DEBUG_METRICS_ENABLE
#endif
#if defined(MODEM_IS_SCPC) || defined(MODEM_IS_TDMA)
#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 #endif //API_DRIVER_STRICTS_ENABLE_H

View File

@ -1,9 +1,10 @@
#include "api-driver/structs.h" #include "api-driver/structs.h"
#include "api-driver/proxy.h" #include "api-driver/proxy.h"
#include "common/nlohmann/json.hpp"
#include <iomanip> #include <iomanip>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include "terminal_api_driver.h"
#define TIME_NOW() std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count() #define TIME_NOW() std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count()
@ -13,6 +14,10 @@ typedef boost::property_tree::ptree::path_type json_path;
static constexpr const char* DEFAULT_QOS_CLASSES = R"({"rt1":[],"rt2":[],"rt3":[],"cd":[]})"; static constexpr const char* DEFAULT_QOS_CLASSES = R"({"rt1":[],"rt2":[],"rt3":[],"cd":[]})";
// пороговое значение сна // пороговое значение сна
double translateCoordinates(uint8_t deg, uint8_t min) {
return static_cast<double>(deg) + static_cast<double>(min) / 60;
}
// static int calculateSubnetMask(const std::string& subnet_mask) { // static int calculateSubnetMask(const std::string& subnet_mask) {
// int mask = 0; // int mask = 0;
// std::istringstream iss(subnet_mask); // std::istringstream iss(subnet_mask);
@ -93,21 +98,7 @@ std::string makeTimepointFromMillis(int64_t unix_time_ms) {
} }
bool api_driver::obj::CpUpdatebleObject::checkNeedUpdate(int64_t now) const { #ifdef API_OBJECT_DEBUG_METRICS_ENABLE
if (updatePeriodMs < 0) return false;
// тут нет смысла спать меньше чем на 20мс, поэтому можно разрешить чтение на некоторое время раньше
return now - lastUpdate >= (updatePeriodMs - 20);
}
int64_t api_driver::obj::CpUpdatebleObject::getNextUpdate(int64_t now) const {
if (checkNeedUpdate(now)) {
return 0;
}
auto next = now - lastUpdate;
return next < 0 ? 0 : next;
}
api_driver::obj::CpUpdatebleObject::~CpUpdatebleObject() = default;
#if API_OBJECT_STATISTICS_ENABLE
api_driver::obj::StatisticsLogger::StatisticsLogger(): timeStart(TIME_NOW()) {} api_driver::obj::StatisticsLogger::StatisticsLogger(): timeStart(TIME_NOW()) {}
std::string api_driver::obj::StatisticsLogger::getSettings() { std::string api_driver::obj::StatisticsLogger::getSettings() {
@ -189,20 +180,12 @@ void api_driver::obj::StatisticsLogger::putItem(const debug_metrics &item) {
api_driver::obj::StatisticsLogger::~StatisticsLogger() = default; api_driver::obj::StatisticsLogger::~StatisticsLogger() = default;
#endif #endif
#if API_OBJECT_NETWORK_SETTINGS_ENABLE #ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
api_driver::obj::TerminalNetworkSettings::TerminalNetworkSettings() { loadDefaults(); } api_driver::obj::TerminalNetworkSettings::TerminalNetworkSettings() { loadDefaults(); }
api_driver::obj::TerminalNetworkSettings::TerminalNetworkSettings(const TerminalNetworkSettings &src) = default; api_driver::obj::TerminalNetworkSettings::TerminalNetworkSettings(const TerminalNetworkSettings &src) = default;
api_driver::obj::TerminalNetworkSettings & api_driver::obj::TerminalNetworkSettings::operator=(const TerminalNetworkSettings &src) { api_driver::obj::TerminalNetworkSettings & api_driver::obj::TerminalNetworkSettings::operator=(const TerminalNetworkSettings &src) = default;
managementIp = src.managementIp;
managementGateway = src.managementGateway;
dataIp = src.dataIp;
serverName = src.serverName;
isL2 = src.isL2;
dataMtu = src.dataMtu;
return *this;
}
void api_driver::obj::TerminalNetworkSettings::loadDefaults() { void api_driver::obj::TerminalNetworkSettings::loadDefaults() {
managementIp = "0.0.0.0"; managementIp = "0.0.0.0";
@ -268,17 +251,14 @@ std::string api_driver::obj::TerminalNetworkSettings::asJson() {
api_driver::obj::TerminalNetworkSettings::~TerminalNetworkSettings() = default; api_driver::obj::TerminalNetworkSettings::~TerminalNetworkSettings() = default;
#endif #endif
#if API_OBJECT_QOS_SETTINGS_ENABLE #ifdef API_OBJECT_QOS_SETTINGS_ENABLE
api_driver::obj::TerminalQosSettings::TerminalQosSettings() { api_driver::obj::TerminalQosSettings::TerminalQosSettings() = default;
} api_driver::obj::TerminalQosSettings::TerminalQosSettings(const TerminalQosSettings &src) = default;
api_driver::obj::TerminalQosSettings & api_driver::obj::TerminalQosSettings::operator=(const TerminalQosSettings &src) = default;
api_driver::obj::TerminalQosSettings::TerminalQosSettings(const TerminalQosSettings &src) {
}
api_driver::obj::TerminalQosSettings & api_driver::obj::TerminalQosSettings::operator=(const TerminalQosSettings &src) {
}
void api_driver::obj::TerminalQosSettings::loadDefaults() { void api_driver::obj::TerminalQosSettings::loadDefaults() {
qosEnabled = false;
qosSettingsJson = DEFAULT_QOS_CLASSES;
} }
void api_driver::obj::TerminalQosSettings::updateCallback(proxy::CpProxy &cp) { void api_driver::obj::TerminalQosSettings::updateCallback(proxy::CpProxy &cp) {
@ -293,17 +273,15 @@ void api_driver::obj::TerminalQosSettings::store(proxy::CpProxy &cp) {
std::string api_driver::obj::TerminalQosSettings::asJson() { std::string api_driver::obj::TerminalQosSettings::asJson() {
} }
api_driver::obj::TerminalQosSettings::~TerminalQosSettings() { api_driver::obj::TerminalQosSettings::~TerminalQosSettings() = default;
}
#endif #endif
api_driver::obj::TerminalState::TerminalState() = default;
void api_driver::obj::TerminalState::updateCallback(proxy::CpProxy& cp) { void api_driver::obj::TerminalState::updateCallback(proxy::CpProxy& cp) {
modulator_state mod{}; modulator_state mod{};
modulator_settings modSet{};
demodulator_state demod{}; demodulator_state demod{};
#ifdef MODEM_IS_SCPC #ifdef MODEM_IS_SCPC
CinC_state cinc{}; CinC_state cinc{};
@ -311,13 +289,17 @@ void api_driver::obj::TerminalState::updateCallback(proxy::CpProxy& cp) {
try { try {
cp.getModState(mod); cp.getModState(mod);
cp.getDemodState(demod); cp.getDemodState(demod);
#ifdef MODEM_IS_SCPC cp.getModSettings(modSet);
// CinC state прописывается в настройках
{
fTxState = modSet.tx_is_on;
fIsTest = modSet.tx_is_on && (!modSet.is_carrier || modSet.is_test_data);
#ifdef MODEM_IS_SCPC
fIsCinC = modSet.is_cinc;
if (fIsCinC) {
cp.getCincState(cinc);
} }
cp.getCincState(cinc);
#endif #endif
#ifdef MODEM_IS_TDMA #ifdef MODEM_IS_TDMA
fInitState = cp.getDmaDebug("status_init"); fInitState = cp.getDmaDebug("status_init");
#endif #endif
@ -325,165 +307,120 @@ void api_driver::obj::TerminalState::updateCallback(proxy::CpProxy& cp) {
throw std::runtime_error(std::string("api_driver::obj::TerminalState::updateCallback() error: ") + e.what()); throw std::runtime_error(std::string("api_driver::obj::TerminalState::updateCallback() error: ") + e.what());
} }
fRxState = demod.locks.sym_sync_lock && demod.locks.freq_lock && demod.locks.afc_lock && demod.locks.pkt_sync;
fRxSymSyncLock = demod.locks.sym_sync_lock;
fRxFreqSearchLock = demod.locks.freq_lock;
fRxAfcLock = demod.locks.afc_lock;
fRxPktSync = demod.locks.pkt_sync;
fRxSnr = demod.snr;
fRxRssi = demod.rssi;
fRxModcod = demod.modcod;
fRxFrameSizeNormal = !demod.is_short;
fRxIsPilots = demod.is_pilots;
fRxSymError = demod.sym_err;
fRxFreqErr = demod.crs_freq_err;
fRxFreqErrAcc = demod.fine_freq_err;
fRxInputSignalLevel = demod.if_overload;
fRxPllError = demod.afc_err;
fRxSpeedOnRxKbit = static_cast<double>(demod.speed_in_bytes_rx) / 128.0;
fRxSpeedOnIifKbit = static_cast<double>(demod.speed_in_bytes_rx_iface) / 128.0;
fRxPacketsOk = demod.packet_ok_cnt;
fRxPacketsBad = demod.packet_bad_cnt;
fRxPacketsDummy = demod.dummy_cnt;
fTxModcod = mod.modcod;
fTxSpeedOnTxKbit = static_cast<double>(mod.speed_in_bytes_tx) / 128.0;
fTxSpeedOnIifKbit = static_cast<double>(mod.speed_in_bytes_tx_iface) / 128.0;
#ifdef MODEM_IS_SCPC #ifdef MODEM_IS_SCPC
fTxSnr = mod.snr_remote;
bool isCinC = getIsCinC(); fTxFrameSizeNormal = !mod.is_short;
if (isCinC) { fTxIsPilots = mod.is_pilots;
logCpApiError("api_driver::TerminalApiDaemon::updateState()->CP_GetCinCState()", CP_GetCinCState(sid, cinc)); fCincOcc = cinc.ratio_signal_signal;
} fCincCorrelator = cinc.carrier_lock;
fCincCorrelatorFails = cinc.cnt_bad_lock;
fCincFreqErr = cinc.freq_error_offset;
fCincFreqErrAcc = cinc.freq_fine_estimate;
fCincChannelDelay = cinc.delay_dpdi;
#endif #endif
{
#ifdef MODEM_IS_TDMA #ifdef MODEM_IS_TDMA
this->fInitState = tmpDevState; fStatTxCenterFreq = modSet.central_freq_in_kGz;
fStatTxSymSpeed = static_cast<double>(modSet.baudrate) / 1000.0;
#endif #endif
this->fTxState = modulator.is_tx_on;
this->fTxModcod = modulator.modcod;
this->fTxSnr = modulator.snr_remote;
this->fTxframeSizeNormal = modulator.snr_remote;
this->fTx = modulator.snr_remote;
this->fTx = modulator.snr_remote;
this->fTx = modulator.snr_remote;
#ifdef MODEM_IS_SCPC
result << ",\"tx.snr\":"; writeDouble(result, modulator.snr_remote);
if (modulator.is_short) { result << R"(,"tx.frameSizeNormal":false)"; }
else { result << R"(,"tx.frameSizeNormal":true)"; }
if (modulator.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>(modulator.speed_in_bytes_tx) / 128.0);
result << ",\"tx.speedOnIifKbit\":"; writeDouble(result, (static_cast<double>(modulator.speed_in_bytes_tx_iface) / 128.0));
// формируем структуру для RX
result << ",\n\"rx.state\":" << boolAsStr(demodulator.locks.sym_sync_lock && demodulator.locks.freq_lock && demodulator.locks.afc_lock && demodulator.locks.pkt_sync);
result << ",\"rx.sym_sync_lock\":" << boolAsStr(demodulator.locks.sym_sync_lock);
result << ",\"rx.freq_search_lock\":" << boolAsStr(demodulator.locks.freq_lock);
result << ",\"rx.afc_lock\":" << boolAsStr(demodulator.locks.afc_lock);
result << ",\"rx.pkt_sync\":" << boolAsStr(demodulator.locks.pkt_sync);
result << ",\"rx.snr\":"; writeDouble(result, demodulator.snr);
result << ",\"rx.rssi\":"; writeDouble(result, demodulator.rssi);
result << ",\"rx.modcod\":" << demodulator.modcod;
if (demodulator.is_short) {
result << R"(,"rx.frameSizeNormal":false)";
} else {
result << R"(,"rx.frameSizeNormal":true)";
}
if (demodulator.is_pilots) {
result << R"(,"rx.isPilots":true)";
} else {
result << R"(,"rx.isPilots":false)";
}
result << ",\n\"rx.symError\":"; writeDouble(result, demodulator.sym_err);
result << ",\"rx.freqErr\":"; writeDouble(result, demodulator.crs_freq_err);
result << ",\"rx.freqErrAcc\":"; writeDouble(result, demodulator.fine_freq_err);
result << ",\"rx.inputSignalLevel\":"; writeDouble(result, demodulator.if_overload);
result << ",\"rx.pllError\":"; writeDouble(result, demodulator.afc_err);
result << ",\"rx.speedOnRxKbit\":"; writeDouble(result, static_cast<double>(demodulator.speed_in_bytes_rx) / 128.0);
result << ",\"rx.speedOnIifKbit\":"; writeDouble(result, static_cast<double>(demodulator.speed_in_bytes_rx_iface) / 128.0);
result << ",\"rx.packetsOk\":" << demodulator.packet_ok_cnt;
result << ",\"rx.packetsBad\":" << demodulator.packet_bad_cnt;
result << ",\"rx.packetsDummy\":" << demodulator.dummy_cnt;
#ifdef MODEM_IS_SCPC
// формируем структуру для CinC
if (isCinC) {
if (modulator.is_tx_on) {
if (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, cinc.ratio_signal_signal, 3);
result << ",\"cinc.correlatorFails\":" << cinc.cnt_bad_lock;
result << ",\"cinc.freqErr\":" << cinc.freq_error_offset;
result << ",\"cinc.freqErrAcc\":" << cinc.freq_fine_estimate;
result << ",\"cinc.channelDelay\":" << cinc.delay_dpdi;
} else {
result << R"(,"cinc.correlator":null)";
}
#endif
// структура температур девайса
result << ",\n\"device.adrv\":"; writeDouble(result, device.adrv_temp, 1);
result << ",\"device.fpga\":"; writeDouble(result, device.pl_temp, 1);
result << ",\"device.zynq\":"; writeDouble(result, device.zynq_temp, 1);
#ifdef MODEM_IS_TDMA
if (device.cur_image.empty()) {
result << R"(,
"device.upgradeStatus":"Нет обновлений","device.upgradePercent":0,"device.upgradeImage":"")";
} else {
switch (device.status) {
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\":" << device.dwl_percent;
result << ",\"device.upgradeImage\":" << buildEscapedString(device.cur_image);
}
#endif
result << "}";
*/
this->modState = modulator;
this->demodState = demodulator;
#ifdef MODEM_IS_SCPC
this->cincState = cinc;
#endif
}
} }
nlohmann::json api_driver::obj::TerminalState::asJson() {
nlohmann::json res{};
res["initState"] = fInitState;
res["testState"] = fIsTest;
res["fTxState"] = fIsTest;
#ifdef MODEM_IS_SCPC
res["isCinC"] = fIsCinC;
#endif
res["rx"]["state"] = fRxState;
res["rx"]["sym_sync_lock"] = fRxSymSyncLock;
res["rx"]["freq_search_lock"] = fRxFreqSearchLock;
res["rx"]["afc_lock"] = fRxAfcLock;
res["rx"]["pkt_sync"] = fRxPktSync;
res["rx"]["snr"] = fRxSnr;
res["rx"]["rssi"] = fRxRssi;
res["rx"]["modcod"] = fRxModcod;
res["rx"]["frameSizeNormal"] = fRxFrameSizeNormal;
res["rx"]["isPilots"] = fRxIsPilots;
res["rx"]["symError"] = fRxSymError;
res["rx"]["freqErr"] = fRxFreqErr;
res["rx"]["freqErrAcc"] = fRxFreqErrAcc;
res["rx"]["inputSignalLevel"] = fRxInputSignalLevel;
res["rx"]["pllError"] = fRxPllError;
res["rx"]["speedOnRxKbit"] = fRxSpeedOnRxKbit;
res["rx"]["speedOnIifKbit"] = fRxSpeedOnIifKbit;
res["rx"]["packetsOk"] = fRxPacketsOk;
res["rx"]["packetsBad"] = fRxPacketsBad;
res["rx"]["packetsDummy"] = fRxPacketsDummy;
res["tx"]["modcod"] = fTxModcod;
res["tx"]["speedOnTxKbit"] = fTxSpeedOnTxKbit;
res["tx"]["speedOnIifKbit"] = fTxSpeedOnIifKbit;
#ifdef MODEM_IS_SCPC
res["tx"]["snr"] = fTxSnr;
res["tx"]["frameSizeNormal"] = fTxFrameSizeNormal;
res["tx"]["isPilots"] = fTxIsPilots;
if (fIsCinC) {
if (fTxState) {
res["cinc"]["correlator"] = fCincCorrelator;
} else {
res["cinc"]["correlator"] = nullptr;
}
res["cinc"]["occ"] = fCincOcc;
res["cinc"]["correlatorFails"] = fCincCorrelatorFails;
res["cinc"]["freqErr"] = fCincFreqErr;
res["cinc"]["freqErrAcc"] = fCincFreqErrAcc;
res["cinc"]["channelDelay"] = fCincChannelDelay;
} else {
res["cinc"]["correlator"] = nullptr;
}
#endif
#ifdef MODEM_IS_TDMA
res["tx"]["centerFreq"] = fTxCenterFreq;
res["tx"]["symSpeed"] = fTxSymSpeed;
#endif
return res;
}
api_driver::obj::TerminalState::~TerminalState() = default; api_driver::obj::TerminalState::~TerminalState() = default;
api_driver::obj::TerminalDeviceState::TerminalDeviceState() = default; api_driver::obj::TerminalDeviceState::TerminalDeviceState() = default;
api_driver::obj::TerminalDeviceState::TerminalDeviceState(const TerminalDeviceState &src) = default; api_driver::obj::TerminalDeviceState::TerminalDeviceState(const TerminalDeviceState &src) = default;
api_driver::obj::TerminalDeviceState & api_driver::obj::TerminalDeviceState::operator=(const TerminalDeviceState &src) { api_driver::obj::TerminalDeviceState & api_driver::obj::TerminalDeviceState::operator=(const TerminalDeviceState &src) = default;
fOsUptime = src.fOsUptime;
fOsLoad1 = src.fOsLoad1;
fOsLoad5 = src.fOsLoad5;
fOsLoad15 = src.fOsLoad15;
fOsTotalram = src.fOsTotalram;
fOsFreeram = src.fOsFreeram;
fOsProcs = src.fOsProcs;
fTempAdrv = src.fTempAdrv;
fTempZynq = src.fTempZynq;
fTempFpga = src.fTempFpga;
#ifdef MODEM_IS_TDMA
fUpgradeStatus = src.fUpgradeStatus;
fUpgradePercent = src.fUpgradePercent;
fUpgradeImage = src.fUpgradeImage;
#endif
return *this;
}
void api_driver::obj::TerminalDeviceState::updateCallback(proxy::CpProxy &cp) { void api_driver::obj::TerminalDeviceState::updateCallback(proxy::CpProxy &cp) {
{ {
@ -516,39 +453,38 @@ void api_driver::obj::TerminalDeviceState::updateCallback(proxy::CpProxy &cp) {
fOsProcs = info.procs; fOsProcs = info.procs;
} }
std::string api_driver::obj::TerminalDeviceState::asJson() const { nlohmann::json api_driver::obj::TerminalDeviceState::asJson() const {
std::stringstream result; nlohmann::json res;
result << "{\"uptime\":" << fOsUptime res["uptime"] = fOsUptime;
<< ",\"load1min\":" << std::setprecision(2) << fOsLoad1 res["load1min"] = fOsLoad1;
<< ",\"load5min\":" << std::setprecision(2) << fOsLoad5 res["load5min"] = fOsLoad5;
<< ",\"load15min\":" << std::setprecision(2) << fOsLoad15 res["load15min"] = fOsLoad15;
<< ",\"totalram\":" << fOsTotalram res["totalram"] = fOsTotalram;
<< ",\"freeram\":" << fOsFreeram res["freeram"] = fOsFreeram;
<< ",\"procs\":" << fOsProcs res["procs"] = fOsProcs;
<< ",\"adrv\":" << std::setprecision(1) << fTempAdrv res["adrv"] = fTempAdrv;
<< ",\"fpga\":" << std::setprecision(1) << fTempFpga res["fpga"] = fTempFpga;
<< ",\"zynq\":" << std::setprecision(1) << fTempZynq; res["zynq"] = fTempZynq;
#ifdef MODEM_IS_TDMA #ifdef MODEM_IS_TDMA
if (fUpgradeImage.empty()) { if (fUpgradeImage.empty()) {
result << R"(, res["upgradeStatus"] = "Нет обновлений";
"upgradeStatus":"Нет обновлений","upgradePercent":0,"upgradeImage":"")"; res["upgradePercent"] = 0;
res["upgradeImage"] = "";
} else { } else {
switch (fUpgradeStatus) { switch (fUpgradeStatus) {
case NORM_RX_OBJECT_NEW_API: result << ",\n" R"("upgradeStatus": "Начало загрузки")"; break; case NORM_RX_OBJECT_NEW_API: res["upgradeStatus"] = "Начало загрузки"; break;
case NORM_RX_OBJECT_INFO_API: result << ",\n" R"("upgradeStatus": "Получено имя образа")"; break; case NORM_RX_OBJECT_INFO_API: res["upgradeStatus"] = "Получено имя образа"; break;
case NORM_RX_OBJECT_UPDATED_API: result << ",\n" R"("upgradeStatus": "Загружается")"; break; case NORM_RX_OBJECT_UPDATED_API: res["upgradeStatus"] = "Загружается"; break;
case NORM_RX_OBJECT_COMPLETED_API: result << ",\n" R"("upgradeStatus": "Загрузка завершена")"; break; case NORM_RX_OBJECT_COMPLETED_API: res["upgradeStatus"] = "Загрузка завершена"; break;
case NORM_RX_OBJECT_ABORTED_API: result << ",\n" R"("upgradeStatus": "Загрузка прервана")"; break; case NORM_RX_OBJECT_ABORTED_API: res["upgradeStatus"] = "Загрузка прервана"; break;
default: result << ",\n" R"("upgradeStatus": "?")"; default: res["upgradeStatus"] = "?";
} }
result << ",\"upgradePercent\":" << fUpgradePercent; res["upgradePercent"] = fUpgradePercent;
result << ",\"upgradeImage\":" << buildEscapedString(fUpgradeImage); res["upgradeImage"] = fUpgradeImage;
} }
#endif #endif
result << "}"; return res;
return result.str();
} }
api_driver::obj::TerminalDeviceState::~TerminalDeviceState() = default; api_driver::obj::TerminalDeviceState::~TerminalDeviceState() = default;

View File

@ -10,33 +10,12 @@
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <boost/property_tree/ptree_fwd.hpp> #include <boost/property_tree/ptree_fwd.hpp>
#include "common/nlohmann/json.hpp"
namespace api_driver::obj { namespace api_driver::obj {
/** #ifdef API_OBJECT_DEBUG_METRICS_ENABLE
* Обертка для объектов, доступных для обновления class StatisticsLogger {
* 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 {
public: public:
StatisticsLogger(); StatisticsLogger();
@ -55,7 +34,7 @@ namespace api_driver::obj {
std::string getSettings(); std::string getSettings();
void setSettings(boost::property_tree::ptree &pt); void setSettings(boost::property_tree::ptree &pt);
void updateCallback(proxy::CpProxy& cp) override; void updateCallback(proxy::CpProxy& cp);
/** /**
* Записать значение в "базу данных". Метку при этом вставлять не нужно, она будет вставлена автоматически. * Записать значение в "базу данных". Метку при этом вставлять не нужно, она будет вставлена автоматически.
* @param item * @param item
@ -69,7 +48,7 @@ namespace api_driver::obj {
// logs.clear(); // logs.clear();
// } // }
~StatisticsLogger() override; ~StatisticsLogger();
private: private:
// std::pmr::deque<LogItem> logs; // std::pmr::deque<LogItem> logs;
std::fstream logFile{}; std::fstream logFile{};
@ -87,8 +66,8 @@ namespace api_driver::obj {
#error "Selected modem type not supported!" #error "Selected modem type not supported!"
#endif #endif
#if API_OBJECT_NETWORK_SETTINGS_ENABLE #ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
class TerminalNetworkSettings: public CpUpdatebleObject { class TerminalNetworkSettings {
public: public:
std::string managementIp, managementGateway, dataIp, serverName; std::string managementIp, managementGateway, dataIp, serverName;
bool isL2 = true; bool isL2 = true;
@ -100,17 +79,17 @@ namespace api_driver::obj {
void loadDefaults(); void loadDefaults();
void updateCallback(proxy::CpProxy& cp) override; void updateCallback(proxy::CpProxy& cp);
void updateFromPt(boost::property_tree::ptree &pt); void updateFromPt(boost::property_tree::ptree &pt);
void store(proxy::CpProxy& cp); void store(proxy::CpProxy& cp);
std::string asJson(); std::string asJson();
~TerminalNetworkSettings() override; ~TerminalNetworkSettings();
}; };
#endif #endif
#if API_OBJECT_QOS_SETTINGS_ENABLE #ifdef API_OBJECT_QOS_SETTINGS_ENABLE
class TerminalQosSettings: public CpUpdatebleObject { class TerminalQosSettings {
public: public:
static constexpr const char* DEFAULT_QOS_CLASSES = R"({"rt1":[],"rt2":[],"rt3":[],"cd":[]})"; static constexpr const char* DEFAULT_QOS_CLASSES = R"({"rt1":[],"rt2":[],"rt3":[],"cd":[]})";
std::string qosSettingsJson; std::string qosSettingsJson;
@ -122,12 +101,12 @@ namespace api_driver::obj {
void loadDefaults(); void loadDefaults();
void updateCallback(proxy::CpProxy& cp) override; void updateCallback(proxy::CpProxy& cp);
void updateFromPt(boost::property_tree::ptree &pt); void updateFromPt(boost::property_tree::ptree &pt);
void store(proxy::CpProxy& cp); void store(proxy::CpProxy& cp);
std::string asJson(); std::string asJson();
~TerminalQosSettings() override; ~TerminalQosSettings();
}; };
#endif #endif
@ -154,7 +133,7 @@ namespace api_driver::obj {
/** /**
* Обертка состояния терминала, тут состояние девайса, модулятора/демодулятора, состояние автоматического обновления. * Обертка состояния терминала, тут состояние девайса, модулятора/демодулятора, состояние автоматического обновления.
*/ */
class TerminalState: public CpUpdatebleObject { class TerminalState {
public: public:
std::string fInitState{}; std::string fInitState{};
bool fIsTest = false; // daemon->isTest() bool fIsTest = false; // daemon->isTest()
@ -163,62 +142,60 @@ namespace api_driver::obj {
bool fIsCinC = false; bool fIsCinC = false;
#endif #endif
bool fStatRxState; bool fRxState;
bool fStatRxSymSyncLock; bool fRxSymSyncLock;
bool fStatRxFreqSearchLock; bool fRxFreqSearchLock;
bool fStatRxAfcLock; bool fRxAfcLock;
bool fStatRxPktSync; bool fRxPktSync;
float fStatRxSnr; float fRxSnr;
float fStatRxRssi; float fRxRssi;
uint16_t fStatRxModcod; uint16_t fRxModcod;
bool fStatRxFrameSizeNormal; bool fRxFrameSizeNormal;
bool fStatRxIsPilots; bool fRxIsPilots;
double fStatRxSymError; double fRxSymError;
double fStatRxFreqErr; double fRxFreqErr;
double fStatRxFreqErrAcc; double fRxFreqErrAcc;
double fStatRxInputSignalLevel; double fRxInputSignalLevel;
double fStatRxPllError; double fRxPllError;
double fStatRxSpeedOnRxKbit; double fRxSpeedOnRxKbit;
double fStatRxSpeedOnIifKbit; double fRxSpeedOnIifKbit;
uint32_t fStatRxPacketsOk; uint32_t fRxPacketsOk;
uint32_t fStatRxPacketsBad; uint32_t fRxPacketsBad;
uint32_t fStatRxPacketsDummy; uint32_t fRxPacketsDummy;
bool fStatTxState; uint16_t fTxModcod;
uint16_t fStatTxModcod; double fTxSpeedOnTxKbit;
double fStatTxSpeedOnTxKbit; double fTxSpeedOnIifKbit;
double fStatTxSpeedOnIifKbit;
#ifdef MODEM_IS_SCPC #ifdef MODEM_IS_SCPC
float fStatTxSnr; float fTxSnr;
bool fStatTxFrameSizeNormal; bool fTxFrameSizeNormal;
bool fStatTxIsPilots; bool fTxIsPilots;
double fStatCincOcc; double fCincOcc;
bool fStatCincCorrelator; bool fCincCorrelator;
uint32_t fStatCincCorrelatorFails; uint32_t fCincCorrelatorFails;
int32_t fStatCincFreqErr; int32_t fCincFreqErr;
int32_t fStatCincFreqErrAcc; int32_t fCincFreqErrAcc;
float fStatCincChannelDelay; float fCincChannelDelay;
#endif #endif
#ifdef MODEM_IS_TDMA #ifdef MODEM_IS_TDMA
fStatTxCenterFreq; TODO fTxCenterFreq;
fStatTxSymSpeed; TODO fTxSymSpeed;
#endif #endif
TerminalState();
/** /**
* Обновление основной части статистики, то есть RX/TX и sysinfo * Обновление основной части статистики, то есть RX/TX и sysinfo
*/ */
void updateCallback(proxy::CpProxy& cp) override; void updateCallback(proxy::CpProxy& cp);
nlohmann::json asJson();
void updateFromPt(boost::property_tree::ptree &pt); ~TerminalState();
void store(TSID sid, CP_Result& lastCpError);
std::string asJson();
~TerminalState() override;
}; };
class TerminalDeviceState: public CpUpdatebleObject { class TerminalDeviceState {
public: public:
time_t fOsUptime{}; time_t fOsUptime{};
double fOsLoad1{}; double fOsLoad1{};
@ -241,23 +218,23 @@ namespace api_driver::obj {
TerminalDeviceState(const TerminalDeviceState& src); TerminalDeviceState(const TerminalDeviceState& src);
TerminalDeviceState& operator= (const TerminalDeviceState& src); TerminalDeviceState& operator= (const TerminalDeviceState& src);
void updateCallback(proxy::CpProxy& cp) override; void updateCallback(proxy::CpProxy& cp);
std::string asJson() const; nlohmann::json asJson() const;
~TerminalDeviceState() override; ~TerminalDeviceState();
}; };
class TerminalRxTxSettings: public CpUpdatebleObject { class TerminalRxTxSettings {
public: public:
// TODO описать все параметры для всех терминалов // TODO описать все параметры для всех терминалов
void updateCallback(proxy::CpProxy& cp) override; void updateCallback(proxy::CpProxy& cp);
void updateFromPt(boost::property_tree::ptree &pt); void updateFromPt(boost::property_tree::ptree &pt);
void store(proxy::CpProxy& cp); void store(proxy::CpProxy& cp);
std::string asJson(); std::string asJson();
~TerminalRxTxSettings() override; ~TerminalRxTxSettings();
}; };
} }

24765
src/common/nlohmann/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
#include "auth/resources.h" #include "auth/resources.h"
#include "auth/jwt.h" #include "auth/jwt.h"
#include "auth/utils.h" #include "auth/utils.h"
#include "common/nlohmann/json.hpp"
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp> namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
@ -76,19 +77,19 @@ class ServerResources {
} }
void doTerminalUpgrade() const { void doTerminalUpgrade() const {
api->executeInApi([](TSID sid) { api->executeInApi([](api_driver::proxy::CpProxy& cp) {
CP_SetDmaDebug(sid, "begin_save_config", ""); cp.setDmaDebug("begin_save_config", "");
std::string cmd(UPGRADE_COMMAND); std::string cmd(UPGRADE_COMMAND);
cmd += " "; cmd += " ";
cmd += FIRMWARE_LOCATION; cmd += FIRMWARE_LOCATION;
system(cmd.c_str()); system(cmd.c_str());
CP_SetDmaDebug(sid, "save_config", ""); cp.setDmaDebug("begin_save_config", "");
}); });
} }
#ifdef MODEM_IS_TDMA #ifdef MODEM_IS_TDMA
void doTerminalUpgradeOta() const { void doTerminalUpgradeOta() const {
api->executeInApi([&](TSID sid) { api->executeInApi([&](proxy::CpProxy&) {
CP_SetDmaDebug(sid, "begin_save_config", ""); CP_SetDmaDebug(sid, "begin_save_config", "");
std::string cmd(UPGRADE_COMMAND); std::string cmd(UPGRADE_COMMAND);
cmd += " "; cmd += " ";
@ -222,11 +223,7 @@ public:
rep.status = http::server::ok; rep.status = http::server::ok;
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)}); rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
std::string result = R"({"mainState":)"; const auto result = api->loadTerminalState();
result += api->loadTerminalState();
result += R"(,"sysinfo":)";
result += api->loadSysInfo();
result += "}";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size()); rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
})); }));
@ -494,17 +491,16 @@ public:
if (func == "SetDmaDebug") { 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("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; } if (req.url->params.find("value") == req.url->params.end()) { http::server::stockReply(http::server::bad_request, rep); return; }
this->api->executeInApi([&](auto sid) { this->api->executeInApi([&](auto& cp) {
CP_SetDmaDebug(sid, req.url->params["param"].c_str(), req.url->params["value"]); cp.setDmaDebug(req.url->params["param"], req.url->params["value"]);
}); });
} else if (func == "GetDmaDebug") { } else if (func == "GetDmaDebug") {
if (req.url->params.find("param") == req.url->params.end()) { http::server::stockReply(http::server::bad_request, rep); return; } if (req.url->params.find("param") == req.url->params.end()) { http::server::stockReply(http::server::bad_request, rep); return; }
this->api->executeInApi([&](auto sid) { this->api->executeInApi([&](auto& cp) {
std::string tmp{}; nlohmann::json tmp;
CP_GetDmaDebug(sid, req.url->params["param"].c_str(), &tmp); tmp["status"] = "ok";
result = R"({"status":"ok","result":)"; tmp["result"] = cp.getDmaDebug(req.url->params["param"]);
result += api_driver::buildEscapedString(tmp); result = tmp.dump();
result += "}";
}); });
} else { } else {
http::server::stockReply(http::server::not_implemented, rep); http::server::stockReply(http::server::not_implemented, rep);

View File

@ -1,7 +1,6 @@
#include "terminal_api_driver.h" #include "terminal_api_driver.h"
#include <cmath> #include <cmath>
#include "terminal_api/ControlProtoCInterface.h"
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
#include <shared_mutex> #include <shared_mutex>
@ -9,215 +8,11 @@
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
#include "common/nlohmann/json.hpp"
#define TIME_NOW() std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count() #include "api-driver/daemon.h"
typedef boost::property_tree::ptree::path_type json_path; 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; 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) + "\""; 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) { std::tuple<uint8_t, uint8_t> translateCoordinates(double abs) {
auto deg = static_cast<uint8_t>(abs); auto deg = static_cast<uint8_t>(abs);
double min_double = (abs - deg) * 60; double min_double = (abs - deg) * 60;
@ -265,126 +48,15 @@ std::string api_driver::ApiDriver::loadTerminalState() const {
if (daemon == nullptr) { if (daemon == nullptr) {
return R"({"error": "api daemon not started!"})"; return R"({"error": "api daemon not started!"})";
} }
std::stringstream result;
result << "{\n\"initState\":" << buildEscapedString(daemon->getDeviceInitState()); obj::TerminalState state;
result << ",\n\"testState\":" << boolAsStr(daemon->isTest()); daemon->getState(state);
obj::TerminalDeviceState devState;
daemon->getDeviceState(devState);
auto state = daemon->getState(); auto res = state.asJson();
#ifdef MODEM_IS_SCPC res["device"] = devState.asJson();
const bool isCinC = this->daemon->getIsCinC(); return res.dump();
#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();
} }
@ -450,118 +122,8 @@ std::string api_driver::ApiDriver::loadSettings() const {
return R"({"error": "api daemon not started!"})"; return R"({"error": "api daemon not started!"})";
} }
modulator_settings modSettings{}; // TODO сделать получение настроек
demodulator_settings demodSettings{}; return "{}";
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);
#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);
#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";
}
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 { std::string api_driver::ApiDriver::loadFirmwareVersion() const {
@ -601,178 +163,33 @@ static uint32_t buildModcodFromPt(const boost::property_tree::ptree& pt, const s
#endif #endif
void api_driver::ApiDriver::setRxTxSettings(boost::property_tree::ptree &pt) { void api_driver::ApiDriver::setRxTxSettings(boost::property_tree::ptree &pt) {
modulator_settings mod{}; // TODO
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 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
} }
void api_driver::ApiDriver::setDpdiSettings(boost::property_tree::ptree &pt) { void api_driver::ApiDriver::setDpdiSettings(boost::property_tree::ptree &pt) {
DPDI_parmeters s{}; // TODO
#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");
#endif
auto ctmp = translateCoordinates(pt.get<double>("dpdiPositionStationLatitude"));
s.latitude_station_grad = std::get<0>(ctmp);
s.latitude_station_minute = std::get<1>(ctmp);
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");
#endif
this->daemon->setSettingsDpdi(s);
} }
void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) { void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) {
buc_lnb_settings s{}; // TODO
#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) { void api_driver::ApiDriver::setQosSettings(boost::property_tree::ptree &pt) {
bool enabled = pt.get<bool>("en"); // TODO
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) { void api_driver::ApiDriver::setNetworkSettings(boost::property_tree::ptree &pt) {
TerminalNetworkSettings s; // TODO
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() { void api_driver::ApiDriver::resetDefaultSettings() {
daemon->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 { try {
std::lock_guard lock(this->daemon->cpApiMutex); std::lock_guard lock(this->daemon->cpApiMutex);
callback(this->daemon->sid); callback(this->daemon->cp);
} catch (std::exception& e) { } catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "ApiDriver::executeInApi(): failed to exec with error: " << e.what(); BOOST_LOG_TRIVIAL(error) << "ApiDriver::executeInApi(): failed to exec with error: " << e.what();
} }

View File

@ -1,10 +1,11 @@
#ifndef TERMINAL_API_DRIVER_H #ifndef TERMINAL_API_DRIVER_H
#define TERMINAL_API_DRIVER_H #define TERMINAL_API_DRIVER_H
#include "api-driver/stricts-enable.h"
#include "api-driver/proxy.h"
#include <memory> #include <memory>
#include <string> #include <string>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <terminal_api/ControlProtoCInterface.h>
namespace api_driver { namespace api_driver {
@ -13,7 +14,6 @@ namespace api_driver {
constexpr int CACHE_SETTINGS_UPDATE_MS = 5000; constexpr int CACHE_SETTINGS_UPDATE_MS = 5000;
constexpr int CACHE_QOS_UPDATE_MS = 5000; constexpr int CACHE_QOS_UPDATE_MS = 5000;
class StatisticsLogger;
class TerminalApiDaemon; class TerminalApiDaemon;
/** /**
@ -48,30 +48,37 @@ namespace api_driver {
*/ */
void setRxTxSettings(boost::property_tree::ptree &pt); void setRxTxSettings(boost::property_tree::ptree &pt);
#ifdef API_OBJECT_DPDI_SETTINGS_ENABLE
/** /**
* Установить настройки DPDI, readback можно получить используя loadTerminalState. * Установить настройки DPDI, readback можно получить используя loadTerminalState.
* @note Для TDMA и SCPC модемов эти настройки доступны * @note Для TDMA и SCPC модемов эти настройки доступны
*/ */
void setDpdiSettings(boost::property_tree::ptree &pt); void setDpdiSettings(boost::property_tree::ptree &pt);
#endif
#ifdef API_OBJECT_BUCLNB_SETTINGS_ENABLE
/** /**
* Установить настройки BUC и LNB, readback можно получить используя loadTerminalState. * Установить настройки BUC и LNB, readback можно получить используя loadTerminalState.
*/ */
void setBucLnbSettings(boost::property_tree::ptree &pt); void setBucLnbSettings(boost::property_tree::ptree &pt);
#endif
#ifdef API_OBJECT_QOS_SETTINGS_ENABLE
/** /**
* Установить настройки QoS, readback можно получить используя loadTerminalState. * Установить настройки QoS, readback можно получить используя loadTerminalState.
*/ */
void setQosSettings(boost::property_tree::ptree &pt); void setQosSettings(boost::property_tree::ptree &pt);
#endif
#ifdef API_OBJECT_NETWORK_SETTINGS_ENABLE
void setNetworkSettings(boost::property_tree::ptree &pt); void setNetworkSettings(boost::property_tree::ptree &pt);
#endif
void resetDefaultSettings(); void resetDefaultSettings();
void executeInApi(const std::function<void(TSID sid)> &callback); void executeInApi(const std::function<void(proxy::CpProxy&)> &callback);
#ifdef MODEM_IS_SCPC #ifdef API_OBJECT_DEBUG_METRICS_ENABLE
std::string getLoggingStatisticsSettings(); std::string getLoggingStatisticsSettings();
void setLoggingStatisticsSettings(boost::property_tree::ptree &pt); void setLoggingStatisticsSettings(boost::property_tree::ptree &pt);
@ -90,8 +97,6 @@ namespace api_driver {
std::string getOtaFileLocation() const; std::string getOtaFileLocation() const;
#endif #endif
static std::string loadSysInfo();
~ApiDriver(); ~ApiDriver();
private: private: