mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2026-01-27 10:23:13 +00:00
137 lines
3.8 KiB
C++
137 lines
3.8 KiB
C++
//
|
|
// Created by stephane bourque on 2021-06-17.
|
|
//
|
|
#include <thread>
|
|
#include <fstream>
|
|
#include <vector>
|
|
|
|
#include "OUIServer.h"
|
|
|
|
#include "Poco/String.h"
|
|
#include "Poco/StringTokenizer.h"
|
|
#include "Poco/URIStreamOpener.h"
|
|
#include "Poco/StreamCopier.h"
|
|
#include "Poco/URI.h"
|
|
#include "Poco/File.h"
|
|
|
|
#include "OUIServer.h"
|
|
#include "framework/MicroService.h"
|
|
|
|
namespace OpenWifi {
|
|
|
|
int OUIServer::Start() {
|
|
Running_ = true;
|
|
UpdaterCallBack_ = std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
|
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
|
|
Timer_.setPeriodicInterval(7 * 24 * 60 * 60 * 1000);
|
|
Timer_.start(*UpdaterCallBack_);
|
|
return 0;
|
|
}
|
|
|
|
void OUIServer::Stop() {
|
|
Running_=false;
|
|
Timer_.stop();
|
|
}
|
|
|
|
void OUIServer::reinitialize(Poco::Util::Application &self) {
|
|
MicroService::instance().LoadConfigurationFile();
|
|
Logger().information("Reinitializing.");
|
|
Stop();
|
|
Start();
|
|
}
|
|
|
|
bool OUIServer::GetFile(const std::string &FileName) {
|
|
try {
|
|
Logger().information(Poco::format("Start: Retrieving OUI file: %s",MicroService::instance().ConfigGetString("oui.download.uri")));
|
|
std::unique_ptr<std::istream> pStr(
|
|
Poco::URIStreamOpener::defaultOpener().open(MicroService::instance().ConfigGetString("oui.download.uri")));
|
|
std::ofstream OS;
|
|
Poco::File F(FileName);
|
|
if(F.exists())
|
|
F.remove();
|
|
OS.open(FileName);
|
|
Poco::StreamCopier::copyStream(*pStr, OS);
|
|
OS.close();
|
|
Logger().information(Poco::format("Done: Retrieving OUI file: %s",MicroService::instance().ConfigGetString("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 (auto 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(Poco::Timer & timer) {
|
|
if(Updating_)
|
|
return;
|
|
Updating_ = true;
|
|
|
|
// fetch data from server, if not available, just use the file we already have.
|
|
std::string LatestOUIFileName{ MicroService::instance().DataDir() + "/newOUIFile.txt"};
|
|
std::string CurrentOUIFileName{ MicroService::instance().DataDir() + "/current_oui.txt"};
|
|
|
|
OUIMap TmpOUIs;
|
|
if(GetFile(LatestOUIFileName) && ProcessFile(LatestOUIFileName, TmpOUIs)) {
|
|
std::lock_guard G(Mutex_);
|
|
OUIs_ = std::move(TmpOUIs);
|
|
LastUpdate_ = std::time(nullptr);
|
|
Poco::File F1(CurrentOUIFileName);
|
|
if(F1.exists())
|
|
F1.remove();
|
|
Poco::File F2(LatestOUIFileName);
|
|
F2.renameTo(CurrentOUIFileName);
|
|
Logger().information(Poco::format("New OUI file %s downloaded.",LatestOUIFileName));
|
|
} else if(OUIs_.empty()) {
|
|
if(ProcessFile(CurrentOUIFileName, TmpOUIs)) {
|
|
LastUpdate_ = std::time(nullptr);
|
|
std::lock_guard G(Mutex_);
|
|
OUIs_ = std::move(TmpOUIs);
|
|
}
|
|
}
|
|
Updating_ = false;
|
|
}
|
|
|
|
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
|
std::lock_guard Guard(Mutex_);
|
|
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
|
if(Manufacturer != OUIs_.end())
|
|
return Manufacturer->second;
|
|
return "";
|
|
}
|
|
};
|