Interfaceando GTK + SNMP + Lintouch

Há algum tempo atrás fiz um programa para controlar um velocimetro no Lintouch, o objetivo era ter o servidor SNMP pegando dados de um programa visual (GTK) e enviando estes mesmos dados para visualização no Lintouch.

Como tudo que não é documentado se perde, resolvi discutir a implementação aqui.
O MIB é simples:

UFRGS-MIB DEFINITIONS ::= BEGIN

IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, Integer32,
Counter32, IpAddress, enterprises FROM SNMPv2-SMI
MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF;
--
-- A brief description and update information about this mib.
--

ufrgs MODULE-IDENTITY
LAST-UPDATED "0104010000Z" -- 01 Apr 2001, midnight
ORGANIZATION "UFRGS"
CONTACT-INFO
" Author: Alan Carvalho de Assis
UFRGS, Departamento de Engenharia Eletrica
Av. Oswaldo Aranha
Porto Alegre
BRAZIL
email: acassis@gmail.com
tel: +55-051-3316-3561"

DESCRIPTION "MIB Agent for Baja-by-Wire"
::= { enterprises 12619 }

-- the meters group
meters OBJECT IDENTIFIER ::= { ufrgs 1 }
reserved OBJECT IDENTIFIER::= { ufrgs 2 }

--
-- The Speed (to speedometer)
--
speed OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The speed variable."
DEFVAL { 0 }
::= { meters 1 }

--
-- The RPM (to tachometer)
--
rpm OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The engine rotation variable."
DEFVAL { 0 }
::= { meters 2 }

--
-- The temperature variable
--
temperature OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-write
STATUS current
DESCRIPTION
"The engine temperature."
DEFVAL { 0 }
::= { meters 3 }

END

Na inicialização do MIB (init-ufrgs) eu crio uma área de memória compartilhada:

typedef struct {
int speed;
int rpm;
int temperature;
}meter;

#define SHM_SIZE 12  /* 12 bytes (meter struct size) */

static u_long speed;
static u_long rpm;
static u_long temperature;

meter *m;

void init_ufrgs(void)
{
static oid speed_oid[] = { 1,3,6,1,4,1,12619,1,1 };
static oid rpm_oid[] = { 1,3,6,1,4,1,12619,1,2 };
static oid temperature_oid[] = { 1,3,6,1,4,1,12619,1,3 };

key_t key;
int shmid;
int *data;
int mode;
FILE *f;


/* create the identifier file*/
if((f=fopen("/tmp/meter","w")) == NULL)
{
perror("fopen");
exit(1);
}

/* close it*/
fclose(f);

/* make the key: */
if ((key = ftok("/tmp/meter", 'R')) == -1) {
perror("ftok");
exit(1);
}

/* connect to (and possibly create) the segment: */
if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) {
perror("shmget");
exit(1);
}

/* attach to the segment to get a pointer to it: */
data = shmat(shmid, (void *)0, 0);
m = (meter *) data;

if (data == (int *)(-1)) {
perror("shmat");
exit(1);
}


DEBUGMSGTL(("ufrgs", "Initializing\n"));

}

E na requisição MODE_GET de cada variável lemos o valor que nos foi enviado pela aplicação GTK (discutida abaixo):

case MODE_GET:

speed = (u_long) m->speed;
snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, (u_char *) &speed, sizeof(speed));
break;

Na aplicação GTK abrimos a região de memória (mesmo código de init_ufrgs) compartilhada e escrevemos os valores lidos dos sliders:

void on_hscale1_value_changed(GtkRange *range, gpointer user_data){
gdouble vel;
vel = gtk_range_get_value(range);
m->speed = (int)vel;
}


void on_hscale2_value_changed(GtkRange *range, gpointer user_data){
gdouble rot;
rot = gtk_range_get_value(range);
m->rpm = (int)rot;
}


void on_hscale3_value_changed(GtkRange *range, gpointer user_data){
gdouble temp;
temp = gtk_range_get_value(range);
m->temperature = (int)temp;
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s