/*
* 'SNMPValue.java' NOTE: This copyright does *not* cover user programs that use
* HQ program services by normal system calls through the application program
* interfaces provided as part of the Hyperic Plug-in Development Kit or the
* Hyperic Client Development Kit - this is merely considered normal use of the
* program, and does *not* fall under the heading of "derived work". Copyright
* (C) [2004, 2005, 2006, 2007, 2008, 2009], Hyperic, Inc. This file is part of
* HQ. HQ is free software; you can redistribute it and/or modify it under the
* terms version 2 of the GNU General Public License as published by the Free
* Software Foundation. This program is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
package org.hyperic.snmp;
import java.util.Calendar;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.SMIConstants;
import org.snmp4j.smi.Variable;
import org.snmp4j.smi.VariableBinding;
public class SNMPValue {
private static Log log = LogFactory.getLog(SNMPValue.class);
public static final int TYPE_LONG = 0;
public static final int TYPE_STRING = 1;
public static final int TYPE_LONG_CONVERTABLE = 2;
OID oid;
Variable var;
private SNMPValue() {
}
SNMPValue(VariableBinding vb) {
this(vb.getOid(), vb.getVariable());
}
SNMPValue(OID oid, Variable var) {
this.oid = oid;
this.var = var;
}
private boolean isOctetString() {
return this.var.getSyntax() == SMIConstants.SYNTAX_OCTET_STRING;
}
public byte[] getBytes() {
return ((OctetString) this.var).getValue();
}
public String toString() {
if (isOctetString()) {
// Avoid OctetString.toString() hex encoding
// if bytes contain any ISO control chars
return new String(getBytes());
} else {
return this.var.toString();
}
}
private String toHex(int val) {
return Integer.toHexString(val & 0xff);
}
// From SNMPv2-TC:
// PhysAddress ::= TEXTUAL-CONVENTION
// DISPLAY-HINT "1x:"
// STATUS current
// DESCRIPTION
// "Represents media- or physical-level addresses."
// SYNTAX OCTET STRING
public String toPhysAddressString() {
byte[] data = getBytes();
if (data.length == 0) {
return "0:0:0:0:0:0"; // e.g. loopback...
}
StringBuffer buffer = new StringBuffer();
buffer.append(toHex(data[0]));
for (int i = 1; i < data.length; i++) {
buffer.append(':').append(toHex(data[i]));
}
return buffer.toString();
}
public String getOID() {
return this.oid.toString();
}
public int getType() {
switch (this.var.getSyntax()) {
case SMIConstants.SYNTAX_INTEGER32:
case SMIConstants.SYNTAX_COUNTER32:
case SMIConstants.SYNTAX_COUNTER64:
case SMIConstants.SYNTAX_TIMETICKS:
case SMIConstants.SYNTAX_GAUGE32:
return TYPE_LONG;
case SMIConstants.SYNTAX_OCTET_STRING:
// While we are able to convert long
// does not mean we should. treat as a string
// for now.
// return TYPE_LONG_CONVERTABLE;
return TYPE_STRING;
default:
return TYPE_STRING;
}
}
// A bit of a hack - if it is an OctetString, treat
// it like a DateAndTime (from the SNMPv2-TC MIB)
private long convertDateAndTimeToLong() throws SNMPException {
byte[] bytes = getBytes();
if (bytes.length < 8) {
String msg = "OctetString is not in DateAndTime syntax";
throw new SNMPException(msg);
}
Calendar cal = Calendar.getInstance();
int ix = 0;
int year = (bytes[ix] > 0) ? bytes[ix] : (256 + bytes[ix]);
year <<= 8;
ix++;
year += (bytes[ix] > 0) ? bytes[ix] : (256 + bytes[ix]);
ix++;
int month = bytes[ix++];
int day = bytes[ix++];
int hour = bytes[ix++];
int minutes = bytes[ix++];
int seconds = bytes[ix++];
int deciseconds = bytes[ix++];
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, (month - 1));
cal.set(Calendar.DAY_OF_MONTH, day);
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minutes);
cal.set(Calendar.SECOND, seconds);
cal.set(Calendar.MILLISECOND, (100 * deciseconds));
cal.set(Calendar.ZONE_OFFSET, 0);
cal.set(Calendar.DST_OFFSET, 0);
if (log.isDebugEnabled()) {
log.debug("converted to DateAndTime: millis=" + cal.getTimeInMillis() + ", date=" + cal.getTime());
}
return cal.getTimeInMillis();
}
public long toLong() throws SNMPException {
if (isOctetString()) {
return convertDateAndTimeToLong();
} else {
try {
return this.var.toLong();
} catch (UnsupportedOperationException e) {
String msg = "Cannot convert " + this.var.getSyntaxString() + " to long";
throw new SNMPException(msg);
}
}
}
}