Adding WifiClientHistory.

This commit is contained in:
stephb9959
2022-05-15 21:42:17 -07:00
parent f69b9ef411
commit 13fdc370bb
13 changed files with 116 additions and 68 deletions

View File

@@ -582,9 +582,9 @@ components:
properties:
timestamp:
type: integer
stationId:
station_id:
type: string
bssId:
bssid:
type: string
ssid:
type: string
@@ -652,6 +652,8 @@ components:
type: integer
tx_retries:
type: integer
venue_id:
type: string
WifiClientHistoryList:
type: object
@@ -1212,6 +1214,13 @@ paths:
example:
112233445566, 11223344*, *5566
required: false
- in: query
description: The venue to for the search.
name: venue
schema:
type: string
format: uuid
required: true
responses:
200:
$ref: '#/components/schemas/StringList'

View File

@@ -258,9 +258,9 @@ namespace OpenWifi {
GetJSON("inactive",association,TP.inactive, (uint64_t)0 );
AnalyticsObjects::WifiClientHistory WFH;
WFH.stationId = mac_filter(TP.station);
std::cout << "Adding WiFiClient: " << WFH.stationId << std::endl;
WFH.bssId = mac_filter(SSIDTP.bssid);
WFH.station_id = mac_filter(TP.station);
std::cout << "Adding WiFiClient: " << WFH.station_id << std::endl;
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);
@@ -304,9 +304,9 @@ namespace OpenWifi {
GetJSON("inactive",association,WFH.inactive,(uint64_t)0);
GetJSON("tx_retries",association,WFH.tx_retries,(uint64_t)0);
std::cout << "Adding WiFiClient: " << WFH.stationId << std::endl;
std::cout << "Adding WiFiClient: " << WFH.station_id << std::endl;
WifiClientCache()->AddSerialNumber(WFH.stationId);
WifiClientCache()->AddSerialNumber(venue_id_,WFH.station_id);
StorageService()->WifiClientHistoryDB().CreateRecord(WFH);
std::cout << __LINE__ << std::endl;

View File

@@ -13,7 +13,8 @@ namespace OpenWifi {
class AP {
public:
explicit AP(uint64_t mac, const std::string &BoardId, Poco::Logger &L) :
explicit AP(uint64_t mac, const std::string &venue_id, const std::string &BoardId, Poco::Logger &L) :
venue_id_(venue_id),
boardId_(BoardId),
Logger_(L)
{
@@ -26,6 +27,7 @@ namespace OpenWifi {
[[nodiscard]] const AnalyticsObjects::DeviceInfo & Info() const { return DI_; }
private:
std::string venue_id_;
std::string boardId_;
AnalyticsObjects::DeviceInfo DI_;
AnalyticsObjects::DeviceTimePoint tp_base_;

View File

@@ -11,9 +11,14 @@ namespace OpenWifi {
std::cout << __LINE__ << std::endl;
if(GetBoolParameter("macsOnly")) {
auto venue = GetParameter("venue","");
if(venue.empty()) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
auto macFilter = GetParameter("macFilter","");
std::vector<uint64_t> Macs;
WifiClientCache()->FindNumbers(macFilter,500,Macs);
WifiClientCache()->FindNumbers(venue,macFilter,500,Macs);
Poco::JSON::Array Arr;
for(const auto &mac: Macs)
Arr.add(Utils::IntToSerialNumber(mac));

View File

@@ -538,8 +538,8 @@ namespace OpenWifi::AnalyticsObjects {
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,"station_id",station_id);
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);
@@ -573,13 +573,14 @@ namespace OpenWifi::AnalyticsObjects {
field_to_json(Obj,"connected",connected);
field_to_json(Obj,"inactive",inactive);
field_to_json(Obj,"tx_retries",tx_retries);
field_to_json(Obj,"venue_id",venue_id);
}
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,"station_id",station_id);
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);
@@ -613,6 +614,7 @@ namespace OpenWifi::AnalyticsObjects {
field_from_json(Obj,"connected",connected);
field_from_json(Obj,"inactive",inactive);
field_from_json(Obj,"tx_retries",tx_retries);
field_from_json(Obj,"venue_id",venue_id);
return true;
} catch(...) {

View File

@@ -376,8 +376,8 @@ namespace OpenWifi {
struct WifiClientHistory {
uint64_t timestamp=OpenWifi::Now();
std::string stationId;
std::string bssId;
std::string station_id;
std::string bssid;
std::string ssid;
int64_t rssi=0;
uint32_t rx_bitrate=0;
@@ -411,6 +411,7 @@ namespace OpenWifi {
uint64_t connected=0;
uint64_t inactive=0;
uint64_t tx_retries=0;
std::string venue_id;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);

View File

@@ -94,7 +94,7 @@ namespace OpenWifi {
if(GetDevicesForBoard(B,Devices,VenueExists)) {
std::lock_guard G(Mutex_);
ExistingBoards_[B.info.id] = Devices;
Watchers_[B.info.id] = std::make_shared<VenueWatcher>(B.info.id, Logger(), Devices);
Watchers_[B.info.id] = std::make_shared<VenueWatcher>(B.info.id, B.venueList[0].id, Logger(), Devices);
Watchers_[B.info.id]->Start();
Logger().information(fmt::format("Started board {}", B.info.name));
return true;

View File

@@ -11,7 +11,7 @@ namespace OpenWifi {
void VenueWatcher::Start() {
for(const auto &mac:SerialNumbers_) {
auto ap = std::make_shared<AP>(mac, boardId_, Logger());
auto ap = std::make_shared<AP>(mac, venue_id_, boardId_, Logger());
APs_[mac ] = ap;
}

View File

@@ -35,8 +35,9 @@ namespace OpenWifi {
class VenueWatcher : public Poco::Runnable {
public:
explicit VenueWatcher(const std::string &boardId, Poco::Logger &L, const std::vector<uint64_t> & SerialNumbers) :
explicit VenueWatcher(const std::string &boardId, const std::string &venue_id,Poco::Logger &L, const std::vector<uint64_t> & SerialNumbers) :
boardId_(boardId),
venue_id_(venue_id),
Logger_(L),
SerialNumbers_(SerialNumbers) {
std::sort(SerialNumbers_.begin(),SerialNumbers_.end());
@@ -72,6 +73,7 @@ namespace OpenWifi {
private:
std::recursive_mutex Mutex_;
std::string boardId_;
std::string venue_id_;
Poco::NotificationQueue Queue_;
Poco::Logger &Logger_;
Poco::Thread Worker_;

View File

@@ -22,48 +22,58 @@ namespace OpenWifi {
}
void WifiClientCache::onTimer([[maybe_unused]] Poco::Timer & timer) {
std::vector<std::string> WifiClients;
std::vector<std::pair<std::string,std::string>> WifiClients;
if(StorageService()->WifiClientHistoryDB().GetClientMacs(WifiClients)) {
// Let's replace current cache...
std::lock_guard G(Mutex_);
SNs_.clear();
Reverse_SNs_.clear();
Cache_.clear();
for(const auto &mac:WifiClients)
AddSerialNumber(mac,G);
AddSerialNumber(mac.second,mac.first,G);
}
}
void WifiClientCache::AddSerialNumber(const std::string &S) {
void WifiClientCache::AddSerialNumber(const std::string &venue_id, const std::string &S) {
std::lock_guard G(Mutex_);
AddSerialNumber(S,G);
AddSerialNumber(venue_id, S,G);
}
void WifiClientCache::AddSerialNumber(const std::string &S, [[maybe_unused]] std::lock_guard<std::recursive_mutex> & G) {
void WifiClientCache::AddSerialNumber(const std::string &venue_id, const std::string &S, [[maybe_unused]] std::lock_guard<std::recursive_mutex> & G) {
bool added=false;
auto VenueIt = Cache_.find(venue_id);
if(VenueIt==Cache_.end())
std::pair(VenueIt,added) = Cache_.insert(std::pair(venue_id,Cache{}));
uint64_t SN = std::stoull(S, nullptr, 16);
if (std::find(std::begin(SNs_), std::end(SNs_), SN) == std::end(SNs_)) {
auto insert_point = std::lower_bound(SNs_.begin(), SNs_.end(), SN);
SNs_.insert(insert_point, SN);
if (std::find(std::begin(VenueIt->second.SNs_), std::end(VenueIt->second.SNs_), SN) == std::end(VenueIt->second.SNs_)) {
auto insert_point = std::lower_bound(VenueIt->second.SNs_.begin(), VenueIt->second.SNs_.end(), SN);
VenueIt->second.SNs_.insert(insert_point, SN);
auto R = ReverseSerialNumber(S);
uint64_t RSN = std::stoull(R, nullptr, 16);
auto rev_insert_point = std::lower_bound(Reverse_SNs_.begin(), Reverse_SNs_.end(), RSN);
Reverse_SNs_.insert(rev_insert_point, RSN);
auto rev_insert_point = std::lower_bound(VenueIt->second.Reverse_SNs_.begin(), VenueIt->second.Reverse_SNs_.end(), RSN);
VenueIt->second.Reverse_SNs_.insert(rev_insert_point, RSN);
}
}
void WifiClientCache::DeleteSerialNumber(const std::string &S) {
void WifiClientCache::DeleteSerialNumber(const std::string &venue_id, const std::string &S) {
std::lock_guard G(Mutex_);
uint64_t SN = std::stoull(S,nullptr,16);
auto It = std::find(SNs_.begin(),SNs_.end(),SN);
if(It != SNs_.end()) {
SNs_.erase(It);
auto VenueIt = Cache_.find(venue_id);
if(VenueIt==Cache_.end())
return;
auto It = std::find(VenueIt->second.SNs_.begin(),VenueIt->second.SNs_.end(),SN);
if(It != VenueIt->second.SNs_.end()) {
VenueIt->second.SNs_.erase(It);
auto R = ReverseSerialNumber(S);
uint64_t RSN = std::stoull(R, nullptr, 16);
auto RIt = std::find(Reverse_SNs_.begin(),Reverse_SNs_.end(),RSN);
if(RIt != Reverse_SNs_.end()) {
Reverse_SNs_.erase(RIt);
auto RIt = std::find(VenueIt->second.Reverse_SNs_.begin(),VenueIt->second.Reverse_SNs_.end(),RSN);
if(RIt != VenueIt->second.Reverse_SNs_.end()) {
VenueIt->second.Reverse_SNs_.erase(RIt);
}
}
}
@@ -115,11 +125,18 @@ namespace OpenWifi {
}
}
void WifiClientCache::FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A) {
void WifiClientCache::FindNumbers(const std::string &venue_id, const std::string &S, uint HowMany, std::vector<uint64_t> &A) {
std::lock_guard G(Mutex_);
A.clear();
auto VenueIt = Cache_.find(venue_id);
if(VenueIt==Cache_.end())
return;
if(S.empty()) {
auto Start = SNs_.begin();
while(HowMany && Start!=SNs_.end()) {
auto Start = VenueIt->second.SNs_.begin();
while(HowMany && Start!=VenueIt->second.SNs_.end()) {
A.push_back(*Start);
Start++;
HowMany--;
@@ -132,9 +149,9 @@ namespace OpenWifi {
std::copy(rbegin(S), rend(S)-1, std::back_inserter(Reversed));
if(Reversed.empty())
return;
return ReturnNumbers(Reversed, HowMany, Reverse_SNs_, A, true);
return ReturnNumbers(Reversed, HowMany, VenueIt->second.Reverse_SNs_, A, true);
} else {
return ReturnNumbers(S, HowMany, SNs_, A, false);
return ReturnNumbers(S, HowMany, VenueIt->second.SNs_, A, false);
}
}
}

View File

@@ -18,12 +18,15 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
void AddSerialNumber(const std::string &SerialNumber);
void DeleteSerialNumber(const std::string &SerialNumber);
void FindNumbers(const std::string &SerialNumber, uint HowMany, std::vector<uint64_t> &A);
inline bool NumberExists(uint64_t SerialNumber) {
void AddSerialNumber(const std::string &venueId, const std::string &SerialNumber);
void DeleteSerialNumber(const std::string &venueId, const std::string &SerialNumber);
void FindNumbers(const std::string &venueId, const std::string &SerialNumber, uint HowMany, std::vector<uint64_t> &A);
inline bool NumberExists(const std::string &venueId, uint64_t SerialNumber) {
std::lock_guard G(Mutex_);
return std::find(SNs_.begin(),SNs_.end(),SerialNumber)!=SNs_.end();
auto It = Cache_.find(venueId);
if(It==Cache_.end())
return false;
return std::find(It->second.SNs_.begin(),It->second.SNs_.end(),SerialNumber)!=It->second.SNs_.end();
}
static inline std::string ReverseSerialNumber(const std::string &S) {
@@ -34,19 +37,21 @@ namespace OpenWifi {
void onTimer(Poco::Timer & timer);
private:
std::vector<uint64_t> SNs_;
std::vector<uint64_t> Reverse_SNs_;
struct Cache {
std::vector<uint64_t> SNs_;
std::vector<uint64_t> Reverse_SNs_;
};
std::map<std::string,Cache> Cache_;
Poco::Timer Timer_;
std::unique_ptr<Poco::TimerCallback<WifiClientCache>> TimerCallback_;
void AddSerialNumber(const std::string &S, std::lock_guard<std::recursive_mutex> & G);
void AddSerialNumber(const std::string &venueId, const std::string &S, std::lock_guard<std::recursive_mutex> & G);
void ReturnNumbers(const std::string &S, uint HowMany, const std::vector<uint64_t> & SNArr, std::vector<uint64_t> &A, bool ReverseResult);
WifiClientCache() noexcept:
SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache")
{
SNs_.reserve(2000);
}
};

View File

@@ -14,8 +14,8 @@ 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{"station_id",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},
@@ -48,17 +48,20 @@ namespace OpenWifi {
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}
ORM::Field{"tx_retries",ORM::FieldType::FT_BIGINT},
ORM::Field{"venue_id",ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec BoardsDB_Indexes{
{ std::string("stationid_name_index"),
ORM::IndexEntryVec{
{std::string("stationId"),
{std::string("station_id"),
ORM::Indextype::ASC} } },
{ std::string("stationtsid_name_index"),
{ std::string("station_ven_ts_id_name_index"),
ORM::IndexEntryVec{
{std::string("stationId"),
{std::string("venue_id"),
ORM::Indextype::ASC} ,
{std::string("station_id"),
ORM::Indextype::ASC} ,
{std::string("timestamp"),
ORM::Indextype::ASC}} }
@@ -75,13 +78,13 @@ namespace OpenWifi {
return true;
}
bool WifiClientHistoryDB::GetClientMacs(std::vector<std::string> &Macs) {
bool WifiClientHistoryDB::GetClientMacs(std::vector<std::pair<std::string,std::string>> &Macs) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
std::string St = "Select distinct(stationId) from " + TableName_;
typedef Poco::Tuple< std::string > Record;
std::string St = "Select distinct stationId, venue_id from " + TableName_;
typedef Poco::Tuple< std::string, std::string > Record;
std::vector<Record> RecordList;
Select << St,
@@ -89,7 +92,7 @@ namespace OpenWifi {
Select.execute();
for(const auto &i:RecordList)
Macs.push_back(i.get<0>());
Macs.push_back(std::pair(i.get<0>(),i.get<1>()));
return true;
} catch (const Poco::Exception &E) {
@@ -102,8 +105,8 @@ namespace OpenWifi {
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.station_id = In.get<1>();
Out.bssid= In.get<2>();
Out.ssid= In.get<3>();
Out.rssi= In.get<4>();
Out.rx_bitrate= In.get<5>();
@@ -137,12 +140,13 @@ template<> void ORM::DB<OpenWifi::WifiClientHistoryDBRecordType, OpenWifi::Analy
Out.connected= In.get<33>();
Out.inactive= In.get<34>();
Out.tx_retries= In.get<35>();
Out.venue_id= In.get<36>();
}
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<1>(In.station_id);
Out.set<2>(In.bssid);
Out.set<3>(In.ssid);
Out.set<4>(In.rssi);
Out.set<5>(In.rx_bitrate);
@@ -176,5 +180,5 @@ template<> void ORM::DB<OpenWifi::WifiClientHistoryDBRecordType, OpenWifi::Analy
Out.set<33>(In.connected);
Out.set<34>(In.inactive);
Out.set<35>(In.tx_retries);
Out.set<36>(In.venue_id);
}

View File

@@ -44,14 +44,15 @@ namespace OpenWifi {
int64_t, // ack_signal_avg=0;
int64_t, // connected=0;
int64_t, // inactive=0;
int64_t // tx_retries=0;
int64_t, // tx_retries=0;
std::string
> WifiClientHistoryDBRecordType;
class WifiClientHistoryDB : public ORM::DB<WifiClientHistoryDBRecordType, AnalyticsObjects::WifiClientHistory> {
public:
WifiClientHistoryDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
virtual ~WifiClientHistoryDB() {};
bool GetClientMacs(std::vector<std::string> &Macs);
bool GetClientMacs(std::vector<std::pair<std::string,std::string>> &Macs);
private:
bool Upgrade(uint32_t from, uint32_t &to) override;
};