mirror of
https://github.com/Telecominfraproject/wlan-cloud-owls.git
synced 2026-01-27 10:22:52 +00:00
644 lines
26 KiB
C++
644 lines
26 KiB
C++
//
|
|
// Created by stephane bourque on 2021-03-12.
|
|
//
|
|
#include <chrono>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <sys/time.h>
|
|
#include <thread>
|
|
#include <tuple>
|
|
|
|
#include "OWLS_utils.h"
|
|
|
|
#include "Poco/NObserver.h"
|
|
#include "Poco/Net/Context.h"
|
|
#include "Poco/Net/HTTPRequest.h"
|
|
#include "Poco/Net/HTTPResponse.h"
|
|
#include "Poco/Net/HTTPSClientSession.h"
|
|
#include "Poco/Net/SSLException.h"
|
|
#include "Poco/URI.h"
|
|
|
|
#include "OWLSclient.h"
|
|
#include "OWLSdefinitions.h"
|
|
#include "framework/MicroServiceFuncs.h"
|
|
|
|
#include "SimStats.h"
|
|
#include "SimulationCoordinator.h"
|
|
#include "fmt/format.h"
|
|
#include <nlohmann/json.hpp>
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
namespace OpenWifi {
|
|
|
|
OWLSclient::OWLSclient(std::string SerialNumber,
|
|
Poco::Logger &Logger, SimulationRunner *runner)
|
|
: Logger_(Logger), SerialNumber_(std::move(SerialNumber)),
|
|
Memory_(1),
|
|
Load_(1),
|
|
Runner_(runner) {
|
|
|
|
AllInterfaceNames_[ap_interface_types::upstream] = "up0v0";
|
|
AllInterfaceNames_[ap_interface_types::downstream] = "down0v0";
|
|
AllInterfaceRoles_[ap_interface_types::upstream] = "upstream";
|
|
AllInterfaceRoles_[ap_interface_types::downstream] = "downstream";
|
|
AllPortNames_[ap_interface_types::upstream] = "eth0";
|
|
AllPortNames_[ap_interface_types::downstream] = "eth1";
|
|
SetFirmware();
|
|
Active_ = UUID_ = Utils::Now();
|
|
srand(UUID_);
|
|
mac_lan = OWLSutils::MakeMac(SerialNumber_.c_str(), 0);
|
|
CurrentConfig_ = SimulationCoordinator()->GetSimConfigurationPtr(Utils::Now());
|
|
UpdateConfiguration();
|
|
Valid_ = true;
|
|
}
|
|
|
|
void OWLSclient::CreateLanClients(uint64_t min, uint64_t max) {
|
|
AllLanClients_.clear();
|
|
uint64_t Num = MicroServiceRandom(min, max);
|
|
for (uint64_t i = 0; i < Num; i++) {
|
|
MockLanClient CI;
|
|
CI.mac = OWLSutils::RandomMAC();
|
|
CI.ipv4_addresses.push_back(OWLSutils::RandomIPv4());
|
|
CI.ipv6_addresses.push_back(OWLSutils::RandomIPv6());
|
|
CI.ports.emplace_back("eth1");
|
|
AllLanClients_.push_back(CI);
|
|
}
|
|
Load_.SetSize(AllLanClients_.size()+CountAssociations());
|
|
Memory_.SetSize(AllLanClients_.size()+CountAssociations());
|
|
}
|
|
|
|
void OWLSclient::CreateAssociations(const interface_location_t &interface, const std::string &bssid, uint64_t min,
|
|
uint64_t max) {
|
|
|
|
auto interface_hint = AllAssociations_.find(interface);
|
|
if(interface_hint==end(AllAssociations_)) {
|
|
MockAssociations M;
|
|
AllAssociations_[interface] = M;
|
|
interface_hint = AllAssociations_.find(interface);
|
|
}
|
|
|
|
interface_hint->second.clear();
|
|
auto NumberOfAssociations = MicroServiceRandom(min, max);
|
|
while (NumberOfAssociations) {
|
|
MockAssociation FA;
|
|
FA.bssid = bssid;
|
|
FA.station = OWLSutils::RandomMAC();
|
|
FA.ack_signal_avg = OWLSutils::local_random(-40, -60);
|
|
FA.ack_signal = FA.ack_signal_avg;
|
|
FA.ipaddr_v4 = OWLSutils::RandomIPv4();
|
|
FA.ipaddr_v6 = OWLSutils::RandomIPv6();
|
|
FA.rssi = OWLSutils::local_random(-40, -90);
|
|
interface_hint->second.push_back(FA);
|
|
--NumberOfAssociations;
|
|
}
|
|
Load_.SetSize(AllLanClients_.size()+CountAssociations());
|
|
Memory_.SetSize(AllLanClients_.size()+CountAssociations());
|
|
}
|
|
|
|
void OWLSclient::Update() {
|
|
Memory_.next();
|
|
Load_.next();
|
|
for(auto &[_,radio]:AllRadios_) {
|
|
radio.next();
|
|
}
|
|
for(auto &[_,counters]:AllCounters_) {
|
|
counters.next();
|
|
}
|
|
for(auto &[_,associations]:AllAssociations_) {
|
|
for(auto &association:associations) {
|
|
association.next();
|
|
}
|
|
}
|
|
for(auto &lan_client:AllLanClients_) {
|
|
lan_client.next();
|
|
}
|
|
}
|
|
|
|
bool OWLSclient::FindInterfaceRole(const std::string &role,
|
|
OpenWifi::ap_interface_types &interface) {
|
|
for (const auto &[interface_type, interface_name] : AllInterfaceRoles_) {
|
|
if (role == interface_name) {
|
|
interface = interface_type;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void OWLSclient::Reset() {
|
|
Memory_.reset();
|
|
Load_.reset();
|
|
|
|
for (auto &[_, radio] : AllRadios_) {
|
|
radio.reset();
|
|
}
|
|
|
|
for (auto &[_, association_list] : AllAssociations_) {
|
|
for (auto &association : association_list) {
|
|
association.reset();
|
|
}
|
|
}
|
|
|
|
for (auto &[_, counter] : AllCounters_) {
|
|
counter.reset();
|
|
}
|
|
|
|
for(auto &lan_client:AllLanClients_) {
|
|
lan_client.reset();
|
|
}
|
|
}
|
|
|
|
void OWLSclient::UpdateConfiguration() {
|
|
// go through the config and harvest the SSID names, also update all the client stuff
|
|
auto Interfaces = CurrentConfig_->getArray("interfaces");
|
|
AllAssociations_.clear();
|
|
AllLanClients_.clear();
|
|
AllRadios_.clear();
|
|
bssid_index = 1;
|
|
for (uint interface_index=0;interface_index<Interfaces->size();interface_index++) {
|
|
auto interfacePtr = Interfaces->get(interface_index);
|
|
auto interface = interfacePtr.extract<Poco::JSON::Object::Ptr>();
|
|
if (interface->has("role")) {
|
|
ap_interface_types current_interface_role = upstream;
|
|
if (FindInterfaceRole(interface->get("role"), current_interface_role)) {
|
|
auto SSIDs = interface->getArray("ssids");
|
|
for (uint ssid_index=0; ssid_index< SSIDs->size(); ++ssid_index) {
|
|
auto SSIDptr = SSIDs->get(ssid_index);
|
|
auto SSID = SSIDptr.extract<Poco::JSON::Object::Ptr>();
|
|
auto Bands = SSID->getArray("wifi-bands");
|
|
for(uint band_index=0;band_index<Bands->size(); band_index++) {
|
|
std::string band = Bands->get(band_index);
|
|
std::string ssidName = SSID->get("name");
|
|
auto bssid_num = Utils::SerialToMAC(Utils::IntToSerialNumber(
|
|
Utils::SerialNumberToInt(SerialNumber_) +
|
|
bssid_index++));
|
|
if (band == "2G") {
|
|
auto index = std::make_tuple(current_interface_role, ssidName,
|
|
radio_bands::band_2g);
|
|
CreateAssociations(index, bssid_num,
|
|
Runner_->Details().minAssociations,
|
|
Runner_->Details().maxAssociations);
|
|
}
|
|
if (band == "5G") {
|
|
auto index = std::make_tuple(current_interface_role, ssidName,
|
|
radio_bands::band_5g);
|
|
CreateAssociations(index, bssid_num,
|
|
Runner_->Details().minAssociations,
|
|
Runner_->Details().maxAssociations);
|
|
}
|
|
if (band == "6G") {
|
|
auto index = std::make_tuple(current_interface_role, ssidName,
|
|
radio_bands::band_6g);
|
|
CreateAssociations(index,bssid_num,
|
|
Runner_->Details().minAssociations,
|
|
Runner_->Details().maxAssociations);
|
|
}
|
|
}
|
|
}
|
|
MockCounters F;
|
|
AllCounters_[current_interface_role] = F;
|
|
}
|
|
}
|
|
}
|
|
|
|
CreateLanClients(Runner_->Details().minClients, Runner_->Details().maxClients);
|
|
|
|
auto radios = CurrentConfig_->getArray("radios");
|
|
for (uint radio_index=0;radio_index<radios->size();radio_index++) {
|
|
auto radioPtr = radios->get(radio_index);
|
|
auto radio = radioPtr.extract<Poco::JSON::Object::Ptr>();
|
|
|
|
std::string band = radio->get("band");
|
|
MockRadio R;
|
|
|
|
R.band.push_back(band);
|
|
if (band == "2G") {
|
|
R.radioBands = radio_bands::band_2g;
|
|
} else if (band == "5G") {
|
|
R.radioBands = radio_bands::band_5g;
|
|
} else if (band == "6G") {
|
|
R.radioBands = radio_bands::band_6g;
|
|
}
|
|
|
|
if(radio->has("channel-width")) {
|
|
R.channel_width = radio->get("channel-width");
|
|
} else {
|
|
R.channel_width = 20;
|
|
}
|
|
|
|
if (!radio->has("channel")) {
|
|
R.channel = OWLSutils::FindAutoChannel(R.radioBands,R.channel_width);
|
|
} else {
|
|
std::string channel = radio->get("channel").toString();
|
|
if(OWLSutils::is_integer(channel)) {
|
|
R.channel = std::strtoll(channel.c_str(), nullptr,10);
|
|
}
|
|
R.channel = OWLSutils::FindAutoChannel(R.radioBands, R.channel_width);
|
|
}
|
|
|
|
OWLSutils::FillinFrequencies(R.channel, R.radioBands, R.channel_width, R.channels, R.frequency);
|
|
|
|
OWLSutils::AssignIfPresent(radio, "tx_power", R.tx_power, (uint_fast64_t)23);
|
|
|
|
if (radio_index == 0)
|
|
R.phy = "platform/soc/c000000.wifi";
|
|
else
|
|
R.phy = "platform/soc/c000000.wifi+" + std::to_string(radio_index);
|
|
R.index = radio_index;
|
|
AllRadios_[R.radioBands] = R;
|
|
}
|
|
}
|
|
|
|
Poco::JSON::Object OWLSclient::CreateLinkStatePtr() {
|
|
Poco::JSON::Object res;
|
|
for (const auto &[interface_type, _] : AllCounters_) {
|
|
Poco::JSON::Object InterfaceInfo, InterfacePort;
|
|
InterfaceInfo.set("carrier",1);
|
|
InterfaceInfo.set("duplex","full");
|
|
InterfaceInfo.set("speed",1000);
|
|
InterfacePort.set(AllPortNames_[interface_type],InterfaceInfo);
|
|
res.set(AllInterfaceRoles_[interface_type], InterfacePort);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
Poco::JSON::Object OWLSclient::CreateStatePtr() {
|
|
Poco::JSON::Object State,Unit;
|
|
|
|
auto now = Utils::Now();
|
|
Memory_.to_json(Unit);
|
|
Load_.to_json(Unit);
|
|
Unit.set("localtime", now);
|
|
Unit.set("uptime", now - StartTime_);
|
|
Unit.set("temperature", std::vector<std::int64_t> { OWLSutils::local_random(48,58), OWLSutils::local_random(48,58)});
|
|
|
|
Poco::JSON::Array RadioArray;
|
|
for (auto &[_, radio] : AllRadios_) {
|
|
Poco::JSON::Object doc;
|
|
radio.to_json(doc);
|
|
RadioArray.add(doc);
|
|
}
|
|
|
|
Poco::JSON::Array all_interfaces;
|
|
for (const auto &ap_interface_type :
|
|
{ap_interface_types::upstream, ap_interface_types::downstream}) {
|
|
if (AllCounters_.find(ap_interface_type) != AllCounters_.end()) {
|
|
Poco::JSON::Object current_interface;
|
|
Poco::JSON::Array ue_clients, up_ssids;
|
|
uint64_t ssid_num = 0, interfaces = 0;
|
|
|
|
for (auto &[interface, associations] : AllAssociations_) {
|
|
auto &[interface_type, ssid, band] = interface;
|
|
if (interface_type == ap_interface_type) {
|
|
Poco::JSON::Array association_list;
|
|
std::string bssid;
|
|
for (auto &association : associations) {
|
|
bssid = association.bssid;
|
|
Poco::JSON::Object doc;
|
|
association.to_json(doc);
|
|
association_list.add(doc);
|
|
Poco::JSON::Object ue;
|
|
ue.set("mac", association.station);
|
|
ue.set("ipv4_addresses", std::vector<std::string>{association.ipaddr_v4});
|
|
ue.set("ipv6_addresses", std::vector<std::string>{association.ipaddr_v6});
|
|
if(interface_type==upstream)
|
|
ue.set("ports", std::vector<std::string>{"wwan0"});
|
|
else
|
|
ue.set("ports", std::vector<std::string>{"wlan0"});
|
|
ue.set("last_seen", 0);
|
|
ue_clients.add(ue);
|
|
}
|
|
Poco::JSON::Object ssid_info;
|
|
ssid_info.set("associations", association_list);
|
|
ssid_info.set("bssid", bssid);
|
|
ssid_info.set("band", OpenWifi::to_string(band));
|
|
Poco::JSON::Object Counters;
|
|
AllCounters_[interface_type].to_json(Counters);
|
|
ssid_info.set("counters", Counters);
|
|
ssid_info.set("frequency", AllRadios_[band].frequency);
|
|
ssid_info.set("iface", AllPortNames_[interface_type]);
|
|
ssid_info.set("mode", "ap");
|
|
ssid_info.set("ssid", ssid);
|
|
ssid_info.set("phy", AllRadios_[band].phy);
|
|
ssid_info.set("location", "/interfaces/" + std::to_string(interfaces) +
|
|
"/ssids/" + std::to_string(ssid_num++));
|
|
ssid_info.set("name", AllInterfaceNames_[ap_interface_type]);
|
|
Poco::JSON::Object R;
|
|
R.set("$ref",
|
|
"#/radios/" + std::to_string(AllRadios_[band].index));
|
|
ssid_info.set("radio", R);
|
|
up_ssids.add(ssid_info);
|
|
}
|
|
}
|
|
current_interface.set("ssids", up_ssids);
|
|
Poco::JSON::Object C;
|
|
AllCounters_[ap_interface_type].to_json(C);
|
|
current_interface.set("counters", C);
|
|
|
|
// if we have 2 interfaces, then the clients go to the downstream interface
|
|
// if we only have 1 interface then this is bridged and therefore clients go on the
|
|
// upstream
|
|
if ((AllCounters_.size() == 1 &&
|
|
ap_interface_type == ap_interface_types::upstream) ||
|
|
(AllCounters_.size() == 2 &&
|
|
ap_interface_type == ap_interface_types::downstream)) {
|
|
Poco::JSON::Array ip_clients;
|
|
for (const auto &lan_client : AllLanClients_) {
|
|
Poco::JSON::Object d;
|
|
lan_client.to_json(d);
|
|
ip_clients.add(d);
|
|
}
|
|
for (const auto &ue_client : ue_clients) {
|
|
ip_clients.add(ue_client);
|
|
}
|
|
current_interface.set("clients", ip_clients);
|
|
}
|
|
current_interface.set("name", AllInterfaceNames_[ap_interface_type]);
|
|
all_interfaces.add(current_interface);
|
|
}
|
|
}
|
|
|
|
State.set("version" , 1 );
|
|
State.set("radios", RadioArray);
|
|
State.set("link-state", CreateLinkStatePtr());
|
|
State.set("unit", Unit);
|
|
State.set("interfaces", all_interfaces);
|
|
|
|
return State;
|
|
}
|
|
|
|
void OWLSclient::DoConfigure([[maybe_unused]] std::shared_ptr<OWLSclient> Client, uint64_t Id, const Poco::JSON::Object::Ptr Params) {
|
|
try {
|
|
DEBUG_LINE("start");
|
|
if (Params->has("serial") && Params->has("uuid") && Params->has("config")) {
|
|
uint64_t When = Params->has("when") ? (uint64_t) Params->get("when") : 0;
|
|
std::string Serial = Params->get("serial");
|
|
std::uint64_t UUID = Params->get("uuid");
|
|
auto Configuration = Params->getObject("config");
|
|
if(Configuration->has("uuid"))
|
|
std::cout << "UUID from config: " << (std::uint64_t)Configuration->get("uuid");
|
|
std::cout << "UUID from call: " << UUID;
|
|
CurrentConfig_ = Configuration;
|
|
UUID_ = Active_ = UUID;
|
|
|
|
auto Metrics = Configuration->getObject("metrics");
|
|
auto Health = Metrics->getObject("health");
|
|
HealthInterval_ = Health->get("interval");
|
|
auto Statistics = Metrics->getObject("statistics");
|
|
StatisticsInterval_ = Statistics->get("interval");
|
|
|
|
// prepare response...
|
|
Poco::JSON::Object Answer, Result, Status;
|
|
Status.set("error", 0);
|
|
Status.set("when", When);
|
|
Status.set("text", "No errors were found");
|
|
Result.set("serial", Serial);
|
|
Result.set("uuid", UUID);
|
|
Result.set("status", Status);
|
|
Answer.set("jsonrpc", "2.0");
|
|
Answer.set("id", Id);
|
|
Answer.set("result", Result);
|
|
poco_information(Logger_,fmt::format("configure({}): done.", SerialNumber_));
|
|
SendObject(Answer);
|
|
} else {
|
|
poco_warning(Logger_,fmt::format("configure({}): Illegal command.", SerialNumber_));
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
DEBUG_LINE("exception 1");
|
|
poco_warning(Logger_,
|
|
fmt::format("configure({}): Exception. {}", SerialNumber_, E.displayText()));
|
|
} catch (const std::exception &E) {
|
|
DEBUG_LINE("exception2");
|
|
}
|
|
}
|
|
|
|
void OWLSclient::Disconnect() {
|
|
if(Valid_) {
|
|
Runner_->Report().ev_disconnect++;
|
|
if (Connected_) {
|
|
Runner_->RemoveClientFd(fd_);
|
|
fd_ = -1;
|
|
Runner_->Reactor().removeEventHandler(
|
|
*WS_, Poco::NObserver<SimulationRunner, Poco::Net::ReadableNotification>(
|
|
*Runner_, &SimulationRunner::OnSocketReadable));
|
|
Runner_->Reactor().removeEventHandler(
|
|
*WS_, Poco::NObserver<SimulationRunner, Poco::Net::ErrorNotification>(
|
|
*Runner_, &SimulationRunner::OnSocketError));
|
|
Runner_->Reactor().removeEventHandler(
|
|
*WS_, Poco::NObserver<SimulationRunner, Poco::Net::ShutdownNotification>(
|
|
*Runner_, &SimulationRunner::OnSocketShutdown));
|
|
(*WS_).close();
|
|
}
|
|
Connected_ = false;
|
|
}
|
|
}
|
|
|
|
void OWLSclient::DoReboot(std::shared_ptr<OWLSclient> Client, uint64_t Id, const Poco::JSON::Object::Ptr Params) {
|
|
try {
|
|
if (Params->has("serial") && Params->has("when")) {
|
|
uint64_t When = Params->has("when") ? (uint64_t) Params->get("when") : 0;
|
|
std::string Serial = Params->get("serial");
|
|
|
|
Poco::JSON::Object Answer, Result, Status;
|
|
Status.set("error", 0);
|
|
Status.set("when", When);
|
|
Status.set("text", "No errors were found");
|
|
Result.set("serial", Serial);
|
|
Result.set("uuid", UUID_);
|
|
Result.set("status", Status);
|
|
Answer.set("jsonrpc", "2.0");
|
|
Answer.set("id", Id);
|
|
Answer.set("result", Result);
|
|
poco_information(Logger_,fmt::format("reboot({}): done.", SerialNumber_));
|
|
SendObject(Answer);
|
|
Disconnect();
|
|
Reset();
|
|
std::this_thread::sleep_for(std::chrono::seconds(20));
|
|
OWLSclientEvents::Disconnect(Client, Runner_, "Command: reboot", true);
|
|
} else {
|
|
Logger_.warning(fmt::format("reboot({}): Illegal command.", SerialNumber_));
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
Logger_.warning(
|
|
fmt::format("reboot({}): Exception. {}", SerialNumber_, E.displayText()));
|
|
}
|
|
}
|
|
|
|
std::string GetFirmware(const std::string &U) {
|
|
Poco::URI uri(U);
|
|
|
|
auto p = uri.getPath();
|
|
auto tokens = Poco::StringTokenizer(p, "-");
|
|
if (tokens.count() > 4 &&
|
|
(tokens[2] == "main" || tokens[2] == "next" || tokens[2] == "staging")) {
|
|
return "TIP-devel-" + tokens[3];
|
|
}
|
|
|
|
if (tokens.count() > 5) {
|
|
return "TIP-" + tokens[2] + "-" + tokens[3] + "-" + tokens[4];
|
|
}
|
|
|
|
return p;
|
|
}
|
|
|
|
void OWLSclient::DoUpgrade(std::shared_ptr<OWLSclient> Client, uint64_t Id, const Poco::JSON::Object::Ptr Params) {
|
|
try {
|
|
if (Params->has("serial") && Params->has("uri")) {
|
|
uint64_t When = Params->has("when") ? (uint64_t) Params->get("when") : 0;
|
|
std::string Serial = Params->get("serial");
|
|
std::string URI = Params->get("uri");
|
|
|
|
Poco::JSON::Object Answer, Result, Status;
|
|
Status.set("error", 0);
|
|
Status.set("when", When);
|
|
Status.set("text", "No errors were found");
|
|
Result.set("serial", Serial);
|
|
Result.set("uuid", UUID_);
|
|
Result.set("status", Status);
|
|
Answer.set("jsonrpc", "2.0");
|
|
Answer.set("id", Id);
|
|
Answer.set("result", Result);
|
|
poco_information(Logger_,fmt::format("upgrade({}): from URI={}.", SerialNumber_, URI));
|
|
SendObject(Answer);
|
|
Disconnect();
|
|
Version_++;
|
|
SetFirmware(GetFirmware(URI));
|
|
std::this_thread::sleep_for(std::chrono::seconds(30));
|
|
Reset();
|
|
OWLSclientEvents::Disconnect(Client, Runner_, "Command: upgrade", true);
|
|
} else {
|
|
Logger_.warning(fmt::format("upgrade({}): Illegal command.", SerialNumber_));
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
Logger_.warning(
|
|
fmt::format("upgrade({}): Exception. {}", SerialNumber_, E.displayText()));
|
|
}
|
|
}
|
|
|
|
void OWLSclient::DoFactory(std::shared_ptr<OWLSclient> Client, uint64_t Id, const Poco::JSON::Object::Ptr Params) {
|
|
try {
|
|
if (Params->has("serial") && Params->has("when")) {
|
|
uint64_t When = Params->has("when") ? (uint64_t) Params->get("when") : 0;
|
|
std::string Serial = Params->get("serial");
|
|
|
|
Version_ = 1;
|
|
SetFirmware();
|
|
|
|
Poco::JSON::Object Answer, Result, Status;
|
|
Status.set("error", 0);
|
|
Status.set("when", When);
|
|
Status.set("text", "No errors were found");
|
|
Result.set("serial", Serial);
|
|
Result.set("uuid", UUID_);
|
|
Result.set("status", Status);
|
|
Answer.set("jsonrpc", "2.0");
|
|
Answer.set("id", Id);
|
|
Answer.set("result", Result);
|
|
poco_information(Logger_, fmt::format("factory({}): done.", SerialNumber_));
|
|
SendObject(Answer);
|
|
Disconnect();
|
|
CurrentConfig_ = SimulationCoordinator()->GetSimConfigurationPtr(Utils::Now());
|
|
UpdateConfiguration();
|
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
|
Reset();
|
|
OWLSclientEvents::Disconnect(Client, Runner_, "Command: upgrade", true);
|
|
} else {
|
|
Logger_.warning(fmt::format("factory({}): Illegal command.", SerialNumber_));
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
Logger_.warning(
|
|
fmt::format("factory({}): Exception. {}", SerialNumber_, E.displayText()));
|
|
}
|
|
}
|
|
|
|
void OWLSclient::DoLEDs([[maybe_unused]] std::shared_ptr<OWLSclient> Client, uint64_t Id, const Poco::JSON::Object::Ptr Params) {
|
|
try {
|
|
if (Params->has("serial") && Params->has("pattern")) {
|
|
uint64_t When = Params->has("when") ? (uint64_t) Params->get("when") : 0;
|
|
std::string Serial = Params->get("serial");
|
|
auto Pattern = Params->get("pattern").toString();
|
|
uint64_t Duration = Params->has("when") ? (uint64_t)Params->get("durarion") : 10;
|
|
|
|
Poco::JSON::Object Answer, Result, Status;
|
|
Status.set("error", 0);
|
|
Status.set("when", When);
|
|
Status.set("text", "No errors were found");
|
|
Result.set("serial", Serial);
|
|
Result.set("uuid", UUID_);
|
|
Result.set("status", Status);
|
|
Answer.set("jsonrpc", "2.0");
|
|
Answer.set("id", Id);
|
|
Answer.set("result", Result);
|
|
poco_information(Logger_,fmt::format("LEDs({}): pattern set to: {} for {} ms.",
|
|
SerialNumber_, Duration, Pattern));
|
|
SendObject(Answer);
|
|
} else {
|
|
Logger_.warning(fmt::format("LEDs({}): Illegal command.", SerialNumber_));
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
Logger_.warning(fmt::format("LEDs({}): Exception. {}", SerialNumber_, E.displayText()));
|
|
}
|
|
}
|
|
|
|
bool OWLSclient::Send(const std::string &Cmd) {
|
|
|
|
try {
|
|
uint32_t BytesSent = WS_->sendFrame(Cmd.c_str(), Cmd.size());
|
|
if (BytesSent == Cmd.size()) {
|
|
SimStats()->AddOutMsg(Runner_->Id(),Cmd.size());
|
|
return true;
|
|
} else {
|
|
DEBUG_LINE("fail to send");
|
|
Logger_.warning(
|
|
fmt::format("SEND({}): incomplete. Sent: {}", SerialNumber_, BytesSent));
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
DEBUG_LINE("exception1");
|
|
Logger_.log(E);
|
|
} catch (const std::exception &E) {
|
|
DEBUG_LINE("exception2");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool OWLSclient::SendWSPing() {
|
|
try {
|
|
DEBUG_LINE("start");
|
|
WS_->sendFrame(
|
|
"", 0, Poco::Net::WebSocket::FRAME_OP_PING | Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
|
return true;
|
|
} catch (const Poco::Exception &E) {
|
|
DEBUG_LINE("failed");
|
|
Logger_.log(E);
|
|
} catch (const std::exception &E) {
|
|
DEBUG_LINE("exception2");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool OWLSclient::SendObject(const Poco::JSON::Object &O) {
|
|
try {
|
|
std::ostringstream os;
|
|
O.stringify(os);
|
|
uint32_t BytesSent = WS_->sendFrame(os.str().c_str(), os.str().size());
|
|
if (BytesSent == os.str().size()) {
|
|
SimStats()->AddOutMsg(Runner_->Id(),BytesSent);
|
|
return true;
|
|
} else {
|
|
DEBUG_LINE("failed");
|
|
Logger_.warning(
|
|
fmt::format("SEND({}): incomplete send. Sent: {}", SerialNumber_, BytesSent));
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
DEBUG_LINE("exception1");
|
|
Logger_.log(E);
|
|
} catch (const std::exception &E) {
|
|
DEBUG_LINE("exception2");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
} // namespace OpenWifi
|