My first question here ;) I am stuck with trying to set a value on a device with SNMP protocol by using SNMP++ library (http://www.agentpp.com/doc/snmp++3.x/index.html). When I check the value with visual MIB browser, it is shown as Opaque (on device it is, in fact, a float).
So, the current value of the variable is 1.0 (which is represented as an Octed String as 9F 78 04 3F 80 00 00, no idea why first 4 hex-pairs are this way, but 3F 80 00 00 is exactly 1.0 in floatish). I have modified snmpSet console example a little bit, so now when I want to set the value, I do as follows:
(inside determine_vb(...) function)
case sNMP_SYNTAX_OPAQUE:
{
string str;
cout << "Opaque\n";
cout << "Please enter new value: ";
cin >> str;
// float value_float = atof(str.c_str());
const char * value_char = str.c_str();
vb.set_value(value_char);
return true;
}
(here you have full .cpp file) http://pastebin.com/8sLTyP8D
Unfortunately, setting data for vb this way does not seem to work, since setting a parameter gives me following error:
Set Status = SNMP: Cannot create/set variable, Wrong Encoding
Does anyone of you have any idea how to properly encode a float for a SNMP query, so it will be accepted?
Best regards! Filip
For anyone looking for the answer, I have finally found a solution, and it required conversions, string to float and the other way around:
static const unsigned char * convertFloatToSnmpOpaqueFloat(float valueToBeConverted) {
// Reinterpret floating point value as 4-byte array of unsigned chars
const char * reinterpretedFloat = reinterpret_cast<const char *> (&valueToBeConverted);
// This prefix is used by SNMP to determine that we are using floating-point number.
// Check ASN1 standard for details. 9F78 = FLOATTYPE, 04 = length
std::string stringToBeReturned = "";
stringToBeReturned += '\x9F';
stringToBeReturned += '\x78';
stringToBeReturned += '\x04';
// We have to reverse the order of bytes to get it right
for (int i = sizeof (float) - 1; i >= 0; --i) {
//for (int i = 0; i < sizeof (float); ++i) {
stringToBeReturned = stringToBeReturned + reinterpretedFloat[i];
}
const unsigned char * uCharToBeReturned = (const unsigned char *) stringToBeReturned.c_str();
return (const unsigned char *) stringToBeReturned.c_str();
}
static float convertSnmpOpaqueFloatToFloat(const std::string & valueToBeConverted) {
float floatToBeReturned;
unsigned char * reinterpretedFloat = reinterpret_cast<unsigned char *> (&floatToBeReturned);
int one, two, three, four;
std::sscanf(valueToBeConverted.c_str(), "%*X %*X %*X %X %X %X %X", &one, &two, &three, &four);
reinterpretedFloat[0] = four;
reinterpretedFloat[1] = three;
reinterpretedFloat[2] = two;
reinterpretedFloat[3] = one;
return floatToBeReturned;
}