Initial commit

This commit is contained in:
stephb9959
2022-03-11 22:56:06 -08:00
parent 157f3ab206
commit 3cb57d85e9
19 changed files with 2197 additions and 13 deletions

View File

@@ -83,7 +83,7 @@ add_executable(owanalytics
src/RESTAPI/RESTAPI_routers.cpp
src/Daemon.cpp src/Daemon.h
src/Dashboard.h src/Dashboard.cpp
src/StorageService.cpp src/StorageService.h src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h src/StateReceiver.cpp src/StateReceiver.h src/VenueWatcher.cpp src/VenueWatcher.h src/VenueCoordinator.cpp src/VenueCoordinator.h src/sdks/SDK_prov.cpp src/sdks/SDK_prov.h src/storage/storage_boards.cpp src/storage/storage_boards.h)
src/StorageService.cpp src/StorageService.h src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h src/StateReceiver.cpp src/StateReceiver.h src/VenueWatcher.cpp src/VenueWatcher.h src/VenueCoordinator.cpp src/VenueCoordinator.h src/sdks/SDK_prov.cpp src/sdks/SDK_prov.h src/storage/storage_boards.cpp src/storage/storage_boards.h src/RESTAPI/RESTAPI_board_list_handler.cpp src/RESTAPI/RESTAPI_board_list_handler.h src/RESTAPI/RESTAPI_board_handler.cpp src/RESTAPI/RESTAPI_board_handler.h src/RESTAPI/RESTAPI_analytics_db_helpers.h src/APStats.cpp src/APStats.h src/dict_ssid.h src/dict_ue.h src/dict_bssid.h)
target_link_libraries(owanalytics PUBLIC
${Poco_LIBRARIES} ${MySQL_LIBRARIES}

13
src/APStats.cpp Normal file
View File

@@ -0,0 +1,13 @@
//
// Created by stephane bourque on 2022-03-11.
//
#include "APStats.h"
namespace OpenWifi {
void AP::Update(std::shared_ptr<nlohmann::json> &State) {
std::cout << "MAC: " << Utils::IntToSerialNumber(mac_) << std::endl;
}
}

65
src/APStats.h Normal file
View File

@@ -0,0 +1,65 @@
//
// Created by stephane bourque on 2022-03-11.
//
#pragma once
#include <mutex>
#include "framework/MicroService.h"
#include "nlohmann/json.hpp"
namespace OpenWifi {
const uint32_t interval = 20; // how big per sample
const uint32_t ap_length = 2 * 24 * 60 * 60; // buffer length in seconds
const uint32_t ue_length = 2 * 60 * 60; // buffer length in seconds
const uint32_t ap_buffer_size = ap_length / interval;
const uint32_t ue_buffer_size = ue_length / interval;
enum wifi_band {
band_2g=0, band_5g=1, band_6g=2
};
struct AP_Point {
uint32_t rx_bytes=0, tx_bytes=0;
uint32_t rx_pkts=0,tx_pkts=0;
u_char bands[4];
};
struct UE_Point {
uint32_t bssid_index;
int8_t rssi;
uint32_t rx_bytes,tx_bytes;
uint16_t tx_retries;
wifi_band band;
};
class UE {
public:
UE(uint64_t Station):
Station_(Station) {
}
private:
uint64_t last_contact_=0;
uint64_t Station_=0;
uint64_t Start_=std::time(nullptr);
uint64_t Current_BSSID_=0;
uint32_t Current_BSSID_index_=0;
std::array<UE_Point,ue_buffer_size> Data_;
};
class AP {
public:
AP(uint64_t mac) : mac_(mac) {
}
void Update(std::shared_ptr<nlohmann::json> & State);
private:
uint64_t mac_=0;
uint64_t last_contact_=0;
std::array<AP_Point,ap_buffer_size> Data_;
};
}

View File

@@ -35,7 +35,7 @@ namespace OpenWifi {
return instance_;
}
void Daemon::initialize() {
void Daemon::initialize() {
}
void MicroServicePostInitialization() {

View File

@@ -0,0 +1,62 @@
//
// Created by stephane bourque on 2022-03-11.
//
#pragma once
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_AnalyticsObjects.h"
#include "StorageService.h"
#include "framework/orm.h"
namespace OpenWifi {
template <typename DB> void ReturnRecordList(const char *ArrayName,DB & DBInstance, RESTAPIHandler & R) {
Poco::JSON::Array ObjArr;
for(const auto &i:R.SelectedRecords()) {
typename DB::RecordName Rec;
if(DBInstance.GetRecord("id",i,Rec)) {
Poco::JSON::Object Obj;
Rec.to_json(Obj);
ObjArr.add(Obj);
} else {
return R.BadRequest(RESTAPI::Errors::UnknownId + i);
}
}
Poco::JSON::Object Answer;
Answer.set(ArrayName, ObjArr);
return R.ReturnObject(Answer);
}
template <typename T> void MakeJSONObjectArray(const char * ArrayName, const std::vector<T> & V, RESTAPIHandler & R) {
Poco::JSON::Array ObjArray;
for(const auto &i:V) {
Poco::JSON::Object Obj;
i.to_json(Obj);
ObjArray.add(Obj);
}
Poco::JSON::Object Answer;
Answer.set(ArrayName,ObjArray);
return R.ReturnObject(Answer);
}
template<typename DB>
void ListHandler(const char *BlockName, DB &DBInstance, RESTAPIHandler &R) {
typedef typename DB::RecordVec RecVec;
typedef typename DB::RecordName RecType;
if (!R.QB_.Select.empty()) {
return ReturnRecordList(BlockName, DBInstance, R);
} else if (R.QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = DBInstance.Count();
return R.ReturnCountOnly(C);
} else {
RecVec Entries;
DBInstance.GetRecords(R.QB_.Offset, R.QB_.Limit, Entries);
return MakeJSONObjectArray(BlockName, Entries, R);
}
}
}

View File

@@ -0,0 +1,98 @@
//
// Created by stephane bourque on 2022-03-11.
//
#include "RESTAPI_board_handler.h"
#include "VenueCoordinator.h"
namespace OpenWifi {
void RESTAPI_board_handler::DoGet() {
auto id = GetBinding("id","");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
AnalyticsObjects::BoardInfo B;
if(!StorageService()->BoardsDB().GetRecord("id",id,B)) {
return NotFound();
}
Poco::JSON::Object Answer;
B.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_board_handler::DoDelete() {
auto id = GetBinding("id","");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
AnalyticsObjects::BoardInfo B;
if(!StorageService()->BoardsDB().GetRecord("id",id,B)) {
return NotFound();
}
if(!StorageService()->BoardsDB().DeleteRecord("id",id)) {
return NotFound();
}
VenueCoordinator()->StopVenue(id);
return OK();
}
void RESTAPI_board_handler::DoPost() {
auto id= GetBinding("id","");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
auto RawObject = ParseStream();
AnalyticsObjects::BoardInfo NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info);
if(StorageService()->BoardsDB().CreateRecord(NewObject)) {
VenueCoordinator()->AddVenue(NewObject.info.id);
AnalyticsObjects::BoardInfo NewBoard;
StorageService()->BoardsDB().GetRecord("id",NewObject.info.id,NewBoard);
Poco::JSON::Object Answer;
NewBoard.to_json(Answer);
return ReturnObject(Answer);
}
}
void RESTAPI_board_handler::DoPut() {
auto id= GetBinding("id","");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
AnalyticsObjects::BoardInfo Existing;
if(!StorageService()->BoardsDB().GetRecord("id",id,Existing)) {
return NotFound();
}
auto RawObject = ParseStream();
AnalyticsObjects::BoardInfo NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info);
if(RawObject->has("venueList")) {
// reconsile new venuelist compared to old...
}
if(StorageService()->BoardsDB().CreateRecord(NewObject)) {
VenueCoordinator()->ModifyVenue(NewObject.info.id);
AnalyticsObjects::BoardInfo NewBoard;
StorageService()->BoardsDB().GetRecord("id",NewObject.info.id,NewBoard);
Poco::JSON::Object Answer;
NewBoard.to_json(Answer);
return ReturnObject(Answer);
}
}
}

View File

@@ -0,0 +1,35 @@
//
// Created by stephane bourque on 2022-03-11.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_board_handler : public RESTAPIHandler {
public:
RESTAPI_board_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/board/{id}"}; };
private:
BoardsDB & DB_=StorageService()->BoardsDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
};
}

View File

@@ -0,0 +1,14 @@
//
// Created by stephane bourque on 2022-03-11.
//
#include "RESTAPI_board_list_handler.h"
#include "StorageService.h"
#include "RESTAPI/RESTAPI_analytics_db_helpers.h"
namespace OpenWifi {
void RESTAPI_board_list_handler::DoGet() {
return ListHandler<BoardsDB>("boards", DB_, *this);
}
}

View File

@@ -0,0 +1,33 @@
//
// Created by stephane bourque on 2022-03-11.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
#include "RESTObjects/RESTAPI_AnalyticsObjects.h"
namespace OpenWifi {
class RESTAPI_board_list_handler : public RESTAPIHandler {
public:
RESTAPI_board_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/boards"}; };
private:
BoardsDB & DB_=StorageService()->BoardsDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -3,20 +3,26 @@
//
#include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_board_list_handler.h"
#include "RESTAPI/RESTAPI_board_handler.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router<
RESTAPI_system_command
RESTAPI_system_command,
RESTAPI_board_handler,
RESTAPI_board_list_handler
>(Path,Bindings,L, S, TransactionId);
}
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router_I<
RESTAPI_system_command
RESTAPI_system_command,
RESTAPI_board_handler,
RESTAPI_board_list_handler
>(Path, Bindings, L, S, TransactionId);
}

View File

@@ -44,4 +44,16 @@ namespace OpenWifi {
}
}
void VenueCoordinator::StopVenue(const std::string &id) {
}
void VenueCoordinator::ModifyVenue(const std::string &id) {
}
void VenueCoordinator::AddVenue(const std::string &id) {
}
}

View File

@@ -20,6 +20,10 @@ namespace OpenWifi {
void Stop() override;
void run() override;
void StopVenue(const std::string &id);
void ModifyVenue(const std::string &id);
void AddVenue(const std::string &id);
private:
Poco::Thread Worker_;
std::atomic_bool Running_=false;

View File

@@ -27,8 +27,10 @@ namespace OpenWifi {
if(MsgContent!= nullptr) {
try {
auto State = MsgContent->Payload();
std::cout << "SerialNumber: " << Utils::IntToSerialNumber(MsgContent->SerialNumber()) << std::endl;
std::cout << to_string(*State) << std::endl;
auto It = APs_.find(MsgContent->SerialNumber());
if(It!=end(APs_)) {
It->second->Update(MsgContent->Payload());
}
} catch (const Poco::Exception &E) {
Logger().log(E);
} catch (...) {

View File

@@ -5,6 +5,7 @@
#pragma once
#include "framework/MicroService.h"
#include "APStats.h"
namespace OpenWifi {
@@ -27,9 +28,15 @@ namespace OpenWifi {
Id_(id),
Logger_(L),
SerialNumbers_(SerialNumbers) {
std::sort(SerialNumbers_.begin(),SerialNumbers_.end());
auto last = std::unique(SerialNumbers_.begin(),SerialNumbers_.end());
SerialNumbers_.erase(last,SerialNumbers_.end());
for(const auto &mac:SerialNumbers_) {
auto ap = std::make_shared<AP>(mac);
APs_[mac ] = ap;
}
}
void Post(uint64_t SerialNumber, std::shared_ptr<nlohmann::json> &Msg) {
@@ -45,13 +52,14 @@ namespace OpenWifi {
void ModifySerialNumbers(const std::vector<uint64_t> &SerialNumbers);
private:
std::recursive_mutex Mutex_;
std::string Id_;
Poco::NotificationQueue Queue_;
Poco::Logger &Logger_;
Poco::Thread Worker_;
std::atomic_bool Running_=false;
std::vector<uint64_t> SerialNumbers_;
std::recursive_mutex Mutex_;
std::string Id_;
Poco::NotificationQueue Queue_;
Poco::Logger &Logger_;
Poco::Thread Worker_;
std::atomic_bool Running_=false;
std::vector<uint64_t> SerialNumbers_;
std::map<uint64_t, std::shared_ptr<AP>> APs_;
};
}

41
src/dict_bssid.h Normal file
View File

@@ -0,0 +1,41 @@
//
// Created by stephane bourque on 2022-03-11.
//
#pragma once
#include <mutex>
#include <map>
namespace OpenWifi {
class BSSID_DICT {
public:
static auto instance() {
static auto instance_ = new BSSID_DICT;
return instance_;
}
inline uint32_t Get(uint64_t bssid) {
std::lock_guard G(Mutex_);
auto it = Dict_.find(bssid);
if(it==end(Dict_)) {
auto I = Index_++;
Dict_[bssid]=I;
return I;
} else {
return it->second;
}
}
inline void Remove(uint64_t bssid) {
std::lock_guard G(Mutex_);
Dict_.erase(bssid);
}
private:
uint32_t Index_=1;
std::mutex Mutex_;
std::map<uint64_t,uint32_t> Dict_;
};
inline auto BSSID_DICT() { return BSSID_DICT::instance(); }
}

38
src/dict_ssid.h Normal file
View File

@@ -0,0 +1,38 @@
#include <mutex>
#include <map>
#include <string>
namespace OpenWifi {
class SSID_DICT {
public:
static auto instance() {
static auto instance_ = new SSID_DICT;
return instance_;
}
inline uint32_t Add(const std::string &ssid) {
std::lock_guard G(Mutex_);
auto it = Dict_.find(ssid);
if (it == end(Dict_)) {
auto Id = Index_++;
Dict_[station] = Id;
return Id;
} else {
return it->second;
}
}
inline void Remove(const std::string &ssid) {
std::lock_guard G(Mutex_);
Dict_.erase(ssid);
}
private:
std::mutex Mutex_;
uint32_t Index_=1;
std::map<std::string,uint32_t> Dict_;
};
inline auto SSID_DICT() { return SSID_DICT::instance(); }
}

49
src/dict_ue.h Normal file
View File

@@ -0,0 +1,49 @@
//
// Created by stephane bourque on 2022-03-11.
//
#pragma once
#include <mutex>
#include <map>
namespace OpenWifi {
class UE_DICT {
public:
static auto instance() {
static auto instance_ = new UE_DICT;
return instance_;
}
inline void Add(uint64_t station, UE *ue) {
std::lock_guard G(Mutex_);
auto it = Dict_.find(station);
if (it == end(Dict_)) {
Dict_[station] = ue;
return;
} else {
it->second = ue;
}
}
inline void Remove(uint64_t station) {
std::lock_guard G(Mutex_);
Dict_.erase(station);
}
inline UE *Get(uint64_t station) {
std::lock_guard G(Mutex_);
auto it = Dict_.find(station);
if (it == end(Dict_))
return nullptr;
return it->second;
}
private:
std::mutex Mutex_;
std::map<uint64_t, UE *> Dict_;
};
inline auto UE_DICT() { return UE_DICT::instance(); }
}

File diff suppressed because it is too large Load Diff

150
stats_sample/nat_stats.json Normal file
View File

@@ -0,0 +1,150 @@
{
"interfaces": [
{
"clients": [
{
"ipv4_addresses": [
"10.2.140.145"
],
"mac": "00:23:a4:05:05:95",
"ports": [
"eth1"
]
},
{
"ipv4_addresses": [
"10.2.0.1"
],
"ipv6_addresses": [
"fe80:0:0:0:a8a2:caff:fe45:bc6b"
],
"mac": "e2:63:da:86:64:8e",
"ports": [
"eth1"
]
}
],
"counters": {
"collisions": 0,
"multicast": 662754,
"rx_bytes": 151712263,
"rx_dropped": 0,
"rx_errors": 0,
"rx_packets": 939389,
"tx_bytes": 17826254,
"tx_dropped": 0,
"tx_errors": 0,
"tx_packets": 91600
},
"dns_servers": [
"10.2.0.1"
],
"ipv4": {
"addresses": [
"10.2.172.66/16"
],
"dhcp_server": "10.2.0.1",
"leasetime": 86400
},
"location": "/interfaces/0",
"name": "up0v0",
"uptime": 116194
},
{
"counters": {
"collisions": 0,
"multicast": 819,
"rx_bytes": 12894844,
"rx_dropped": 0,
"rx_errors": 0,
"rx_packets": 79306,
"tx_bytes": 31429410,
"tx_dropped": 0,
"tx_errors": 0,
"tx_packets": 92656
},
"ipv4": {
"addresses": [
"192.168.1.1/24"
]
},
"location": "/interfaces/1",
"name": "down1v0",
"ssids": [
{
"bssid": "04:f8:f8:fc:37:74",
"iface": "wlan0",
"mode": "ap",
"phy": "soc/1b700000.pci/pci0001:00/0001:00:00.0/0001:01:00.0",
"radio": {
"$ref": "#/radios/0"
},
"ssid": "OpenWifi-fc3771"
},
{
"bssid": "04:f8:f8:fc:37:73",
"iface": "wlan1",
"mode": "ap",
"phy": "soc/1b900000.pci/pci0002:00/0002:00:00.0/0002:01:00.0",
"radio": {
"$ref": "#/radios/1"
},
"ssid": "OpenWifi-fc3771"
}
],
"uptime": 116195
}
],
"link-state": {
"lan": {
"eth1": {
"carrier": 0
}
},
"wan": {
"eth0": {
"carrier": 0
}
}
},
"radios": [
{
"active_ms": 116149120,
"busy_ms": 1061014,
"channel": 157,
"channel_width": "40",
"noise": -102,
"phy": "soc/1b700000.pci/pci0001:00/0001:00:00.0/0001:01:00.0",
"receive_ms": 749022,
"transmit_ms": 130980,
"tx_power": 24
},
{
"active_ms": 116142427,
"busy_ms": 4820047,
"channel": 1,
"channel_width": "20",
"noise": -94,
"phy": "soc/1b900000.pci/pci0002:00/0002:00:00.0/0002:01:00.0",
"receive_ms": 1345110,
"transmit_ms": 121020,
"tx_power": 24
}
],
"unit": {
"load": [
0,
0,
0
],
"localtime": 1646897100,
"memory": {
"buffered": 6762496,
"cached": 17715200,
"free": 100237312,
"total": 217239552
},
"uptime": 116225
},
"version": 1
}