SNMP:无法 create/set 变量,编码错误

SNMP: Cannot create/set variable, Wrong Encoding

我的第一个问题 ;) 我一直试图通过使用 SNMP++ 库 (http://www.agentpp.com/doc/snmp++3.x/index.html) 在具有 SNMP 协议的设备上设置一个值。当我使用可视化 MIB 浏览器检查该值时,它显示为不透明(在设备上它实际上是一个浮点数)。

因此,变量的当前值为 1.0(表示为八进制字符串 9F 78 04 3F 80 00 00,不知道为什么前 4 个十六进制对是这样,但 3F 80 00 00 是floatish 正好是 1.0)。我稍微修改了 snmpSet console example,所以现在当我想设置值时,我做如下:

(在 determine_vb(...) 函数内)

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;
}

(这里有完整的 .cpp 文件) http://pastebin.com/8sLTyP8D

不幸的是,以这种方式为 vb 设置数据似乎不起作用,因为设置参数会出现以下错误:

Set Status = SNMP: Cannot create/set variable, Wrong Encoding

你们有没有人知道如何为 SNMP 查询正确编码浮点数,以便接受它?

此致! 菲利普

SNMP 没有浮点数据类型,这就是它被包裹在不透明编码中的原因(或者,它可以使用带有 DISPLAY-HINT 的整数类型进行十进制移位)。它在 Opaque 内部的编码方式将特定于 OBJECT-TYPE 定义。这将需要了解如何将浮点值 1.0 编码为 9F 78 04 3F 80 00 00.

对于任何寻找答案的人,我终于找到了解决方案,它需要转换,字符串到浮动,反之亦然:

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;
}