mirror of
https://github.com/Telecominfraproject/wlan-cloud-analytics.git
synced 2026-01-27 10:22:33 +00:00
Adding WifiClientHistory.
This commit is contained in:
@@ -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}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
70
src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp
Normal file
70
src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
33
src/RESTAPI/RESTAPI_wificlienthistory_handler.h
Normal file
33
src/RESTAPI/RESTAPI_wificlienthistory_handler.h
Normal 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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
156
src/storage/storage_wificlients.cpp
Normal file
156
src/storage/storage_wificlients.cpp
Normal 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);
|
||||
|
||||
}
|
||||
57
src/storage/storage_wificlients.h
Normal file
57
src/storage/storage_wificlients.h
Normal 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;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user