Instalar chan_dongle en Isabel 4 con asterisk 11

Para los que no lo sepan Issabel PBX es el proyecto que continuo con el legado del extinto proyecto elastix, muchos colaboradores del anterior proyecto se sumaron en una nueva aventura y dieron forma a Issabel una solución PBX al mero estilo de Elastix: fácil de manejar e intuitiva en su configuración.

En este manual explicare como instalar chan_dongle para tener un Gateway GSM operativo al 100% en conjunto con Isabbel PBX, no entrare en tema en como instalar Issabel puesto que existen infinidad de manuales e internet para poder instalar Issabel, por lo cual, partiré que ya tienen Issabel PBX funcionando y con una sesión de root lista.

NOTA: A día de hoy Issabel PBX se encuentra en su version 47, que nos brinda la posibilidad de realizar la instalación con diversas versiones de asterisk, para este manual emplee la version 11 (como lo indica el título del manual).

issabel-pbx-4-chan_dongle
issabel-pbx-4-chan_dongle

Configurando e instalando chan_dongle en Issabel 4

Para comenzar con la instalación deberemos instalar algunas dependencias:

yum install git

Después dentro del directorio de /root/ (por practicidad) procederemos a clonar el repositorio de chan_dongle:

[root@issabel ~]# git clone https://github.com/wdoekes/asterisk-chan-dongle

Después empezaremos el proceso de compilación:

[root@issabel asterisk-chan-dongle]# ./bootstrap
configure.ac:6: installing './config.guess'
configure.ac:6: installing './config.sub'
configure.ac:7: installing './install-sh'
configure.ac:7: installing './missing'

Despues:

[root@issabel asterisk-chan-dongle]# ./configure --with-astversion=11.25.3
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... none
checking how to run the C preprocessor... gcc -E
checking for strip... strip
checking for rm... rm
checking for library containing iconv... none required

Despues:

[root@issabel asterisk-chan-dongle]# make
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT app.o -MF .app.o.d -MP -o app.o -c app.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT at_command.o -MF .at_command.o.d -MP -o at_command.o -c at_comman
d.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT at_parse.o -MF .at_parse.o.d -MP -o at_parse.o -c at_parse.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT at_queue.o -MF .at_queue.o.d -MP -o at_queue.o -c at_queue.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT at_read.o -MF .at_read.o.d -MP -o at_read.o -c at_read.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT at_response.o -MF .at_response.o.d -MP -o at_response.o -c at_res
ponse.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT chan_dongle.o -MF .chan_dongle.o.d -MP -o chan_dongle.o -c chan_d
ongle.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT channel.o -MF .channel.o.d -MP -o channel.o -c channel.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT char_conv.o -MF .char_conv.o.d -MP -o char_conv.o -c char_conv.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT cli.o -MF .cli.o.d -MP -o cli.o -c cli.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT helpers.o -MF .helpers.o.d -MP -o helpers.o -c helpers.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT manager.o -MF .manager.o.d -MP -o manager.o -c manager.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT memmem.o -MF .memmem.o.d -MP -o memmem.o -c memmem.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT ringbuffer.o -MF .ringbuffer.o.d -MP -o ringbuffer.o -c ringbuffe
r.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT cpvt.o -MF .cpvt.o.d -MP -o cpvt.o -c cpvt.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT dc_config.o -MF .dc_config.o.d -MP -o dc_config.o -c dc_config.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT pdu.o -MF .pdu.o.d -MP -o pdu.o -c pdu.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT mixbuffer.o -MF .mixbuffer.o.d -MP -o mixbuffer.o -c mixbuffer.c
gcc -g -O2 -O6 -Wno-old-style-declaration -I. -DAST_MODULE_SELF_SYM=__internal_chan_dongle_self -D_GNU_SOURCE -I/usr/include -I/usr/include -DHAVE_CONFIG_H -fvisibility=hidden -fPIC -Wall -Wextra -MD -MT pdiscovery.o -MF .pdiscovery.o.d -MP -o pdiscovery.o -c pdiscover
y.c
gcc -shared -Xlinker -x -o chan_dongle.so app.o at_command.o at_parse.o at_queue.o at_read.o at_response.o chan_dongle.o channel.o char_conv.o cli.o helpers.o manager.o memmem.o ringbuffer.o cpvt.o dc_config.o pdu.o mixbuffer.o pdiscovery.o

Despues:

[root@issabel asterisk-chan-dongle]# make install
strip chan_dongle.so
/usr/bin/install -c -m 644 chan_dongle.so /usr/lib64/asterisk/modules

Después una vez generado el modulo, procederemos a copiarlo al directorio de asterisk:

cp /root/asterisk-chan-dongle/etc/dongle.conf /etc/asterisk/

Después ingresaremos a asterisk y cargaremos el modulo recién compilado:

asterisk –rv
Connected to Asterisk 11.25.3 currently running on issabel (pid = 9216)
issabel*CLI> module load chan_dongle.so
Loaded chan_dongle.so
== Parsing '/etc/asterisk/dongle.conf': Found
[2020-01-31 12:37:05] NOTICE[11486]: chan_dongle.c:1588 reload_config: [dongle0] Loaded device
== Registered channel type 'Dongle' (Huawei 3G Dongle Channel Driver)
== Registered application 'DongleStatus'
== Registered application 'DongleSendSMS'
== Registered application 'DongleSendUSSD'
== Manager registered action DongleShowDevices
== Manager registered action DongleSendUSSD
== Manager registered action DongleSendSMS
== Manager registered action DongleSendPDU
== Manager registered action DongleSetCCWA
== Manager registered action DongleReset
== Manager registered action DongleRestart
== Manager registered action DongleStop
== Manager registered action DongleStart
== Manager registered action DongleRemove
== Manager registered action DongleReload

En este instante, deberemos conectar nuestro modem y en “teoría” debería de funcionar pero resulta que nos arroja un error:

[dongle0] Trying to connect on /dev/ttyUSB2...
[2020-01-31 12:37:35] ERROR[11487]: chan_dongle.c:137 lock_create: open('/var/lock/LCK..ttyUSB2') failed: Permission denied
[2020-01-31 12:37:35] WARNING[11487]: chan_dongle.c:222 opentty: unable to open /dev/ttyUSB2: No such file or directory
issabel*CLI>
-- [dongle0] Trying to connect on /dev/ttyUSB2...
[2020-01-31 12:37:50] ERROR[11487]: chan_dongle.c:137 lock_create: open('/var/lock/LCK..ttyUSB2') failed: Permission denied
[2020-01-31 12:37:50] WARNING[11487]: chan_dongle.c:222 opentty: unable to open /dev/ttyUSB2: No such file or directory
-- [dongle0] Trying to connect on /dev/ttyUSB2...
[2020-01-31 12:38:05] ERROR[11487]: chan_dongle.c:137 lock_create: open('/var/lock/LCK..ttyUSB2') failed: Permission denied
[2020-01-31 12:38:05] WARNING[11487]: chan_dongle.c:222 opentty: unable to open /dev/ttyUSB2: No such file or directory

Esto hace alusión a que el dispositivo /dev/ttyUSBX no puede ser accedido por asterisk, esto es un tema de permisos por lo que debemos de cambiarle permisos al dispositivo, esto lo logramos con:

[root@issabel asterisk-chan-dongle]# chmod 777 /dev/ttyUSB*

Donde después volveremos a ingresar a asterisk y nos percataremos que ya está funcionando y operativo nuestro modem:

-- [dongle0] Dongle has connected, initializing...
-- [dongle0] Dongle initialized and ready
issabel*CLI> dongle show devices
ID Group State RSSI Mode Submode Provider Name Model Firmware IMEI IMSI Number
dongle0 0 Free 27 0 0 weex E153 11.609.18.00.00 861435000361846 334030882534042 Unknown
issabel*CLI>
issabel*CLI>

Configurar Isabel vía Web para llamar a travez de chan_dongle

Ahora una vez que está configurado y cargado el módulo de chan_dongle procedemos a acceder a la interface web de Issabel para poder ejecutar llamadas a través de nuestro nuevo gateway GSM.

Lo primero que haremos será generar una extensión, esto lo realizaremos (como en el viejo Elastix) dentro de:

PBX > Configuración PBX > Extensiones > Añadir una extensión > Dispositivo SIP genérico > Enviar

No voy a explicar cómo crear una extensión dentro de Issabel/Elastix porque es algo bastante documentado en internet, pero solo mencionare que es fundamental tener presente el usuario/número de extensión y el password generado o el secret (como lo nombra Issabel).

extension-Issabel-PBX
extension-Issabel-PBX

Para validar que nuestra extensión configurada se registró de manera correcta en nuestro PBX veremos un mensaje como el siguiente en la consola:

Registered SIP '1337' at 172.16.151.1:59107
> Saved useragent "Z 5.3.5 rv2.9.26-mod" for peer 1337
[2020-01-31 15:19:51] NOTICE[9341]: chan_sip.c:23892 handle_response_peerpoke: Peer '1337' is now Reachable. (1ms / 2000ms)

Una vez que tenemos registrada nuestra extensión generaremos una troncal, esto lo realizaremos en:

PBX > Configuración PBX > Básico > Troncales > Añadir línea troncal personalizada

troncal-GSM-Issabel
troncal-GSM-Issabel

Donde los datos importantes serán el nombre de la troncal (para temas de identificación/control) y la “Cadena de marcación peronalizada”, que como vemos en la imagen es:

dongle/dongle0/$OUTNUM$

Esto es de suma importancia para que salgan las llamadas.
Después de realizado esto procederemos a generar una “Ruta Saliente” esto lo podremos efectuar desde:
PBX > Configuración PBX > Básico > Rutas Salientes > Añadir ruta

ruta-de-salida-Issabel-GSM
ruta-de-salida-Issabel-GSM

Donde los datos más importantes serán: “Dial Patterns that will use this Route” que básicamente es la coincidencia en la marcación, en este caso emplee un “punto” que nos dice que todo lo que se marque saldrá por ahí, de igual forma, otro campo importante es “Trunk Sequence for Matched Routes” que es la ruta que empleara para sacar el tráfico, en la imagen aparece seleccionada la troncal chan_dongle porque es así como nombre la troncal personalizada en el paso anterior.

Una vez efectuados todos los pasos que se mencionaron anteriormente, en la consola de asterisk podremos observar la correcta salida de las llamadas cuando marcamos a un número cualquiera des nuestra extension: 5556581111 (una dependencia de gobierno aquí en MX).

-- Goto (macro-dialout-trunk,s,29)
-- Executing [s@macro-dialout-trunk:29] Set("SIP/1337-00000000", "the_num=5556581111") in new stack
-- Executing [s@macro-dialout-trunk:30] Dial("SIP/1337-00000000", "dongle/dongle0/5556581111,300,T") in new stack
-- Called dongle/dongle0/5556581111
-- Dongle/dongle0-0100000000 is making progress passing it to SIP/1337-00000000
> 0x7f0a1c03bfd0 -- Strict RTP switching source address to 172.16.151.1:8000
> 0x7f0a1c03bfd0 -- Strict RTP learning complete - Locking on source address 172.16.151.1:8000
-- Dongle/dongle0-0100000000 answered SIP/1337-00000000

De esta forma ya tendríamos configurado chan_dongle e Issabel y se encontrarían listos para sacar cualquier cantidad de tráfico que deseemos. Para cualquier duda o comentario puedes escribirlo en la sección de comentarios y con gusto responderé. O en su caso en la sección de contacto si tu duda es muy específica.

Habilitar modems USB para ser ocupados con Chan Dongle

BAM-modemUSB-chan_dongle

A lo largo de mi blog existen algunos artículos que tienen más consultas que otras, donde uno de los top es justamente mi artículo que habla sobre montar un telular en asterisk (si no sabes de que va puedes visitar el articulo), donde en su tiempo trate de documentarlo de la mejor manera para que, si se seguía al pie de la letra la persona que lo realizara no tuviera problema alguno.

Lo interesante, es que hace poco me contacto una persona que tenía demasiados problemas para poder implementar la función CHAN_DONGLE en asterisk, ya que según parece omití muchas situaciones que considere obvias, por eso escribo este post, para acortar cada vez más la estrecha línea entre darse de topes contra la pared y lograr tener un equipo asterisk listo para realizar llamadas a través de los modem USB – BAM (Banda Ancha Móvil).

BAM-modemUSB-chan_dongle
BAM-modemUSB-chan_dongle

Como muchos sabrán las compañías telefónicas brindan modems USB para poder conectarse a internet, recibir SMS e incluso poder ocuparse como medio de almacenamiento (con su respectiva microSD instalada). Tan solo basta en conectar el dispositivo a nuestra computadora para que la misma lo reconozca como una unidad de CR-ROM, donde una vez instalado el software para la conexión a internet NUNCA JAMAS se volverá a conectar de ese modo (CD-ROM), para todas las veces futuras se conectara en modo MODEM, brindándonos asi el acceso para poder navegar por internet con el chip de nuestra compañía telefónica.

Hasta ahora muy bonito, pero: ¿Qué pasa si conectas el MODEM USB al sistema Linux donde planeas hacer funcionar CHAN_DONGLE? Pues sí, en efecto adivinaron; no funcionara ya que el modem sera reconocido como un CD-ROM y nunca podremos ocuparlo como modem.

Afortunadamente para este tipo de situaciones “alguien más” trabajo en la solución y creo el proyecto USB_MODESWITCH que básicamente hace justo eso que necesitamos, hacer que nuestro dispositivo sea reconocido como un modem para que nosotros podamos ya sea: ocuparlo con nuestro CHAN_DONGLE o en su caso ocuparlo con nuestro amado minicom para poder ingresarle comandos AT para “configurarlo” a nuestro gusto y de paso deshabilitar la opción CD-ROM para siempre y garantizar así que SIEMPRE inicie como modem.

Ahora, una vez puesto todo en contexto procederemos a ejemplificar el problema y como es que se llega a la solución.

Partiremos de que actualmente tenemos una banda ancha móvil (BAM=ModemUSB) y que deseamos realizar la configuración del modem en nuestro amado sistema GNU/Linux, lo primero que haremos después de conectarlo sera ingresar el siguiente comando para ver cómo fue que nos lo reconoció:

lsusb

Como podemos observar nos lo reconoció como un:

Huawei Technologies Co., Ltd. Broadband stick (modem on)

chan_dongle_lsusb
chan_dongle_lsusb

Lo curioso e interesante es que en el sistema donde se inserto dicho modem (un ubuntu) el mismo fue reconocido como un CD-ROM y no hay manera de pasarlo a modo modem, prueba de ello a continuación:

mass-storage-USBDongle
mass-storage-USBDongle

Ahora es aquí donde el proyecto usb_modeswitch hace acto de aparición y nos ayuda a “convertir” nuestro CR-ROM en un modem, para ello si no lo tenemos instalado, en un sistema basado en Debian con gestor de paquetes dpkg lo instalaremos con el siguiente comando:

apt-get install usb-modeswitch

Lo cual nos instalara el software en nuestro equipo, lo siguiente sera generar el archivo de configuración para que nuestro modem sea reconocido por el sistema. Para ello nos dirigiremos a la siguiente página.

Como podremos observar en esa página se encuentran infinidad de modems enlistados, la pregunta sería: ¿Cómo encontrar la configuración que es válida para nuestro modem? En mi caso es un modem Huawei E153. Si son observadores verán que a la salida del comando lsusb nos brindó un ID 12d1:1446 esa sera justo el ID que buscaremos en la página anterior donde la configuración válida para mi modem es:

# Huawei E1550
# Huawei E1750
#
# Contributor: Anders Blomdell, Ahmed Soliman

DefaultVendor= 0x12d1
DefaultProduct= 0x1446

TargetVendor= 0x12d1
TargetProduct= 0x1001

MessageContent=”55534243123456780000000000000011060000000000000000000000000000″

Dice que dicha configuración es válida para un modem E1550 y para un E1750, eso no importa ya que el ID Vendor y el IDProduct es el mismo, por lo cual nos funcionara sin problemas.

Tan solo nos restara copiar el contenido del archivo en: /etc/usb_modeswitch.d/e153 , ese directorio no es obligatorio y yolo emplee para mantener el “orden” en mi equipo.

Posteriormente ejecutaremos el siguiente comando:

usb_modeswitch -c /etc/usb_modeswitch.d/e153

Con esto ya tendremos listo nuestro modem para ser utilizado como MODEM y en teoría con esto deberíamos poder ocuparlo sin problemas para realizar llamadas con nuestro CHAN_DONGLE (si no sabes a qué me refiero, lee el artículo que menciono al principio del articulo).

usb_modeswitch-chan_dongle
usb_modeswitch-chan_dongle

Ahora tan solo nos restara deshabilitar la función de CD-ROM para SIEMPRE y dejar la función solo modem habilitada, para ello nos auxiliaremos de minicom:

minicom -c on -D /dev/ttyUSB5

Y después ingresaremos este comando AT:

AT^U2DIAG=0

Con esto nuestro modem para las próximas veces que sea ocupado, independientemente de la computadora donde sea conectado se conectara solo como modem 🙂 .

Si tienes dudas o comentarios o simplemente tu proyecto no funciona, con gusto te puedes poner en contacto conmigo en la sección de contacto.