куча изменений, но зато теперь сохраняются настройки QoS и есть алгоритм сохранения параметров в API
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#include <shared_mutex>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
|
||||
#include "../dependencies/control_system/common/protocol_commands.h"
|
||||
|
||||
|
||||
@@ -20,16 +22,16 @@ private:
|
||||
|
||||
void updateStatistics() {
|
||||
modulator_state modulator{};
|
||||
CP_GetModulatorState(sid, modulator);
|
||||
|
||||
demodulator_state demodulator{};
|
||||
CP_GetDemodulatorState(sid, demodulator);
|
||||
|
||||
device_state device{};
|
||||
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
CP_GetModulatorState(sid, modulator);
|
||||
CP_GetDemodulatorState(sid, demodulator);
|
||||
CP_GetDeviceState(sid, device);
|
||||
|
||||
{
|
||||
std::lock_guard lock(this->stateMutex);
|
||||
std::lock_guard lock2(this->stateMutex);
|
||||
this->modState = modulator;
|
||||
this->demodState = demodulator;
|
||||
this->devState = device;
|
||||
@@ -38,20 +40,22 @@ private:
|
||||
|
||||
void updateSettings() {
|
||||
modulator_settings mod{};
|
||||
CP_GetModulatorSettings(sid, mod);
|
||||
// uint32_t modulatorModcod;
|
||||
// CP_GetModulatorParams(sid, "modcod", &modulatorModcod);
|
||||
demodulator_settings demod{};
|
||||
CP_GetDemodulatorSettings(sid, demod);
|
||||
ACM_parameters_serv_ acm{};
|
||||
CP_GetAcmParams(sid, &acm);
|
||||
DPDI_parmeters dpdi{};
|
||||
CP_GetDpdiParams(sid, &dpdi);
|
||||
buc_lnb_settings bucLnb{};
|
||||
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
CP_GetModulatorSettings(sid, mod);
|
||||
CP_GetDemodulatorSettings(sid, demod);
|
||||
CP_GetAcmParams(sid, &acm);
|
||||
CP_GetDpdiParams(sid, &dpdi);
|
||||
CP_GetBUC_LNB_settings(sid, bucLnb);
|
||||
|
||||
{
|
||||
std::lock_guard lock(this->settingsMutex);
|
||||
std::lock_guard lock2(this->settingsMutex);
|
||||
this->modSettings = mod;
|
||||
this->demodSettings = demod;
|
||||
this->acmSettings = acm;
|
||||
@@ -60,6 +64,17 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void updateQos() {
|
||||
bool tmp1; std::string tmp2;
|
||||
std::scoped_lock lock{this->cpApiMutex};
|
||||
CP_GetQoSSettings(this->sid, tmp2, tmp1);
|
||||
{
|
||||
std::lock_guard lock2(this->qosSettingsMutex);
|
||||
this->qosEnabled = tmp1;
|
||||
this->qosClassesJson = tmp2;
|
||||
}
|
||||
}
|
||||
|
||||
void run() {
|
||||
// это демон, который в бесконечном цикле опрашивает API
|
||||
|
||||
@@ -67,12 +82,14 @@ private:
|
||||
int64_t lastUpdate;
|
||||
int64_t periodMs;
|
||||
|
||||
bool checkNeedUpdate(int64_t now) {
|
||||
std::function<void()> callback;
|
||||
|
||||
bool checkNeedUpdate(int64_t now) const {
|
||||
// тут нет смысла спать меньше чем на 20мс, поэтому можно разрешить чтение на некоторое время раньше
|
||||
return now - lastUpdate >= (periodMs - 20);
|
||||
}
|
||||
|
||||
int64_t getNextUpdate(int64_t now) {
|
||||
int64_t getNextUpdate(int64_t now) const {
|
||||
if (checkNeedUpdate(now)) {
|
||||
return 0;
|
||||
}
|
||||
@@ -81,40 +98,57 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
IntervalUpdate_t statUpdate{.lastUpdate = 0, .periodMs = CACHE_STATISTICS_UPDATE_MS};
|
||||
IntervalUpdate_t settingsUpdate{.lastUpdate = 0, .periodMs = CACHE_SETTINGS_UPDATE_MS};
|
||||
|
||||
while (true) {
|
||||
auto now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
if (statUpdate.checkNeedUpdate(now)) {
|
||||
statUpdate.lastUpdate = now;
|
||||
IntervalUpdate_t updaters[] = {
|
||||
// обновление статистики
|
||||
{.lastUpdate = 0, .periodMs = CACHE_STATISTICS_UPDATE_MS, .callback = [this]() {
|
||||
try {
|
||||
updateStatistics();
|
||||
this->updateStatistics();
|
||||
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateStatistics(): success update!";
|
||||
} catch (std::exception& e) {
|
||||
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateStatistics(): " << e.what();
|
||||
}
|
||||
now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
if (settingsUpdate.checkNeedUpdate(now)) {
|
||||
settingsUpdate.lastUpdate = now;
|
||||
}},
|
||||
// обновление кеша настроек
|
||||
{.lastUpdate = 0, .periodMs = CACHE_SETTINGS_UPDATE_MS, .callback = [this]() {
|
||||
try {
|
||||
updateSettings();
|
||||
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();
|
||||
}
|
||||
now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}},
|
||||
// обновление кеша QoS
|
||||
{.lastUpdate = 0, .periodMs = CACHE_QOS_UPDATE_MS, .callback = [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();
|
||||
}
|
||||
}}
|
||||
};
|
||||
|
||||
while (true) {
|
||||
int64_t sleepTime = 60000; // минута по-умолчанию
|
||||
auto now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
for (auto& u: updaters) {
|
||||
if (u.checkNeedUpdate(now)) {
|
||||
u.lastUpdate = now;
|
||||
u.callback();
|
||||
now = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
|
||||
}
|
||||
|
||||
sleepTime = std::min(sleepTime, u.getNextUpdate(now));
|
||||
}
|
||||
|
||||
auto sleepTime = statUpdate.getNextUpdate(now);
|
||||
sleepTime = std::min(sleepTime, settingsUpdate.getNextUpdate(now));
|
||||
if (sleepTime > 0) {
|
||||
boost::this_thread::sleep_for(boost::chrono::duration(boost::chrono::milliseconds(sleepTime)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::mutex cpApiMutex;
|
||||
|
||||
std::shared_mutex stateMutex;
|
||||
modulator_state modState{};
|
||||
demodulator_state demodState{};
|
||||
@@ -127,8 +161,14 @@ private:
|
||||
DPDI_parmeters dpdiSettings{};
|
||||
buc_lnb_settings bucLnbSettings{};
|
||||
|
||||
std::shared_mutex qosSettingsMutex;
|
||||
bool qosEnabled;
|
||||
std::string qosClassesJson;
|
||||
|
||||
public:
|
||||
explicit TerminalApiDaemon(TSID sid): sid(sid), daemon([this]() { this->run(); }) {}
|
||||
explicit TerminalApiDaemon(TSID sid): sid(sid), daemon([this]() { this->run(); }), qosEnabled(false) {
|
||||
this->qosClassesJson = "{}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение статистики, копирует текущие значения в структуры, переданные по указателю. Если передан пустой указатель, копирования не произойдет.
|
||||
@@ -159,6 +199,26 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void getQosSettings(bool& isEnabled, std::string& json) {
|
||||
std::shared_lock lock(this->settingsMutex);
|
||||
isEnabled = this->qosEnabled;
|
||||
json = this->qosClassesJson;
|
||||
}
|
||||
|
||||
void setQosSettings(bool enabled, const std::string& str, bool readback = true) {
|
||||
std::lock_guard lock(this->cpApiMutex);
|
||||
CP_SetQoSSettings(this->sid, str, enabled);
|
||||
if (readback) {
|
||||
bool tmp1; std::string tmp2;
|
||||
CP_GetQoSSettings(this->sid, tmp2, tmp1);
|
||||
{
|
||||
std::lock_guard lock2(this->qosSettingsMutex);
|
||||
this->qosEnabled = tmp1;
|
||||
this->qosClassesJson = tmp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~TerminalApiDaemon() {
|
||||
try {
|
||||
daemon.interrupt();
|
||||
@@ -404,12 +464,27 @@ std::string api_driver::ApiDriver::loadSettings() const {
|
||||
result << ",\n\"serviceSettings.refClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_output);
|
||||
result << ",\"serviceSettings.autoStart\":" << boolAsStr(bucLnb.is_save_current_state);
|
||||
|
||||
bool qosEnabled = false; std::string qosClasses;
|
||||
daemon->getQosSettings(qosEnabled, qosClasses);
|
||||
result << ",\n\"qos.enabled\":" << boolAsStr(qosEnabled);
|
||||
result << ",\"qos.profile\":" << qosClasses;
|
||||
|
||||
result << "}";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
api_driver::ApiDriver::~ApiDriver() = default;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
bool api_driver::ApiDriver::getIsCinC() const {
|
||||
modulator_settings s{};
|
||||
daemon->getSettings(&s, nullptr, nullptr, nullptr, nullptr);
|
||||
|
Reference in New Issue
Block a user