Adding WifiClientHistory.

This commit is contained in:
stephb9959
2022-05-15 10:39:42 -07:00
parent cf7e87e3f2
commit e4869d23bf
12 changed files with 705 additions and 15 deletions

View File

@@ -100,7 +100,7 @@ add_executable(owanalytics
src/HealthReceiver.cpp src/HealthReceiver.h
src/StatFunc.h
src/RESTAPI/RESTAPI_board_timepoint_handler.cpp src/RESTAPI/RESTAPI_board_timepoint_handler.h
src/storage/storage_timepoints.cpp src/storage/storage_timepoints.h)
src/storage/storage_timepoints.cpp src/storage/storage_timepoints.h src/storage/storage_wificlients.cpp src/storage/storage_wificlients.h src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp src/RESTAPI/RESTAPI_wificlienthistory_handler.h)
target_link_libraries(owanalytics PUBLIC
${Poco_LIBRARIES}

2
build
View File

@@ -1 +1 @@
59
63

View File

@@ -498,7 +498,7 @@ components:
format: uuid
boardId:
type: string
format:
format: uuid
serialNumber:
type: string
timestamp:
@@ -577,6 +577,90 @@ components:
type: integer
format: int64
WifiClientHistory:
type: object
properties:
timestamp:
type: integer
stationId:
type: string
bssId:
type: string
ssid:
type: string
rssi:
type: integer
rx_bitrate:
type: integer
rx_chwidth:
type: integer
rx_mcs:
type: integer
rx_nss:
type: integer
rx_vht:
type: boolean
tx_bitrate:
type: integer
tx_chwidth:
type: integer
tx_mcs:
type: integer
tx_nss:
type: integer
tx_vht:
type: boolean
rx_bytes:
type: integer
tx_bytes:
type: integer
rx_duration:
type: integer
tx_duration:
type: integer
rx_packets:
type: integer
tx_packets:
type: integer
ipv4:
type: string
ipv6:
type: string
channel_width:
type: integer
noise:
type: integer
tx_power:
type: integer
channel:
type: integer
active_ms:
type: integer
busy_ms:
type: integer
receive_ms:
type: integer
mode:
type: string
ack_signal:
type: integer
ack_signal_avg:
type: integer
connected:
type: integer
inactive:
type: integer
tx_retries:
type: integer
WifiClientHistoryList:
type: object
properties:
entries:
type: array
items:
$ref: '#/components/schemas/WifiClientHistory'
#########################################################################################
##
## These are endpoints that all services in the OPenWiFI stack must provide
@@ -998,6 +1082,16 @@ paths:
default: false
required: false
responses:
200:
$ref: '#/components/schemas/DeviceTimePointList'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- Board data
@@ -1066,6 +1160,50 @@ paths:
404:
$ref: '#/components/responses/NotFound'
/wifiClientHistory/{client}:
get:
tags:
- WiFiClientHistory
operationId: getWifiClientHistory
summary: Retrieve WiFi client history for debugging purpose
parameters:
- in: path
name: client
schema:
type: string
example:
"112233aabbcc"
required: true
- in: query
name: fromDate
schema:
type: integer
required: false
- in: query
name: endDate
schema:
type: integer
required: false
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
responses:
200:
$ref: '#/components/schemas/WifiClientHistoryList'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
#########################################################################################
##
## These are endpoints that all services in the OpenWiFi stack must provide

View File

@@ -8,12 +8,31 @@
namespace OpenWifi {
static std::string mac_filter(const std::string &m) {
std::string r;
for(const auto &c:m)
if(c!=':' && c!='-') r += c;
return r;
}
template <typename T> void GetJSON(const char *field, const nlohmann::json & doc, T & v , const T & def ) {
if(doc.contains(field) && !doc[field].is_null()) {
try {
v = doc[field].get<T>();
} else {
v = def;
return;
} catch (...) {
}
v = def;
}
template <typename T> void GetJSON(const char *field1, const char *field2, const nlohmann::json & doc, T & v , const T & def ) {
try {
v = doc[field1][field2].get<T>();
return;
} catch (...) {
}
v = def;
}
inline double safe_div(uint64_t a , uint64_t b) {
@@ -115,6 +134,7 @@ namespace OpenWifi {
GetJSON("active_ms", radio, RTP.active_ms, (uint64_t) 0);
GetJSON("channel", radio, RTP.channel, (uint64_t) 0);
GetJSON("temperature", radio, RTP.temperature, (int64_t) 20);
GetJSON("channel_width", radio, RTP.channel_width, (uint64_t) 20);
if(RTP.temperature==0)
RTP.temperature = 20;
GetJSON("noise", radio, RTP.noise, (int64_t) -90);
@@ -168,9 +188,9 @@ namespace OpenWifi {
GetJSON("ssid",ssid,SSIDTP.ssid, std::string{""} );
if (ssid.contains("associations") && ssid["associations"].is_array()) {
auto associations = ssid["associations"];
auto it = radio_map.find(radio_location);
if(it!=radio_map.end()) {
auto the_radio = it->second.first;
auto radio_it = radio_map.find(radio_location);
if(radio_it!=radio_map.end()) {
auto the_radio = radio_it->second.first;
if (the_radio == 2)
DI_.associations_2g += associations.size();
else if (the_radio == 5)
@@ -179,6 +199,7 @@ namespace OpenWifi {
DI_.associations_6g += associations.size();
}
for(const auto &association:associations) {
AnalyticsObjects::UETimePoint TP;
GetJSON("station",association,TP.station, std::string{} );
GetJSON("rssi",association,TP.rssi, (int64_t)0 );
@@ -192,6 +213,54 @@ namespace OpenWifi {
GetJSON("connected",association,TP.connected, (uint64_t)0 );
GetJSON("inactive",association,TP.inactive, (uint64_t)0 );
AnalyticsObjects::WifiClientHistory WFH;
WFH.stationId = mac_filter(TP.station);
WFH.bssId = mac_filter(SSIDTP.bssid);
WFH.ssid = SSIDTP.ssid;
WFH.rssi = TP.rssi;
GetJSON("rx_rate","bitrate",association,WFH.rx_bitrate,(uint32_t)0);
GetJSON("rx_rate","chwidth",association,WFH.rx_chwidth,(uint32_t)0);
GetJSON("rx_rate","mcs",association,WFH.rx_mcs,(uint16_t)0);
GetJSON("rx_rate","nss",association,WFH.rx_nss,(uint16_t)0);
GetJSON("rx_rate","vht",association,WFH.rx_vht,false);
GetJSON("tx_rate","bitrate",association,WFH.tx_bitrate,(uint32_t)0);
GetJSON("tx_rate","chwidth",association,WFH.tx_chwidth,(uint32_t)0);
GetJSON("tx_rate","mcs",association,WFH.tx_mcs,(uint16_t)0);
GetJSON("tx_rate","nss",association,WFH.tx_nss,(uint16_t)0);
GetJSON("tx_rate","vht",association,WFH.tx_vht,false);
GetJSON("rx_bytes",association,WFH.rx_bytes,(uint64_t)0);
GetJSON("tx_bytes",association,WFH.tx_bytes,(uint64_t)0);
GetJSON("rx_duration",association,WFH.rx_duration,(uint64_t)0);
GetJSON("tx_duration",association,WFH.tx_duration,(uint64_t)0);
GetJSON("rx_packets",association,WFH.rx_packets,(uint64_t)0);
GetJSON("tx_packets",association,WFH.tx_packets,(uint64_t)0);
WFH.ipv4 = "---";
WFH.ipv6 = "----";
for(const auto &rd:DTP.radio_data) {
if(rd.band == SSIDTP.band) {
WFH.channel_width = rd.channel_width;
WFH.noise = rd.noise;
WFH.tx_power = rd.tx_power;
WFH.channel = rd.channel;
WFH.active_ms = rd.active_ms;
WFH.busy_ms = rd.busy_ms;
WFH.receive_ms = rd.receive_ms;
break;
}
}
WFH.mode = SSIDTP.mode;
GetJSON("ack_signal",association,WFH.ack_signal,(int64_t)0);
GetJSON("ack_signal_avg",association,WFH.ack_signal_avg,(int64_t)0);
GetJSON("connected",association,WFH.connected,(uint64_t)0);
GetJSON("inactive",association,WFH.inactive,(uint64_t)0);
GetJSON("tx_retries",association,WFH.tx_retries,(uint64_t)0);
StorageService()->WifiClientHistoryDB().CreateRecord(WFH);
if(association.contains("tid_stats") && association["tid_stats"].is_array()) {
auto tid_stats = association["tid_stats"];
for(const auto &tid_stat:tid_stats) {

View File

@@ -0,0 +1,70 @@
//
// Created by stephane bourque on 2022-05-15.
//
#include "RESTAPI_wificlienthistory_handler.h"
#include "RESTAPI/RESTAPI_analytics_db_helpers.h"
namespace OpenWifi {
void RESTAPI_wificlienthistory_handler::DoGet() {
auto stationId = GetBinding("client");
if(!Utils::ValidSerialNumber(stationId)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
auto fromDate = GetParameter("fromDate",0);
auto endDate = GetParameter("endDate",0);
WifiClientHistoryDB::RecordVec Results;
std::string Where;
if(fromDate && endDate)
Where = fmt::format(" stationId='{}' and timestamp>={} and timestamp<={} ", stationId, fromDate, endDate);
else if(fromDate && !endDate)
Where = fmt::format(" stationId='{}' and timestamp>={} ", stationId, fromDate);
else if(!fromDate && endDate)
Where = fmt::format(" stationId='{}' and timestamp<={} ", stationId, endDate);
else
Where = fmt::format(" stationId='{}' ", stationId);
if(StorageService()->WifiClientHistoryDB().GetRecords(QB_.Offset,QB_.Limit, Results, Where)) {
return ReturnObject("entries",Results);
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_wificlienthistory_handler::DoDelete() {
if(UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
auto stationId = GetBinding("client");
if(!Utils::ValidSerialNumber(stationId)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
auto fromDate = GetParameter("fromDate",0);
auto endDate = GetParameter("endDate",0);
WifiClientHistoryDB::RecordVec Results;
std::string Where;
if(fromDate && endDate)
Where = fmt::format(" stationId='{}' and timestamp>={} and timestamp<={} ", stationId, fromDate, endDate);
else if(fromDate && !endDate)
Where = fmt::format(" stationId='{}' and timestamp>={} ", stationId, fromDate);
else if(!fromDate && endDate)
Where = fmt::format(" stationId='{}' and timestamp<={} ", stationId, endDate);
else
Where = fmt::format(" stationId='{}' ", stationId);
if(StorageService()->WifiClientHistoryDB().DeleteRecords(Where)) {
return OK();
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
}

View File

@@ -0,0 +1,33 @@
//
// Created by stephane bourque on 2022-05-15.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_wificlienthistory_handler : public RESTAPIHandler {
public:
RESTAPI_wificlienthistory_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_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1//wifiClientHistory/{client}"}; };
private:
OpenWifi::WifiClientHistoryDB & DB_=StorageService()->WifiClientHistoryDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final;
};
}

View File

@@ -316,7 +316,7 @@ namespace OpenWifi::AnalyticsObjects {
void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"band",band);
field_to_json(Obj,"radio_channel",radio_channel);
field_to_json(Obj,"channel_width",channel_width);
field_to_json(Obj,"active_ms",active_ms);
field_to_json(Obj,"busy_ms",busy_ms);
field_to_json(Obj,"receive_ms",receive_ms);
@@ -334,7 +334,7 @@ namespace OpenWifi::AnalyticsObjects {
bool RadioTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"band",band);
field_from_json(Obj,"radio_channel",radio_channel);
field_from_json(Obj,"channel_width",channel_width);
field_from_json(Obj,"active_ms",active_ms);
field_from_json(Obj,"busy_ms",busy_ms);
field_from_json(Obj,"receive_ms",receive_ms);
@@ -514,4 +514,109 @@ namespace OpenWifi::AnalyticsObjects {
return false;
}
void WifiClientRate::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"bitrate",bitrate);
field_to_json(Obj,"chwidth",chwidth);
field_to_json(Obj,"mcs",mcs);
field_to_json(Obj,"nss",nss);
field_to_json(Obj,"vht",vht);
}
bool WifiClientRate::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"bitrate",bitrate);
field_from_json(Obj,"chwidth",chwidth);
field_from_json(Obj,"mcs",mcs);
field_from_json(Obj,"nss",nss);
field_from_json(Obj,"vht",vht);
return true;
} catch(...) {
}
return false;
}
void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"timestamp",timestamp);
field_to_json(Obj,"stationId",stationId);
field_to_json(Obj,"bssId",bssId);
field_to_json(Obj,"ssid",ssid);
field_to_json(Obj,"rssi",rssi);
field_to_json(Obj,"rx_bitrate",rx_bitrate);
field_to_json(Obj,"rx_chwidth",rx_chwidth);
field_to_json(Obj,"rx_mcs",rx_mcs);
field_to_json(Obj,"rx_nss",rx_nss);
field_to_json(Obj,"rx_vht",rx_vht);
field_to_json(Obj,"tx_bitrate",tx_bitrate);
field_to_json(Obj,"tx_chwidth",tx_chwidth);
field_to_json(Obj,"tx_mcs",tx_mcs);
field_to_json(Obj,"tx_nss",tx_nss);
field_to_json(Obj,"tx_vht",tx_vht);
field_to_json(Obj,"rx_bytes",rx_bytes);
field_to_json(Obj,"tx_bytes",tx_bytes);
field_to_json(Obj,"rx_duration",rx_duration);
field_to_json(Obj,"tx_duration",tx_duration);
field_to_json(Obj,"rx_packets",rx_packets);
field_to_json(Obj,"tx_packets",tx_packets);
field_to_json(Obj,"ipv4",ipv4);
field_to_json(Obj,"ipv6",ipv6);
field_to_json(Obj,"channel_width",channel_width);
field_to_json(Obj,"noise",noise);
field_to_json(Obj,"tx_power",tx_power);
field_to_json(Obj,"channel",channel);
field_to_json(Obj,"active_ms",active_ms);
field_to_json(Obj,"busy_ms",busy_ms);
field_to_json(Obj,"receive_ms",receive_ms);
field_to_json(Obj,"mode",mode);
field_to_json(Obj,"ack_signal",ack_signal);
field_to_json(Obj,"ack_signal_avg",ack_signal_avg);
field_to_json(Obj,"connected",connected);
field_to_json(Obj,"inactive",inactive);
field_to_json(Obj,"tx_retries",tx_retries);
}
bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"timestamp",timestamp);
field_from_json(Obj,"stationId",stationId);
field_from_json(Obj,"bssId",bssId);
field_from_json(Obj,"ssid",ssid);
field_from_json(Obj,"rssi",rssi);
field_from_json(Obj,"rx_bitrate",rx_bitrate);
field_from_json(Obj,"rx_chwidth",rx_chwidth);
field_from_json(Obj,"rx_mcs",rx_mcs);
field_from_json(Obj,"rx_nss",rx_nss);
field_from_json(Obj,"rx_vht",rx_vht);
field_from_json(Obj,"tx_bitrate",tx_bitrate);
field_from_json(Obj,"tx_chwidth",tx_chwidth);
field_from_json(Obj,"tx_mcs",tx_mcs);
field_from_json(Obj,"tx_nss",tx_nss);
field_from_json(Obj,"tx_vht",tx_vht);
field_from_json(Obj,"rx_bytes",rx_bytes);
field_from_json(Obj,"tx_bytes",tx_bytes);
field_from_json(Obj,"rx_duration",rx_duration);
field_from_json(Obj,"tx_duration",tx_duration);
field_from_json(Obj,"rx_packets",rx_packets);
field_from_json(Obj,"tx_packets",tx_packets);
field_from_json(Obj,"ipv4",ipv4);
field_from_json(Obj,"ipv6",ipv6);
field_from_json(Obj,"channel_width",channel_width);
field_from_json(Obj,"noise",noise);
field_from_json(Obj,"tx_power",tx_power);
field_from_json(Obj,"channel",channel);
field_from_json(Obj,"active_ms",active_ms);
field_from_json(Obj,"busy_ms",busy_ms);
field_from_json(Obj,"receive_ms",receive_ms);
field_from_json(Obj,"mode",mode);
field_from_json(Obj,"ack_signal",ack_signal);
field_from_json(Obj,"ack_signal_avg",ack_signal_avg);
field_from_json(Obj,"connected",connected);
field_from_json(Obj,"inactive",inactive);
field_from_json(Obj,"tx_retries",tx_retries);
return true;
} catch(...) {
}
return false;
}
}

View File

@@ -237,7 +237,7 @@ namespace OpenWifi {
struct RadioTimePoint {
uint64_t band = 0,
radio_channel = 0;
channel_width = 0;
uint64_t active_ms = 0,
busy_ms = 0,
receive_ms = 0,
@@ -362,5 +362,60 @@ namespace OpenWifi {
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WifiClientRate {
uint32_t bitrate=0;
uint32_t chwidth=0;
uint16_t mcs=0;
uint16_t nss=0;
bool vht=false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WifiClientHistory {
uint64_t timestamp=OpenWifi::Now();
std::string stationId;
std::string bssId;
std::string ssid;
int64_t rssi=0;
uint32_t rx_bitrate=0;
uint32_t rx_chwidth=0;
uint16_t rx_mcs=0;
uint16_t rx_nss=0;
bool rx_vht=false;
uint32_t tx_bitrate=0;
uint32_t tx_chwidth=0;
uint16_t tx_mcs=0;
uint16_t tx_nss=0;
bool tx_vht=false;
uint64_t rx_bytes=0;
uint64_t tx_bytes=0;
uint64_t rx_duration=0;
uint64_t tx_duration=0;
uint64_t rx_packets=0;
uint64_t tx_packets=0;
std::string ipv4;
std::string ipv6;
uint64_t channel_width=0;
int64_t noise=0;
uint64_t tx_power=0;
uint64_t channel=0;
uint64_t active_ms=0;
uint64_t busy_ms=0;
uint64_t receive_ms=0;
std::string mode;
int64_t ack_signal=0;
int64_t ack_signal_avg=0;
uint64_t connected=0;
uint64_t inactive=0;
uint64_t tx_retries=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
}

View File

@@ -17,9 +17,13 @@ namespace OpenWifi {
StorageClass::Start();
BoardsDB_ = std::make_unique<OpenWifi::BoardsDB>(dbType_,*Pool_, Logger());
BoardsDB_->Create();
TimePointsDB_ = std::make_unique<OpenWifi::TimePointDB>(dbType_,*Pool_, Logger());
WifiClientHistoryDB_ = std::make_unique<OpenWifi::WifiClientHistoryDB>(dbType_,*Pool_, Logger());
TimePointsDB_->Create();
BoardsDB_->Create();
WifiClientHistoryDB_->Create();
PeriodicCleanup_ = MicroService::instance().ConfigGetInt("storage.cleanup.interval", 6*60*60);
if(PeriodicCleanup_<1*60*60)
PeriodicCleanup_ = 1*60*60;

View File

@@ -12,6 +12,7 @@
#include "framework/StorageClass.h"
#include "storage/storage_boards.h"
#include "storage/storage_timepoints.h"
#include "storage/storage_wificlients.h"
namespace OpenWifi {
class Storage : public StorageClass, Poco::Runnable {
@@ -25,13 +26,15 @@ namespace OpenWifi {
void Stop() override;
void run() final;
OpenWifi::BoardsDB & BoardsDB() { return *BoardsDB_; };
OpenWifi::TimePointDB & TimePointsDB() { return *TimePointsDB_; };
auto & BoardsDB() { return *BoardsDB_; };
auto & TimePointsDB() { return *TimePointsDB_; };
auto & WifiClientHistoryDB() { return *WifiClientHistoryDB_; };
void onTimer(Poco::Timer & timer);
private:
std::unique_ptr<OpenWifi::BoardsDB> BoardsDB_;
std::unique_ptr<OpenWifi::TimePointDB> TimePointsDB_;
std::unique_ptr<OpenWifi::WifiClientHistoryDB> WifiClientHistoryDB_;
Poco::Thread Updater_;
std::atomic_bool Running_=false;
Poco::Timer Timer_;

View File

@@ -0,0 +1,156 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "framework/MicroService.h"
#include "storage_wificlients.h"
#include "framework/OpenWifiTypes.h"
namespace OpenWifi {
static ORM::FieldVec Boards_Fields{
ORM::Field{"timestamp",ORM::FieldType::FT_BIGINT},
ORM::Field{"stationId",ORM::FieldType::FT_TEXT},
ORM::Field{"bssId",ORM::FieldType::FT_TEXT},
ORM::Field{"ssid",ORM::FieldType::FT_TEXT},
ORM::Field{"rssi",ORM::FieldType::FT_BIGINT},
ORM::Field{"rx_bitrate",ORM::FieldType::FT_BIGINT},
ORM::Field{"rx_chwidth",ORM::FieldType::FT_BIGINT},
ORM::Field{"rx_mcs",ORM::FieldType::FT_BIGINT},
ORM::Field{"rx_nss",ORM::FieldType::FT_BIGINT},
ORM::Field{"rx_vht",ORM::FieldType::FT_BOOLEAN},
ORM::Field{"tx_bitrate",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_chwidth",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_mcs",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_nss",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_vht",ORM::FieldType::FT_BOOLEAN},
ORM::Field{"rx_bytes",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_bytes",ORM::FieldType::FT_BIGINT},
ORM::Field{"rx_duration",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_duration",ORM::FieldType::FT_BIGINT},
ORM::Field{"rx_packets",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_packets",ORM::FieldType::FT_BIGINT},
ORM::Field{"ipv4",ORM::FieldType::FT_TEXT},
ORM::Field{"ipv6",ORM::FieldType::FT_TEXT},
ORM::Field{"channel_width",ORM::FieldType::FT_BIGINT},
ORM::Field{"noise",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_power",ORM::FieldType::FT_BIGINT},
ORM::Field{"channel",ORM::FieldType::FT_BIGINT},
ORM::Field{"active_ms",ORM::FieldType::FT_BIGINT},
ORM::Field{"busy_ms",ORM::FieldType::FT_BIGINT},
ORM::Field{"receive_ms",ORM::FieldType::FT_BIGINT},
ORM::Field{"mode",ORM::FieldType::FT_TEXT},
ORM::Field{"ack_signal",ORM::FieldType::FT_BIGINT},
ORM::Field{"ack_signal_avg",ORM::FieldType::FT_BIGINT},
ORM::Field{"connected",ORM::FieldType::FT_BIGINT},
ORM::Field{"inactive",ORM::FieldType::FT_BIGINT},
ORM::Field{"tx_retries",ORM::FieldType::FT_BIGINT}
};
static ORM::IndexVec BoardsDB_Indexes{
{ std::string("stationid_name_index"),
ORM::IndexEntryVec{
{std::string("stationId"),
ORM::Indextype::ASC} } },
{ std::string("stationtsid_name_index"),
ORM::IndexEntryVec{
{std::string("stationId"),
ORM::Indextype::ASC} ,
{std::string("timestamp"),
ORM::Indextype::ASC}} }
};
WifiClientHistoryDB::WifiClientHistoryDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L) :
DB(T, "wificlienthistory", Boards_Fields, BoardsDB_Indexes, P, L, "wfh") {}
bool WifiClientHistoryDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) {
std::vector<std::string> Statements{
};
RunScript(Statements);
to = 2;
return true;
}
}
template<> void ORM::DB<OpenWifi::WifiClientHistoryDBRecordType, OpenWifi::AnalyticsObjects::WifiClientHistory>::Convert(const OpenWifi::WifiClientHistoryDBRecordType &In, OpenWifi::AnalyticsObjects::WifiClientHistory &Out) {
Out.timestamp = In.get<0>();
Out.stationId = In.get<1>();
Out.bssId= In.get<2>();
Out.ssid= In.get<3>();
Out.rssi= In.get<4>();
Out.rx_bitrate= In.get<5>();
Out.rx_chwidth= In.get<6>();
Out.rx_mcs= In.get<7>();
Out.rx_nss= In.get<8>();
Out.rx_vht= In.get<9>();
Out.tx_bitrate= In.get<10>();
Out.tx_chwidth= In.get<11>();
Out.tx_mcs= In.get<12>();
Out.tx_nss= In.get<13>();
Out.tx_vht= In.get<14>();
Out.rx_bytes= In.get<15>();
Out.tx_bytes= In.get<16>();
Out.rx_duration= In.get<17>();
Out.tx_duration= In.get<18>();
Out.rx_packets= In.get<19>();
Out.tx_packets= In.get<20>();
Out.ipv4= In.get<21>();
Out.ipv6= In.get<22>();
Out.channel_width= In.get<23>();
Out.noise= In.get<24>();
Out.tx_power= In.get<25>();
Out.channel= In.get<26>();
Out.active_ms= In.get<27>();
Out.busy_ms= In.get<28>();
Out.receive_ms= In.get<29>();
Out.mode= In.get<30>();
Out.ack_signal= In.get<31>();
Out.ack_signal_avg= In.get<32>();
Out.connected= In.get<33>();
Out.inactive= In.get<34>();
Out.tx_retries= In.get<35>();
}
template<> void ORM::DB<OpenWifi::WifiClientHistoryDBRecordType, OpenWifi::AnalyticsObjects::WifiClientHistory>::Convert(const OpenWifi::AnalyticsObjects::WifiClientHistory &In, OpenWifi::WifiClientHistoryDBRecordType &Out) {
Out.set<0>(In.timestamp);
Out.set<1>(In.stationId);
Out.set<2>(In.bssId);
Out.set<3>(In.ssid);
Out.set<4>(In.rssi);
Out.set<5>(In.rx_bitrate);
Out.set<6>(In.rx_chwidth);
Out.set<7>(In.rx_mcs);
Out.set<8>(In.rx_nss);
Out.set<9>(In.rx_vht);
Out.set<10>(In.tx_bitrate);
Out.set<11>(In.tx_chwidth);
Out.set<12>(In.tx_mcs);
Out.set<13>(In.tx_nss);
Out.set<14>(In.tx_vht);
Out.set<15>(In.rx_bytes);
Out.set<16>(In.tx_bytes);
Out.set<17>(In.rx_duration);
Out.set<18>(In.tx_duration);
Out.set<19>(In.rx_packets);
Out.set<20>(In.tx_packets);
Out.set<21>(In.ipv4);
Out.set<22>(In.ipv6);
Out.set<23>(In.channel_width);
Out.set<24>(In.noise);
Out.set<25>(In.tx_power);
Out.set<26>(In.channel);
Out.set<27>(In.active_ms);
Out.set<28>(In.busy_ms);
Out.set<29>(In.receive_ms);
Out.set<30>(In.mode);
Out.set<31>(In.ack_signal);
Out.set<32>(In.ack_signal_avg);
Out.set<33>(In.connected);
Out.set<34>(In.inactive);
Out.set<35>(In.tx_retries);
}

View File

@@ -0,0 +1,57 @@
//
// Created by stephane bourque on 2022-05-15.
//
#pragma once
#include "framework/orm.h"
#include "RESTObjects/RESTAPI_AnalyticsObjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
uint64_t, // timestamp=OpenWifi::Now();
std::string, // stationId;
std::string, // bssId;
std::string, // ssid;
int64_t, // rssi=0;
uint32_t, // rx_bitrate=0;
uint32_t, // rx_chwidth=0;
uint16_t, // rx_mcs=0;
uint16_t, // rx_nss=0;
bool, // rx_vht=false;
uint32_t, // tx_bitrate=0;
uint32_t, // tx_chwidth=0;
uint16_t, // tx_mcs=0;
uint16_t, // tx_nss=0;
bool, // tx_vht=false;
uint64_t, // rx_bytes=0,
uint64_t, // tx_bytes=0;
int64_t, // rx_duration=0,
uint64_t, // tx_duration=0;
uint64_t, // rx_packets=0,
uint64_t, // tx_packets=0;
std::string, // ipv4;
std::string, // ipv6;
uint64_t, // channel_width=0;
int64_t, // noise=0;
uint64_t, // tx_power=0;
uint64_t, // channel=0;
uint64_t, // active_ms=0,
uint64_t, // busy_ms=0,
uint64_t, // receive_ms=0;
std::string, // mode;
int64_t, // ack_signal=0;
int64_t, // ack_signal_avg=0;
int64_t, // connected=0;
int64_t, // inactive=0;
int64_t // tx_retries=0;
> WifiClientHistoryDBRecordType;
class WifiClientHistoryDB : public ORM::DB<WifiClientHistoryDBRecordType, AnalyticsObjects::WifiClientHistory> {
public:
WifiClientHistoryDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
virtual ~WifiClientHistoryDB() {};
private:
bool Upgrade(uint32_t from, uint32_t &to) override;
};
}