lunes, 25 de junio de 2012

KANNEL - Celular

Desconectar y conectar el celular de nuestro linux

El software que utilizamos para el envio es KANNEL un software muy completo y profesional que he utilizado en varias ocasiones para conexiones SMPP contra centros de mensajería de operadoras móviles (servic SMS). En este caso funciona como Gateway entre una aplicación WEB y el celular antes mencionado.
Sin embargo existe un problema, si por diferentes motivos necesitamos desconectar el celular para luego volverlo a conectar es necesario reconfigurar el kannel y reiniciar.
Esto pasa porque kannel está ocupando el nombre de archivo original que representaba al dispositivo (/dev/ttyACM0) y este no se borra cuando desconectamos el celular, entonces al volverlo a conectar crea uno nuevo (/dev/ttyACM1) y pierde la comunicación con kannel.

Conexión del Kannel al celular.

Kannel se conecta a través de comandos AT obviamente se comunica con el celular a través del archivo de dispositivo que se genera en /dev/. Por ende es necesario configurar en kannel el dispositivo con el que debe hablar. El problema cuando se desconecta el celular es que kannel sigue corriendo y ocupando ese archivo y cuando el celular se vuelve a conectar éste cambia de nombre por lo que kannel está conectado con “otro” dispositivo y no utiliza el celular.
Pero además en caso de que el celular siempre conectara con el mismo nombre de archivo es necesario avisarle a kannel que reinicie la conexión con ese dispositivo pues quedaría colgado utilizando una conexión que ya no existe. Es por eso que debemos resolver dos problemas:
1- Que podamos acceder al celular utilizando un único nombre de archivo.
2- Que kannel reconecte si el celular es desconectado y conectado de nuevo.
Para eso vamos a configurar Kannel con las siguientes líneas (en el grupo smsc donde se configura el contacto con el modem):
group = smsc
smsc = at
modemtype = auto
max-error-count = 3
device = /dev/celular
speed = 0
keepalive=10
Nos interesan las líneas device, y keepalive. En device puse un nombre fijo que será un enlace simbólico /dev/celular al nombre de dispositivo que se cree cuando se conecte el celular via USB (así siempre usamos este y no necesitamos estar cambiando el dispositivo en la conf de kannel cada vez que conectemos el celular). Con keepalive le decimos a kannel que se fije si el celular responde (en nuestro caso cada 10 segundos), de no hacerlo kannel intetará conectarse nuevamente con /dev/celular.

Utilizando UDEV para crear el enlace simbólico cuando conectamos el dispositivo.

Udev es el gestor de dispósitivos que utiliza el kernel de linux. Tiene un sistema de reglas que nos permite hacer muchísimas cosas que nos facilitan la vida con dispositivos de todo tipo (como en este caso con un celular que se conecta a través de USB). Entonces lo que vamos a hacer es identificar cuando conectamos el celular y decirle a undev que cree un enlace simbólico. Primero miro las características del celular (se que se conecta en ttyACM por mirar en messages cuando lo conecto al puerto USB). Busco en cual directorio se encuentra el dispositivo para poder estudiarlo:
find /sys/ -name dev | grep ACM

/sys/class/tty/ttyACM0/dev
Ahora veo las características del dispositivo:
[root@localhost ~]# udevinfo -a -p /sys/class/tty/ttyACM0

Udevinfo starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

looking at device '/class/tty/ttyACM0':
KERNEL=="ttyACM0"
SUBSYSTEM=="tty"
SYSFS{dev}=="166:0"

looking at parent device '/devices/pci0000:00/0000:00:10.3/usb5/5-1/5-1:1.0':
ID=="5-1:1.0"
BUS=="usb"
DRIVER=="cdc_acm"
SYSFS{modalias}=="usb:v04E8p687Cd0100dc02dsc00dp00ic02isc02ip01"
SYSFS{bInterfaceProtocol}=="01"
SYSFS{bInterfaceSubClass}=="02"
SYSFS{bInterfaceClass}=="02"
SYSFS{bNumEndpoints}=="01"
SYSFS{bAlternateSetting}==" 0"
SYSFS{bInterfaceNumber}=="00"

looking at parent device '/devices/pci0000:00/0000:00:10.3/usb5/5-1':
ID=="5-1"
BUS=="usb"
DRIVER=="usb"
SYSFS{configuration}==""
SYSFS{product}=="USB VCom Port "
SYSFS{manufacturer}=="SAMSUNG Electronics Co.,Ltd "
SYSFS{maxchild}=="0"
SYSFS{version}==" 1.10"
SYSFS{devnum}=="33"
SYSFS{speed}=="12"
SYSFS{bMaxPacketSize0}=="64"
SYSFS{bNumConfigurations}=="1"
SYSFS{bDeviceProtocol}=="00"
SYSFS{bDeviceSubClass}=="00"
SYSFS{bDeviceClass}=="02"
SYSFS{bcdDevice}=="0100"
SYSFS{idProduct}=="687c"
SYSFS{idVendor}=="04e8"
SYSFS{bMaxPower}=="500mA"
SYSFS{bmAttributes}=="80"
SYSFS{bConfigurationValue}=="1"
SYSFS{bNumInterfaces}==" 2"
Identifico que es tty y el nombre de manufacturer (con esto se que voy a identificar a ese celular y no a cualquier dispositivo que utilice ttyACM). Entonces ahora que tengo estos datos creo la regla en /etc/udev/rules.d/celular.rules:
SUBSYSTEM=="tty", SYSFS{manufacturer}=="SAMSUNG Electronics Co.,Ltd ", SYMLINK+="celular"
Con esta regla digo que cuando se conecte un dispositivo al subsistema tty cuyo nombre de manufacturador (SYSFS{manufacturer}) sea el del celular, cree un enlace simbólico llamado celular (si el nombre de manufacturador del dev es otro no lo crea).
Ahora testeamos y:
[root@localhost rules.d]# ll /dev/celular
lrwxrwxrwx 1 root root 7 Sep 9 01:30 /dev/celular -> ttyACM0
Lo creó, ahora vemos si el kannel retomó bien con el keepalive:
2011-09-09 01:30:15 [21199] [6] INFO: AT2[/dev/celular]: opening device
2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: device opened. Telnet mode = 0
2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: device opened
2011-09-09 01:30:15 [21199] [6] INFO: AT2[/dev/celular]: Logging in
2011-09-09 01:30:15 [21199] [6] INFO: AT2[/dev/celular]: init device
2011-09-09 01:30:15 [21199] [6] INFO: AT2[/dev/celular]: speed set to 115200
2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: --> ATZ^M
2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: 2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: AT^M
2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: 2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: AT&F^M
2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: 2011-09-09 01:30:15 [21199] [6] DEBUG: AT2[/dev/celular]: ATE0^M
2011-09-09 01:30:16 [21199] [6] DEBUG: AT2[/dev/celular]: 2011-09-09 01:30:16 [21199] [6] DEBUG: AT2[/dev/celular]: AT+IFC=.
Perfecto, funciona maravillosamente. Ahora podemos desconectar y conectar el celu cuando queramos que siempre va a funcionar sin tener que estar pendientes del kannel. En breve pondré un mini tutorial de undev para aquellos que desconozcan como crear reglas, en prncipio no es mucho mas dificil de lo que hicimos ahora y está mas que claro en la documentación que viene por defecto.

Special Thanks:  

agulean    http://develoblog.com/tag/kannel/

 

No hay comentarios:

Publicar un comentario