247 lines
10 KiB
C++
247 lines
10 KiB
C++
#include "terminal_api_driver.h"
|
|
|
|
#include <cmath>
|
|
|
|
#include "terminal_api/ControlProtoCInterface.h"
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
|
|
#include "../dependencies/control_system/common/protocol_commands.h"
|
|
|
|
|
|
api_driver::ApiDriver::ApiDriver() {
|
|
CP_Login("admin", "pass", &sid, &access);
|
|
CP_GetDmaDebug(sid, "status_init", &deviceInitState);
|
|
}
|
|
|
|
static const char* boolAsStr(bool value) {
|
|
return value ? "true" : "false";
|
|
}
|
|
|
|
static std::string buildEscapedString(const std::string& source) {
|
|
std::string str(source);
|
|
size_t start_pos = 0;
|
|
while((start_pos = str.find('\"', start_pos)) != std::string::npos) {
|
|
str.replace(start_pos, 1, "\\\"");
|
|
start_pos += 2;
|
|
}
|
|
return "\"" + str + "\"";
|
|
}
|
|
|
|
static bool DriverCP_GetCinC(TSID sid) {
|
|
modulator_settings s{};
|
|
CP_GetModulatorSettings(sid, s);
|
|
return s.is_cinc;
|
|
}
|
|
|
|
void writeDouble(std::ostream& out, double value, int prec = 2) {
|
|
if (std::isnan(value) || std::isinf(value)) {
|
|
out << "\"nan\"";
|
|
} else {
|
|
out << std::fixed << std::setprecision(prec) << value;
|
|
}
|
|
}
|
|
|
|
double translateCoordinates(uint8_t deg, uint8_t min) {
|
|
return static_cast<double>(deg) + static_cast<double>(min) / 60;
|
|
}
|
|
|
|
std::tuple<uint8_t, uint8_t> translateCoordinates(double abs) {
|
|
auto deg = static_cast<uint8_t>(abs);
|
|
double min_double = (abs - deg) * 60;
|
|
auto min = static_cast<uint8_t>(min_double);
|
|
return std::make_tuple(deg, min);
|
|
}
|
|
|
|
|
|
std::string api_driver::ApiDriver::loadTerminalState() const {
|
|
std::stringstream result;
|
|
result << "{\n\"initState\":" << buildEscapedString(this->deviceInitState);
|
|
|
|
modulator_state modulator{};
|
|
CP_GetModulatorState(sid, modulator);
|
|
|
|
demodulator_state demodulator{};
|
|
CP_GetDemodulatorState(sid, demodulator);
|
|
|
|
device_state device{};
|
|
CP_GetDeviceState(sid, device);
|
|
|
|
const bool isCinC = DriverCP_GetCinC(sid);
|
|
|
|
result << ",\"isCinC\":" << boolAsStr(isCinC);
|
|
|
|
// формируем структуру для TX
|
|
result << ",\n\"tx.state\":" << boolAsStr(modulator.is_tx_on);
|
|
result << ",\"tx.modcod\":" << modulator.modcod;
|
|
result << ",\"tx.snr\":"; writeDouble(result, modulator.snr_remote);
|
|
|
|
if (modulator.is_short) {
|
|
result << R"(,"tx.frameSize":"short")";
|
|
} else {
|
|
result << R"(,"tx.frameSize":"normal")";
|
|
}
|
|
|
|
if (modulator.is_pilots) {
|
|
result << R"(,"tx.pilots":"pilots")";
|
|
} else {
|
|
result << R"(,"tx.pilots":"no pilots")";
|
|
}
|
|
|
|
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.frameSize":"short")";
|
|
} else {
|
|
result << R"(,"rx.frameSize":"normal")";
|
|
}
|
|
|
|
if (demodulator.is_pilots) {
|
|
result << R"(,"rx.pilots":"pilots")";
|
|
} else {
|
|
result << R"(,"rx.pilots":"no pilots")";
|
|
}
|
|
|
|
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;
|
|
|
|
// формируем структуру для CinC
|
|
if (isCinC) {
|
|
CinC_state state_cinc{};
|
|
CP_GetCinCState(sid,state_cinc);
|
|
|
|
if (modulator.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)";
|
|
}
|
|
|
|
// структура температур девайса
|
|
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);
|
|
|
|
result << "}";
|
|
|
|
return result.str();
|
|
}
|
|
|
|
|
|
void api_driver::ApiDriver::resetPacketStatistics() const {
|
|
std::string tmp;
|
|
CP_GetDmaDebug(sid, "reset_cnt_rx", &tmp);
|
|
}
|
|
|
|
std::string api_driver::ApiDriver::loadSettings() const {
|
|
modulator_settings modSettings{};
|
|
CP_GetModulatorSettings(sid, modSettings);
|
|
uint32_t modulatorModcod;
|
|
CP_GetModulatorParams(sid, "modcod", &modulatorModcod);
|
|
|
|
demodulator_settings demodSettings{};
|
|
CP_GetDemodulatorSettings(sid, demodSettings);
|
|
ACM_parameters_serv_ acmSettings{};
|
|
CP_GetAcmParams(sid, &acmSettings);
|
|
DPDI_parmeters dpdiSettings{};
|
|
CP_GetDpdiParams(sid, &dpdiSettings);
|
|
buc_lnb_settings bucLnb{};
|
|
CP_GetBUC_LNB_settings(sid, bucLnb);
|
|
|
|
std::stringstream result;
|
|
result << "{\n\"general.isCinC\":" << boolAsStr(modSettings.is_cinc);
|
|
result << ",\"general.txEn\":" << boolAsStr(modSettings.tx_is_on);
|
|
result << ",\"general.modulatorMode\":" << (modSettings.is_carrier ? "\"normal\"" : "\"test\"");
|
|
result << ",\"general.autoStartTx\":" << boolAsStr(modSettings.is_save_current_state);
|
|
result << ",\"general.isTestInputData\":" << boolAsStr(modSettings.is_test_data);
|
|
|
|
result << ",\n\"tx.attenuation\":"; writeDouble(result, modSettings.attenuation);
|
|
result << ",\"tx.rolloff\":" << static_cast<int>(modSettings.rollof * 100);
|
|
result << ",\"tx.cymRate\":" << modSettings.baudrate;
|
|
result << ",\"tx.centerFreq\":"; writeDouble(result, modSettings.central_freq_in_kGz, 3);
|
|
|
|
result << ",\n\"dvbs2.isAcm\":" << boolAsStr(acmSettings.enable);
|
|
result << ",\"dvbs2.frameSize\":" << ((modulatorModcod & 2) ? "\"short\"" : "\"normal\"");
|
|
// result << ",\"dvbs2.pilots\":" << "null";
|
|
result << ",\"dvbs2.ccm_modcod\":" << (modulatorModcod >> 4);
|
|
result << ",\"dvbs2.acm_maxModcod\":" << (acmSettings.max_modcod >> 2);
|
|
result << ",\"dvbs2.acm_minModcod\":" << (acmSettings.min_modcod >> 2);
|
|
result << ",\"dvbs2.snrReserve\":"; writeDouble(result, acmSettings.min_attenuation);
|
|
result << ",\"dvbs2.servicePacketPeriod\":" << acmSettings.period_pack;
|
|
|
|
result << ",\n\"acm.en\":" << boolAsStr(acmSettings.enable_auto_atten);
|
|
result << ",\"acm.maxAttenuation\":"; writeDouble(result, acmSettings.max_attenuation);
|
|
result << ",\"acm.minAttenuation\":"; writeDouble(result, acmSettings.min_attenuation);
|
|
result << ",\"acm.requiredSnr\":"; writeDouble(result, acmSettings.snr_treashold_acm);
|
|
|
|
result << ",\n\"rx.gainMode\":" << (demodSettings.is_aru_on ? "\"auto\"" : "\"manual\"");
|
|
result << ",\"rx.manualGain\":"; writeDouble(result, demodSettings.gain);
|
|
result << ",\"rx.spectrumInversion\":" << boolAsStr(demodSettings.is_rvt_iq);
|
|
result << ",\"rx.rolloff\":" << static_cast<int>(demodSettings.rollof * 100);
|
|
result << ",\"rx.cymRate\":" << demodSettings.baudrate;
|
|
result << ",\"rx.centerFreq\":"; writeDouble(result, demodSettings.central_freq_in_kGz);
|
|
|
|
result << ",\n\"cinc.mode\":" << (dpdiSettings.is_delay_window ? "\"delay\"" : "\"positional\"");
|
|
result << ",\"cinc.searchBandwidth\":" << dpdiSettings.freq_offset; // полоса поиска в кГц
|
|
result << ",\"cinc.position.station.latitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.latitude_station_grad, dpdiSettings.latitude_station_minute), 6);
|
|
result << ",\"cinc.position.station.longitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_station_grad, dpdiSettings.longitude_station_minute), 6);
|
|
result << ",\"cinc.position.satelliteLongitude\":"; writeDouble(result, translateCoordinates(dpdiSettings.longitude_sattelite_grad, dpdiSettings.longitude_sattelite_minute), 6);
|
|
result << ",\"cinc.delayMin\":" << dpdiSettings.min_delay;
|
|
result << ",\"cinc.delayMax\":" << dpdiSettings.max_delay;
|
|
|
|
result << ",\n\"buc.refClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_buc);
|
|
switch (bucLnb.buc) {
|
|
case voltage_buc::DISABLE: result << ",\"buc.powering\":0"; break;
|
|
case voltage_buc::_24V: result << ",\"buc.powering\":24"; break;
|
|
case voltage_buc::_48V: result << ",\"buc.powering\":48"; break;
|
|
}
|
|
|
|
result << ",\n\"lnb.refClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_lnb);
|
|
switch (bucLnb.lnb) {
|
|
case voltage_lnb::DISABLE: result << ",\"lnb.powering\":0"; break;
|
|
case voltage_lnb::_13V: result << ",\"lnb.powering\":13"; break;
|
|
case voltage_lnb::_18V: result << ",\"lnb.powering\":18"; break;
|
|
case voltage_lnb::_24V: result << ",\"lnb.powering\":24"; break;
|
|
}
|
|
|
|
result << ",\n\"serviceSettings.refClk10M\":" << boolAsStr(bucLnb.is_ref_10MHz_output);
|
|
result << ",\"serviceSettings.autoStart\":" << boolAsStr(bucLnb.is_save_current_state);
|
|
|
|
result << "}";
|
|
return result.str();
|
|
}
|
|
|
|
api_driver::ApiDriver::~ApiDriver() = default;
|