mirror of
https://github.com/Telecominfraproject/wlan-cloud-analytics.git
synced 2025-11-26 19:25:09 +00:00
Adding WifiClientHistory.
This commit is contained in:
@@ -84,6 +84,7 @@ add_executable(owanalytics
|
||||
src/Daemon.cpp src/Daemon.h
|
||||
src/Dashboard.h src/Dashboard.cpp
|
||||
src/StorageService.cpp src/StorageService.h
|
||||
src/WifiClientCache.cpp src/WifiClientCache.h
|
||||
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h
|
||||
src/StateReceiver.cpp src/StateReceiver.h
|
||||
src/VenueWatcher.cpp src/VenueWatcher.h
|
||||
@@ -100,7 +101,9 @@ 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_wificlients.cpp src/storage/storage_wificlients.h src/RESTAPI/RESTAPI_wificlienthistory_handler.cpp src/RESTAPI/RESTAPI_wificlienthistory_handler.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}
|
||||
|
||||
@@ -661,6 +661,14 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/WifiClientHistory'
|
||||
|
||||
MacList:
|
||||
type: object
|
||||
properties:
|
||||
entries:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
## These are endpoints that all services in the OPenWiFI stack must provide
|
||||
@@ -1196,9 +1204,30 @@ paths:
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: Maximum number of entries to return (if absent, no limit is assumed)
|
||||
name: macsOnly
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
description: Maximum number of entries to return (if absent, no limit is assumed)
|
||||
name: macFilter
|
||||
schema:
|
||||
type: string
|
||||
example:
|
||||
112233445566, 11223344*, *5566
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/WifiClientHistoryList'
|
||||
description: Successfully returning list of records
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/WifiClientHistoryList'
|
||||
- $ref: '#/components/schemas/StringList'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "APStats.h"
|
||||
#include "dict_ssid.h"
|
||||
#include "StorageService.h"
|
||||
#include "WifiClientCache.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -259,6 +260,7 @@ namespace OpenWifi {
|
||||
GetJSON("inactive",association,WFH.inactive,(uint64_t)0);
|
||||
GetJSON("tx_retries",association,WFH.tx_retries,(uint64_t)0);
|
||||
|
||||
WifiClientCache()->AddSerialNumber(WFH.stationId);
|
||||
StorageService()->WifiClientHistoryDB().CreateRecord(WFH);
|
||||
|
||||
if(association.contains("tid_stats") && association["tid_stats"].is_array()) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "StateReceiver.h"
|
||||
#include "DeviceStatusReceiver.h"
|
||||
#include "HealthReceiver.h"
|
||||
#include "WifiClientCache.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance_ = nullptr;
|
||||
@@ -32,7 +33,8 @@ namespace OpenWifi {
|
||||
StateReceiver(),
|
||||
DeviceStatusReceiver(),
|
||||
HealthReceiver(),
|
||||
VenueCoordinator()
|
||||
VenueCoordinator(),
|
||||
WifiClientCache()
|
||||
});
|
||||
}
|
||||
return instance_;
|
||||
|
||||
@@ -3,12 +3,24 @@
|
||||
//
|
||||
|
||||
#include "RESTAPI_wificlienthistory_handler.h"
|
||||
#include "RESTAPI/RESTAPI_analytics_db_helpers.h"
|
||||
#include "WifiClientCache.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_wificlienthistory_handler::DoGet() {
|
||||
|
||||
if(GetBoolParameter("macsOnly")) {
|
||||
auto macFilter = GetParameter("macFilter","");
|
||||
std::vector<uint64_t> Macs;
|
||||
WifiClientCache()->FindNumbers(macFilter,500,Macs);
|
||||
Poco::JSON::Array Arr;
|
||||
for(const auto &mac: Macs)
|
||||
Arr.add(Utils::IntToSerialNumber(mac));
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set("entries", Arr);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
auto stationId = GetBinding("client");
|
||||
if(!Utils::ValidSerialNumber(stationId)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
|
||||
|
||||
132
src/WifiClientCache.cpp
Normal file
132
src/WifiClientCache.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-11.
|
||||
//
|
||||
|
||||
#include "WifiClientCache.h"
|
||||
#include <mutex>
|
||||
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
int WifiClientCache::Start() {
|
||||
TimerCallback_ = std::make_unique<Poco::TimerCallback<WifiClientCache>>(*this,&WifiClientCache::onTimer);
|
||||
Timer_.setStartInterval( 30 * 1000); // first run in 20 seconds
|
||||
Timer_.setPeriodicInterval( 60 * 60 * 1000); // 1 hours
|
||||
Timer_.start(*TimerCallback_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WifiClientCache::Stop() {
|
||||
Timer_.stop();
|
||||
}
|
||||
|
||||
void WifiClientCache::onTimer([[maybe_unused]] Poco::Timer & timer) {
|
||||
std::vector<std::string> WifiClients;
|
||||
if(StorageService()->WifiClientHistoryDB().GetClientMacs(WifiClients)) {
|
||||
// Let's replace current cache...
|
||||
std::lock_guard G(Mutex_);
|
||||
SNs_.clear();
|
||||
Reverse_SNs_.clear();
|
||||
for(const auto &mac:WifiClients)
|
||||
AddSerialNumber(mac,G);
|
||||
}
|
||||
}
|
||||
|
||||
void WifiClientCache::AddSerialNumber(const std::string &S) {
|
||||
std::lock_guard G(Mutex_);
|
||||
AddSerialNumber(S,G);
|
||||
}
|
||||
|
||||
void WifiClientCache::AddSerialNumber(const std::string &S, [[maybe_unused]] std::lock_guard<std::recursive_mutex> & G) {
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void WifiClientCache::DeleteSerialNumber(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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Reverse(uint64_t N) {
|
||||
uint64_t Res = 0;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
Res = (Res << 4) + (N & 0x000000000000000f);
|
||||
N >>= 4;
|
||||
}
|
||||
Res >>= 16;
|
||||
return Res;
|
||||
}
|
||||
|
||||
void WifiClientCache::ReturnNumbers(const std::string &S, uint HowMany, const std::vector<uint64_t> &SNArr, std::vector<uint64_t> &A, bool ReverseResult) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
if (S.length() == 12) {
|
||||
uint64_t SN = std::stoull(S, nullptr, 16);
|
||||
auto It = std::find(SNArr.begin(), SNArr.end(), SN);
|
||||
if (It != SNArr.end()) {
|
||||
A.push_back(ReverseResult ? Reverse(*It) : *It);
|
||||
}
|
||||
} else if (S.length() < 12) {
|
||||
std::string SS{S};
|
||||
SS.insert(SS.end(), 12 - SS.size(), '0');
|
||||
uint64_t SN = std::stoull(SS, nullptr, 16);
|
||||
auto LB = std::lower_bound(SNArr.begin(), SNArr.end(), SN);
|
||||
if (LB != SNArr.end()) {
|
||||
for (; LB != SNArr.end() && HowMany; ++LB, --HowMany) {
|
||||
if(ReverseResult) {
|
||||
const auto TSN = ReverseSerialNumber(Utils::IntToSerialNumber(Reverse(*LB)));
|
||||
if (S == TSN.substr(0,S.size())) {
|
||||
A.emplace_back(Reverse(*LB));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
const auto TSN = Utils::IntToSerialNumber(*LB);
|
||||
if (S == TSN.substr(0, S.size())) {
|
||||
A.emplace_back(*LB);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WifiClientCache::FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A) {
|
||||
if(S.empty())
|
||||
return;
|
||||
|
||||
if (S[0] == '*') {
|
||||
std::string Reversed;
|
||||
std::copy(rbegin(S), rend(S)-1, std::back_inserter(Reversed));
|
||||
if(Reversed.empty())
|
||||
return;
|
||||
return ReturnNumbers(Reversed, HowMany, Reverse_SNs_, A, true);
|
||||
} else {
|
||||
return ReturnNumbers(S, HowMany, SNs_, A, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
55
src/WifiClientCache.h
Normal file
55
src/WifiClientCache.h
Normal file
@@ -0,0 +1,55 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-11.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class WifiClientCache : public SubSystemServer {
|
||||
public:
|
||||
|
||||
static auto instance() {
|
||||
static auto instance_ = new WifiClientCache;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
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) {
|
||||
std::lock_guard G(Mutex_);
|
||||
return std::find(SNs_.begin(),SNs_.end(),SerialNumber)!=SNs_.end();
|
||||
}
|
||||
|
||||
static inline std::string ReverseSerialNumber(const std::string &S) {
|
||||
std::string ReversedString;
|
||||
std::copy(rbegin(S),rend(S),std::back_inserter(ReversedString));
|
||||
return ReversedString;
|
||||
}
|
||||
void onTimer(Poco::Timer & timer);
|
||||
|
||||
private:
|
||||
std::vector<uint64_t> SNs_;
|
||||
std::vector<uint64_t> Reverse_SNs_;
|
||||
Poco::Timer Timer_;
|
||||
std::unique_ptr<Poco::TimerCallback<WifiClientCache>> TimerCallback_;
|
||||
|
||||
void AddSerialNumber(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);
|
||||
}
|
||||
};
|
||||
|
||||
inline auto WifiClientCache() { return WifiClientCache::instance(); }
|
||||
|
||||
} // namespace OpenWiFi
|
||||
@@ -74,6 +74,30 @@ namespace OpenWifi {
|
||||
to = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WifiClientHistoryDB::GetClientMacs(std::vector<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::vector<Record> RecordList;
|
||||
|
||||
Select << St,
|
||||
Poco::Data::Keywords::into(RecordList);
|
||||
Select.execute();
|
||||
|
||||
for(const auto &i:RecordList)
|
||||
Macs.push_back(i.get<0>());
|
||||
return true;
|
||||
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<> void ORM::DB<OpenWifi::WifiClientHistoryDBRecordType, OpenWifi::AnalyticsObjects::WifiClientHistory>::Convert(const OpenWifi::WifiClientHistoryDBRecordType &In, OpenWifi::AnalyticsObjects::WifiClientHistory &Out) {
|
||||
|
||||
@@ -51,6 +51,7 @@ namespace OpenWifi {
|
||||
public:
|
||||
WifiClientHistoryDB( OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
|
||||
virtual ~WifiClientHistoryDB() {};
|
||||
bool GetClientMacs(std::vector<std::string> &Macs);
|
||||
private:
|
||||
bool Upgrade(uint32_t from, uint32_t &to) override;
|
||||
};
|
||||
|
||||
@@ -85,6 +85,7 @@ findbrowser() {
|
||||
setprov() {
|
||||
if [ -z ${OWPROV_OVERRIDE+x} ]; then
|
||||
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/systemEndpoints" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
rawurl="$(cat ${result_file} | jq -r '.endpoints[] | select( .type == "owprov" ) | .uri')"
|
||||
@@ -111,7 +112,8 @@ fi
|
||||
setanalytics() {
|
||||
if [ -z ${OWANALYTICS_OVERRIDE+x} ]; then
|
||||
curl ${FLAGS} -X GET "https://${OWSEC}/api/v1/systemEndpoints" \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
rawurl="$(cat ${result_file} | jq -r '.endpoints[] | select( .type == "owanalytics" ) | .uri')"
|
||||
if [[ ! -z "${rawurl}" ]]; then
|
||||
@@ -136,9 +138,9 @@ setanalytics() {
|
||||
|
||||
|
||||
logout() {
|
||||
curl ${FLAGS} -X DELETE -H "Content-Type: application/json" \
|
||||
curl ${FLAGS} -X DELETE "https://${OWSEC}/api/v1/oauth2/${token}" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
"https://${OWSEC}/api/v1/oauth2/${token}"
|
||||
-H "Content-Type: application/json"
|
||||
rm -rf token.json
|
||||
}
|
||||
|
||||
@@ -154,14 +156,15 @@ contactcount() {
|
||||
curl ${FLAGS} "https://${OWPROV}/api/v1/contact?countOnly=true" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-H "accept: application/json" > ${result_file}
|
||||
-H "Accept: application/json" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
setloglevel() {
|
||||
payload="{ \"command\" : \"setloglevel\" , \"subsystems\" : [ { \"tag\" : \"$1\" , \"value\" : \"$2\" } ] }"
|
||||
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-d "$payload"
|
||||
}
|
||||
@@ -169,7 +172,8 @@ setloglevel() {
|
||||
getloglevels() {
|
||||
payload="{ \"command\" : \"getloglevels\" }"
|
||||
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-d "$payload"
|
||||
}
|
||||
@@ -177,7 +181,8 @@ getloglevels() {
|
||||
getloglevelnames() {
|
||||
payload="{ \"command\" : \"getloglevelnames\" }"
|
||||
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-d "$payload"
|
||||
}
|
||||
@@ -185,14 +190,15 @@ getloglevelnames() {
|
||||
getsubsystemnames() {
|
||||
payload="{ \"command\" : \"getsubsystemnames\" }"
|
||||
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-d "$payload"
|
||||
}
|
||||
|
||||
systeminfo() {
|
||||
curl ${FLAGS} -X GET "https://${OWPROV}/api/v1/system?command=info" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
@@ -200,70 +206,86 @@ systeminfo() {
|
||||
reloadsubsystem() {
|
||||
payload="{ \"command\" : \"reload\", \"subsystems\" : [ \"$1\" ] }"
|
||||
curl ${FLAGS} -X POST "https://${OWPROV}/api/v1/system" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-d "$payload"
|
||||
}
|
||||
|
||||
tree() {
|
||||
curl ${FLAGS} "https://${OWPROV}/api/v1/entity?getTree=true" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-H "accept: application/json" > ${result_file}
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
createboard() {
|
||||
payload="{ \"name\" : \"MegaLab\", \"venueList\" : [ { \"id\" : \"$1\" , \"name\" : \"MegaLab Venue\" , \"retention\" : 86000 , \"interval\" : 60, \"monitorSubVenues\" : true } ] }"
|
||||
curl ${FLAGS} -X POST "https://${OWANALYTICS}/api/v1/board/0" \
|
||||
-H "accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" \
|
||||
-d "$payload" > ${result_file}
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
deleteboard() {
|
||||
curl ${FLAGS} -X DELETE "https://${OWANALYTICS}/api/v1/board/$1" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
listboards() {
|
||||
curl ${FLAGS} -X GET "https://${OWANALYTICS}/api/v1/boards" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
boardsforvenue() {
|
||||
curl ${FLAGS} -X GET "https://${OWANALYTICS}/api/v1/boards?forVenue=$1" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
boarddevices() {
|
||||
curl ${FLAGS} -X GET "https://${OWANALYTICS}/api/v1/board/$1/devices" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
points() {
|
||||
curl ${FLAGS} -X GET "https://${OWANALYTICS}/api/v1/board/$1/timepoints?pointsStatsOnly=true" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
pointstats() {
|
||||
curl ${FLAGS} -X GET "https://${OWANALYTICS}/api/v1/board/$1/timepoints?stats=true" \
|
||||
-H "accept: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
wificlientsonly() {
|
||||
curl ${FLAGS} -X GET "https://${OWANALYTICS}/api/v1/wifiClientHistory?macsOnly=true&macFilter=$1" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
|
||||
shopt -s nocasematch
|
||||
case "$1" in
|
||||
"login") login; echo "You are logged in..." ; logout ;;
|
||||
@@ -281,6 +303,7 @@ case "$1" in
|
||||
"boardsforvenue") login; boardsforvenue $2; logout;;
|
||||
"points") login; points $2; logout;;
|
||||
"pointstats") login; pointstats $2; logout;;
|
||||
"wificlientsonly") login; wificlientsonly $2; logout;;
|
||||
*) help ;;
|
||||
esac
|
||||
|
||||
|
||||
Reference in New Issue
Block a user