mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-12-24 22:37:04 +00:00
184 lines
5.0 KiB
C++
184 lines
5.0 KiB
C++
//
|
|
// Created by stephane bourque on 2021-06-17.
|
|
//
|
|
#include <fstream>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
#include "Poco/File.h"
|
|
#include "Poco/StreamCopier.h"
|
|
#include "Poco/String.h"
|
|
#include "Poco/StringTokenizer.h"
|
|
#include "Poco/URIStreamOpener.h"
|
|
|
|
#include "framework/MicroServiceFuncs.h"
|
|
#include "framework/utils.h"
|
|
|
|
#include "fmt/format.h"
|
|
|
|
#include "OUIServer.h"
|
|
|
|
namespace OpenWifi {
|
|
|
|
int OUIServer::Start() {
|
|
Running_ = true;
|
|
LatestOUIFileName_ = MicroServiceDataDirectory() + "/newOUIFile.txt";
|
|
CurrentOUIFileName_ = MicroServiceDataDirectory() + "/current_oui.txt";
|
|
|
|
bool Recovered = false;
|
|
Poco::File OuiFile(CurrentOUIFileName_);
|
|
if (OuiFile.exists()) {
|
|
std::lock_guard Lock(LocalMutex_);
|
|
Recovered = ProcessFile(CurrentOUIFileName_, OUIs_);
|
|
if (Recovered) {
|
|
poco_notice(Logger(),
|
|
fmt::format("Recovered last OUI file - {}", CurrentOUIFileName_));
|
|
}
|
|
} else {
|
|
poco_notice(Logger(), fmt::format("No existing OUIFile.", CurrentOUIFileName_));
|
|
}
|
|
|
|
UpdaterCallBack_ =
|
|
std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
|
if (Recovered) {
|
|
Timer_.setStartInterval(60 * 60 * 1000); // first run in 1 hour
|
|
} else {
|
|
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
|
|
}
|
|
Timer_.setPeriodicInterval(7 * 24 * 60 * 60 * 1000);
|
|
Timer_.start(*UpdaterCallBack_, MicroServiceTimerPool());
|
|
return 0;
|
|
}
|
|
|
|
void OUIServer::Stop() {
|
|
poco_notice(Logger(), "Stopping...");
|
|
Running_ = false;
|
|
Timer_.stop();
|
|
poco_notice(Logger(), "Stopped...");
|
|
}
|
|
|
|
void OUIServer::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
|
MicroServiceLoadConfigurationFile();
|
|
poco_information(Logger(), "Reinitializing.");
|
|
Stop();
|
|
Start();
|
|
}
|
|
|
|
bool OUIServer::GetFile(const std::string &FileName) {
|
|
try {
|
|
LastUpdate_ = Utils::Now();
|
|
poco_information(Logger(),
|
|
fmt::format("Start: Retrieving OUI file: {}",
|
|
MicroServiceConfigGetString("oui.download.uri", "")));
|
|
std::unique_ptr<std::istream> pStr(Poco::URIStreamOpener::defaultOpener().open(
|
|
MicroServiceConfigGetString("oui.download.uri", "")));
|
|
std::ofstream OS;
|
|
OS.open(FileName);
|
|
Poco::StreamCopier::copyStream(*pStr, OS);
|
|
OS.close();
|
|
poco_information(Logger(),
|
|
fmt::format("Done: Retrieving OUI file: {}",
|
|
MicroServiceConfigGetString("oui.download.uri", "")));
|
|
return true;
|
|
} catch (const Poco::Exception &E) {
|
|
Logger().log(E);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool OUIServer::ProcessFile(const std::string &FileName, OUIMap &Map) {
|
|
try {
|
|
std::ifstream Input;
|
|
Input.open(FileName, std::ios::binary);
|
|
|
|
while (!Input.eof()) {
|
|
if (!Running_)
|
|
return false;
|
|
char buf[1024];
|
|
Input.getline(buf, sizeof(buf));
|
|
std::string Line{buf};
|
|
auto Tokens = Poco::StringTokenizer(Line, " \t",
|
|
Poco::StringTokenizer::TOK_TRIM |
|
|
Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
|
|
|
if (Tokens.count() > 2) {
|
|
if (Tokens[1] == "(hex)") {
|
|
auto MAC = Utils::SerialNumberToOUI(Tokens[0]);
|
|
if (MAC > 0) {
|
|
std::string Manufacturer;
|
|
for (size_t i = 2; i < Tokens.count(); i++)
|
|
Manufacturer += Tokens[i] + " ";
|
|
auto M = Poco::trim(Manufacturer);
|
|
if (!M.empty())
|
|
Map[MAC] = M;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
} catch (const Poco::Exception &E) {
|
|
Logger().log(E);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void OUIServer::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
|
Utils::SetThreadName("ouisvr-timer");
|
|
if (Updating_)
|
|
return;
|
|
Updating_ = true;
|
|
|
|
poco_information(Logger(), "Starting to process OUI file...");
|
|
|
|
// fetch data from server, if not available, just use the file we already have.
|
|
Poco::File Current(CurrentOUIFileName_);
|
|
if (Current.exists()) {
|
|
if ((Utils::Now() - Current.getLastModified().epochTime()) < (7 * 24 * 60 * 60)) {
|
|
if (!Initialized_) {
|
|
if (ProcessFile(CurrentOUIFileName_, OUIs_)) {
|
|
Initialized_ = true;
|
|
Updating_ = false;
|
|
poco_information(Logger(), "Using cached file.");
|
|
return;
|
|
}
|
|
} else {
|
|
Updating_ = false;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
OUIMap TmpOUIs;
|
|
if (GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
|
std::lock_guard G(LocalMutex_);
|
|
OUIs_ = std::move(TmpOUIs);
|
|
LastUpdate_ = Utils::Now();
|
|
Poco::File F1(CurrentOUIFileName_);
|
|
if (F1.exists())
|
|
F1.remove();
|
|
Poco::File F2(LatestOUIFileName_);
|
|
F2.renameTo(CurrentOUIFileName_);
|
|
poco_information(Logger(),
|
|
fmt::format("New OUI file {} downloaded.", LatestOUIFileName_));
|
|
} else if (OUIs_.empty()) {
|
|
if (ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
|
LastUpdate_ = Utils::Now();
|
|
std::lock_guard G(LocalMutex_);
|
|
OUIs_ = std::move(TmpOUIs);
|
|
}
|
|
}
|
|
Initialized_ = true;
|
|
Updating_ = false;
|
|
poco_information(Logger(), "Done processing OUI file...");
|
|
}
|
|
|
|
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
|
std::lock_guard Lock(LocalMutex_);
|
|
|
|
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
|
if (Manufacturer != OUIs_.end())
|
|
return Manufacturer->second;
|
|
return "";
|
|
}
|
|
}; // namespace OpenWifi
|