Go Down

Topic: Cosa SNMP agent library (Read 1 time) previous topic - next topic

kowalski

The second increment of the SNMP agent support is completed. The example sketch demonstrates SNMP MIB-2 handling (system attributes) and example Arduino MIB with digital pin, analog pin and power supply voltage read.

An OID match function (SNMP::OID::match) has been introduced to make it easy to compare request PDU OIDs and dispatch GET/SET response code. Below is a snippet from the updated CosaSNMP.ino example sketch; https://github.com/mikaelpatel/Cosa/blob/master/examples/Ethernet/CosaSNMP/CosaSNMP.ino
Code: [Select]

bool system_mib(SNMP::PDU& pdu)
{
  // Match with SNMP MIB-2 System OID root
  int sys = pdu.oid.match(SNMP::MIB2_SYSTEM);
  if (sys < SNMP::sysDescr || sys > SNMP::sysServices) return (false);

  // Get system value
  if (pdu.type == SNMP::PDU_GET) {
    switch (sys) {
    case SNMP::sysDescr:
      ...
      break;
    ...
    }
  }

  // Set system value
  else if (pdu.type == SNMP::PDU_SET) {
    switch (sys) {
    case SNMP::sysContact:
      ...
      break;
    default:
      pdu.error_status = SNMP::READ_ONLY;
    }
  }
  return (true);
}

The example root OIDs (SNMP::MIB2_SYSTEM and SNMP::ARDUINO_MIB) are defined in program memory to reduce SRAM usage. Below are the definitions in SNMP.hh. Note that the root OID is a length prefixed sequnce of bytes and the access object is defined as a symbol in an enum to allows simple switch-case dispatch as above.
Code: [Select]

class SNMP {
public:
  ...
  // SNMP MIB-2 System OID(1.3.6.1.2.1.1)
  const static uint8_t MIB2_SYSTEM[] PROGMEM;
  enum {
    sysDescr = 1, // DisplayString(0..255), read-only, mandatory
    sysObjectID = 2, // OID, read-only, mandatory
    sysUpTime = 3, // TimeTicks, read-only, mandatory
    sysContact = 4, // DisplayString(0..255), read-write, mandatory
    sysName = 5, // DisplayString(0..255), read-write, mandatory
    sysLocation = 6, // DisplayString(0..255), read-write, mandatory
    sysServices = 7 // Integer(0..127), read-only, mandatory
  } __attribute__((packet));

  // Arduino MIB OID(1.3.6.1.4.1.36582)
  const static uint8_t ARDUINO_MIB[] PROGMEM;
  enum {
    ardDigitalPin = 1, // DigitalPin[0..22](0..1), read-write
    ardAnalogPin = 2, // AnalogPin[0..7](0..1023), read-only
    ardVcc = 3,         // Power supply[n](0..VCC), mV, read-only
  } __attribute__((packet));
  ...
};

Some examples of access with snmpget and snmpwalk. The options and parameters are (left-to-right); debug mode, version(1), community string(public), device network address and object identity(OID).
Code: [Select]

# Get value of digital pin 8
snmpget -d -v 1 -c public 192.168.0.22 0.1.3.6.1.4.1.36582.1.8
# Get value of analog pin 4
snmpget -d -v 1 -c public 192.168.0.22 0.1.3.6.1.4.1.36582.2.4
# Get power supply voltage (in milli-volt)
snmpget -d -v 1 -c public 192.168.0.22 0.1.3.6.1.4.1.36582.3.0
# Get system uptime
snmpget -d -v 1 -c public 192.168.0.22 0.1.3.6.1.2.1.1.3

The command snmpwalk (and snmpgetnext) can be used to iterate over the MIB and access all value; System MIB settings and status (uptime), and the Arduino Pins (Digital, Analog) and Power supply voltage. Below is a test run.
Code: [Select]

$ snmpwalk -v1 -c public 192.168.0.22 0
ccitt.1.3.6.1.2.1.1.1 = STRING: "<description>"
ccitt.1.3.6.1.2.1.1.2 = OID: ccitt.9.1.3.6.1.4.1.36582
ccitt.1.3.6.1.2.1.1.3 = 806
ccitt.1.3.6.1.2.1.1.4 = STRING: "<your name>"
ccitt.1.3.6.1.2.1.1.5 = STRING: "<device name>"
ccitt.1.3.6.1.2.1.1.6 = STRING: "<device location>"
ccitt.1.3.6.1.2.1.1.7 = INTEGER: 66
ccitt.1.3.6.1.4.1.36582.1.0 = INTEGER: 1
ccitt.1.3.6.1.4.1.36582.1.1 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.2 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.3 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.4 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.5 = INTEGER: 1
ccitt.1.3.6.1.4.1.36582.1.6 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.7 = INTEGER: 1
ccitt.1.3.6.1.4.1.36582.1.8 = INTEGER: 1
ccitt.1.3.6.1.4.1.36582.1.9 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.10 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.11 = INTEGER: 1
ccitt.1.3.6.1.4.1.36582.1.12 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.13 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.14 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.15 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.16 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.17 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.18 = INTEGER: 1
ccitt.1.3.6.1.4.1.36582.1.19 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.20 = INTEGER: 1
ccitt.1.3.6.1.4.1.36582.1.21 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.1.22 = INTEGER: 0
ccitt.1.3.6.1.4.1.36582.2.0 = INTEGER: 1023
ccitt.1.3.6.1.4.1.36582.2.1 = INTEGER: 1023
ccitt.1.3.6.1.4.1.36582.2.2 = INTEGER: 753
ccitt.1.3.6.1.4.1.36582.2.3 = INTEGER: 620
ccitt.1.3.6.1.4.1.36582.2.4 = INTEGER: 510
ccitt.1.3.6.1.4.1.36582.2.5 = INTEGER: 437
ccitt.1.3.6.1.4.1.36582.2.6 = INTEGER: 368
ccitt.1.3.6.1.4.1.36582.2.7 = INTEGER: 336
ccitt.1.3.6.1.4.1.36582.3.0 = INTEGER: 4673
End of MIB

Cheers!

Fred_Tuga

Hi all,

What about to receive SNMP Trap?
Anyone knows if there is a library to show the information of received traps?

How can I manage incoming SNMP Traps with Arduino?

Thanks and best regards,
Fred

gukhan

Hi All,
        How about sending SNMP trap from Arduino? Can anyone help?

SurferTim

The SNMP trap is a udp packet sent from the agent to port 162 on the SNMP manager.
http://en.wikipedia.org/wiki/Simple_Network_Management_Protocol

The format of the packet depends on the SNMP version. Do a Google search for "SNMP trap packet".


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy