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/