GSM gateway con Asterisk + USB 3G utilizando "socat"

Muchas gracias a Cesar por dejarme escribir en su super-blog, yo quería hablaros de cómo utilizar una llave USB 3G con Asterisk. Las tarjetas GSM de Asterisk son bastante caras pero existe un projecto que se llama chan_dongle que permite utilizar un USB 3G como un "trunk" de Asterisk.

Utilizar un USB 3G con Asterisk es interesante para evitar los costes de roaming en países extranjeros, o cuando no hay acuerdos de roaming. Con un trunk GSM podemos recibir una llamada de móvil en un pais y encaminarla por internet hasta otro pais. Por ejemplo si estoy trabajando en Vietnam es muy posible que no haya acuerdos de roaming entre MoviStar y Vietnam-Télecom, pero la gente podría seguir llamándome à mi número MoviStar como si estuviera en España, y yo recibiría la llamada por internet.

Con dos llaves USBs, una en España y otra en Vietnam, junto con un abono móvil de Vietnam-Télécom, podría incluso recibir las llamadas de mi móvil español en mi móvil vietnamian. La persona que llama paga una llamada local, y la recepción se realiza al coste local del destino.

Un pequeño detalle es que mi centralita Asterisk se encuentra en un servido dedicado en OVH. Me resulta imposible conectar el USB 3G en mi servidor directamente. Sin embargo en mi casa tengo una BananaPi siempre encendida, y gracias a la funcionalidad del commando "socat", es posible hacer visible mi USB 3G como un puerto serie local del servidor OVH. En realidad exportamos el puerto serie de la BananaPi por internet.

Antes de utilizar el USB 3G hay que asegurarse que es un USB compatible, en la pagina oficial de chan_dongle (http://wiki.e1550.mobi/) podéis ver los detalles de la configuration. En realidad hay que hacer 3 cosas :

  • Desactivar el código PIN
  • Activar el servicio de voz
  • Actualizar el firmware à la última versión

Por supuesto, si queréis utilizar una tarjeta de Orange en una llave MoviStar, tendréis también que liberar la llave USB. El firmware no es obligatorio, pero se recomienda. Chan_dongle no funcionara si no activáis el servicio de voz y si no desactiváis el código PIN. Para todas estas gestiones podéis utilizar dc-unlocker (https://www.dc-unlocker.com/)

También hay que tener en cuenta que los USB 3G tienen una opción que permite almacenar el software en la propia llave. Linux por defecto monta el dispositivo como un disco USB. Para evitar esto hay que utilizar
el commando "usb_modeswitch".

Si todo va bien deberéis tener los siguientes dispositivos ttyUSB:

root@bananapi:~# ls -la /dev/ttyUSB* crw-rw---T 1 root dialout 188, 0 Aug 24 19:14 /dev/ttyUSB0 crw-rw---T 1 root dialout 188, 1 Sep 5 17:35 /dev/ttyUSB1 crw-rw---T 1 root dialout 188, 2 Sep 7 11:10 /dev/ttyUSB2

chan_dongle utiliza el ttyUSB1 para el audio, y el ttyUSB2 para los commandos AT del módem. No me preguntéis para qué sirve el ttyUSB0, no tengo ni idea :)

Para exportar el dispositivo serie por internet, he utilizado socat con UDP. He hecho pruebas con TCP, pero tenía problemas con los forks y casi se me bloquea la BananaPI. Como tengo la fibra en casa y hoy en dia casi no hay pérdidas de paquetes, creo que UDP es incluso mejor opción que utilizar TCP.

Aqui podéis ver los comandos de la parte servidor ejecutados en la BananaPI (no os olvidéis de abrir vuestro firewall) :
chmod 777 /dev/ttyUSB* /usr/bin/screen -d -m bash -c 'while true; do /usr/bin/socat udp-l:51000,reuseaddr file:/dev/ttyUSB1,raw,echo=0; echo "sleeping..."; sleep 30; done' /usr/bin/screen -d -m bash -c 'while true; do /usr/bin/socat udp-l:52000,reuseaddr file:/dev/ttyUSB2,raw,echo=0; echo "sleeping..."; sleep 30; done'

Es decir, el dispositivo ttyUSB1 es accesible a través del puerto 51000, mientras que el ttyUSB2 es accesible a traves del socket 52000. He metido el commandeo socat en un bucle infinito lo que me permite enchufar y desenchufar el USB 3G sin problemas.

En mi servidor Asterisk, utilizo "socat" en modo cliente para conectarme a estos puertos y simular el dispositivo serie :

/usr/bin/screen -d -m bash -c 'while true; do socat pty,link=/dev/ttyUSB1,raw,echo=0,unlink-close=0,mode=777 udp:freebox.tuxe.es:51000,reuseaddr; echo "sleeping..."; sleep 10; done' /usr/bin/screen -d -m bash -c 'while true; do socat pty,link=/dev/ttyUSB2,raw,echo=0,unlink-close=0,mode=777 udp:freebox.tuxe.es:52000,reuseaddr; echo "sleeping..."; sleep 10; done'

El commando socat con la opción "pty" crea un enlace simbólico /dev/ttyUSB1 que apunta hacia un dispositivo virtual que se crea dinámicamente y que se enlaza con el socket de la BananaPi. Si queremos ver lo que se recibe y se envia para vérificar que todo funciona correctamente es suficiente con añadir la option -v en ambos lados del commando socat.

Una vez que tenemos el USB 3G accesible desde nuestro servidor Asterisk, sólo nos queda compilar el chan_dongle. Desgraciadamente la version que yo he encontrado no es compatible con Asterisk 10.5 que es la version que yo utilizo, pero buscando en forums et conseguido encontrar un parche.

La version de chan_dongle que yo utilizo es esta : https://github.com/bg111/asterisk-chan-dongle.git

El parche que permite compilar chan_dongle en versiones de Asterisk iguales o superiores a la 10, os lo dejo aquí http://www.tuxe.es/chan-dongle-asterisk10.patch

Una vez instalado, tendreis que configurar el fichero /etc/asterisk/dongle.conf, en realidad no hay nada que cambiar salvo "the exten for start incoming calls" (exten), que hay que rellenar con el numéro de teléfono de la tarjeta SIM.

Si todo va bien, ejecutando "dongle show devices" deberías obtener una línea como esta :

tuxe*CLI> dongle show devices ID Group State RSSI Mode Submode Provider Name Model Firmware IMEI IMSI NUMBER dongle0 0 Free 17 5 4 Free E1752 11.126.03.01.314 353145XXXXXXX 20815XXXXXXXX Unknown

Para realizar llamadas, en la configuration del dialplan hay que poder algo como esto :

Dial(dongle/dongle0/${EXTEN},60,o)

Aqui os dejo un ejemplo para la recepción de llamadas :

exten => +34XXXXXXXXX,1,Dial(SIP/yonailo,30,ro) exten => +34XXXXXXXXX,n,Set(CHANNEL(language)=en) exten => +34XXXXXXXXX,n,VoiceMail(0980577477)

Incluso podemos recibir los SMS y enviarlos por correo !

exten => sms,1,Noop(Incoming SMS from ${CALLERID(num)} ${BASE64_DECODE(${SMS_BASE64})}) exten => sms,n,System(echo "${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME} - ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})}" >> /var/log/asterisk/sms.txt) exten => sms,n,System(echo "${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)} - ${DONGLENAME} - ${CALLERID(num)}: ${BASE64_DECODE(${SMS_BASE64})}" | /usr/sbin/sendmail [email protected]) exten => sms,n,Hangup()

Esto es todo amigos, espero que la explicación haya sido suficientemente clara. En el momento en el que os escribo la web de chan_dongle parece que no funciona (http://wiki.e1550.mobi/), allí encontrareis todo esto con mucho mas detalle, espero que vuelva pronto a la vida. Yo me despido de vosotros hasta el próximo post friki y os dejo como canción https://www.youtube.com/watch?v=UIizmkPIQzs