diff --git a/src/common/lookups/AdjSiteMapLookup.h b/src/common/lookups/AdjSiteMapLookup.h index 6f690440..ee9db8bd 100644 --- a/src/common/lookups/AdjSiteMapLookup.h +++ b/src/common/lookups/AdjSiteMapLookup.h @@ -226,6 +226,12 @@ namespace lookups */ void setReloadTime(uint32_t reloadTime) { m_reloadTime = reloadTime; } + /** + * @brief Returns the last load time of this lookup table. + * @return const uint64_t Last load time in milliseconds since epoch. + */ + const uint64_t lastLoadTime() const { return m_lastLoadTime; } + private: std::string m_rulesFile; uint32_t m_reloadTime; diff --git a/src/common/lookups/LookupTable.h b/src/common/lookups/LookupTable.h index c610d978..e0bcfb22 100644 --- a/src/common/lookups/LookupTable.h +++ b/src/common/lookups/LookupTable.h @@ -186,6 +186,12 @@ namespace lookups */ void setReloadTime(uint32_t reloadTime) { m_reloadTime = reloadTime; } + /** + * @brief Returns the last load time of this lookup table. + * @return const uint64_t Last load time in milliseconds since epoch. + */ + const uint64_t lastLoadTime() const { return m_lastLoadTime; } + protected: std::string m_filename; uint32_t m_reloadTime; diff --git a/src/common/lookups/TalkgroupRulesLookup.h b/src/common/lookups/TalkgroupRulesLookup.h index fff6c874..04de671d 100644 --- a/src/common/lookups/TalkgroupRulesLookup.h +++ b/src/common/lookups/TalkgroupRulesLookup.h @@ -636,6 +636,12 @@ namespace lookups */ void setReloadTime(uint32_t reloadTime) { m_reloadTime = reloadTime; } + /** + * @brief Returns the last load time of this lookup table. + * @return const uint64_t Last load time in milliseconds since epoch. + */ + const uint64_t lastLoadTime() const { return m_lastLoadTime; } + private: std::string m_rulesFile; uint32_t m_reloadTime; diff --git a/src/fne/CryptoContainer.h b/src/fne/CryptoContainer.h index dab9d3ad..b2242efe 100644 --- a/src/fne/CryptoContainer.h +++ b/src/fne/CryptoContainer.h @@ -245,6 +245,12 @@ public: */ void setReloadTime(uint32_t reloadTime) { m_reloadTime = reloadTime; } + /** + * @brief Returns the last load time of this lookup table. + * @return const uint64_t Last load time in milliseconds since epoch. + */ + const uint64_t lastLoadTime() const { return m_lastLoadTime; } + private: std::string m_file; std::string m_password; diff --git a/src/fne/HostFNE.cpp b/src/fne/HostFNE.cpp index 0a8f1915..169bb56b 100644 --- a/src/fne/HostFNE.cpp +++ b/src/fne/HostFNE.cpp @@ -521,7 +521,7 @@ bool HostFNE::initializeRESTAPI() // initialize network remote command if (restApiEnable) { m_RESTAPI = new RESTAPI(restApiAddress, restApiPort, restApiPassword, restApiSSLKey, restApiSSLCert, restApiEnableSSL, this, restApiDebug); - m_RESTAPI->setLookups(m_ridLookup, m_tidLookup, m_peerListLookup, m_adjSiteMapLookup); + m_RESTAPI->setLookups(m_ridLookup, m_tidLookup, m_peerListLookup, m_adjSiteMapLookup, m_cryptoLookup); bool ret = m_RESTAPI->open(); if (!ret) { delete m_RESTAPI; diff --git a/src/fne/network/FNENetwork.cpp b/src/fne/network/FNENetwork.cpp index 664d5b2a..d94c1cff 100644 --- a/src/fne/network/FNENetwork.cpp +++ b/src/fne/network/FNENetwork.cpp @@ -143,6 +143,7 @@ FNENetwork::FNENetwork(HostFNE* host, const std::string& address, uint16_t port, m_verbosePacketData(false), m_sndcpStartAddr(__IP_FROM_STR("10.10.1.10")), m_sndcpEndAddr(__IP_FROM_STR("10.10.1.254")), + m_totalCallsProcessed(0U), m_logDenials(false), m_logUpstreamCallStartEnd(true), m_reportPeerPing(reportPeerPing), diff --git a/src/fne/network/FNENetwork.h b/src/fne/network/FNENetwork.h index 2377dd27..c3e9aac5 100644 --- a/src/fne/network/FNENetwork.h +++ b/src/fne/network/FNENetwork.h @@ -406,6 +406,8 @@ namespace network uint32_t m_sndcpStartAddr; uint32_t m_sndcpEndAddr; + uint64_t m_totalCallsProcessed; + bool m_logDenials; bool m_logUpstreamCallStartEnd; bool m_reportPeerPing; diff --git a/src/fne/network/callhandler/TagAnalogData.cpp b/src/fne/network/callhandler/TagAnalogData.cpp index 8933c2cd..88a82320 100644 --- a/src/fne/network/callhandler/TagAnalogData.cpp +++ b/src/fne/network/callhandler/TagAnalogData.cpp @@ -265,6 +265,8 @@ bool TagAnalogData::processFrame(const uint8_t* data, uint32_t len, uint32_t pee m_status[dstId].activeCall = true; m_status.unlock(); + m_network->m_totalCallsProcessed++; + #define CALL_START_LOG "Analog, Call Start, peer = %u, ssrc = %u, srcId = %u, dstId = %u, streamId = %u, fromUpstream = %u", peerId, ssrc, srcId, dstId, streamId, fromUpstream if (m_network->m_logUpstreamCallStartEnd && fromUpstream) LogInfoEx(LOG_PEER, CALL_START_LOG); diff --git a/src/fne/network/callhandler/TagDMRData.cpp b/src/fne/network/callhandler/TagDMRData.cpp index f32b87b2..b5d0162e 100644 --- a/src/fne/network/callhandler/TagDMRData.cpp +++ b/src/fne/network/callhandler/TagDMRData.cpp @@ -366,6 +366,8 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId m_status[dstId].activeCall = true; m_status.unlock(); + m_network->m_totalCallsProcessed++; + // is this a private call? if (flco == FLCO::PRIVATE) { m_statusPVCall.lock(false); diff --git a/src/fne/network/callhandler/TagNXDNData.cpp b/src/fne/network/callhandler/TagNXDNData.cpp index 48701672..f4498e83 100644 --- a/src/fne/network/callhandler/TagNXDNData.cpp +++ b/src/fne/network/callhandler/TagNXDNData.cpp @@ -402,6 +402,8 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI m_status[dstId].activeCall = true; m_status.unlock(); + m_network->m_totalCallsProcessed++; + // is this a private call? if (!group) { m_statusPVCall.lock(false); diff --git a/src/fne/network/callhandler/TagP25Data.cpp b/src/fne/network/callhandler/TagP25Data.cpp index af1f09ea..c41f8092 100644 --- a/src/fne/network/callhandler/TagP25Data.cpp +++ b/src/fne/network/callhandler/TagP25Data.cpp @@ -445,6 +445,8 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId m_status[dstId].activeCall = true; m_status.unlock(); + m_network->m_totalCallsProcessed++; + // is this a private call? if (lco == LCO::PRIVATE) { m_statusPVCall.lock(false); diff --git a/src/fne/restapi/RESTAPI.cpp b/src/fne/restapi/RESTAPI.cpp index 17d715e4..12d2edfb 100644 --- a/src/fne/restapi/RESTAPI.cpp +++ b/src/fne/restapi/RESTAPI.cpp @@ -506,6 +506,7 @@ RESTAPI::RESTAPI(const std::string& address, uint16_t port, const std::string& p m_tidLookup(nullptr), m_peerListLookup(nullptr), m_adjSiteMapLookup(nullptr), + m_cryptoLookup(nullptr), m_authTokens() { assert(!address.empty()); @@ -556,12 +557,14 @@ RESTAPI::~RESTAPI() /* Sets the instances of the Radio ID and Talkgroup ID lookup tables. */ void RESTAPI::setLookups(lookups::RadioIdLookup* ridLookup, lookups::TalkgroupRulesLookup* tidLookup, - ::lookups::PeerListLookup* peerListLookup, ::lookups::AdjSiteMapLookup* adjMapLookup) + ::lookups::PeerListLookup* peerListLookup, ::lookups::AdjSiteMapLookup* adjMapLookup, + CryptoContainer* cryptoLookup) { m_ridLookup = ridLookup; m_tidLookup = tidLookup; m_peerListLookup = peerListLookup; m_adjSiteMapLookup = adjMapLookup; + m_cryptoLookup = cryptoLookup; } /* Sets the instance of the FNE network. */ @@ -664,7 +667,10 @@ void RESTAPI::initializeEndpoints() m_dispatcher.match(FNE_GET_RELOAD_TGS).get(REST_API_BIND(RESTAPI::restAPI_GetReloadTGs, this)); m_dispatcher.match(FNE_GET_RELOAD_RIDS).get(REST_API_BIND(RESTAPI::restAPI_GetReloadRIDs, this)); + m_dispatcher.match(FNE_GET_RELOAD_PEERLIST).get(REST_API_BIND(RESTAPI::restAPI_GetReloadPeerList, this)); + m_dispatcher.match(FNE_GET_RELOAD_CRYPTO).get(REST_API_BIND(RESTAPI::restAPI_GetReloadCrypto, this)); + m_dispatcher.match(FNE_GET_STATS).get(REST_API_BIND(RESTAPI::restAPI_GetStats, this)); m_dispatcher.match(FNE_GET_AFF_LIST).get(REST_API_BIND(RESTAPI::restAPI_GetAffList, this)); m_dispatcher.match(FNE_GET_SPANNING_TREE).get(REST_API_BIND(RESTAPI::restAPI_GetSpanningTree, this)); @@ -1615,6 +1621,211 @@ void RESTAPI::restAPI_GetReloadRIDs(const HTTPPayload& request, HTTPPayload& rep reply.payload(response); } +/* REST API endpoint; implements get reload peer list request. */ + +void RESTAPI::restAPI_GetReloadPeerList(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match) +{ + if (!validateAuth(request, reply)) { + return; + } + + json::object response = json::object(); + setResponseDefaultStatus(response); + + if (m_network != nullptr) { + m_network->m_peerListLookup->reload(); + } + + reply.payload(response); +} + +/* REST API endpoint; implements get reload crypto container request. */ + +void RESTAPI::restAPI_GetReloadCrypto(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match) +{ + if (!validateAuth(request, reply)) { + return; + } + + json::object response = json::object(); + setResponseDefaultStatus(response); + + if (m_network != nullptr) { + m_network->m_cryptoLookup->reload(); + } + + reply.payload(response); +} + +/* REST API endpoint; implements get statistics request. */ + +void RESTAPI::restAPI_GetStats(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match) +{ + if (!validateAuth(request, reply)) { + return; + } + + json::object response = json::object(); + setResponseDefaultStatus(response); + + if (m_network != nullptr) { + // peer statistics (right now this is just a list of connected peers) + json::array peerStats = json::array(); + if (m_network->m_peers.size() > 0) { + for (auto entry : m_network->m_peers) { + uint32_t peerId = entry.first; + network::FNEPeerConnection* peer = entry.second; + if (peer != nullptr) { + json::object peerObj = json::object(); + peerObj["peerId"].set(peerId); + uint32_t masterId = peer->masterId(); + peerObj["masterId"].set(masterId); + + peerObj["address"].set(peer->address()); + uint16_t port = peer->port(); + peerObj["port"].set(port); + + // format last ping into human readable form + { + std::chrono::milliseconds lastPing(peer->lastPing()); + std::chrono::system_clock::time_point tp = std::chrono::system_clock::time_point() + lastPing; + std::time_t lastPingTime = std::chrono::system_clock::to_time_t(tp); + + char timeBuf[26]; + ::memset(timeBuf, 0x00U, 26); + ::ctime_r(&lastPingTime, timeBuf); + + // remove newline character from ctime_r output + std::string timeStr = std::string(timeBuf); + timeStr.erase(std::remove(timeStr.begin(), timeStr.end(), '\n'), timeStr.end()); + peerObj["lastPing"].set(timeStr); + } + + uint32_t pingsReceived = peer->pingsReceived(); + peerObj["pingsReceived"].set(pingsReceived); + uint32_t missedMetadataUpdates = peer->missedMetadataUpdates(); + peerObj["missedMetadataUpdates"].set(missedMetadataUpdates); + + bool isNeighbor = peer->isNeighborFNEPeer(); + bool isReplica = peer->isReplica(); + peerObj["isNeighbor"].set(isNeighbor); + peerObj["isReplica"].set(isReplica); + + peerStats.push_back(json::value(peerObj)); + } + } + } + response["peerStats"].set(peerStats); + + // table load statistics + json::object tableLastLoad = json::object(); + + // RID table load time + { + // format last load time into human readable form + std::chrono::milliseconds lastLoad(m_network->m_ridLookup->lastLoadTime()); + std::chrono::system_clock::time_point tp = std::chrono::system_clock::time_point() + lastLoad; + std::time_t lastLoadTime = std::chrono::system_clock::to_time_t(tp); + + char timeBuf[26]; + ::memset(timeBuf, 0x00U, 26); + ::ctime_r(&lastLoadTime, timeBuf); + + // remove newline character from ctime_r output + std::string timeStr = std::string(timeBuf); + timeStr.erase(std::remove(timeStr.begin(), timeStr.end(), '\n'), timeStr.end()); + tableLastLoad["ridLastLoadTime"].set(timeStr); + } + + // talkgroup table load time + { + // format last load time into human readable form + std::chrono::milliseconds lastLoad(m_network->m_tidLookup->lastLoadTime()); + std::chrono::system_clock::time_point tp = std::chrono::system_clock::time_point() + lastLoad; + std::time_t lastLoadTime = std::chrono::system_clock::to_time_t(tp); + + char timeBuf[26]; + ::memset(timeBuf, 0x00U, 26); + ::ctime_r(&lastLoadTime, timeBuf); + + // remove newline character from ctime_r output + std::string timeStr = std::string(timeBuf); + timeStr.erase(std::remove(timeStr.begin(), timeStr.end(), '\n'), timeStr.end()); + tableLastLoad["tgLastLoadTime"].set(timeStr); + } + + // peer list table load time + { + // format last load time into human readable form + std::chrono::milliseconds lastLoad(m_peerListLookup->lastLoadTime()); + std::chrono::system_clock::time_point tp = std::chrono::system_clock::time_point() + lastLoad; + std::time_t lastLoadTime = std::chrono::system_clock::to_time_t(tp); + + char timeBuf[26]; + ::memset(timeBuf, 0x00U, 26); + ::ctime_r(&lastLoadTime, timeBuf); + + // remove newline character from ctime_r output + std::string timeStr = std::string(timeBuf); + timeStr.erase(std::remove(timeStr.begin(), timeStr.end(), '\n'), timeStr.end()); + tableLastLoad["peerListLastLoadTime"].set(timeStr); + } + + // adjacent site map table load time + { + // format last load time into human readable form + std::chrono::milliseconds lastLoad(m_adjSiteMapLookup->lastLoadTime()); + std::chrono::system_clock::time_point tp = std::chrono::system_clock::time_point() + lastLoad; + std::time_t lastLoadTime = std::chrono::system_clock::to_time_t(tp); + + char timeBuf[26]; + ::memset(timeBuf, 0x00U, 26); + ::ctime_r(&lastLoadTime, timeBuf); + + // remove newline character from ctime_r output + std::string timeStr = std::string(timeBuf); + timeStr.erase(std::remove(timeStr.begin(), timeStr.end(), '\n'), timeStr.end()); + tableLastLoad["adjSiteMapLastLoadTime"].set(timeStr); + } + + // crypto key table load time + { + // format last load time into human readable form + std::chrono::milliseconds lastLoad(m_cryptoLookup->lastLoadTime()); + std::chrono::system_clock::time_point tp = std::chrono::system_clock::time_point() + lastLoad; + std::time_t lastLoadTime = std::chrono::system_clock::to_time_t(tp); + + char timeBuf[26]; + ::memset(timeBuf, 0x00U, 26); + ::ctime_r(&lastLoadTime, timeBuf); + + // remove newline character from ctime_r output + std::string timeStr = std::string(timeBuf); + timeStr.erase(std::remove(timeStr.begin(), timeStr.end(), '\n'), timeStr.end()); + tableLastLoad["cryptoKeyLastLoadTime"].set(timeStr); + } + response["tableLastLoad"].set(tableLastLoad); + + // total calls processed + uint32_t totalCallsProcessed = m_network->m_totalCallsProcessed; + response["totalCallsProcessed"].set(totalCallsProcessed); + + // table totals + uint32_t ridTotalEntries = m_network->m_ridLookup->table().size(); + response["ridTotalEntries"].set(ridTotalEntries); + uint32_t tgTotalEntries = m_network->m_tidLookup->groupVoice().size(); + response["tgTotalEntries"].set(tgTotalEntries); + uint32_t peerListTotalEntries = m_peerListLookup->table().size(); + response["peerListTotalEntries"].set(peerListTotalEntries); + uint32_t adjSiteMapTotalEntries = m_adjSiteMapLookup->adjPeerMap().size(); + response["adjSiteMapTotalEntries"].set(adjSiteMapTotalEntries); + uint32_t cryptoKeyTotalEntries = m_cryptoLookup->keys().size(); + response["cryptoKeyTotalEntries"].set(cryptoKeyTotalEntries); + } + + reply.payload(response); +} + /* REST API endpoint; implements get affiliation list request. */ void RESTAPI::restAPI_GetAffList(const HTTPPayload& request, HTTPPayload& reply, const RequestMatch& match) diff --git a/src/fne/restapi/RESTAPI.h b/src/fne/restapi/RESTAPI.h index 66684a71..9d373ea4 100644 --- a/src/fne/restapi/RESTAPI.h +++ b/src/fne/restapi/RESTAPI.h @@ -23,7 +23,9 @@ #include "common/lookups/AdjSiteMapLookup.h" #include "common/lookups/RadioIdLookup.h" #include "common/lookups/TalkgroupRulesLookup.h" +#include "common/lookups/PeerListLookup.h" #include "common/Thread.h" +#include "fne/CryptoContainer.h" #include "fne/restapi/RESTDefines.h" #include @@ -71,9 +73,11 @@ public: * @param tidLookup Talkgroup Rules Lookup Table Instance * @param peerListLookup Peer List Lookup Table Instance * @param adjPeerMapLookup Adjacent Site Map Lookup Table Instance + * @param cryptoLookup Crypto Container Instance */ void setLookups(::lookups::RadioIdLookup* ridLookup, ::lookups::TalkgroupRulesLookup* tidLookup, - ::lookups::PeerListLookup* peerListLookup, ::lookups::AdjSiteMapLookup* adjPeerMapLookup); + ::lookups::PeerListLookup* peerListLookup, ::lookups::AdjSiteMapLookup* adjPeerMapLookup, + CryptoContainer* cryptoLookup); /** * @brief Sets the instance of the FNE network. * @param network Instance oft he FNENetwork class. @@ -114,6 +118,7 @@ private: ::lookups::TalkgroupRulesLookup* m_tidLookup; ::lookups::PeerListLookup* m_peerListLookup; ::lookups::AdjSiteMapLookup* m_adjSiteMapLookup; + CryptoContainer* m_cryptoLookup; typedef std::unordered_map::value_type AuthTokenValueType; std::unordered_map m_authTokens; @@ -333,6 +338,30 @@ private: */ void restAPI_GetReloadRIDs(const HTTPPayload& request, HTTPPayload& reply, const restapi::RequestMatch& match); + /** + * @brief REST API endpoint; implements get reload peer list request. + * @param request HTTP request. + * @param reply HTTP reply. + * @param match HTTP request matcher. + */ + void restAPI_GetReloadPeerList(const HTTPPayload& request, HTTPPayload& reply, const restapi::RequestMatch& match); + + /** + * @brief REST API endpoint; implements get reload crypto container request. + * @param request HTTP request. + * @param reply HTTP reply. + * @param match HTTP request matcher. + */ + void restAPI_GetReloadCrypto(const HTTPPayload& request, HTTPPayload& reply, const restapi::RequestMatch& match); + + /** + * @brief REST API endpoint; implements get statistics request. + * @param request HTTP request. + * @param reply HTTP reply. + * @param match HTTP request matcher. + */ + void restAPI_GetStats(const HTTPPayload& request, HTTPPayload& reply, const restapi::RequestMatch& match); + /** * @brief REST API endpoint; implements get affiliation list request. * @param request HTTP request. diff --git a/src/fne/restapi/RESTDefines.h b/src/fne/restapi/RESTDefines.h index 52a8d149..b7e4db15 100644 --- a/src/fne/restapi/RESTDefines.h +++ b/src/fne/restapi/RESTDefines.h @@ -54,7 +54,10 @@ #define FNE_GET_RELOAD_TGS "/reload-tgs" #define FNE_GET_RELOAD_RIDS "/reload-rids" +#define FNE_GET_RELOAD_PEERLIST "/reload-peers" +#define FNE_GET_RELOAD_CRYPTO "/reload-crypto" +#define FNE_GET_STATS "/stats" #define FNE_GET_AFF_LIST "/report-affiliations" #define FNE_GET_SPANNING_TREE "/spanning-tree" diff --git a/src/remote/RESTClientMain.cpp b/src/remote/RESTClientMain.cpp index 01c49e79..dc07ea63 100644 --- a/src/remote/RESTClientMain.cpp +++ b/src/remote/RESTClientMain.cpp @@ -44,6 +44,8 @@ #define RCD_FNE_GET_AFFLIST "fne-affs" #define RCD_FNE_GET_RELOADTGS "fne-reload-tgs" #define RCD_FNE_GET_RELOADRIDS "fne-reload-rids" +#define RCD_FNE_GET_RELOADPEERLIST "fne-reload-peerlist" +#define RCD_FNE_GET_RELOADCRYPTO "fne-reload-crypto" #define RCD_FNE_PUT_RESETPEER "fne-reset-peer" #define RCD_FNE_PUT_PEER_ACL_ADD "fne-peer-acl-add" @@ -54,6 +56,8 @@ #define RCD_FNE_SAVE_TGID_ACL "fne-tgid-commit" #define RCD_FNE_SAVE_PEER_ACL "fne-peer-commit" +#define RCD_FNE_GET_STATS "fne-stats" + #define RCD_FNE_GET_SPANNINGTREE "fne-spanning-tree" #define RCD_MODE "mdm-mode" @@ -214,6 +218,8 @@ void usage(const char* message, const char* arg) reply += " fne-affs Retrieves the list of currently affiliated SUs (Converged FNE only)\r\n"; reply += " fne-reload-tgs Forces the FNE to reload its TGID list from disk (Converged FNE only)\r\n"; reply += " fne-reload-rids Forces the FNE to reload its RID list from disk (Converged FNE only)\r\n"; + reply += " fne-reload-peerlist Forces the FNE to reload its peer list from disk (Converged FNE only)\r\n"; + reply += " fne-reload-crypto Forces the FNE to reload its crypto containers from disk (Converged FNE only)\r\n"; reply += "\r\n"; reply += " fne-reset-peer Forces the FNE to reset the connection of the given peer ID (Converged FNE only)\r\n"; reply += " fne-peer-acl-add Adds the specified peer ID to the FNE ACL tables (Converged FNE only)\r\n"; @@ -224,6 +230,8 @@ void usage(const char* message, const char* arg) reply += " fne-tgid-commit Saves the current TGID ACL to permenant storage (Converged FNE only)\r\n"; reply += " fne-peer-commit Saves the current peer ACL to permenant storage (Converged FNE only)\r\n"; reply += "\r\n"; + reply += " fne-stats Retrieves current FNE statistics (Converged FNE only)\r\n"; + reply += "\r\n"; reply += " fne-spanning-tree Retrieves the current FNE spanning tree (Converged FNE only)\r\n"; reply += "\r\n"; reply += " mdm-mode Set current mode of host (idle, lockout, dmr, p25, nxdn)\r\n"; @@ -892,6 +900,12 @@ int main(int argc, char** argv) else if (rcom == RCD_FNE_GET_RELOADRIDS) { retCode = client->send(HTTP_GET, FNE_GET_RELOAD_RIDS, json::object(), response); } + else if (rcom == RCD_FNE_GET_RELOADPEERLIST) { + retCode = client->send(HTTP_GET, FNE_GET_RELOAD_PEERLIST, json::object(), response); + } + else if (rcom == RCD_FNE_GET_RELOADCRYPTO) { + retCode = client->send(HTTP_GET, FNE_GET_RELOAD_CRYPTO, json::object(), response); + } else if (rcom == RCD_FNE_PUT_RESETPEER && argCnt >= 1U) { uint32_t peerId = getArgUInt32(args, 0U); json::object req = json::object(); @@ -929,6 +943,9 @@ int main(int argc, char** argv) else if (rcom == RCD_FNE_SAVE_PEER_ACL) { retCode = client->send(HTTP_GET, FNE_GET_PEER_COMMIT, json::object(), response); } + else if (rcom == RCD_FNE_GET_STATS) { + retCode = client->send(HTTP_GET, FNE_GET_STATS, json::object(), response); + } else if (rcom == RCD_FNE_GET_SPANNINGTREE) { retCode = client->send(HTTP_GET, FNE_GET_SPANNING_TREE, json::object(), response); }