diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/CMakeLists.txt b/src/v2i-hub/RSUHealthMonitorPlugin/CMakeLists.txt new file mode 100755 index 000000000..7146a51a6 --- /dev/null +++ b/src/v2i-hub/RSUHealthMonitorPlugin/CMakeLists.txt @@ -0,0 +1,13 @@ +PROJECT(RSUHealthMonitorPlugin VERSION 7.5.1 LANGUAGES CXX) + +set(TMX_PLUGIN_NAME "RSU Health Monitor") + +find_library(NETSNMPAGENT "netsnmpagent") +find_library(NETSNMPMIBS "netsnmpmibs") +find_library(NETSNMP "netsnmp") +find_library(libasn1c .) + +BuildTmxPlugin() + +TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${NETSNMP_INCLUDE_DIRS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} PUBLIC tmxutils ${NETSNMPAGENT} ${NETSNMPMIBS} ${NETSNMP} ${NETSNMP_LIBRARIES}) \ No newline at end of file diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/manifest.json b/src/v2i-hub/RSUHealthMonitorPlugin/manifest.json new file mode 100755 index 000000000..da6d33044 --- /dev/null +++ b/src/v2i-hub/RSUHealthMonitorPlugin/manifest.json @@ -0,0 +1,46 @@ +{ + "name": "RSUHealthMonitor", + "description": "Monitor RSU health status", + "version": "@PROJECT_VERSION@", + "exeLocation": "/bin/RSUHealthMonitorPlugin", + "coreIpAddr":"127.0.0.1", + "corePort":24601, + "messageTypes": [], + "configuration": [ + { + "key": "LogLevel", + "default": "INFO", + "description": "The log level for this plugin" + }, + { + "key":"Interval", + "default":"1", + "description": "Sending RSU SNMP GET request at every configured interval. Default every 1 second. Unit of measure: second." + }, + { + "key":"RSUIp", + "default":"192.168.XX.XX", + "description":"An IP address of the RSU the V2X hub is connected to." + }, + { + "key":"SNMPPort", + "default":"161", + "description":"The SNMP port for sending message or command." + }, + { + "key":"AuthPassPhrase", + "default":"dummy", + "description":"SNMP v3 authentication passphrase" + }, + { + "key":"SecurityUser", + "default":"authOnlyUser", + "description":"SNMP Security Name" + }, + { + "key":"RSUOIDConfigMap", + "default":"{\"RSUOIDConfig\":[{\"RsuField\":\"rsuGpsOutpuString\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuID\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuMibVersion\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuFirmwareVersion\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuManufacturer\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuIFMIndex\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuIFMPsid\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuIFMDsrcMsgId\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuIFMTxMode\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuIFMTxChannel\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuIFMEnable\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuIFMStatus\",\"OID\":\"1.0.15628.4.1.8.5.0\"},{\"RsuField\":\"rsuMode\",\"OID\":\"1.0.15628.4.1.8.5.0\"}]}", + "description":"OID (Object Identifier) uniquely identify managed objects in a MIB database." + } + ] +} \ No newline at end of file diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.cpp b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.cpp new file mode 100755 index 000000000..87746a732 --- /dev/null +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.cpp @@ -0,0 +1,90 @@ +#include "RSUHealthMonitorPlugin.h" + +using namespace RSUHealthMonitor; +using namespace tmx::utils; + +namespace RSUHealthMonitor +{ + + RSUHealthMonitorPlugin::RSUHealthMonitorPlugin(std::string name) : PluginClient(name) + { + UpdateConfigSettings(); + + // Send SNMP call to RSU status at configurable interval. + std::thread rsuStatus_t(&RSUHealthMonitorPlugin::PeriodicRSUStatusReq, this); + rsuStatus_t.detach(); + } + + void RSUHealthMonitorPlugin::UpdateConfigSettings() + { + PLOG(logINFO) << "Updating configuration settings."; + + lock_guard lock(_configMutex); + GetConfigValue("Interval", _interval); + GetConfigValue("RSUIp", _rsuIp); + GetConfigValue("SNMPPort", _snmpPort); + GetConfigValue("AuthPassPhrase", _authPassPhrase); + GetConfigValue("SecurityUser", _securityUser); + string rsuOIDMapJsonStr; + GetConfigValue("RSUOIDConfigMap", rsuOIDMapJsonStr); + UpdateRSUOIDConfig(rsuOIDMapJsonStr); + } + + bool RSUHealthMonitorPlugin::UpdateRSUOIDConfig(string &json_str) + { + + if (json_str.length() == 0) + { + return false; + } + try + { + // Example:"{\"RSUOIDConfig\": [{\"RsuField\": \"rsuGpsOutpuString\", \"OID\": \"1.0.15628.4.1.8.5.0\"}, {\"RsuField\": \"rsuID\", \"OID\": \"1.0.15628.4.1.8.5.0\"}] }" + ptree pt; + istringstream iss(json_str); + read_json(iss, pt); + BOOST_FOREACH (ptree::value_type &child, pt.get_child("RSUOIDConfig")) + { + // Array elements have no names. + assert(child.first.empty()); + RSUOIDConfig config; + config.field = child.second.get("RsuField"); + config.oid = child.second.get("OID"); + PLOG(logINFO) << "RSU OID Config: Field: " << config.field << ", OID: " << config.oid; + // Add RSU OID to the map + _rsuOIDConfigMap.push_back(config); + } + } + catch (const std::exception &e) + { + PLOG(logERROR) << "Error updating RSU OID config" << e.what(); + return false; + } + return true; + } + + void RSUHealthMonitorPlugin::OnConfigChanged(const char *key, const char *value) + { + PluginClient::OnConfigChanged(key, value); + UpdateConfigSettings(); + } + + void RSUHealthMonitorPlugin::PeriodicRSUStatusReq() + { + while (true) + { + PLOG(logERROR) << "RSU status update call at every " << _interval; + this_thread::sleep_for(chrono::seconds(_interval)); + } + } + + RSUHealthMonitorPlugin::~RSUHealthMonitorPlugin() + { + } + +} // namespace RSUHealthMonitor + +int main(int argc, char *argv[]) +{ + return run_plugin("RSU Health Monitor", argc, argv); +} diff --git a/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.h b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.h new file mode 100755 index 000000000..01388399b --- /dev/null +++ b/src/v2i-hub/RSUHealthMonitorPlugin/src/RSUHealthMonitorPlugin.h @@ -0,0 +1,51 @@ + +#ifndef RSUHEALTHMONITORLUGIN_H_ +#define RSUHEALTHMONITORLUGIN_H_ + +#include "PluginClient.h" +#include +#include +#include +#include + +using namespace tmx::utils; +using namespace std; +using namespace boost::property_tree; + +namespace RSUHealthMonitor +{ + + struct RSUOIDConfig + { + string field; + string oid; + }; + + class RSUHealthMonitorPlugin : public PluginClient + { + private: + mutex _configMutex; + uint16_t _interval; + string _rsuIp; + uint16_t _snmpPort; + string _authPassPhrase; + string _securityUser; + vector _rsuOIDConfigMap; + /** + * @brief Update RSU OID configuration map with input JSON string. + * @param JSON string with RSU OID configuration. + * @return boolean indicator whether the RSU OID configuration map is updated successfully or not. + */ + bool UpdateRSUOIDConfig(string &json_str); + void PeriodicRSUStatusReq(); + + public: + RSUHealthMonitorPlugin(std::string name); + virtual ~RSUHealthMonitorPlugin(); + void UpdateConfigSettings(); + void OnConfigChanged(const char *key, const char *value); + }; + +} // namespace RSUHealthMonitorPlugin + +#endif \ No newline at end of file