Day: April 25, 2015

Controlling the LEDs of a USB Keyboard connected to RaspberryPi using SNMP

I will show you how to read the LEDs’ status of a USB Keyboard connected to RaspberryPi and how to change the status of Scroll-Lock LED remotely (X11 libs don’t accept to control CapsLock and NumLock). We will use the SNMP protocol to read the LEDs status and write to Scroll-Lock LED.

Because I only found a 2GB SD Card here in my house I was forced to use the old “2012-10-28-wheezy-raspbian.img” Raspbian image to fit inside this card.

After installing and configuring Raspbian it returned “403 Forbidden Failed” when attempting to install packages.

You can fix it editing /etc/apt/source.list removing the default repository and adding:

deb http://archive.raspbian.org/raspbian wheezy main contrib non-free

Install all necessary software to get SNMP working and X11 lib to control keyboard LEDs:

$ sudo apt-get install snmp-mibs-downloader libsnmp-dev snmp snmpd libx11-dev

Verify the paths where “snmpd” are looking for snmpd.conf and for MIBs:

$ net-snmp-config --default-mibdirs

As you can see it returned many paths, but among them the /home/pi/.snmp. This is a place where snmpd will look to find a config file. We will put our file there.

First let create the .snmpd directory:

$ mkdir -p ~/.snmp/mibs/
$ mkdir -p ~/snmp/src/

Download the file exemplo.zip

Decompress it and copy EXEMPLO-MIB file to ~/.snmp/mibs:

$ cp snmp/EXEMPLO-MIB ~/.snmp/mibs

Edit the file /etc/snmp/snmp.conf and replace “mibs :” by:

mibs +EXEMPLO-MIB

Also copy exemplo.c and exemplo.h files to ~/snmp/src:

$ cp snmp/exemplo.* ~/snmp/src

Enter inside ~/snmp/src and create the shared library (AKA snmp module) :

$ cd ~/snmp/src
$ gcc `net-snmp-config --cflags` -fPIC -shared -g -O0 -o exemplo.so exemplo.c `net-snmp-config --libs` -lX11

Copy it to /usr/lib:

$ sudo cp exemplo.so /usr/lib
$ sudo ldconfig

We need to load this library using SNMP commands, but to use SNMP commands we need to create an User and Password.

To do it enter inside ~/.snmp and create a basic configuration (snmpd.conf) file there:

$ cd ~/.snmp
$ snmpconf -r none -g basic_setup

Do you want to configure the information returned in the system MIB group
(contact info, etc)? (default = y):y

The location of the system: your location

The contact information: your name

Do you want to properly set the value of the sysServices.0 OID
(if you don't know, just say no)? (default = y): n

Do you want to allow SNMPv3 read-write user based access (default = y):y

The SNMPv3 user that should have read-write access: raspi

The minimum security level required for that user
[noauth|auth|priv, default = auth]: auth

The OID that this community should be restricted to [if appropriate]: 

Finished Output: rwuser raspi auth
Do another rwuser line? (default = y):n

Do you want to allow SNMPv3 read-only user based access (default = y):y

Enter the SNMPv3 user that should have read-only access to the system: joe

The minimum security level required for that user [noauth|auth|priv, default = auth]: auth

The OID that this community should be restricted to [if appropriate]: .1.3.6.1.4.1.54321

Do another rouser line? (default = y): n

Do you want to allow SNMPv1/v2c read-write community access (default = y): y

Enter the community name to add read-write access for: acme

The hostname or network address to accept this community name from [RETURN for all]: 

The OID that this community should be restricted to [RETURN for no-restriction]: 

Do another rwcommunity line? (default = y): n

Do you want to allow SNMPv1/v2c read-only community access (default = y): n

Do you want to configure where and if the agent will send traps? (default = y): n

Do you want to configure the agent's ability to monitor varios aspects of your system (default = y): n

It will create the snmpd.conf file at our current location (/home/pi/.snmp/)

Stop snmpd and start it manually:

$ sudo service snmpd stop
$ sudo snmpd -f -L -Dexemplo,dlmod

If you faced some user/password issues at this point you can stop the snmp service and configure the /etc/snmp/snmp.conf this way:

mibs +EXEMPLO-MIB
defSecurityName raspi
defContext ""
defAuthType MD5
defSecurityLevel authNoPriv
defAuthPassphrase password
defVersion 3

You can replace “defAuthPassphrase password” by “defAuthPassphrase yourpass” but “yourpass” needs to have at least 8 characters.

Remember to start the snmpd server before execute next commands.

Now we can load the library, to do it create a new row in the dlmod table:

$ snmpset -c acme -v3 -u raspi -A password localhost UCD-DLMOD-MIB::dlmodStatus.1 i create 

UCD-DLMOD-MIB::dlmodStatus.1 = INTEGER: create(6)

We can see its content using this command:

$ snmptable -c acme -v3 -u raspi -A password localhost UCD-DLMOD-MIB::dlmodTable 

SNMP table: UCD-DLMOD-MIB::dlmodTable

 dlmodName dlmodPath dlmodError dlmodStatus
                                   unloaded

We need to update this new row with our dynamic module info:

$ snmpset -c acme -v3 -u raspi -A password localhost UCD-DLMOD-MIB::dlmodName.1 s "exemplo" UCD-DLMOD-MIB::dlmodPath.1 s "/usr/lib/exemplo.so"

MIB::dlmodName.1 = STRING: exemplo
UCD-DLMOD-MIB::dlmodPath.1 = STRING: /usr/lib/exemplo.so

Load the dynamic module:

$ snmpset -c acme -v3 -u raspi -A password localhost UCD-DLMOD-MIB::dlmodStatus.1 i load

UCD-DLMOD-MIB::dlmodStatus.1 = INTEGER: load(4)

Confirm it was loaded successfully:

$ snmptable -c acme -v3 -u raspi -A password localhost UCD-DLMOD-MIB::dlmodTable 

SNMP table: UCD-DLMOD-MIB::dlmodTable

 dlmodName           dlmodPath dlmodError dlmodStatus
   exemplo /usr/lib/exemplo.so                 loaded

You can test if it is working this way:

$ snmpget -c acme -v3 -u raspi -A password localhost EXEMPLO-MID::scrollLock.0

EXEMPLO-MIB::scrollLock.0 = INTEGER: 0

Now you can write to Scroll-Lock LED this way:

$ snmpset -c acme -v3 -u raspi -A password localhost EXEMPLO-MID::scrollLock.0 i 1

EXEMPLO-MIB::scrollLock.0 = INTEGER: aceso(1)

If everything worked fine the Scroll-Lock LED of keyboard connected to RaspiberryPi will turn on!

Now time to try the remote access! My Raspi board got the IP 192.168.0.15 and my computer got the IP 192.168.0.14. Then from my computer I tried to control the Scroll-Lock this way:

$ snmpset -c acme -v3 -u raspi -A password 192.168.0.15 EXEMPLO-MIB::scrollLock.0 i 1
snmpset: Timeout

Unfortunately it didn’t work! More some Internet search and I discovered that I need to use the interface IP in the snmpd command line to get it working:

$ sudo snmpd -f -L -Dexemplo,dlmod 192.168.0.15

Let me try again:

$ snmpset -c acme -v3 -u raspi -A password 192.168.0.15 EXEMPLO-MIB::scrollLock.0 i 1
Error in packet.
Reason: authorizationError (access denied to that object)

Now the error changed to authorization access.

Just more some search and I find out the right way to go:

$ snmpset -c acme -v3 -u raspi -A password -l authNoPriv 192.168.0.15 EXEMPLO-MIB::scrollLock.0 i 1
EXEMPLO-MIB::scrollLock.0 = INTEGER: aceso(1)

If you want to enable the SNMPv1 support in the snmpd you need to edit the /etc/snmp/snmpd.conf and add:

view         acmeonly      included    .1.3.6.1.4.1.54321
rwcommunity  acme          default     -V acmeonly

You can test if it worked this way:

$ snmpset -c acme -v1 192.168.0.15 EXEMPLO-MIB::scrollLock.0 i 1

EXEMPLO-MIB::scrollLock.0 = INTEGER: 1

All done!

Source for SNMP configuration: http://net-snmp.sourceforge.net/tutorial/tutorial-5/demon/snmpd.html