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.

Voice GSM Gateway: El poder del software libre

Si hay algo que me apasiona del mundo informático es la magnificencia que pueden llegar a alcanzar un sistema informático, cosa que a día de hoy no he logrado a encontrar en alguna otra rama del conocimiento (abogados, contadores, etc.) de igual manera algo que me fascina y hasta cierto punto me llena de éxtasis son los proyectos de software libre: si, esos proyectos sin ánimo de lucro (en la mayoría de los casos) que solo se realizan por el solo placer de hacer las cosas para el beneficio de la humanidad, pero sobre todo por satisfacción personal.

Un claro ejemplo de ello es asterisk un sistema que nos da la posibilidad de tener un sistema PBX a nuestra medida sin desembolsar un solo peso, ya que el mismo está basado en la filosofía de software libre. Si queremos darnos tan solo una idea de a lo que me refiero cuando mencione magnificencia, basta tan solo en plantear los costos que se conllevarían en implementar un PBX con tecnología asterisk que es software libre y un PBX con tecnología CISCO (si ese gigante del networking), donde este último resultaría ser más caro y nos llevaría a desembolsar presupuesto que no está al alcance de muchas pequeñas y medianas empresas, cosa diferente ocurre con un sistema basado en asterisk que puede ser implementado hasta con un equipo que pudiera ser rescatado del reciclaje. Como bien se observa la diferencia puede ser abismal.
Una vez planteado el panorama de los beneficios del mundo del software libre les platicare de un pequeño caso de éxito con software libre.

GSM Gateway con Asterisk

Resulta que me contacto una empresa Argentina (que por confidencialidad me reservare el nombre) que se veía en la necesidad de implementar un GSM Gateway para poder realizar llamadas. Después de varias búsquedas en google llego con mi post de: Como montar un telular en asterisk/Elastix. Su necesidad era poder enrutar llamadas (una media de 100 000 minutos mensuales) por medio de líneas celulares ya que los costos que se manejan hacia líneas celulares suelen ser bastante altos, por lo que planeaba sacar ese tráfico por SIM’s , en terminos practicos necesitaba un telular VOIP. Pero en mi tutorial yo solo realice la salida de tráfico por tan solo 1 linea sim y el por la cantidad de tráfico que necesitaba enviar iba a requerir al menos 20 canales de voz simultáneos.

Después de platicar a detalle con el me dijo las cosas sin “pelos en la lengua”, me dijo: cotice un equipo telular VOIP y es estúpidamente caro, cuesta alrededor $5000.00 USD (a día de hoy por el tipo de cambio en México serian $100000.00 MXN) y es un gasto que por ahora no puedo pagar. Por lo cual después de llegar a un acuerdo con el tema de mis honorarios como consultor procedimos a realizar la implementación.

He aquí lo maravilloso del mundo del software libre, gracias a foros, documentación oficial del proyecto asterisk y en general todos los blogs de geeks y apasionados de la informática fue como pudimos hacer funcionar su proyecto. El sistema quedo implementado bajo un sistema Ubuntu (si soy nena y que) con asterisk corriendo como núcleo, nuestro amado chan_Dongle y diversos modems Huawei banda ancha E303 con la función de voz activada. De igual manera se realizó la instalación del proyecto FreePBX en el servidor para poder brindar reportes de llamadas (CDR) algo fundamental si se tiene un call center y se desean medir resultados.

A continuación algunas fotografías del Gateway GSM:

GSM Gateway Server
GSM Gateway Server
chan_dongle
chan_dongle
chan_dongle asterisk-elastix
chan_dongle asterisk-elastix
VOIP GSM Gateway in asterisk
VOIP GSM Gateway in asterisk

Revisando el estado de nuestros modems Huawei E303 dentro de la consola de Asterisk:

asterisk-chan-dongle-huawei
asterisk-chan-dongle-huawei

Por lo cual: ¡amen por el software libre! Ademas, si tienes alguna duda o deseas contar con alguna implementación similar o simplemente algo no te sale como debiera funcionar no dudes en ponerte en contacto conmigo en la sección de contacto y con gusto te ayudare en lo que pueda.