Skip to content

Commit

Permalink
renamed: src/v2i-hub/ERVCloudForwardingPlugin/src/SNMPClient.cpp -> …
Browse files Browse the repository at this point in the history
…src/tmx/TmxUtils/src/SNMPClient.cpp

	renamed:    src/v2i-hub/ERVCloudForwardingPlugin/src/SNMPClient.h -> src/tmx/TmxUtils/src/SNMPClient.h
	renamed:    src/v2i-hub/ERVCloudForwardingPlugin/src/SNMPClientException.h -> src/tmx/TmxUtils/src/SNMPClientException.h
	modified:   src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt
	modified:   src/v2i-hub/ERVCloudForwardingPlugin/manifest.json
	modified:   src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.cpp
	modified:   src/v2i-hub/ERVCloudForwardingPlugin/src/ERVCloudForwardingPlugin.h
	modified:   src/v2i-hub/ERVCloudForwardingPlugin/test/SNMPClientTest.cpp
	modified:   src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt
	modified:   src/v2i-hub/ImmediateForwardPlugin/manifest.json
	modified:   src/v2i-hub/ImmediateForwardPlugin/src/ImmediateForwardPlugin.cpp
	modified:   src/v2i-hub/ImmediateForwardPlugin/src/ImmediateForwardPlugin.h
  • Loading branch information
jwillmartin committed Jun 15, 2023
1 parent 47a1dc3 commit 2e5b097
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 114 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include "SNMPClient.h"

SNMPClient::SNMPClient(const std::string &rsuIP, uint16_t snmp_port, const std::string &securityUser, const std::string &authPassPhrase)
namespace tmx {
namespace utils {

SNMPClient::SNMPClient(const std::string &rsuIP, uint16_t snmp_port, const std::string &snmp_user, const std::string &securityLevel, const std::string &authPassPhrase)
: _snmp_port(snmp_port)
, _rsuIP(rsuIP)
{
Expand All @@ -10,15 +13,14 @@ SNMPClient::SNMPClient(const std::string &rsuIP, uint16_t snmp_port, const std::
snmp_sess_init(&session);
session.peername = ip_port;
session.version = SNMP_VERSION_3;
session.securityName = (char *)securityUser.c_str();
session.securityNameLen = securityUser.length();
if (securityUser == "authPrivUser") {
session.securityName = (char *)snmp_user.c_str();
session.securityNameLen = snmp_user.length();
if (securityLevel == "authPriv") {
session.securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
}
else if (securityUser == "authOnlyUser") {
else if (securityLevel == "authNoPriv") {
session.securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
}

else session.securityLevel = SNMP_SEC_LEVEL_NOAUTH;
session.securityAuthProto = snmp_duplicate_objid(usmHMACSHA1AuthProtocol, USM_AUTH_PROTO_SHA_LEN);
session.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
Expand Down Expand Up @@ -47,7 +49,6 @@ SNMPClient::SNMPClient(const std::string &rsuIP, uint16_t snmp_port, const std::
std::string SNMPClient::SNMPGet(const std::string &req_oid)
{
std::string result = "";
netsnmp_pdu *response;
auto pdu = snmp_pdu_create(SNMP_MSG_GET);
if (!snmp_parse_oid(req_oid.c_str(), anOID, &anOID_len))
{
Expand Down Expand Up @@ -88,48 +89,92 @@ std::string SNMPClient::SNMPGet(const std::string &req_oid)
return result;
}

std::string SNMPClient::SNMPSet(const std::string &req_oid)
bool SNMPClient::SNMPSet(const std::string &oid, int32_t value)
{
std::string result = "";
netsnmp_pdu *response;
auto pdu = snmp_pdu_create(SNMP_MSG_GET);
if (!snmp_parse_oid(req_oid.c_str(), anOID, &anOID_len))
{
snmp_perror(req_oid.c_str());
std::string errMsg = "OID could not be created from input:" + req_oid;
throw SNMPClientException(errMsg);
SOCK_CLEANUP;
return SNMPClient::SNMPSet(oid, ASN_INTEGER, (const void *)&value, sizeof(value));
}

bool SNMPClient::SNMPSet(const std::string &oid, u_char type, const void *value, size_t len)
{
bool rc = true;
static int quiet = 0;
int arg;
int count;
int current_name = 0;
int current_type = 0;
int current_value = 0;
char *names[SNMP_MAX_CMDLINE_OIDS];
char types[SNMP_MAX_CMDLINE_OIDS];
char *values[SNMP_MAX_CMDLINE_OIDS];
int status;
int failures = 0;
int exitval = 0;
auto pdu = snmp_pdu_create(SNMP_MSG_SET);

// if (!snmp_parse_oid(oid.c_str(), anOID, &anOID_len))
// {
// snmp_perror(oid.c_str());
// std::string errMsg = "OID could not be created from input:" + oid;
// throw SNMPClientException(errMsg);
// SOCK_CLEANUP;
// }
for (count = 0; count < current_name; count++) {
if (snmp_parse_oid(names[count], anOID, &anOID_len) == NULL) {
snmp_perror(names[count]);
failures++;
} else
if (snmp_add_var
(pdu, anOID, anOID_len, types[count], values[count])) {
snmp_perror(names[count]);
failures++;
}
}
snmp_add_null_var(pdu, anOID, anOID_len);
auto status = snmp_synch_response(ss, pdu, &response);
if (!response)
{
throw SNMPClientException("No response for SNMP Get request!");

if (failures) {
snmp_close(ss);
SOCK_CLEANUP;
exit(1);
}
else if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR)
{
// SUCCESS: Return the response as result
for (auto vars = response->variables; vars; vars = vars->next_variable)
{
if (vars->type == ASN_OCTET_STR)
{
result = reinterpret_cast<char *>(vars->val.string);

// snmp_add_null_var(pdu, anOID, anOID_len);
// snmp_pdu_add_variable(pdu, anOID, anOID_len, type, value, len);

auto status = snmp_synch_response(ss, pdu, &response);
if (status == STAT_SUCCESS) {
if (response->errstat == SNMP_ERR_NOERROR) {
if (!quiet) {
for (vars = response->variables; vars;
vars = vars->next_variable)
print_variable(vars->name, vars->name_length, vars);
}
else
{
throw SNMPClientException("Received respones type is not a string");
} else {
fprintf(stderr, "Error in packet.\nReason: %s\n",
snmp_errstring(response->errstat));
if (response->errindex != 0) {
fprintf(stderr, "Failed object: ");
for (count = 1, vars = response->variables;
vars && (count != response->errindex);
vars = vars->next_variable, count++);
if (vars)
fprint_objid(stderr, vars->name, vars->name_length);
fprintf(stderr, "\n");
}
exitval = 2;
}
} else if (status == STAT_TIMEOUT) {
fprintf(stderr, "Timeout: No Response from %s\n",
session.peername);
exitval = 1;
} else { /* status == STAT_ERROR */
snmp_sess_perror("snmpset", ss);
exitval = 1;
}
else
{
// FAILURE: Print what went wrong!
std::string errMsg = snmp_errstring(response->errstat);
throw SNMPClientException("Error in packet. Reason:" + errMsg);
}

if (response)
snmp_free_pdu(response);
return result;
snmp_close(ss);
SOCK_CLEANUP;
return exitval;
}

int SNMPClient::GetPort() const
Expand All @@ -147,3 +192,5 @@ SNMPClient::~SNMPClient()
fprintf(stdout, "Closing snmp session\n");
snmp_close(ss);
}

}} // namespace tmx::utils
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
#include <sstream>
#include <SNMPClientException.h>


namespace tmx::utils {

class SNMPClient
{
private:
netsnmp_session session;
netsnmp_session *ss;
netsnmp_pdu *pdu, *response = NULL;
netsnmp_variable_list *vars;
oid anOID[MAX_OID_LEN];
size_t anOID_len = MAX_OID_LEN;
int _snmp_port;
Expand All @@ -26,29 +31,33 @@ class SNMPClient
* @param ip RSU IP
* @param port SNMP port
*/
SNMPClient(const std::string &rsuIP, uint16_t snmp_port, const std::string &securityUser, const std::string &authPassPhrase);
SNMPClient(const std::string &rsuIP, uint16_t snmp_port, const std::string &snmp_user, const std::string &securityLevel, const std::string &authPassPhrase);
/**
* @brief Send SNMP v3 Get request to an RSU to retrieve data
* @param oid OID (Object Identifier) uniquely identify managed objects in a MIB database. Concept refers to: https://en.wikipedia.org/wiki/Management_information_base
* @return std::string identified by the oid. If SNMP response is not string, exit with failure.
*/
std::string SNMPGet(const std::string &oid);
/**
* @brief Send SNMP v3 Get request to an RSU to retrieve data
* @param oid OID (Object Identifier) uniquely identify managed objects in a MIB database. Concept refers to: https://en.wikipedia.org/wiki/Management_information_base
* @brief Send SNMP v3 Set request to an RSU to write data
* @param oid OID (Object Identifier) uniquely identify managed objects in a MIB database.
* @return std::string identified by the oid. If SNMP response is not string, exit with failure.
*/
std::string SNMPSet(const std::string &oid);
bool SNMPSet(const std::string &oid, int32_t value);
bool SNMPSet(const std::string &oid, u_char type, const void *value, size_t len);
/**
* @brief Retrieve the port used by this SNMP client as an integer.
* @return The port as expected in a host integer.
*/
virtual int GetPort() const;
/**
* @brief Retrieve a copy of the rsu ipv4 address.
* @return A string with a copy of the constructor input address.
* @brief Retrieve a copy of the RSU IPv4 address.
* @return std::string with a copy of the constructor input address.
*/
virtual std::string GetAddress() const;
~SNMPClient();
};
#endif

} // namespace tmx::utils

#endif /* SNMPCLIENT_H_ */
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define SNMPCLIENTEXCEPTION_H_
#include <iostream>

namespace tmx::utils {

class SNMPClientException : public std::exception
{
private:
Expand All @@ -15,4 +17,7 @@ class SNMPClientException : public std::exception
}
~SNMPClientException() override = default;
};
#endif

} // namespace tmx::utils

#endif /* SNMPCLIENTEXCEPTION_H_ */
2 changes: 1 addition & 1 deletion src/v2i-hub/ERVCloudForwardingPlugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ link_directories(${CMAKE_PREFIX_PATH}/lib)
# ############
enable_testing()
include_directories(${PROJECT_SOURCE_DIR}/src)
add_library(${PROJECT_NAME}_lib src/ERVCloudForwardingWorker.cpp src/SNMPClient.cpp)
add_library(${PROJECT_NAME}_lib src/ERVCloudForwardingWorker.cpp) # src/SNMPClient.cpp)
target_link_libraries(${PROJECT_NAME}_lib PUBLIC NemaTode ${TMXAPI_LIBRARIES}
${ASN_J2735_LIBRARIES} tmxutils ${NETSNMPAGENT} ${NETSNMPMIBS} ${NETSNMP} ${NETSNMP_LIBRARIES})
set(BINARY ${PROJECT_NAME}_test)
Expand Down
13 changes: 9 additions & 4 deletions src/v2i-hub/ERVCloudForwardingPlugin/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,15 @@
"description":"SNMP v3 authentication passphrase"
},
{
"key":"SecurityUser",
"default":"authOnlyUser",
"description":"SNMP Security Name"
},
"key":"SNMPUser",
"default":"dummyUser",
"description":"SNMP v3 user."
},
{
"key":"SecurityLevel",
"default":"authNoPriv",
"description":"SNMP Access Control. Usage: noAuthNoPriv, authNoPriv, or authPriv."
},
{
"key":"GPSOID",
"default":"1.0.15628.4.1.8.5.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ namespace ERVCloudForwardingPlugin
PLOG(logINFO) << "Attempting to register RSU " << attempt << " times." << endl;
try
{
PLOG(logINFO) << "Create SNMP Client to connect to RSU. RSU IP:" << _rsuIp << ",\tRSU Port:" << _snmpPort << ",\tSecurity Name:" << _securityUser << ",\tAuthentication Passphrase: " << _authPassPhrase << endl;
auto snmpClient = std::make_shared<SNMPClient>(_rsuIp, _snmpPort, _securityUser, _authPassPhrase);
PLOG(logINFO) << "Create SNMP Client to connect to RSU. RSU IP:" << _rsuIp << ",\tRSU Port:" << _snmpPort << ",\tSecurity Level:" << _securityLevel << "\tSNMP User: " << _snmpUser << ",\tAuthentication Passphrase: " << _authPassPhrase << endl;
auto snmpClient = std::make_shared<SNMPClient>(_rsuIp, _snmpPort, _snmpUser, _securityLevel, _authPassPhrase);
auto gps_sentence = snmpClient->SNMPGet(_GPSOID);
auto gps_map = ERVCloudForwardingWorker::ParseGPS(gps_sentence);
long latitude = 0;
Expand Down Expand Up @@ -106,7 +106,8 @@ namespace ERVCloudForwardingPlugin
GetConfigValue<uint16_t>("WebServicePort", _webPort);
GetConfigValue<string>("RSUIp", _rsuIp);
GetConfigValue<uint16_t>("SNMPPort", _snmpPort);
GetConfigValue<string>("SecurityUser", _securityUser);
GetConfigValue<string>("SecurityLevel", _securityLevel);
GetConfigValue<string>("SNMPUser", _snmpUser);
GetConfigValue<string>("AuthPassPhrase", _authPassPhrase);
GetConfigValue<string>("GPSOID", _GPSOID);
GetConfigValue<string>("RSUName", _rsuName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ namespace ERVCloudForwardingPlugin
uint32_t _max_rsu_connection_attempt = 30;
// Waiting to start the web service
uint32_t _max_web_service_waiting = 10; // unit of second
string _securityUser;
string _snmpUser;
string _securityLevel;
string _authPassPhrase;
string _GPSOID;
const string _CLOUDURL = "http://127.0.0.1:33333";
Expand Down
14 changes: 9 additions & 5 deletions src/v2i-hub/ERVCloudForwardingPlugin/test/SNMPClientTest.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <gtest/gtest.h>
#include "SNMPClient.h"

using namespace tmx::utils;

namespace unit_test
{
class SNMPClientTest : public ::testing::Test
Expand All @@ -11,20 +13,22 @@ namespace unit_test
{
const std::string rsu_ip = "127.0.0.1";
uint16_t snmp_port = 161;
std::string securityUser = "dummy";
std::string snmp_user = "dummy";
std::string securityLevel = "authPriv";
std::string authPassPhrase = "dummy"; // Error: passphrase chosen is below the length requirements of the USM (min=8).
ASSERT_ANY_THROW(SNMPClient(rsu_ip, snmp_port, securityUser, authPassPhrase));
ASSERT_ANY_THROW(SNMPClient(rsu_ip, snmp_port, snmp_user, securityLevel, authPassPhrase));
authPassPhrase = "dummydummy";
ASSERT_NO_THROW(SNMPClient(rsu_ip, snmp_port, securityUser, authPassPhrase));
ASSERT_NO_THROW(SNMPClient(rsu_ip, snmp_port, snmp_user, securityLevel, authPassPhrase));
}

TEST_F(SNMPClientTest, SNMPGet)
{
const std::string rsu_ip = "127.0.0.1";
uint16_t snmp_port = 161;
std::string securityUser = "dummy";
std::string snmp_user = "dummy";
std::string securityLevel = "authPriv";
std::string authPassPhrase = "dummydummy";
auto snmpClient = SNMPClient(rsu_ip, snmp_port, securityUser, authPassPhrase);
auto snmpClient = SNMPClient(rsu_ip, snmp_port, snmp_user, securityLevel, authPassPhrase);
ASSERT_THROW(snmpClient.SNMPGet("1.0.15628.4.1.8.5.0"), SNMPClientException);
}
}
7 changes: 5 additions & 2 deletions src/v2i-hub/ImmediateForwardPlugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ SET (TMX_PLUGIN_NAME "Immediate Forward")

FIND_PACKAGE (XercesC REQUIRED)
find_package(CURL REQUIRED)
find_library(NETSNMPAGENT "netsnmpagent")
find_library(NETSNMPMIBS "netsnmpmibs")
find_library(NETSNMP "netsnmp")

#SET(CMAKE_BOTAN_SOURCE_DIR {CMAKE_SOURCE_DIR}/../../../ext/botan)
#include_directories(${CMAKE_BOTAN_SOURCE_DIR}/build/include)
Expand All @@ -15,5 +18,5 @@ BuildTmxPlugin ()



TARGET_INCLUDE_DIRECTORIES ( ${PROJECT_NAME} PUBLIC ${XercesC_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES ( ${PROJECT_NAME} tmxutils ${XercesC_LIBRARY} ) #libbotan-2 )
TARGET_INCLUDE_DIRECTORIES ( ${PROJECT_NAME} PUBLIC ${XercesC_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${NETSNMP_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES ( ${PROJECT_NAME} tmxutils ${XercesC_LIBRARY} ${NETSNMPAGENT} ${NETSNMPMIBS} ${NETSNMP} ${NETSNMP_LIBRARIES}) #libbotan-2 )
15 changes: 10 additions & 5 deletions src/v2i-hub/ImmediateForwardPlugin/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"key":"LogLevel",
"default":"INFO",
"description":"The log level for this plugin"
"description":"The log level for this plugin."
},
{
"key": "Messages_Destination_1",
Expand Down Expand Up @@ -75,12 +75,17 @@
{
"key":"AuthPassPhrase",
"default":"dummy",
"description":"SNMP v3 authentication passphrase"
"description":"SNMP v3 authentication passphrase."
},
{
"key":"SecurityUser",
"default":"authPrivUser",
"description":"SNMP Access Control"
"key":"SNMPUser",
"default":"dummyUser",
"description":"SNMP v3 user."
},
{
"key":"SecurityLevel",
"default":"authNoPriv",
"description":"SNMP Access Control. Usage: noAuthNoPriv, authNoPriv, or authPriv."
}
]
}
Loading

0 comments on commit 2e5b097

Please sign in to comment.