Compare commits

..

No commits in common. "ed1bd12c9547bcde95ee9cba571959faa4cb3e80" and "eda26319c420b70f831ebb0eeb05277c149a8995" have entirely different histories.

4 changed files with 56 additions and 291 deletions

View File

@ -212,18 +212,6 @@ public:
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
}));
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/get/aboutFirmware", this->auth, 0, [this](const auto& req, auto& rep) {
if (req.method != "GET") {
http::server::stockReply(http::server::bad_request, rep);
}
rep.status = http::server::ok;
rep.headers.clear();
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
const auto result = api->loadFirmwareVersion();
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
}));
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/resetPacketStatistics", this->auth, http::auth::User::RESET_PACKET_STATISTICS, [this](const auto& req, auto& rep) {
if (req.method != "POST") {
http::server::stockReply(http::server::bad_request, rep);
@ -349,62 +337,6 @@ public:
}
}));
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/network", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
if (req.method != "POST") {
http::server::stockReply(http::server::bad_request, rep);
}
rep.status = http::server::ok;
rep.headers.clear();
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
try {
std::stringstream ss;
ss.str(std::string(req.payload.begin(), req.payload.end()));
boost::property_tree::ptree pt;
read_json(ss, pt);
api->setNetworkSettings(pt);
std::string result = R"({"status":"ok","settings":)";
result += api->loadSettings();
result += "}";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
} catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/rxtx): Can't set RX/TX settings: " << e.what();
const std::string result = R"({"status":"error"})";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
}
}));
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/set/debugSend", this->auth, http::auth::User::EDIT_SETTINGS, [this](const auto& req, auto& rep) {
if (req.method != "POST") {
http::server::stockReply(http::server::bad_request, rep);
}
rep.status = http::server::ok;
rep.headers.clear();
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
try {
std::stringstream ss;
ss.str(std::string(req.payload.begin(), req.payload.end()));
boost::property_tree::ptree pt;
read_json(ss, pt);
api->setDebugSendSettings(pt);
std::string result = R"({"status":"ok","settings":)";
result += api->loadSettings();
result += "}";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
} catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "WebHandle(/api/set/rxtx): Can't set RX/TX settings: " << e.what();
const std::string result = R"({"status":"error"})";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());
}
}));
s.resources.emplace_back(std::make_unique<http::auth::AuthRequiredResource>("/api/firmwareUpdate", this->auth, http::auth::User::UPDATE_FIRMWARE, [this](const auto& req, auto& rep) {
if (req.method != "PUT") {
http::server::stockReply(http::server::bad_request, rep);
@ -416,7 +348,7 @@ public:
rep.headers.push_back({.name = "Content-Type", .value = toString(mime_types::json)});
std::string result = R"({"status":"ok","fwsize":)";
result += std::to_string(req.payload.size());
result += R"(,"sha256":")";
result += ",\"sha256\":\"";
result += http::utils::sha256(req.payload.data(), req.payload.size());
result += "\"}";
rep.content.insert(rep.content.end(), result.c_str(), result.c_str() + result.size());

View File

@ -30,63 +30,16 @@ static int calculateSubnetMask(const std::string& subnet_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);
}
class TerminalNetworkSettings {
public:
std::string managementIp, managementGateway, mode, dataIp;
unsigned int dataMtu = 1500;
TerminalNetworkSettings() { this->reset(); }
TerminalNetworkSettings() = default;
TerminalNetworkSettings(const TerminalNetworkSettings& src) = default;
~TerminalNetworkSettings() = default;
TerminalNetworkSettings& operator= (const TerminalNetworkSettings& src) = default;
void reset() {
managementIp = "0.0.0.0/0";
managementGateway = "";
mode = "l2";
dataIp = "0.0.0.0/0";
dataMtu = 1500;
}
};
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;
};
/**
@ -97,26 +50,6 @@ private:
TSID sid;
boost::thread daemon;
void updateFirmwareSettings() {
std::string version, chip_id, sn, mac0, mac1;
std::lock_guard lock(this->cpApiMutex);
CP_GetNetwork(sid, "version", &version);
CP_GetNetwork(sid, "chip_id", &chip_id);
CP_GetNetwork(sid, "serial", &sn);
CP_GetNetwork(sid, "mac_eth0", &mac0);
CP_GetNetwork(sid, "mac_eth1", &mac1);
{
std::lock_guard lock2(this->firmwareMutex);
this->firmware.version = version;
this->firmware.modemId = chip_id;
this->firmware.modemSn = sn;
this->firmware.macMang = mac0;
this->firmware.macData = mac1;
}
}
void updateStatistics() {
modulator_state modulator{};
demodulator_state demodulator{};
@ -165,11 +98,11 @@ private:
TerminalNetworkSettings s;
std::string tmp;
std::lock_guard lock(this->cpApiMutex);
CP_GetNetwork(sid, "addr", &tmp);
s.managementIp = tmp + "/";
tmp.clear(); CP_GetNetwork(sid, "mask", &tmp);
CP_GetNetwork(sid, "addr", &s.managementIp);
CP_GetNetwork(sid, "mask", &tmp);
s.managementIp += "/";
s.managementIp += std::to_string(calculateSubnetMask(tmp));
tmp.clear(); CP_GetNetwork(sid, "gateway", &s.managementGateway); s.managementGateway = tmp;
CP_GetNetwork(sid, "gateway", &s.managementGateway);
tmp.clear(); CP_GetNetwork(sid, "mode", &tmp);
if (tmp == "tun") {
s.mode = "l3";
@ -199,7 +132,6 @@ private:
void run() {
// это демон, который в бесконечном цикле опрашивает API
updateFirmwareSettings();
struct IntervalUpdate_t {
int64_t lastUpdate;
@ -243,10 +175,10 @@ private:
// обновление кеша настроек сети (делается отдельно)
{.lastUpdate = 0, .periodMs = CACHE_SETTINGS_UPDATE_MS, .callback = [this]() {
try {
this->updateNetworkSettings();
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateNetworkSettings(): success update!";
this->updateSettings();
BOOST_LOG_TRIVIAL(debug) << "api_driver::TerminalApiDaemon::updateSettings(): success update!";
} catch (std::exception& e) {
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateNetworkSettings(): " << e.what();
BOOST_LOG_TRIVIAL(error) << "api_driver::TerminalApiDaemon::updateSettings(): " << e.what();
}
}},
// обновление кеша QoS
@ -281,9 +213,6 @@ private:
std::mutex cpApiMutex;
std::shared_mutex firmwareMutex;
TerminalFirmwareVersion firmware;
std::shared_mutex stateMutex;
modulator_state modState{};
demodulator_state demodState{};
@ -348,11 +277,6 @@ public:
json = this->qosClassesJson;
}
void getFirmwareVersion(TerminalFirmwareVersion& fw) {
std::shared_lock lock(this->settingsMutex);
fw = this->firmware;
}
void setSettingsRxTx(modulator_settings& mod, demodulator_settings& demod, ACM_parameters_serv_& acm, bool readback = true) {
std::lock_guard lock(this->cpApiMutex);
CP_SetDmaDebug(sid, "begin_save_config", "");
@ -417,51 +341,6 @@ public:
CP_SetDmaDebug(sid, "save_config", "");
}
void setNetworkSettings(TerminalNetworkSettings& s, bool readback = true) {
const auto [mAddr, mMask] = splitIpAndMask(s.managementIp);
const auto [dAddr, dMask] = splitIpAndMask(s.dataIp);
bool isL2;
if (s.mode == "l2") { isL2 = true; }
else if (s.mode == "l3") { isL2 = false; }
else { throw std::runtime_error("invalid mode"); }
std::lock_guard lock(this->cpApiMutex);
CP_SetDmaDebug(sid, "begin_save_config", "");
CP_SetNetwork(sid, "mode", isL2 ? "tap" : "tun");
CP_SetNetwork(sid, "addr", mAddr.c_str());
CP_SetNetwork(sid, "mask", mMask.c_str());
CP_SetNetwork(sid, "gateway", s.managementGateway.c_str());
if (!isL2) {
CP_SetNetwork(sid, "data_addr", dAddr.c_str());
// TODO маска не устанавливается, потому что в API этого нет
}
// TODO MTU не устанавливается, потому что в API этого нет
if (readback) {
std::string tmp;
s.reset();
CP_GetNetwork(sid, "addr", &s.managementIp);
CP_GetNetwork(sid, "mask", &tmp);
s.managementIp += "/";
s.managementIp += std::to_string(calculateSubnetMask(tmp));
CP_GetNetwork(sid, "gateway", &s.managementGateway);
tmp.clear(); CP_GetNetwork(sid, "mode", &tmp);
if (tmp == "tun") {
s.mode = "l3";
CP_GetNetwork(sid, "addr_data", &s.dataIp);
} else {
s.mode = "l2";
s.dataIp = "0.0.0.0/24";
}
s.dataMtu = 1500;
{
std::lock_guard lock2(this->networkSettingsMutex);
this->networkSettings = s;
}
}
CP_SetDmaDebug(sid, "save_config", "");
}
void resetPacketStatistics() {
std::string tmp;
std::lock_guard lock(this->cpApiMutex);
@ -648,6 +527,13 @@ std::string api_driver::ApiDriver::loadSettings() const {
daemon->getSettings(&modSettings, &demodSettings, &acmSettings, &dpdiSettings, &bucLnb);
daemon->getNetworkSettings(network);
// uint32_t modulatorModcod;
// {
// modulator_state ms{};
// daemon->getStatistics(&ms, nullptr, nullptr);
// modulatorModcod = ms.modcod;
// }
std::stringstream result;
result << "{\n\"general.isCinC\":" << boolAsStr(modSettings.is_cinc);
result << ",\"general.txEn\":" << boolAsStr(modSettings.tx_is_on);
@ -724,23 +610,6 @@ std::string api_driver::ApiDriver::loadSettings() const {
return result.str();
}
std::string api_driver::ApiDriver::loadFirmwareVersion() const {
if (daemon == nullptr) {
return R"({"error": "api daemon not started!"})";
}
TerminalFirmwareVersion firmware;
daemon->getFirmwareVersion(firmware);
std::stringstream result;
result << "{\n\"fw.version\":" << buildEscapedString(firmware.version);
result << ",\"fw.modemId\":" << buildEscapedString(firmware.modemId);
result << ",\"fw.modemSn\":" << buildEscapedString(firmware.modemSn);
result << ",\"fw.macMang\":" << buildEscapedString(firmware.macMang);
result << ",\"fw.macData\":" << buildEscapedString(firmware.macData);
result << "\n}";
return result.str();
}
void api_driver::ApiDriver::setRxTxSettings(boost::property_tree::ptree &pt) {
modulator_settings mod{};
demodulator_settings demod{};
@ -839,6 +708,7 @@ void api_driver::ApiDriver::setBucLnbSettings(boost::property_tree::ptree &pt) {
default:
s.lnb = voltage_lnb::DISABLE;
}
// { "lnb": {"powering": 0} }
s.is_ref_10MHz_buc = pt.get<bool>(json_path("buc.refClk10M", '/'));
@ -858,21 +728,6 @@ void api_driver::ApiDriver::setQosSettings(boost::property_tree::ptree &pt) {
this->daemon->setQosSettings(enabled, oss.str());
}
void api_driver::ApiDriver::setNetworkSettings(boost::property_tree::ptree &pt) {
TerminalNetworkSettings s;
s.managementIp = pt.get<std::string>(json_path("network.managementIp", '/'));
s.managementGateway = pt.get<std::string>(json_path("network.managementGateway", '/'));
s.mode = pt.get<std::string>(json_path("network.mode", '/'));
s.dataIp = pt.get<std::string>(json_path("network.dataIp", '/'));
s.dataMtu = pt.get<unsigned int>(json_path("network.dataMtu", '/'));
daemon->setNetworkSettings(s);
}
void api_driver::ApiDriver::setDebugSendSettings(boost::property_tree::ptree &pt) {
boost::ignore_unused(pt);
}
bool api_driver::ApiDriver::getIsCinC() const {
modulator_settings s{};
daemon->getSettings(&s, nullptr, nullptr, nullptr, nullptr);

View File

@ -39,8 +39,6 @@ namespace api_driver {
std::string loadSettings() const;
std::string loadFirmwareVersion() const;
/**
* Установить настройки RX/TX, readback можно получить используя loadTerminalState
*/
@ -61,10 +59,6 @@ namespace api_driver {
*/
void setQosSettings(boost::property_tree::ptree &pt);
void setNetworkSettings(boost::property_tree::ptree & pt);
void setDebugSendSettings(boost::property_tree::ptree & pt);
~ApiDriver();
private:

View File

@ -21,16 +21,6 @@
#content {
padding-top: var(--header-height);
}
.l3-proto-label {
margin: 0 0 0 0.5em;
}
.l3-proto-label > * {
display: inline-block;
}
.l3-proto-label input[type=checkbox] {
width: auto;
}
</style>
</head>
<body>
@ -492,19 +482,21 @@
<!-- expr: ^(((single,)+single)|single)$-->
<input v-model="filter.vlan" type="text" pattern="^((((([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4})),)+(([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4})))|(([0-9]{1,4}-[0-9]{1,4})|([0-9]{1,4})))$">
</label>
<div>
<label>
<span>Протокол L3</span>
<label class="l3-proto-label"><span>AH:</span><input type="checkbox" value="ah" v-model="filter.proto"></label>
<label class="l3-proto-label"><span>COMP:</span><input type="checkbox" value="comp" v-model="filter.proto"></label>
<label class="l3-proto-label"><span>DCCP:</span><input type="checkbox" value="dccp" v-model="filter.proto"></label>
<label class="l3-proto-label"><span>ESP:</span><input type="checkbox" value="esp" v-model="filter.proto"></label>
<label class="l3-proto-label"><span>ICMP:</span><input type="checkbox" value="icmp" v-model="filter.proto"></label>
<!-- <label class="l3-proto-label"><span>ICMPV6:</span><input type="checkbox" value="icmpv6" v-model="filter.proto"></label>-->
<label class="l3-proto-label"><span>SCTP:</span><input type="checkbox" value="sctp" v-model="filter.proto"></label>
<label class="l3-proto-label"><span>TCP:</span><input type="checkbox" value="tcp" v-model="filter.proto"></label>
<label class="l3-proto-label"><span>UDP:</span><input type="checkbox" value="udp" v-model="filter.proto"></label>
<label class="l3-proto-label"><span>UDPLITE:</span><input type="checkbox" value="udplite" v-model="filter.proto"></label>
</div>
<select v-model="filter.proto" multiple>
<option value="ah">AH</option>
<option value="comp">COMP</option>
<option value="dccp">DCCP</option>
<option value="esp">ESP</option>
<option value="icmp">ICMP</option>
<!-- <option value="icmpv6">ICMPv6</option>-->
<option value="sctp">SCTP</option>
<option value="tcp">TCP</option>
<option value="udp">UDP</option>
<option value="udplite">UDP LITE</option>
</select>
</label>
<label>
<span>Порт источника</span>
<input v-model="filter.sport" type="text" pattern="^((((([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})),)+(([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})))|(([0-9]{1,5}-[0-9]{1,5})|([0-9]{1,5})))$">
@ -535,8 +527,8 @@
</template>
<button class="action-button" @click="settingsSubmitQoS()">Применить <span class="submit-spinner" v-show="submitStatus.qos"></span></button>
<h2 hidden>Настройки TCP-акселерации</h2>
<div hidden class="settings-set-container">
<h2>Настройки TCP-акселерации</h2>
<div class="settings-set-container">
<label>
<span>Активировать акселерацию</span>
<span class="toggle-input"><input type="checkbox" v-model="param.tcpAccel.en" /><span class="slider"></span></span>
@ -546,7 +538,7 @@
<input type="number" v-model="param.tcpAccel.maxConnections" min="1" max="10000" />
</label>
</div>
<button hidden class="action-button" @click="settingsSubmitTcpAccel()">Применить <span class="submit-spinner" v-show="submitStatus.tcpAccel"></span></button>
<button class="action-button" @click="settingsSubmitTcpAccel()">Применить <span class="submit-spinner" v-show="submitStatus.tcpAccel"></span></button>
</div>
<div class="tabs-body-item" v-if="activeTab === 'admin' && settingFetchComplete">
<h2>Настройки сети</h2>
@ -609,11 +601,11 @@
<h3>Управление ПО</h3>
<table>
<tbody>
<tr><th>Версия ПО</th><td>{{ about.firmwareVersion }}</td></tr>
<tr><th>ID модема</th><td>{{ about.modemUid }}</td></tr>
<tr><th>Серийный номер</th><td>{{ about.modemSn }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ about.macManagement }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ about.macData }}</td></tr>
<tr><th>Версия ПО</th><td>{{ param.firmware.firmwareVersion }}</td></tr>
<tr><th>ID модема</th><td>{{ param.firmware.modemUid }}</td></tr>
<tr><th>Серийный номер</th><td>{{ param.firmware.modemSn }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ param.firmware.macManagement }}</td></tr>
<tr><th>MAC интерфейса управления</th><td>{{ param.firmware.macData }}</td></tr>
</tbody>
</table>
<div>
@ -938,6 +930,14 @@
portData: 0,
timeout: 0
},
// эти "настройки" - read only
firmware: {
firmwareVersion: '?',
modemUid: '?',
modemSn: '?',
macManagement: '?',
macData: '?',
},
qos: {
en: false,
@ -959,15 +959,6 @@
sha256: null
},
// эти "настройки" - read only
about: {
firmwareVersion: '?',
modemUid: '?',
modemSn: '?',
macManagement: '?',
macData: '?',
},
testState: false,
initState: '',
lastUpdateTime: new Date(),
@ -1230,8 +1221,8 @@
'Content-Type': 'application/json'
},
body: JSON.stringify({
"tcpAccel.en": this.param.tcpAccel.en,
"tcpAccel.maxConnections": this.param.tcpAccel.maxConnections
"tcpAccel.en": this.tcpAccel.en,
"tcpAccel.maxConnections": this.tcpAccel.maxConnections
})
}).then(async (resp) => {
this.submitStatus.tcpAccel = false
@ -1511,6 +1502,13 @@
this.updateQosSettings(vals)
this.updateNetworkSettings(vals)
this.updateDebugSendSettings(vals)
// и отдельно тут обновим настройки прошивки
this.param.firmware.firmwareVersion = vals["settings"]["firmware.firmwareVersion"]
this.param.firmware.modemUid = vals["settings"]["firmware.modemUid"]
this.param.firmware.modemSn = vals["settings"]["firmware.modemSn"]
this.param.firmware.macManagement = vals["settings"]["firmware.macManagement"]
this.param.firmware.macData = vals["settings"]["firmware.macData"]
},
qosAddClass(name) {
@ -1621,21 +1619,7 @@
}, 1000)
}
const doFetchAbout = async () => {
try {
let d = await fetch("/api/get/aboutFirmware")
this.about.firmwareVersion = d["fw.version"]
this.about.modemUid = d["fw.modemId"]
this.about.modemSn = d["fw.modemSn"]
this.about.macManagement = d["fw.macMang"]
this.about.macData = d["fw.macData"]
} catch (e) {
console.log('Ошибка загрузки версии ПО', e)
}
}
doFetchStatistics().then(() => {})
doFetchAbout().then(() => {})
this.performUpdateSettings()