diff --git a/openapi/owanalytics.yaml b/openapi/owanalytics.yaml index baca50b..6d135a6 100644 --- a/openapi/owanalytics.yaml +++ b/openapi/owanalytics.yaml @@ -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' diff --git a/src/APStats.cpp b/src/APStats.cpp index 770899d..daf0281 100644 --- a/src/APStats.cpp +++ b/src/APStats.cpp @@ -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; diff --git a/src/APStats.h b/src/APStats.h index 95a8aca..1476aac 100644 --- a/src/APStats.h +++ b/src/APStats.h @@ -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_; diff --git a/src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp b/src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp index b21a83f..c012501 100644 --- a/src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp +++ b/src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp @@ -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 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)); diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp index aebe317..e7738ba 100644 --- a/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp +++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp @@ -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(...) { diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.h b/src/RESTObjects/RESTAPI_AnalyticsObjects.h index 6573aca..c1328f4 100644 --- a/src/RESTObjects/RESTAPI_AnalyticsObjects.h +++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.h @@ -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); diff --git a/src/VenueCoordinator.cpp b/src/VenueCoordinator.cpp index d11b8fe..de2c28d 100644 --- a/src/VenueCoordinator.cpp +++ b/src/VenueCoordinator.cpp @@ -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(B.info.id, Logger(), Devices); + Watchers_[B.info.id] = std::make_shared(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; diff --git a/src/VenueWatcher.cpp b/src/VenueWatcher.cpp index 409495b..007d262 100644 --- a/src/VenueWatcher.cpp +++ b/src/VenueWatcher.cpp @@ -11,7 +11,7 @@ namespace OpenWifi { void VenueWatcher::Start() { for(const auto &mac:SerialNumbers_) { - auto ap = std::make_shared(mac, boardId_, Logger()); + auto ap = std::make_shared(mac, venue_id_, boardId_, Logger()); APs_[mac ] = ap; } diff --git a/src/VenueWatcher.h b/src/VenueWatcher.h index a742bd2..af47e23 100644 --- a/src/VenueWatcher.h +++ b/src/VenueWatcher.h @@ -35,8 +35,9 @@ namespace OpenWifi { class VenueWatcher : public Poco::Runnable { public: - explicit VenueWatcher(const std::string &boardId, Poco::Logger &L, const std::vector & SerialNumbers) : + explicit VenueWatcher(const std::string &boardId, const std::string &venue_id,Poco::Logger &L, const std::vector & 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_; diff --git a/src/WifiClientCache.cpp b/src/WifiClientCache.cpp index 09f8389..77232a6 100644 --- a/src/WifiClientCache.cpp +++ b/src/WifiClientCache.cpp @@ -22,48 +22,58 @@ namespace OpenWifi { } void WifiClientCache::onTimer([[maybe_unused]] Poco::Timer & timer) { - std::vector WifiClients; + std::vector> 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 & G) { + void WifiClientCache::AddSerialNumber(const std::string &venue_id, const std::string &S, [[maybe_unused]] std::lock_guard & 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 &A) { + void WifiClientCache::FindNumbers(const std::string &venue_id, const std::string &S, uint HowMany, std::vector &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); } } } \ No newline at end of file diff --git a/src/WifiClientCache.h b/src/WifiClientCache.h index f6470c8..fbeb6d7 100644 --- a/src/WifiClientCache.h +++ b/src/WifiClientCache.h @@ -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 &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 &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 SNs_; - std::vector Reverse_SNs_; + struct Cache { + std::vector SNs_; + std::vector Reverse_SNs_; + }; + std::map Cache_; Poco::Timer Timer_; std::unique_ptr> TimerCallback_; - void AddSerialNumber(const std::string &S, std::lock_guard & G); + void AddSerialNumber(const std::string &venueId, const std::string &S, std::lock_guard & G); void ReturnNumbers(const std::string &S, uint HowMany, const std::vector & SNArr, std::vector &A, bool ReverseResult); WifiClientCache() noexcept: SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache") { - SNs_.reserve(2000); } }; diff --git a/src/storage/storage_wificlients.cpp b/src/storage/storage_wificlients.cpp index daf6fbd..adb4f35 100644 --- a/src/storage/storage_wificlients.cpp +++ b/src/storage/storage_wificlients.cpp @@ -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 &Macs) { + bool WifiClientHistoryDB::GetClientMacs(std::vector> &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 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::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(); Out.inactive= In.get<34>(); Out.tx_retries= In.get<35>(); + Out.venue_id= In.get<36>(); } template<> void ORM::DB::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(In.connected); Out.set<34>(In.inactive); Out.set<35>(In.tx_retries); - + Out.set<36>(In.venue_id); } diff --git a/src/storage/storage_wificlients.h b/src/storage/storage_wificlients.h index 54bc7ea..6005480 100644 --- a/src/storage/storage_wificlients.h +++ b/src/storage/storage_wificlients.h @@ -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 { public: WifiClientHistoryDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); virtual ~WifiClientHistoryDB() {}; - bool GetClientMacs(std::vector &Macs); + bool GetClientMacs(std::vector> &Macs); private: bool Upgrade(uint32_t from, uint32_t &to) override; };