какая-то куча изменений (2). тут уже вырисовывается новая архитектура бекенда для cp api
This commit is contained in:
@@ -1,8 +1,68 @@
|
||||
#include "api-driver/structs.h"
|
||||
#include "api-driver/proxy.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sys/sysinfo.h>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
#include "api-driver/proxy.h"
|
||||
|
||||
#define TIME_NOW() std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now()).time_since_epoch().count()
|
||||
|
||||
typedef boost::property_tree::ptree::path_type json_path;
|
||||
|
||||
static constexpr const char* DEFAULT_QOS_CLASSES = R"({"rt1":[],"rt2":[],"rt3":[],"cd":[]})";
|
||||
// пороговое значение сна
|
||||
|
||||
// static int calculateSubnetMask(const std::string& subnet_mask) {
|
||||
// int mask = 0;
|
||||
// std::istringstream iss(subnet_mask);
|
||||
// std::string octet;
|
||||
// while (std::getline(iss, octet, '.')) {
|
||||
// int octet_value = std::stoi(octet);
|
||||
// for (int i = 7; i >= 0; i--) {
|
||||
// if (octet_value & (1 << i)) {
|
||||
// mask++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return mask;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Преобразует строку вида `1.2.3.4/24` в пару строк вида `1.2.3.4` `255.255.255.0`
|
||||
*/
|
||||
// std::pair<std::string, std::string> splitIpAndMask(const std::string& input) {
|
||||
// auto pos = input.find('/');
|
||||
// if (pos == std::string::npos) {
|
||||
// // Обработка ошибки: нет символа '/'
|
||||
// throw std::runtime_error("address not contains mask");
|
||||
// }
|
||||
// std::string ip = input.substr(0, pos);
|
||||
// const unsigned int mask_int = std::stoul(input.substr(pos + 1));
|
||||
//
|
||||
// if (mask_int > 32) {
|
||||
// throw std::runtime_error("invalid mask");
|
||||
// }
|
||||
//
|
||||
// std::string mask_binary = std::string(mask_int, '1') + std::string(32 - mask_int, '0');
|
||||
// std::string mask_str;
|
||||
//
|
||||
// for (unsigned int i = 0; i < 4; ++i) {
|
||||
// std::string octet = mask_binary.substr(i * 8u, 8);
|
||||
// int octet_value = std::stoi(octet, nullptr, 2);
|
||||
// mask_str += std::to_string(octet_value) + (i < 3 ? "." : "");
|
||||
// }
|
||||
//
|
||||
// return std::make_pair(ip, mask_str);
|
||||
// }
|
||||
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";
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, CP_Result result) {
|
||||
switch (result) {
|
||||
@@ -47,23 +107,227 @@ int64_t api_driver::obj::CpUpdatebleObject::getNextUpdate(int64_t now) const {
|
||||
}
|
||||
api_driver::obj::CpUpdatebleObject::~CpUpdatebleObject() = default;
|
||||
|
||||
#if API_OBJECT_STATISTICS_ENABLE
|
||||
api_driver::obj::StatisticsLogger::StatisticsLogger(): timeStart(TIME_NOW()) {}
|
||||
|
||||
void api_driver::obj::TerminalState::updateCallback(TSID sid, CP_Result &lastCpError) {
|
||||
constexpr const char* thisFunc = "api_driver::obj::TerminalState::load()";
|
||||
std::string api_driver::obj::StatisticsLogger::getSettings() {
|
||||
std::lock_guard _lock(mutex);
|
||||
std::stringstream res;
|
||||
res << "{\"en\":" << boolAsStr(this->logEn);
|
||||
res << ",\"logPeriodMs\":" << logPeriodMs;
|
||||
res << ",\"maxAgeMs\":" << maxAgeMs;
|
||||
res << '}';
|
||||
return res.str();
|
||||
}
|
||||
|
||||
modulator_state modulator{};
|
||||
demodulator_state demodulator{};
|
||||
void api_driver::obj::StatisticsLogger::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(LOG_FILENAME, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void api_driver::obj::StatisticsLogger::updateCallback(proxy::CpProxy &cp) {
|
||||
|
||||
}
|
||||
|
||||
void api_driver::obj::StatisticsLogger::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();
|
||||
}
|
||||
}
|
||||
|
||||
api_driver::obj::StatisticsLogger::~StatisticsLogger() = default;
|
||||
#endif
|
||||
|
||||
#if API_OBJECT_NETWORK_SETTINGS_ENABLE
|
||||
api_driver::obj::TerminalNetworkSettings::TerminalNetworkSettings() { loadDefaults(); }
|
||||
|
||||
api_driver::obj::TerminalNetworkSettings::TerminalNetworkSettings(const TerminalNetworkSettings &src) = default;
|
||||
|
||||
api_driver::obj::TerminalNetworkSettings & api_driver::obj::TerminalNetworkSettings::operator=(const TerminalNetworkSettings &src) {
|
||||
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() {
|
||||
managementIp = "0.0.0.0";
|
||||
managementGateway = "";
|
||||
isL2 = true;
|
||||
dataIp = "0.0.0.0";
|
||||
dataMtu = 1500;
|
||||
serverName = DEFAULT_SERVER_NAME;
|
||||
}
|
||||
|
||||
void api_driver::obj::TerminalNetworkSettings::updateCallback(proxy::CpProxy &cp) {
|
||||
loadDefaults();
|
||||
try {
|
||||
managementIp = cp.getNetwork("addr");
|
||||
// s.managementIp += "/";
|
||||
// s.managementIp += std::to_string(calculateSubnetMask(cp.getNetwork("mask")));
|
||||
|
||||
managementGateway = cp.getNetwork("gateway");
|
||||
if (cp.getNetwork("mode") == "tun") {
|
||||
isL2 = false;
|
||||
dataIp = cp.getNetwork("addr_data");
|
||||
} else {
|
||||
isL2 = true;
|
||||
}
|
||||
dataMtu = 1500;
|
||||
serverName = cp.getNetwork("name_serv");
|
||||
if (serverName.empty()) {
|
||||
serverName = DEFAULT_SERVER_NAME;
|
||||
}
|
||||
} catch (std::exception& e) {
|
||||
throw std::runtime_error(std::string("api_driver::obj::TerminalNetworkSettings::updateCallback() error: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void api_driver::obj::TerminalNetworkSettings::updateFromPt(boost::property_tree::ptree &pt) {
|
||||
}
|
||||
|
||||
void api_driver::obj::TerminalNetworkSettings::store(proxy::CpProxy& cp) {
|
||||
try {
|
||||
cp.setNetwork("mode", isL2 ? "tap" : "tun");
|
||||
cp.setNetwork("addr", managementIp);
|
||||
|
||||
if (!isL2) {
|
||||
cp.setNetwork("addr_data", dataIp);
|
||||
}
|
||||
cp.setNetwork("mask", "255.255.255.0");
|
||||
cp.setNetwork("gateway", managementGateway);
|
||||
|
||||
// cp.setNetwork("data_mtu", std::to_string(dataMtu));
|
||||
|
||||
cp.setNetwork("name_serv", serverName);
|
||||
} catch (std::exception& e) {
|
||||
throw std::runtime_error(std::string("api_driver::obj::TerminalNetworkSettings::store() error: ") + e.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::string api_driver::obj::TerminalNetworkSettings::asJson() {
|
||||
std::stringstream out;
|
||||
|
||||
return out.str();
|
||||
}
|
||||
|
||||
api_driver::obj::TerminalNetworkSettings::~TerminalNetworkSettings() = default;
|
||||
#endif
|
||||
|
||||
#if API_OBJECT_QOS_SETTINGS_ENABLE
|
||||
api_driver::obj::TerminalQosSettings::TerminalQosSettings() {
|
||||
}
|
||||
|
||||
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::updateCallback(proxy::CpProxy &cp) {
|
||||
}
|
||||
|
||||
void api_driver::obj::TerminalQosSettings::updateFromPt(boost::property_tree::ptree &pt) {
|
||||
}
|
||||
|
||||
void api_driver::obj::TerminalQosSettings::store(proxy::CpProxy &cp) {
|
||||
}
|
||||
|
||||
std::string api_driver::obj::TerminalQosSettings::asJson() {
|
||||
}
|
||||
|
||||
api_driver::obj::TerminalQosSettings::~TerminalQosSettings() {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void api_driver::obj::TerminalState::updateCallback(proxy::CpProxy& cp) {
|
||||
modulator_state mod{};
|
||||
demodulator_state demod{};
|
||||
#ifdef MODEM_IS_SCPC
|
||||
CinC_state cinc{};
|
||||
#endif
|
||||
try {
|
||||
cp.getModState(mod);
|
||||
cp.getDemodState(demod);
|
||||
#ifdef MODEM_IS_SCPC
|
||||
// CinC state прописывается в настройках
|
||||
{
|
||||
|
||||
proxy::getModState(sid, modulator, thisFunc);
|
||||
proxy::getDemodState(sid, demodulator, thisFunc);
|
||||
#ifdef MODEM_IS_TDMA
|
||||
const auto tmpDevState = proxy::getDmaDebug(sid, "status_init", thisFunc);
|
||||
}
|
||||
cp.getCincState(cinc);
|
||||
#endif
|
||||
#ifdef MODEM_IS_TDMA
|
||||
fInitState = cp.getDmaDebug("status_init");
|
||||
#endif
|
||||
} catch (std::exception& e) {
|
||||
throw std::runtime_error(std::string("api_driver::obj::TerminalState::updateCallback() error: ") + e.what());
|
||||
}
|
||||
|
||||
|
||||
#ifdef MODEM_IS_SCPC
|
||||
|
||||
bool isCinC = getIsCinC();
|
||||
if (isCinC) {
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateState()->CP_GetCinCState()", CP_GetCinCState(sid, cinc));
|
||||
@@ -71,7 +335,6 @@ void api_driver::obj::TerminalState::updateCallback(TSID sid, CP_Result &lastCpE
|
||||
#endif
|
||||
|
||||
{
|
||||
std::lock_guard lock2(this->mutex);
|
||||
#ifdef MODEM_IS_TDMA
|
||||
this->fInitState = tmpDevState;
|
||||
#endif
|
||||
@@ -201,6 +464,96 @@ void api_driver::obj::TerminalState::updateCallback(TSID sid, CP_Result &lastCpE
|
||||
api_driver::obj::TerminalState::~TerminalState() = default;
|
||||
|
||||
|
||||
api_driver::obj::TerminalDeviceState::TerminalDeviceState() = default;
|
||||
api_driver::obj::TerminalDeviceState::TerminalDeviceState(const TerminalDeviceState &src) = default;
|
||||
api_driver::obj::TerminalDeviceState & api_driver::obj::TerminalDeviceState::operator=(const TerminalDeviceState &src) {
|
||||
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) {
|
||||
{
|
||||
device_state ds{};
|
||||
cp.getDeviceState(ds);
|
||||
fTempAdrv = ds.adrv_temp;
|
||||
fTempZynq = ds.pl_temp;
|
||||
fTempFpga = ds.zynq_temp;
|
||||
}
|
||||
#ifdef MODEM_IS_TDMA
|
||||
{
|
||||
progress_msg ds{};
|
||||
logCpApiError("api_driver::TerminalApiDaemon::updateState()->CP_GetUpdateStatus()", CP_GetUpdateStatus(sid, ds));
|
||||
fOtaStatus = ds.status;
|
||||
fOtaPercent = ds.dwl_percent;
|
||||
fOtaImage = ds.cur_image;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct sysinfo info{};
|
||||
sysinfo(&info);
|
||||
|
||||
const double f_load = 100.0 / ((1 << SI_LOAD_SHIFT) * get_nprocs());
|
||||
fOsUptime = info.uptime;
|
||||
fOsLoad1 = f_load * static_cast<double>(info.loads[0]);
|
||||
fOsLoad5 = f_load * static_cast<double>(info.loads[1]);
|
||||
fOsLoad15 = f_load * static_cast<double>(info.loads[2]);
|
||||
fOsTotalram = (info.totalram * info.mem_unit) >> 20; // Mb
|
||||
fOsFreeram = (info.totalram * info.mem_unit) >> 20; // Mb
|
||||
fOsProcs = info.procs;
|
||||
}
|
||||
|
||||
std::string api_driver::obj::TerminalDeviceState::asJson() const {
|
||||
std::stringstream result;
|
||||
result << "{\"uptime\":" << fOsUptime
|
||||
<< ",\"load1min\":" << std::setprecision(2) << fOsLoad1
|
||||
<< ",\"load5min\":" << std::setprecision(2) << fOsLoad5
|
||||
<< ",\"load15min\":" << std::setprecision(2) << fOsLoad15
|
||||
<< ",\"totalram\":" << fOsTotalram
|
||||
<< ",\"freeram\":" << fOsFreeram
|
||||
<< ",\"procs\":" << fOsProcs
|
||||
<< ",\"adrv\":" << std::setprecision(1) << fTempAdrv
|
||||
<< ",\"fpga\":" << std::setprecision(1) << fTempFpga
|
||||
<< ",\"zynq\":" << std::setprecision(1) << fTempZynq;
|
||||
#ifdef MODEM_IS_TDMA
|
||||
if (fUpgradeImage.empty()) {
|
||||
result << R"(,
|
||||
"upgradeStatus":"Нет обновлений","upgradePercent":0,"upgradeImage":"")";
|
||||
} else {
|
||||
switch (fUpgradeStatus) {
|
||||
case NORM_RX_OBJECT_NEW_API: result << ",\n" R"("upgradeStatus": "Начало загрузки")"; break;
|
||||
case NORM_RX_OBJECT_INFO_API: result << ",\n" R"("upgradeStatus": "Получено имя образа")"; break;
|
||||
case NORM_RX_OBJECT_UPDATED_API: result << ",\n" R"("upgradeStatus": "Загружается")"; break;
|
||||
case NORM_RX_OBJECT_COMPLETED_API: result << ",\n" R"("upgradeStatus": "Загрузка завершена")"; break;
|
||||
case NORM_RX_OBJECT_ABORTED_API: result << ",\n" R"("upgradeStatus": "Загрузка прервана")"; break;
|
||||
default: result << ",\n" R"("upgradeStatus": "?")";
|
||||
|
||||
}
|
||||
result << ",\"upgradePercent\":" << fUpgradePercent;
|
||||
result << ",\"upgradeImage\":" << buildEscapedString(fUpgradeImage);
|
||||
}
|
||||
|
||||
#endif
|
||||
result << "}";
|
||||
return result.str();
|
||||
}
|
||||
|
||||
api_driver::obj::TerminalDeviceState::~TerminalDeviceState() = default;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user