asterisk mal aterrizaje

Asterisk 13 ya esta apunto de aterrizar

asterisk 13 mal aterrizajeComo viene siendo ya costumbre en este blog en los últimos años, quiero anunciar que ya queda muy poco para que desembarque la nueva versión LTS, Asterisk 13 y esta vez, no viene excesivamente cargada de novedades. Quizá las mas esperadas por muchos van a seguir sin cubrirse. Aquí voy a hacer un breve resumen de que podemos atenernos en los próximos meses:

(Toda la información esta disponible en la wiki oficial)

En primer lugar, como no podía ser menos, vamos a hablar de la novedad estrella: ARI (Asterisk REST Interface)

Por fin podemos realizar llamadas a Asterisk 13 de manera externa, desde un servidor sin necesidad de tener que monitorizar resultados de la antigua Asterisk Manager Interface (que curiosamente también ha sido BASTANTE mejorada, añadiendo nuevos métodos y acciones a la larga lista de ya existentes).

Hay que tener en cuenta que eventualmente se puede hacer el 90% de la funcionalidad alcanzada a través de un dialplan corriente, aplicando este tipo de interfaces (como la AMI), pero todavía falta para poder llegar a cubrir el 100%. Afortunadamente poder cubrir con una interfaz REST dota de muchísima versatilidad al sistema, especialmente considerando que hoy en día, estamos hablando que estos sistemas son más un framework que un sistema standalone (o los famosos Servidores de Aplicaciones IMS). La verdad es que tengo muy descuidado el blog y lo reconozco, pero me apunto para hacer lo antes posible, un breve tutorial sobre el uso del ARI con un ejemplo práctico

Alguna funcionalidad destacable de Asterisk 13

Entre la nueva funcionalidad de Asterisk 13 más de campo tenemos:

  • Se ha mejorado el soporte de chan_dahdi al SS7
  • Se ha mejorado el soporte al nuevo stack SIP pjsip
  • Ahora necesitamos libxml2-dev para el menuselect
  • Voicemail ahora soporta el japones
  • Confbridge sigue evolucionando en detrimento del antiguo Meetme, y Directory sigue vivo
  • Varias aplicaciones como Chanspy ya se benefician del UniqueID
  • Atención también a la nueva especificación de CDR y CEL heredada de la versión estandar Asterisk 12

Finalmente como punto negativo, quiero destacar que no se ha prestado demasiada atención a la compatibilidad de Asterisk con las nuevas tecnologías WebRTC y los últimos cambios presentados por el estandar. Tampoco hay ninguna novedad sobre el soporte de OPUS que habían anunciado que para Asterisk 13 estaría resuelto lo que me resulta un disgusto bastante grande, más considerando que ya tendremos que esperar posiblemente a la próxima LTS Asterisk 15 para poder ver todo esto integrado en condiciones… si es que llega. Sinceramente, creo que se esta dando muchisimas vueltas con respecto al codec OPUS y la violación de las licencias como ellos justifican, realmente no es del todo cierta y habido bastante polémica en las listas al respecto. Veremos como evoluciona en el 2015 este asunto, bajo mi punto de vista, no haber tratado esto con prioridad da la sensación que la llegada de Asterisk 13 con un sistema WebRTC totalmente disfuncional es más bien un aterrizaje forzoso

Si estais interesados en que haga alguna review de algún aspecto en concreto de Asterisk, comentadme y lo voy viendo!

raspberry pi domotica razberry z-wave

Domotica, Asterisk, Smart Metering y el Internet de las Cosas

Dado que este blog está cogiendo ciertos tintes de orientación del Sistema Asterisk, para entornos caseros o en el mejor de os casos, las pequeñas y medianas empresas, he pensado que sería bastante interesante empezar a introducir terceras aplicaciones relacionadas al mundo de la domotica, automatización de sistemas en casa (y en la oficina), y todo gestionado más allá de la tecnología software convencional como podrían ser las aplicaciones de los Smartphones y los entornos web.

domotica asterisk

Todo mi interés ha surgido a raíz del Tarifazo eléctrico acontecido recientemente en España, y el incremento de la factura de la luz en un porcentaje significativo (Sumado a los altos consumos de Inverno relativos al uso de sistemas de calefacción). Esto me ha llevado a investigar acerca de alguna posible opción domotica para controlar el consumo eléctrico con los populares Smart Meters (medidores Inteligentes de consumo). A esta práctica se le llama “Smart Metering” y en el entorno Demótico está totalmente en Auge.

Soluciones de Smart Metering para nuestro futuro sistema de Domotica

Después de revisar miles de opciones bastante costosas como IPDomo Energy Socket Meter, uno de los pocos dispositivos capaz de medir el consumo de un dispositivo en concreto y enviar la información vía Wifi (a un precio excesivo si cabe >180 euros), y la alternativa, control desde el Cuadro Eléctrico del consumo integral del domicilio, con E2 Efergy, empecé a tantear otras opciones basadas en protocolos propietarios de comunicación tales como la solución de ClienSol, EnviR, unido al módulo de conexión a internet, más un Enchufe con Sensor Inalámbrico por un total de cerca de 180 euros también, siendo toda la comunicación propietaria, y con montones de dispositivos de por medio).

En este momento descubrí los protocolos de comunicación “Inalámbricos” para la domotica (que hasta la fecha solo conocía los cableados como X10), y se presentó ante mí una de las apuestas fuertes, Zigbee, con el sistema Enistic Single Socket Smart Meter, que también tenía un alto coste (módulos más recibidor, etc…). Este fue el momento que estaba a punto de desechar la idea, porque consideraba que montar soluciones de estas características eran excesivamente costosas. Las aplicaciones con sistemas “Open Source” como Arduino eran totalmente rudimentarias, y muy poco fiables, lo que hizo en mí que las desechase prácticamente desde los inicios.

Pero de pronto me topé con una presentación del último evento Voip2Day 2013 sobre domotica, al que no pude Asistir, de Alberto Sagredo:

En esta presentación curiosamente, hace referencia a Z-Wave como otro estándar de comunicaciones para domotica, el cual está siendo ampliamente aceptado, y dispone de una cantidad de dispositivos increíblemente grande. Y concrétamente hubieron dos dispositivos que me llamaron especialmente la atención: Fibaro Wall Plug y RazBerry, y concrétamente este último porque se considera una placa para Raspberry Pi que permitiría una integración con un sistema como Asterisk en el mismo dispositivo y servir como servidor de comunicación para la intercomunicación con este dispositivo de Z-Wave.ME

De momento he realizado el pedido de estos dos dispositivos de domotica para empezar a probarlos. Tal y como ha hecho Alberto Sagredo en su presentación (que en su caso aplica los casos de uso entre Asterisk y un Controlador Z-Wave de la marca Zipato el modelo ZipaBox cuyo coste de 200 euros no es desdeñable, dentro de la franja de otros controladores Entry-Level como Vera Lite Smart Home Controller

Asterisk con Websockets para WebRTC y probando SIPML5

ATENCIÓN: Este artículo ya no es útil puesto que Chrome en su versión 35 en adelante ha pasado su sistema de encriptación para WebRTC de SDES a SRTP/DTLS como estaba planificado desde principios de Enero 2014. Este articulo definía el metodo para montar un sistema Asterisk basado en este sistema. Cuando salga la resolución definitiva en Asterisk creare otro articulo para explicar como configurar con Asterisk este sistema

Volviendo a la carga con Artículos sobre Asterisk, voy a explicar algo que aunque ya está algo visto, ha sido parte de mi experiencia y como viendo haciendo hasta ahora intento explicarlo con el mayor número de detalles

Hay que considerar que en este momento estoy trabajando con la versión CERT de Asterisk concretamente la versión 11.6-cert1

webrtc asterisk

Preparando la instalación del Sistema Asterisk para WebRTC

En primer lugar, sería conveniente tener soporte para el códec OPUS que es una de las claves que WebRTC utilizan de forma nativa y quizá sea de las principales ventajas de su uso.

Si no tenemos autoconf necesitamos instalarlo y también hará falta libtool y pkg-config

# apt-get install autoconf libtool pkg-config

ATENCIÓN (Con Asterisk  >11.6) si compilamos con soporte OPUS habrá un problema de AUDIO (Issue en Git de Meetecho: https://github.com/meetecho/asterisk-opus/issues/6). Por eso este paso de instalación de Opus en este tipo de versiones, seria conveniente saltárselo de momento a partir de aquí:

Para ello lo podemos descargar desde el repositorio GIT de este proyecto. Tenemos que descargar este fichero en el directorio raíz donde esta el código de Asterisk listo para ser compilado.

#wget https://raw.github.com/meetecho/asterisk-opus/master/asterisk_opus+vp8.diff

Desde ahí lanzamos el parche

# patch -p1 -u < asterisk_opus+vp8.diff

Y a continuación preparamos el sistema para que pueda instalarse el códec OPUS:

# ./bootstrap.sh

En mi caso, trabajando con Ubuntu Server 12.04, me hace falta instalar la librería Opus en el sistema, que no viene en los repositorios de Ubuntu por defecto:

# apt-get install python-software-properties
# add-apt-repository ppa:ubuntu-sdk-team/ppa
# apt-get update
# apt-get install libopus-dev

Después de instalar el códec OPUS pasamos a instalar el resto de las dependencias para su funcionamiento

También nos hará falta la librería libsrtp0-dev para gestionar la encriptación de las conexiones WebRTC y las librerias de Universally Unique Identifier, uuid-dev (este último es específico la versión 11 de Asterisk y su no instalación provocaría problemas en la comunicación con ICE, y aunque la llamada entraría en el sistema, no se escucharía nada por una cuestión de RTP) . Podemos instalarlas directamente desde los repositorios del sistema:

# apt-get install libsrtp0-dev libsrtp0 uuid-dev

Con todo preparado realizamos la instalación de Asterisk

# ./configure --with-crypto --with-ssl --with-srtp=/usr/lib

Finalmente seleccionamos el códec Opus y Formato VP8 con make menuselect (Codec Translators -> códec_opus y Format Interpreters -> format_vp8)

Por otro lado, para instalar nuestro sistema websockets en Asterisk primero deberemos instalar el Recurso HTTP Websocket. Esto se realiza durante la instalación de Asterisk (make menuselect) en la sección Resource Modules, y cuyo nombre es res_http_websocket

También se recomienda por cuestiones de calidad, seleccionar los paquetes musicales tanto los mensajes de Asterisk como los de Music On Hold en formato SLN16 (CORE-SOUNDS-ES-SLN16, MOH-OPSOUND-SLN16 y EXTRA-SOUNDS-EN-SLN16)

Y ya podemos compilar Asterisk con todo el soporte necesario

# make && make install

Configurando Asterisk y Websockets

A partir de aquí ya tenemos el sistema preparado para ser configurado simplemente. En primer lugar configurador el servidor HTTP de Asterisk desde el fichero http.conf

[general]
enabled=yes
bindaddr=0.0.0.0
bindport=8088

A continuación pasamos a configurar el soporte ICE y STUN en el fichero RTP.conf para ello añadimos las líneas dentro de la etiqueta [general]

icesupport=true
stunaddr=stun.l.google.com:19302

Finalmente pasamos a configurar un peer SIP para que soporte la comunicación con WebSockets. En el fichero sip.conf dentro de la etiqueta [general]:

allowguest=no
udpbindaddr=0.0.0.0:5060

Y creamos una extensión con los siguientes parámetros

[extension1]
secret=miclavesecreta
transport=udp,wss,ws
encryption=yes
avpf=yes
icesupport=yes
directmedia=no
host=dynamic
nat=force_rport,comedia
qualify=yes // opcional
type=friend
context=phones

Con todo esto solo necesitaremos configurar en nuestro servidor Web un softphone basado en WebRTC y que soporte WebSockets (esto es opcional, si tenemos publicado el servidor SIP el webphone RTC se conectaría directamente, los websockets serían utiles en caso que definieramos en el sip.conf un nombre al dominio (con la propiedad realm) y conectáramos a este realm a traves de una conexión con Websockets (otra de las claves principales de WebRTC junto al Codec OPUS). Por ejemplo,supongamos la dirección pública de nuestro servidor es 123.123.123.123 y hemos abierto el puerto 8088 (del servidor HTTP de Asterisk para habilitar los Websockets). Configuramos en el fichero sip.conf,

[general]
realm=10000horas.com

Ahora en el softphone configuramos (por ejemplo SIPML5, aunque pongo otras opciones más adelante):

Private Entity: la extensión usada, en este caso extension1
Publc Entity: sip:extension1@10000horas.com
Password: la_password_de_la_extension
Realm: 10000horas.com

Y en el apartado “Expert” debemos configurar la dirección a la que apunta el Websocket. Usando comunicación Websockets sin encriptar:

Websocket Server URL: ws://123.123.123.123:8088/ws

Así estableceríamos la conexión en vez de directamente al servidor SIP, lo haríamos gracias al servidor WebSocket, lo que es bastante provechoso y podríamos llegar a incrementar la seguridad del sistema (considerando que tener el Puerto 5060 a libre albedrío es peligroso, aunque no todos opinan lo mismo)

Disponemos de varias opciones entre las más populares SIPML5 y JsSIP. De todas formas si tenemos el servidor delante de un firewall o hemos gestionado los puertos correspondientes podríamos hacer una prueba desde cada uno de los sistemas:

SIPML5: http://sipml5.org/call.htm
JsSIP: http://tryit.jssip.net/

Espero que os haya servido, os recomiendo el cliente de escritorio Phoner Lite (http://phonerlite.de/index_en.htm) si queréis hacer pruebas ya que es de los pocos Softphones que dispone del códec OPUS por defecto.

Asterisk WIKI en el CUSL

logo

Como el año pasado WIKIAsterisk no pudo acceder al Concurso Universitario de Software Libre porque este había acabado cuando el proyecto empezó, he decidido acceder al concurso de este año. Además como en la actualidad me encuentro cursando un Master Oficial en la Universidad de Sevilla, pues tengo permitido el acceso a dicho Concurso.

http://www.concursosoftwarelibre.org

Con el acceso, tengo intención de agregar nuevos elementos a la WIKIAsterisk, tenía dos proyectos en mente: Uno relacionado a Asterisk SCF y otro relacionado al desarrollo orientado a Asterisk. La verdad es que no me encuentro muy ducho en ninguno de estos dos campos, pero como Asterisk SCF fue abandonado hace relativamente poco, pues el único tema que me queda pendiente es el de desarrollo. Me gustaría aprovechar esta actualización de la WIKI para ahondar en mis conocimientos sobre el sistema Asterisk, y acceder a un mundo hasta la fecha totalmente desconocido para mi.

En estos momentos estoy tanteando por donde empezar. Hace poco tenía intención de publicar un mensaje relativo a chan_mobile mostrando como configure mi movil Android con mi maquina Asterisk para cursar llamadas, pero este post no llegó a ver la luz por una sencilla razón: Nunca me llego a funcionar. Teóricamente chan_mobile ha estado ofreciendo una resistencia al sistema desde la versión 1.8 de Asterisk, pero para mi resulta bastante incierto si el problema era raíz del modulo Bluetooth, de la versión Android (4.1) o simplemente de la versión del máquina Asterisk. Quizá un primer acercamiento al mundo de la programación de Asterisk sería la posibilidad ahondar en la programación de este módulo de Asterisk, de todas formas si alguien que lea este blog y tenga experiencia en este tema desea ser mi Mentor le estaré ampliamente agradecido 🙂

Por aquí pasa el proceso de aprendizaje, como el nombre del blog indica: 10000 Horas hacen falta para adquirir la Maestría en algo. Y ya vamos por el buen camino de alcanzarlas en lo relativo a Asterisk.

Seguiré informando sobre futuras novedades sobre esta nueva aventura, y sobre lo relativo a este Concurso.

Asterisk 11: Nueva version LTS

 

Finalmente, tras pasar un par de años desde el lanzamiento de la ultima version LTS de Asterisk (la version 1.8), acaba de salir (sin anunciarse) la version final de Asterisk 11.

En los proximos meses es probable que salga la version Asterisk Certified dentro de Asterisk 11, asi que de momento, no creo que sea buena idea actualizarse a esta version, especialmente como suele decirse en estos casos, dentro de los entornos de produccion.

Pero Asterisk 11 trae una serie de mejoras que merece la pena comentar:

  1. A partir de la version 10 de Asterisk, aunque ya existia, se pretendia estandarizar el uso de la nueva version para Conferencias ConfBridge ante un MeetMe ya obsoleto. Parece que ya la version 11 es un buen momento para empezar a utilizar esta aplicacion y dar de lado la antigua. Recordar que ConfBridge tiene como principal ventaja, que no necesita una fuente de sincronizacion, es decir, que no necesitamos DAHDI para hacerla funcionar.
  2. Resurge la compatibilidad con Google Talk y Jingle de la mano de un Channel Driver llamado chan_motif.
  3. Se ha mejorado al maximo la compatibilidad con Telefonos IP UNIStim antiguamente pertenecientes a Nortel (ahora Avaya). ¿Que ventaja parece ser que tienen estos telefonos? Que segun Digium pueden encontrarse a precios muy baratos (yo no los he visto, si conoceis alguno, comentadlo)
  4. Esto no es nuevo de la version 11 sino de la 10, pero AstDB ya no es de tipo Berkeley DB sino ahora es SQLite, no afecta a efectos practicos pero siempre es bueno saberlo
  5. Para los que utilizan el protocolo XMPP (Jabber para los amigos) en presencia, considerar que muere el Recurso res_jabber y ahora se llama res_xmpp, a efectos, al ser un recurso da igual porque encima es retrocompatible no hay que modificar nada para que todo siga funcionando tal como estaba antes, pero tambien es bueno saberlo
  6. Ahora es mas facil seguir las llamadas dentro de la CLI y los logs porque se ha añadido un parametro que es el ID de Llamada (que no el Caller ID). Con este ID de llamada, si hay varias llamadas entrantes simultaneamente, podremos seguir los pasos de cada llamada, aunque se solapen con otras. Muy practico en situaciones donde hay decenas o cientos de llamadas simultaneas.
  7. Parece que la compatibilidad con IPv6 sigue avanzando, y ahora lo soportan muchos mas modulos de Asterisk, como Asterisk Manager Interface (AMI) y Asterisk Gateway Interface (AGI).
  8. Tambien va a haber soporte para ICE dentro de la configuracion SIP. Esto creo que es fundamental considerando que las comunicaciones SIP siguen siendo el principal caballo de batalla de Asterisk.
  9. Ya supuestamente, hay compatibilidad con websockets desde Asterisk. Necesito probarlo para creerlo, porque definitivamente esto va a ser un paso adelante cuando WebRTC se estandarice en los navegadores por completo
  10. Como el proyecto OpenAIS fue abandonado definitivamente (sistema de Alta Disponibilidad y Clustering para servidores Linux), CoroSync ha tomado el relevo. Eso significa que el Recurso OpenAIS (res_ais) pasa a llamarse res_corosync. Esto es un sistema poco comentado a nivel de Alta Disponibilidad entre la comunidad Asterisk, pero creo que merece la pena ser profundizado un poco en un futuro.

Recordar un tema importante acerca del nuevo sistema de Versiones de Asterisk que ha sufrido grandes cambios en estos dos ultimos años. La politica de actualizaciones de Digium se basa en dos niveles:

  •  Primero se saca una version “Estandar”, que en cierto sentido, no suele ser recomendada para entornos de alta produccion. Podria considerarse una version “Beta” de la versión que vendra a continuacion. Hasta hace poco coincidian estas versiones con numeros Impares (Asterisk 1.5, Asterisk 1.7…) pero como Asterisk ha dado un salto para eliminar el 1 de la version, y pasar directamene al segundo digito, pues de ahora en adelante coincidira con las versiones pares (Asterisk 10, Asterisk 12, Asterisk 14…). Se ve que esta de moda que el software haga referencia a Versiones con un numero Alto (vease Chrome y Ubuntu, seguido de Firefox que ha hecho como 5 versiones en 2 años de un golpe).
  •  A partir de cada Version Estandar, se va forjando una Version LTS, que a partir de ahora ira en numeros impares (Asterisk 11, Asterisk 13…) cuando antiguamente eran las versiones pares (Asterisk 1.4, Asterisk 1.6, Asterisk 1.8). Desde Asterisk 1.8 se anuncio que dentro de una subversion bastante estable del sistema, saldra un “Branch” que no mejorara en funcionalidad, sino exclusivamente en estabilidad y segurida. A esta version se le llamara Asterisk Certified.

Yo desde aqui, recomiendo que para entornos de produccion os quedeis con una version Asterisk Certified siempre. Es donde Digium va a poner mayor enfoque especialmente a nivel de estabilidad, y ademas para aquellos clientes que tengan contratos con acuerdos de nivel de servicio (SLA) va a tener la ventaja que esta version va a ser la soportada por los mismos (exclusivamente en las relaciones con Digium), con lo cual muy probablemente la mayor parte de los redistribuidores de Asterisk tambien se acojan a este sistema de implementacion.

Finalmente comentar que tengo un par de articulos en borrador, muy interesantes pendientes de publicar, pero en estos ultimos meses a raiz de lanzar WIKIAsterisk me he encontrado bastante ocupado y no he tenido tiempo a dedicar a la parte “online” de Asterisk todo el tiempo que me hubiera gustado.

Lanzamiento de WIKI Asterisk

Seguramente muchos de los lectores de este Blog sobre Asterisk, hayan notado mi ausencia en los últimos meses. Evidentemente esto es básicamente porque no escribo desde hace casí 6. Podría parecer como en aquel post que por cuestiones personales, me encontré en la necesidad de dejar de lado el mundo de Asterisk para ocuparme de otros asuntos.

Pero justamente esto no ha sido así en este caso, ya que he estado centrado en Asterisk, quizá más que nunca desde que empece.

Hoy quería hacer este mensaje, para dar la bienvenida a mi nueva página dedicada exclusivamente a Asterisk, en formato WIKI, llamada WIKIAsterisk: http://www.wikiasterisk.com

Mi intención es dar difusión al sistema Asterisk, en un soporte bajo el idioma Español, y que mejor momento que al inicio de la Eurocopa, donde es el único momento cada dos años, todo el mundo se exalta con la bandera Española. Realmente, la intención también es dar cobertura a los países hispanohablantes que también son seguidores de este Blog sobre Asterisk por afinidad de idioma.

De momento la WIKI de Asterisk, aun considerándose como una herramienta colaborativa destinada a ser ampliada abiertamente por la comunidad, permanecerá cerrada seguramente hasta el 1 de Julio, momento en el que empezarán a aceptarse solicitudes de edición.

Es posible que encontréis muchos errores, dado que es una versión llamémosla Release Candidate

Estoy seguro que con el tiempo servirá de referencia por encima de las WIKIs oficiales, dado que no todo el mundo maneja el inglés lo suficientemente bien para poder entender mucho de los conceptos técnicos que se tratan en el mundo de Asterisk. Además hay que reconocer que leer algo en tu idioma natal, supone una asimilación de conceptos mucho más rápida, y la dedicación que requerimos es muchísimo inferior.

Todo sea, como el lema de este Blog de Asterisk, para reducir la curva de aprendizaje. Cualquier cuestión que os surja acerca de esta nueva iniciativa, tenéis mis datos de contacto dentro de la misma web.

También “extraoficialmente” tengo que decir, que uno de los motivos por los cuales se me ocurrió adicionalmente realizar este proyecto que llevaba meses queriendo poner en marcha, es debido a que tengo la intención de presentarme al examen de Asterisk oficial, dCAP el 21 de Septiembre de 2012, y con ello tengo la pretensión de intentar cubrir a modo teórico y práctico todo lo que es posible que caiga en dicho examen, para que sirva como una referencia para todo aquel que quisiera presentarse en un futuro.

Larga vida a Asterisk

Asterisk. Revisando Opciones de Text To Speech

Asterisk: Tenia programado escribir en dos partes, sobre ASR y ahora sobre TTS (serian las dos cara de la moneda)

Siguiendo con la linea de programacion con AGI, ahora se me ocurre la opcion de dotar de un servicio de Text To Speech a nuestro Asterisk, del nivel AT&T Natural Voices utilizando el mismo sistema que aplicamos con nuestro sistema ASR en el anterior mensaje (como es un servicio con un modelo ASP evidentemente no tendremos problemas de licencias siempre y cuando ese sistema permanezca en activo). Lo malo, claro esta, que si ese servicio se modifica (la URL por ejemplo), nos quedamos sin “negocio”. Por eso que es conveniente si el sistema lo utilizamos en produccion y somos capaces de rentabilizarlo, pasar a un sistema de TTS local en nuestro sistema.

Para mantenernos en una linea open source como Asterisk, tenemos la opcion de Festival, el problema es que es de muy baja calidad comparado a soluciones de pago o la que voy a proponer aqui, a traves del TTS de Google

Texto a Voz con Google TTS

Vamos manos a la obra partiendo de la base AGI voy a obviar que se hicieron todos los pasos del mensaje anterior para instalar lo necesario (php-curl, y php-agi lo mas importante), hacemos lo siguiente:

Primero vamos a descargar un sistema para convertir de MP3 a WAV.

# aptitude install lame

Vamos a crear un Script PHP en /var/lib/asterisk/agi-bin/ podemos llamarlo por ejemplo asterisk-tts.php:


#!/usr/bin/php -q
<?php
require_once('phpagi-2.20/phpagi.php');
$agi = new AGI();

# Necesitamos pasarle la Cadena de Texto desde el Asterisk, y la recogemos con esta variable.
$traduccion = $argv[1];

# Aqui descargamos el fichero Mp3 haciendo pensar a Google que somos un Navegador
shell_exec("wget --header='User-Agent:Mozilla/4.0' 'http://translate.google.com/translate_tts?tl=es&q=".$traduccion."' -O /var/lib/asterisk/sounds/google-tts.mp3");
# Y convertimos el fichero con "lame" a wav que es reconocible por Asterisk
shell_exec("lame -h --decode /var/lib/asterisk/sounds/google-tts.mp3 /var/lib/asterisk/sounds/google-tts.wav");
$retString = "Fin de la conversion";
$agi->verbose($retString);
?>

Finalmente creamos una extension en nuestro DialPlan de Asterisk para que haga esta “gestion”:


exten => 2000,1,Answer()
same => n,Set(TTSVAR = "Lo que queramos convertir")
same => n,AGI(asterisk-tts.php,${TTSVAR})
same => n,Playback(google-tts)
same => n,Hangup()

Y ya esta, recargamos el dialplan de Asterisk como siempre, y marcando la extension 2000 oiremos con una voz muy sensual: “Lo que queramos convertir” … o algo asi 🙂

Como veis la dificultad de implantacion es nula, y eso es lo que mas me ha gustado de AGI, que no hace falta estar creando aplicaciones en C-Arcaico y recompilando el Asterisk con la app_c_arcaico y podemos tener una funcionalidad semejante (aunque no nativa y para los mas sibaritas, con menos rendimiento en terminos de picosegundos). Lo que tampoco tengo muy claro es que Google este feliz que esten utilizando su TTS masivamente, aunque estoy seguro que ya habra por ahi algun Call-Center que lo este haciendo. Si tienen experiencia me gustaria que me lo comentaran.

Texto a Voz con Festival TTS

Ahora os voy a explicar como hacer lo mismo, pero con el sistema TTS Festival en local, que os comente antes, y asi podeis comparar que os gusta mas:

Festival TTS digamos que fue desarrollado por una universidad e incorporado nativamente en Asterisk, asi que eso simplifica bastante las cosas ya que existe una Aplicacion especifica para el tratamiento de Texto a Voz directamente para el dial Plan de Asterisk (el modulo app_festival.so). Primero tenemos que comprobar si lo tenemos preparado.

Desde el CLI> module show like festival

Si aparece algo asi como app_festival.so y “1 modules loaded”, entonces ya lo tenemos, sino, nos toca recompilar Asterisk y en la parte de make menuselect tenemos que seleccionar el app_festival antes de hacer el “make && make install”

Ahora vamos a instalar festival

#aptitude install festival

Y ahora necesitamos voces en Español para Asterisk. Yo vivo en Andalucia ahora mismo, asi que barriendo para casa tenemos las que usa la junta de andalucia en la forja de Guadalinex:
http://forja.guadalinex.org/frs/?group_id=21

Vamos a descargar las de Silvia, para comparar el grado de sensualidad con respecto a Isabel de Google, todo sea por motivar a nuestros clientes varones.

# wget http://forja.guadalinex.org/frs/download.php/154/festvox-sflpc16k_1.0-1_all.deb
#dpkg -i  festvox-sflpc16k_1.0-1_all.deb
Y borramos el fichero de configuracion de festival que crea automaticamente, para poder utilizar mejor, el generico de Festival.
#rm /etc/festival.scm

La voz queda automaticamente instalada en la ruta:
/usr/share/festival/voices/spanish/JuntaDeAndalucia_es_sf_diphone

Ahora necesitamos modificar el archivo de configuracion de Festival por defecto ubicado en /usr/share/festival/festival.scm al final del fichero agregamos:


(set! voice_default 'voice_JuntaDeAndalucia_es_sf_diphone)
(define (tts_textasterisk string mode)
(let ((wholeutt (utt.synth (eval (list 'Utterance 'Text string)))))
(utt.wave.resample wholeutt 8000)
(utt.wave.rescale wholeutt 5)
(utt.send.wave.client wholeutt)))
(set! server_access_list '("localhost\\.localdomain" "localhost"))

Con esto, nos permitira por un lado utilizar la voz de Silvia y por otro lado arrancar el servidor Festival

Ahora necesitamos configurar el servidor Festival, bajamos los ficheros de desarrollo de festival
#aptitude install festival-dev

Y copiamos el fichero de autoarranque de festival a nuestro /etc/init.d para que arranque automaticamente el servidor cada vez que iniciemos nuestra maquina Asterisk:
#cp  /usr/share/doc/festival/examples/festival.init /etc/init.d/festival
#chmod +x /etc/init.d/festival

Antes de arrancar el servidor de Festival para Asterisk, necesitamos añadir una linea en /etc/default/festival:
RUN_FESTIVAL = yes

Y ahora si podemos arrancar el servidor Festival para Asterisk con exito:
/etc/init.d/festival start

Y para que arranque cada vez que iniciamos el sistema:
#ln -s /etc/init.d/festival /etc/rcS.d/S99festival

Ya esta todo casi listo, solo nos queda la parte mas facil, crear una extension en el DialPlan para ejectuar la aplicacion Festival
exten=> 3000,1,Answer()
same => n,Festival(Lo que queramos convertir)
same => n,Hangup()

Recargamos el dialplan de Asterisk como siempre y si marcamos la extension 3000, tendremos a Silvia dandonos el resultado.

Algunas cosas curiosas que he observado.
La version 1.0-1 de Guadalinex para Pedro parece que esta mal empaquetada. Instala sobre la version de Silvia (es_sf) en vez de (es_pa)
Se puede resolver de varias formas, una es, bajando las fuentes  (Archivos de desarrollo de la voz de Pedro) en el directorio correspondiente /usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone

Necesitamos desempaquetar tambien el .deb de Pedro con el comando “ar” (#ar x festvox-palpc16k_1.0-1_all.deb)
Y luego descomprimir data.tar.gz y a traves de la estructura de directorios llegar a …/usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone/group
Cambiamos el nombre al fichero que hay y lo copiamos a un nuevo directorio group dentro de nuestro directorio de Pedro antes creado
#mkdir /usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone/group
#mv  sflpc16k.group /usr/share/festival/voices/spanish/JuntaDeAndalucia_es_pa_diphone/group/palpc16k.group
O lo ideal si a  alguien le interesa que arregle ese fichero deb, no voy a ser yo, porque no me gusta demasiado.

Si tuviera que elegir personalmente un fichero para Festival en Español para Asterisk, eligiria de hecho, el fichero por defecto de festvox en español (el_diphone) que es el que mejor se entiende para mi gusto, aunque es voz masculina asi que no podriamos comparar bien para este ejemplo.
Se puede descargar y configurar siguendo los mismos pasos que antes, pero en el idioma por defecto poner “voice_el_diphone”
# aptitude install festvox-ellpc11k

Ahora puestos a comparar entre Festival TTS y Google TTS, creo que no hay color, pero para gustos los colores. Espero vuestras experiencias en el mundo del TTS.

Asterisk @ 10000 Horas

Un AGI Legendario: Publicacion en Twitter mediante ASR

Para muchos, hoy es un dia de fiesta en España, pero para mi, es mi, es como el dia oficial de Asterisk, y me siento especialmente inspirado. Y aprovechando el momento estuve planteando alguna aplicacion curiosa que hacer con AGI.

Echando la mirada atras, durante el penultimo dia del Asterisk Advanced, tuvimos una breve introduccion al AGI (Asterisk Gateway Interface), y porque no decirlo, a mi me resulto de lo mas interesante del curso. Siempre habia sabido que existia tanto AMI como AGI pero hasta ese momento no me “atrevi” a profundizar, sea por desconocimiento, y por complejidad aparente.

De hecho, concretamente en ese mensaje del Dia 4 del curso, no publique nada acerca de estos interfaces de Asterisk, porque me resultaban lo suficientemente interesantes e importantes como para minimo dedicarle uno o varios mensajes a los mismos.

Y aqui va el primero. Durante el curso, la practica basicamente se trataba, de llamando a una extension, esta ejecutaba un script PHP a traves de AGI y se publicaba un tweet generico con cierta informacion en un usuario especifico para el curso (por interes todos van aqui: http://twitter.com/#!/agilabtest)

Realmente la practica lo daba todo bastante “masticado”, los scripts hechos, y exactamente lo que era necesario para que funcionara, y lo que habia que modificar en el DialPlan.

Pero ahora, aprovechando esta idea, se me ocurrio ir un paso mas alla y ademas de poder explicarlo todo un poco mas en detalle, ampliar la funcionalidad a algo muy interesante: Poder escribir un tweet en nuestro Twitter, llamando a traves de una extension, y diciendo lo que queremos escribir, con un sistema de Automatic Speech Recognition, ASR, o Reconocimiento de Voz Automatico, y lo mejor de todo, sin coste alguno (¿es posible?). Hoy me quede con la cita “Everything is possible, even impossible is: I’m possible y tambien aporto su granito.

En primer lugar vamos a “preparar” el sistema con algunos componentes basicos.

Por un lado necesitamos una libreria para poder trabajar con PHP a traves de AGI, llamada PHP-AGI. Es posible su descarga desde aqui:
http://phpagi.sourceforge.net/

Para este ejemplo yo recomiendo la version 2.2X puesto que si en un futuro saliera una version superior es posible que el script aqui realizado ya dejara de funcionar
La descargamos  http://sourceforge.net/projects/phpagi/files/phpagi/2.20/phpagi-2.20.tgz/download

Y descomprimimos aqui: /var/lib/asterisk/agi-bin/
#mv ./phpagi-2.20.tgz /var/lib/asteirsk/agi-bin/
#cd /var/lib/asteirsk/agi-bin/
#tar -xvf phpagi-2.20.tgz

Ahora por otro lado necesitamos un script en php escificamente creado para “operar” con Twitter,  (de hecho es generico, serviria incluso para desarrollar nuestras propias aplicaciones en php en relacion a Twitter).  Aqui hay varias librerias para Twitter: https://dev.twitter.com/docs/twitter-libraries#php .

Pero la que nos interesa para este caso es la siguiente: http://classes.verkoyen.eu/twitter_oauth

La descargamos:

#mkdir twitter-oauth
#cd twitter-ouath
#wget https://github.com/tijsverkoyen/TwitterOAuth/zipball/2.1.2 -O twitter-oauth.zip
#unzip twitter-oauth.zip
Nos crea un directorio con un nombre sacado de GitHub asi que entramos en ese directorio
# cd  <directorio-recien-creado>
# cp twitter.php ../../twitter.php

Asi ya tenemos el script este en nuestro directorio AGI-BIN

Estos scripts utilizan PHP-CURL, asi que, si no lo tenemos instalado es un buen momento para hacerlo:
#aptitude install php5-curl

Tambien nos va a hacer falta un conversor de WAV a FLAC para el Reconocimiento de Voz Automatico. En este caso, instalamos SOX si es que no lo tenemos ya.
#aptitude install sox

Antes de crear el script, necesitamos algo muy importante. Las claves del API de Twitter para el desarrollo de aplicaciones. De hecho necesitamos crear y autorizar una aplicacion en Twitter que va a ser con la que va a operar nuestro Script. Para ello entramos en:
https://dev.twitter.com/user/login?destination=home

Accedemos con nuestra cuenta de Twitter. Le damos a “Create an app”. Ponemos un nombre, una descripcion y una web, si no teneis web, pues poned http://www.10000horas.com para promocionarla !
Despues creamos la aplicacion. Ya en la aplicacion nos vamos a “Settings” y tenemos que picar la opcion: “Read, Write and Access direct messages”. Considerad que vamos a escribir directamente en nuestro tweeter por tanto es fundamental que este permiso este “activado”.

Finalmente necesitamos todas las claves para el script a continuacion y apuntarlas. Son las siguientes
1. Consumer key
2. Consumer secret
Abajo picamos en “Create my access Token” y apareceran dos claves mas:
3. Access token
4. Access token secret
Fijaros que abajo del todo ponga Access Level: Read, write, and direct messages, si pone otra cosa, teneis que fijar el tipo de acceso como comente antes, y volver a recrear las claves.

Y ahora nos toca crear dentro de AGI-BIN el script que vamos a ejecutar desde la Aplicacion AGI en el Dialplan

En este caso creamos un fichero llamamosle por ejemplo agitwitter.php, con el siguiente contenido (gran parte esta extraido del contenido del script ofrecido en las practicas del Asterisk Advanced, por eso hemos utilizado el script Twitter-Oauth de Tijs Verkonyen, en vez de cualquier otro, una cuestion de ahorro de tiempo).


#!/usr/bin/php -q

<?php

# Aqui cargamos el script twitter.php y el phpagi que descargamos antes.
require_once('twitter.php');
require_once('phpagi-2.20/phpagi.php');

# Creamos un nuevo objeto tipo AGI 
$agi = new AGI();
$agi->answer();

# Aqui ponemos las credeciales que obtuvimos antes, en el mismo orden
# Estas que aparecen aqui son las de un usuario que cree de pruebas http://twitter.com/#!/pruebasadvanced
$consumerKey = 'xIpIGMm3kP610xh1sJVDCA';
$consumerSecret = 'vBT8eufZInFTPt02tGZeNdrb7o3YFDspCmtknS48JxY';
$accessToken = '414849063-IUB9SgA2fVr6vgk6zpYoJWAxwolGmlyA8qw361Z8';
$accessTokenSecret = 'ofo0kZrUTIXWJ1tul8zazifrNEhc0qTabzqHBADctvA';

# Aqui viene lo mejor del mensaje. Con estas lineas conseguimos un reconocimiento automatico de voz gracias a un servicio que pocos conocen
# y que ofrece el equipo de Google gratuitamente (al menos hasta lo que yo se).
# Creditos por ofrecerme este descubrimiento a http://www.ardumania.es

# Primero convertimos el fichero que generamos desde Asterisk a formato FLAC (que es el que admite Google)
shell_exec("sox  /var/lib/asterisk/sounds/twitter.wav /var/lib/asterisk/sounds/twitter.flac");

# Despues lanzamos una peticion a Google para que nos convierta el fichero FLAC en texto, nos devuelve una cadena de texto formato JSON
$linea = shell_exec("wget --post-file /var/lib/asterisk/sounds/twitter.flac --header='Content-Type: audio/x-flac; rate=8000' -O - 'http://www.google.com/speech-api/v1/recognize?lang=es_ES'");

# Convertimos esa cadena JSON gracias a PHP en un objeto directamente
$obj = json_decode($linea);

# Y conociendo la estructura exacta de ese objeto (contiene mucha mas informacion interesante, como la "calidad" de la conversion), sacamos el texto ya convertido
$tweet = $obj->{"hypotheses"}[0]->{"utterance"};

# Ya en adelante simplemente lo que hacemos es utilizando las funciones del script Twitter-Oauth publicamos en Twitter nustro Tweet
try

{
$t = new Twitter($consumerKey, $consumerSecret);
$t->setOAuthToken($accessToken);
$t->setOAuthTokenSecret($accessTokenSecret);

$retArray = $t->statusesUpdate($tweet);
$retString = "SUCCESS: Tweet id " . $retArray['id_str'] . " posted at " . $retArray['created_at'];
}
catch(Exception $e)
{
$retString = "FAILURE: " . $e->getMessage();
}

# Para terminar reportamos a Asterisk el resultado (si tenemos activada la opcion verbose en nuestro CLI podremos ver el mensaje de exito si salio bien la cosa
$randNum = rand(1000, 9999);

$retString .= ". ID " . $randNum;
$agi->verbose($retString);
$agi->hangup();

?>

Ahora una vez que tenemos el script PHP listo, solo nos falta editar nuestro DialPlan para ejecutarlo. En este caso he creado una extension minima para que podamos obtener el resultado que estamos buscando

exten => 1000,1,Answer()
same => n,Record(twitter.wav)
same => n,AGI(agitwitter.php)
same => n,Hangup()

Recargamos nuestro dialplan (CLI> dialplan reload) y listo!

Un tema muy importante para que todo esto funcione y que creo que a estas alturas sobra decir: ES FUNDAMENTAL TENER ACCESO A INTERNET EN NUESTRA MAQUINA ASTERISK

Esa es la unica “contrapartida” de poder tener un ASR gratuito y de maxima calidad… creo que en muchos casos es asumible. En otro caso tendremos que plantearnos otras alternativas de reconocimiento de voz automatico como por ejemplo Verbio recomendado por Avanzada 7 o LumenVox recomendado por Digium (que son de pago y nada baratos), o buscarnos la vida con CMUSphinx que es OpenSource y no esta mal (aunque  de momento es muy inferior tanto al ASR de Google y a los dos de pago).

Ahora desde nuestro telefono solo nos queda hacer esa llamada de cortesia a  la extension 1000, suena el tono de hablar, decimos lo que queramos publicar en nuestro tweet (sobra decir que cuanto mas claro hablemos mejor, y si decimos palabra a palabra mejor aun para mejorar el reconocimiento, aunque el ASR de Google para mi gusto es el mejor del mundo y es capaz incluso de reconocer las frase hecha sin demasiada vocalizacion con un amplio numero de aciertos). Despues de hablar pulsamos la Almohadilla (#) para guardar el fichero de Voz (twitter.wav) y finalmente esperamos a que Asterisk haga el resto.

Entramos en nuestro Twitter… y voila! Nuestro mensaje recien escrito (si todo fue bien, sino, como comente, recomiendo activar en el fichero /etc/asterisk/logger.conf para CLI (console =>) la posibilidad de verbose, asi podemos ver los resultados que nos devuelve el script PHP y si hay error, lo que captura el “catch” del script PHP).

Esta vez que con un solo mensaje he matado dos pajaros de un tiro: explicacion de una implementacion de ASR en Asterisk y el funcionamiento de AGI utilizando PHP (que hay que reconocer que a dia de hoy desde que salio PHP5 es el lenguaje de programacion interpretado que mas me gusta, aunque todo esto tambien se podria haber realizado en otros como Ruby On Rails o Python, si os fijasteis en la pagina de scripts para Twitter habia para varios lenguajes).

Y como siempre, y una vez mas, que cualquier comentario sera ampliamente bienvenido! Espero que les sea de provecho.

Montando un Sistema Asterisk Autonomo I

Durante el curso de Asterisk Advanced, una de las cuestiones que surgieron con los compañeros, era el tema de la “practicidad” eventual que podia surgir a la hora de decidir montar una interfaz grafica a pesar de que muchos hayan criticado, es el simple hecho que otorga un “sistema” para que manos inexpertas (bajo nuestra aprobacion y previamente formados), puedan tomar el control de nuestro Asterisk sin nuestra supervision constante.

Evidentemente surgen algunas inconveniencias, que son inevitables en este tipo de situaciones, pero en las manos adecuadas, pueden ser mas pros que contras (por ejemplo explicandole a un equipo tecnico o IT funcionalidades basicas de Asterisk como crear nuevas extensiones para poder cursar llamadas. De esto se trata la idea de montar un sistema Autonomo (al menos autonomamente de nuestra persona).

Un paso mas alla, viendo el sistema RealTime de Asterisk, se me ocurrio la -evidente- idea de crear una micro interfaz grafica (por ejemplo basada en web con PHP como sera el caso que exponga a continuacion), para gestionar esos aspectos de Asterisk especificos, y poder definitivamente, tomando esto como ejemplo generico, poder obviar todas esas interfaces graficas (ejemplo FreePBX) para siempre.

Lo que me planteo de ejemplo ahora: Activar RealTime para los “peers” SIP de nuestro Asterisk y crear la interfaz grafica web en PHP para Crear y Borrar estas extensiones (La funcion de editar seria Borrar y volver a crear para este ejemplo sencillo, aunque realmente no seria nada dificil de implementar)

Como ya comente en su momento en otro mensaje, el montaje de un sistema RealTime es verdaderamente secuencial, es mas ya lo hicimos en las practicas durante Asterisk Advanced en detalle.

En primer lugar, obviamente necesitamos tener instalado un sistema de gestion de bases de datos como MySQL, tambien un servidor web como Apache, y los modulos de PHP para el mismo. En este caso, como ya vimos antes, LAMP es lo ideal. Asi que ejecutamos tasksel y lo instalamos (LAMP Server, Ubuntu/Debian)

Tambien necesitamos las librerias de ODBC puesto que vamos a utilizarlas con Asterisk:

# aptitude install unixodbc libmyodbc

En segundo lugar, configuramos la base de datos y la tabla donde volcar los usuarios SIP:

– Creamos un fichero por ejemplo en /tmp/ llamado por ejemplo sip_buddies.sql con esta informacion (se puede encontrar mas informa acerca de la tabla asociada a los peers SIP  aqui). Atencion al ultimo campo que coloreo en Rojo. Muy importante que lo agreguéis manualmente para lo que vamos a tratar de hacer a continuacion

CREATE TABLE `sip_buddies` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(80) NOT NULL default ”,
`host` varchar(31) NOT NULL default ”,
`nat` varchar(5) NOT NULL default ‘no’,
`type` enum(‘user’,’peer’,’friend’) NOT NULL default ‘friend’,
`accountcode` varchar(20) default NULL,
`amaflags` varchar(13) default NULL,
`call-limit` smallint(5) unsigned default NULL,
`callgroup` varchar(10) default NULL,
`callerid` varchar(80) default NULL,
`cancallforward` char(3) default ‘yes’,
`canreinvite` char(3) default ‘yes’,
`context` varchar(80) default NULL,
`defaultip` varchar(15) default NULL,
`dtmfmode` varchar(7) default NULL,
`fromuser` varchar(80) default NULL,
`fromdomain` varchar(80) default NULL,
`insecure` varchar(4) default NULL,
`language` char(2) default NULL,
`mailbox` varchar(50) default NULL,
`md5secret` varchar(80) default NULL,
`deny` varchar(95) default NULL,
`permit` varchar(95) default NULL,
`mask` varchar(95) default NULL,
`musiconhold` varchar(100) default NULL,
`pickupgroup` varchar(10) default NULL,
`qualify` char(3) default NULL,
`regexten` varchar(80) default NULL,
`restrictcid` char(3) default NULL,
`rtptimeout` char(3) default NULL,
`rtpholdtimeout` char(3) default NULL,
`secret` varchar(80) default NULL,
`setvar` varchar(100) default NULL,
`disallow` varchar(100) default ‘all’,
`allow` varchar(100) default ‘g729;ilbc;gsm;ulaw;alaw’,
`fullcontact` varchar(80) NOT NULL default ”,
`ipaddr` varchar(15) NOT NULL default ”,
`port` smallint(5) unsigned NOT NULL default ‘0’,
`regserver` varchar(100) default NULL,
`regseconds` int(11) NOT NULL default ‘0’,
`lastms` int(11) NOT NULL default ‘0’,
`username` varchar(80) NOT NULL default ”,
`defaultuser` varchar(80) NOT NULL default ”,
`subscribecontext` varchar(80) default NULL,
`useragent` varchar(20) default NULL,
`useradmin`  int(1) NOT NULL DEFAULT ‘0’,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
KEY `name_2` (`name`)
) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;

#mysql -p
Entramos con nuestra password
mysql> create database asterisk;
mysql> use asterisk;
mysql> source /tmp/sip_buddies.sql

En tercer lugar vamos a configurar los ficheros basicos de Asterisk para poder trabajar con el conector ODBC

/etc/asterisk/extconfig.conf

[settings]
sippeers => odbc,asterisk ,sip_buddies

/etc/asterisk/res_odbc.conf

[asterisk]
enabled => yes
pre-connect => yes
dsn => asterisk
username => root
password => (el password que le pusimos al usuario de la base de datos mysql root durante la configuracion de LAMP)

/etc/odbc.ini

[asterisk]
Description = ODBC para MySQL
Driver = MySQL
Server = localhost
Database = asterisk
Socket = /var/run/mysqld/mysqld.sock

/etc/odbcinst.ini

[MySQL]
Description = MySQL ODBC MyODBC Driver
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so

Con esto vamos al CLI de Asterisk
# asterisk -r
CLI> odbc show

Y si vemos “Connected: Yes” entonces ya esta preparado

En cuarto lugar vamos a configurar los usuarios SIP:

Para ello creamos un fichero temporal por ejemplo /tmp/usuarios_sip_buddies.sql con la siguiente info:

INSERT INTO sip_buddies (`name`, `host`, `nat`, `type`, `cancallforward`, `canreinvite`, `context`, `md5secret`, `qualify`, `disallow`, `allow`, `fullcontact`, `ipaddr`, `port`, `regseconds`, `lastms`, `username`, `defaultuser`)
VALUES (‘ext10’, ‘dynamic’, ‘no’, ‘friend’, ‘yes’, ‘yes’, ‘extensiones’, ‘e8a325cb599ad4b6eb95d79aa4506ed2’, ‘yes’, ‘all’, ‘g729;ilbc;gsm;ulaw;alaw’, ”, ”, ‘0’,’0′, ‘0’, ”, ”)

Importante, el ultimo valor a 1, y la clave sera 1234 en formato md5 evidentemente se deberia cambiar.

Ahora como antes lo ejecutamos desde el interfaz de comandos de MySQL

#mysql -p
mysql> use asterisk;
mysql> source /etc/usuarios_sip_buddies.sql

Finalmente necesitamos editar el fichero sip.conf con una configuracion minima. Por ejemplo:

/etc/asterisk/sip.conf

[general]
language = es

Desde este mismo momento ya tenemos el usuario sip ext10 con la clave 1234 listo para funcionar. Podemos probarlo con cualquier telefono SIP.

Puede parecer muchisima historia comparado a configurar un fichero sip.conf, pero con la practica y unas plantillas, esta gestion se realiza en 5 minutos y ahora viene la “potencia”.

El script PHP:

Voy a crear un solo fichero PHP al estilo monolitico para que funcione y nada mas. Evidentemente sera bastante mejorable y ya esta en nuestras manos con unos conocimientos basicos de programacion PHP (y obviamente adaptable a cualquier otro lenguaje de programacion con el que nos sintamos mas comodos)

Lo primero vamos a crear algunos directorios dentro del lugar donde tengamos publicado el servidor web apache, por defecto /var/www
# cd /var/www
# mkdir asterisk
# cd asterisk
# mkdir sip
# cd sip

Ahora vamos a crear un fichero index.php con el siguiente contenido:

 <?php

// Conexion a la base de Datos

$base = "asterisk";
$host = "localhost";
$user = "root";
$password = "nuestra_contraseña_sql";
$conexion = mysql_connect($host,$user,$password);
$result = mysql_select_db($base,$conexion) or die ("Error en la Conexion a BD");

session_start();

// Si no estamos logeados

if (!$_SESSION['login'])
{
 if(isset($_POST['loginsubmit']))
 {
 $usuario = $_POST['usuario'];
 $password = $_POST['password'];

 if((!$usuario) || (!$password))
 {
 echo "Error 1<br>";
 exit();
 }
 $password = $usuario.":asterisk:".$password;
 $password = md5($password);
 $query = mysql_query("SELECT * FROM sip_buddies WHERE name='$usuario' AND md5secret = '$password' AND useradmin = '1'");
 if (mysql_num_rows($query) > 0)
 {
 session_register('login');
 $_SESSION['login'] = '1';
 }
 else
 echo "Error 2<br><br>";

 echo "<a href='index.php'>Home</a>";
 }
 else
 {
 echo "<form method='post' action='?'>";
 echo "Usuario: <input name='usuario' type='text'><br>";
 echo "Contrase&ntilde;a: <input name='password' type='password'><br>";
 echo "<input type='submit' name='loginsubmit'>";
 echo "</form>";
 }

}
// Si ya estamos logeados

else
{
 // Salida del Sistema
 if(isset($_REQUEST['exit']))
 {
 session_destroy();

 if(!session_is_registered('login'))
 echo "<a href='index.php'>Home</a>";

 }
 // Insercion de un nuevo Registro
 elseif(isset($_POST['insertsubmit']))
 {
 $sipuser = $_POST['sipuser'];
 $sippass = $_POST['sippass'];
 $sippass = $sipuser.":asterisk:".$sippass;
 $sippass = md5($sippass);
 $query = mysql_query("INSERT INTO sip_buddies (`name`, `host`, `nat`, `type`, `cancallforward`, `canreinvite`, `context`, 
 `md5secret`, `qualify`, `disallow`, `allow`, `fullcontact`, `ipaddr`, `port`, `regseconds`, `lastms`, `username`, `defaultuser`) 
 VALUES ('$sipuser', 'dynamic', 'no', 'friend', 'yes', 'yes', 'extensiones', '$sippass', 'yes', 'all', 'g729;ilbc;gsm;ulaw;alaw', '', '', 
 '0','0', '0', '', '')");

 echo "<a href='index.php'>Home</a><br>";
 echo "<a href='index.php?exit'>Exit</a>";
 }
 // Borrado de un Registro
 elseif(isset($_POST['deletesubmit']))
 {
 $sipid = $_POST['sipid'];
 $query = mysql_query("DELETE FROM sip_buddies WHERE id = '$sipid'");

 echo "<a href='index.php'>Home</a><br>";
 echo "<a href='index.php?exit'>Exit</a>";
 }
 // Formularios de Insercion y Borrado
 else
 {
 echo "Insertar Registro:<br>"; 
 echo "<p><form method='post' action='?'>";
 echo "Usuario: <input name='sipuser' type='text'><br>";
 echo "Contrase&ntilde;a: <input name='sippass' type='password'><br>";
 echo "<input type='submit' name='insertsubmit' value='Insertar'>";
 echo "</form></p>";

 echo "<table border='1'>";
 echo "<tr><td colspan ='2' align='center'>SIP Peers Activos</td></tr>";
 echo "<tr><td>Usuario</td><td>Borrar</td></tr>"; 

 $query = mysql_query("SELECT * FROM sip_buddies WHERE type = 'friend'");
 $rows = mysql_num_rows($query);
 for ($i=0;$i<$rows;$i++)
 {
 $sippeersarray = mysql_fetch_array($query);
 $sipuser = $sippeersarray['name'];
 $sipid = $sippeersarray['id'];

 echo "<tr>";
 echo "<td>".$sipuser."</td>";
 echo "<td>";
 echo "<form method='post' action='?'>";
 echo "<input type=hidden name='sipid' value='$sipid'>";
 echo "<input type=submit name='deletesubmit' value='Borrar'>";
 echo "</form>";
 echo "</td>"; 
 echo "</tr>";

 } 
 echo "</table>"; 
 echo "<a href='index.php?exit'>Exit</a>";

 }
}

?>

Y eso es todo, ahora podemos acceder a traves de un navegador a la direccion:

http://ip_nuestro_servidor_asterisk/asterisk/sip/

Y aparecera para introducir un usuario y contraseña. Siguiendo el ejemplo seria Usuario: ext10,  Contraseña: 1234

Asi accederiamos a la micro interfaz para Crear y Borrar extensiones.

Evidentemente este codigo tiene bastantes deficiencias “tecnicas”, por ejemplo se podria intentar realizar una tecnica de Inyeccion de Codigo SQL para logearnos como el usuario administrador por las “bravas”, y ya conociendo la estructura, hasta darnos de alta un usuario Administrador para acceder siempre. Pero la idea basica era poder ejemplificar lo que queria mostrar con este articulo, que con solo seguir unos pasos de 5 minutos o menos, y tener este script PHP listo para ser “insertado” en el servidor web, tendriamos una interfaz totalmente Autonoma para nuestro cliente, equivalente a la que “instalamos” en mensajes anteriores, para la gestion de salas de conferencias MeetMe.

Ademas esta claro este codigo se podria mejorar para añadir la posibilidad de editar extensiones, o incluso configurar mas parametros de las extensiones (o tener dos interfaces, una de administrador para nosotros mismos, y otra para los usuarios), asi no tendriamos que andar “trasteando” directamente en el interfaz MySQL si modificamos regularmente las extensiones.

Con esto, ya empiezan a haber motivos para poder ir planteandonos dar un primer paso y dar fin a las interfaces graficas de Asterisk!.

Tengo que reconocer que este mensaje me ha llevado componerlo mas tiempo del previsto originalmente. Toda mejora al codigo, o sugerencia como siempre, sera ampliamente agradecida a traves de los comentarios.

Como conseguir llamadas al minimo precio via SIP

Ya sabeis que una de las famosas ventajas del mundo SIP es la posibilidad de conseguir llamadas muy baratas gracias a los diversos proveedores SIP que hay en el mercado.

La dificultad radica la mayor parte del tiempo, en localizar ese proveedor SIP que ofrezca en un momento determinado la mejor tarifa.

Resulta que existe una web, que mantiene bastante actualizadas, las mejores tarifas, para muchos proveedores SIP, para practicamente todos los paises y todos los tipos de llamadas a los mismos (a moviles y a fijos).

Lo interesante de todo esto, es la posibilidad de configurar multiples proveedores y a la vez enrutar las llamadas segun el destino de las mismas por uno o por otro en funcion de nuestra necesidad.

La pagina web de la que estamos hablando es: http://backsla.sh/betamax

Si observais en el momento en que escribo este mensaje, el mejor operador es EasyVOIP. No todos los proveedores de la lista ofrecen la posibilidad de conectarse via SIP a los servicios, (por ejemplo CheapVOIP no lo permite, solo llamadas a traves de su dialer). En este caso Easy VOIP ofrece llamadas a operadores moviles en España a solo 0,04 dolares el minuto sin establecimiento de llamada (del orden de los 0,03 centimos de euro). No existe ni un solo operador en España que ofrezca este nivel de competitividad. Ni siquiera existe una tarifa plana que pueda competir, lo mas cercano, las tarifas Leon de Orange que son las menos restrictivas a nivel de tiempos. Los OMV (Operadores Moviles Virtuales) al cursar llamadas a traves de los operadores principales (Orange, Movistar, Vodafone o Yoigo), todos imponen el establecimiento de llamada, que para llamadas relativamente cortas (menos de 15 minutos), supone un sobrecoste excesivo (por tanto entramos en restricciones).

Luego hay tarifas baratas, por tramos horarios, numeros preferidos, etc, etc, pero igual entramos en restricciones. Todo esto lo podemos sintetizar en un operador SIP. Hoy en dia con las conexiones a Internet, es practicamente despreciable la baja calidad de la señal (latencias de entre 50 a 70ms con un jitter inferior a 10ms), y por simultaneidad de canales precisamente es el caudal simetrico ya empieza a sobrar (es relativamente facil conseguir caudales de 2Mbits simetricos). Pongamos uno de los peores casos, el codec ULAW G.711, 64kbits/s duplex. En 2 Mbits simetricos tenemos accesible un “troncal” de 32 llamadas simultaneas, podria decirse, semejante a un Primario E1.

Pero si decidimos gastarnos un dinerillo en unas cuantas licencias G.729 (algo muy interesante sinceramente, ya que reducimos gracias a la compresion, hasta 4 veces el caudal de ULAW), es decir 8 kbits/s, por tanto tendriamos acceso a un “troncal” de hasta 128 llamadas simultaneas, o lo mas clasico en estos casos, dedicar, 512kbits simetricos al trafico VoIP para conseguir ese “primario de voz”, mediante politicas QoS, y tener accesible el resto del caudal para aplicativos internos de la empresa en segundo o tercer nivel.  Una licencia G.729 para un canal concurrente, vale solo 10 dolares. Si hablamos de 32, 320 dolares al cambio poco menos de 250 euros es una suma totalmente asumible, mas considerando, que es lo que puede llegar a valer un Primario E1, para una PYME durante solo 1 mes de uso (y descontando el trafico).

Y lo mas interesante, se que proveedores SIP como EasyVOIP soportan este codec.

Como ya comente en entradas anteriores, nos encontramos un gran problema que lidiar: el trafico entrante. Necesitamos proveedores que nos permitan tener DID y trafico entrante sin pedir “nada a cambio” (o que curses llamadas obligatoriamente a traves de ellos). Esta tarea aun no la tengo resuelta, puesto que sobre todo en el ambito casero lo que es a quien va principalmente orientados estos proveedores SIP, lo primordial es llamar barato, pero todos “tenemos” una linea movil a los que ser llamados, o una linea fija de Telefonica…

Netelip sigue ofreciendo servicios de llamadas de bastante bajo nivel. Telsome, tambien tiene unas tarifas aceptables, pero la calidad es intermedia. Llama la atencion que hasta EasyVOIP operador extranjero ofrece mejor calidad que estas dos operadores IP Españolas. Asi que VozTelecom sigue siendo la mejor opcion todavia aun a costa de ser un poco caros.

VozTele ofrecia dos canales entrante por 9 euros al mes, y luego cada DID por 4 euros aparte. Esto es una configuracion ejemplo: 4 DID + 2 canales entrantes = 25 euros al mes. Por ejemplo un proveedor mundial de DID, DIDWW ofrece un canal entrante por cada DID contratado, peor servicio, por 5 euros de SETUP y 5 euros al mes. 5 x 4 = 20 euros. En este caso nos ahorrariamos 5 euros pero con inferior servicio.

Evidentemente, es totalmente “injusto” que cursemos llamadas por un operador externo del que las recibimos ya que no ofrecemos la oportunidad de “ganar” al segundo. Por eso todavia estas soluciones mixtas para mi criterio son una asignatura pendiente.

Vuelvo a dejar abierto este tema por si alguien tiene ideas mejores, o propuestas para poder entrar a ser planteadas. Desde luego aun teniendo estas dos soluciones separadas siguen siendo de resultado mucho mas baratas que “quedarse” en la PSTN o en los operadores moviles. De hecho podrian conseguirse telefonos moviles para llamadas entrantes a coste 0 (por ejemplo con OMV) e introducirlos en nuestra PBX a traves de un enlace movil o un modem 3G que permita funciones de Voz (como hicieron en las “practicas” los de chan_sebi).

Proxy Movil

Y justamente de esta idea, se me ocurre diseñar un “Proxy Movil” aprovechando las tarifas corporativas (llamadas a numeros internos de la empresa ilimitadas, a coste 0, con “tarifas planas para este proposito, de solo 3 euros”. Dado que realmente consumir 1000 minutos que es lo que ofrecen la mayoria de las tarifas planas es bastante complejo, ¿Que ocurriria si utilizaramos varias de estas lineas de 1000 minutos unidas, para tener una suma pongamos de 5000 minutos, a repartir entre 25 lineas corporativas?

Asi a desglose economico:

30 (+9 tracks entrantes) x 3 euros = 117 euros
9000 minutos x 0,03 centimos (EasyVOIP) = 270 euros
Total = 387 euros al mes

Son 300 minutos por linea. La tarifa plana mas barata, no baja de 20 euros, Leon 24 , 300 minutos por 24 euros al mes = 30 x 24 = 720 euros al mes.

Ahorro de mas de 300 euros al mes por aplicar esta filosofia. Y las posibilidades que ofrece son muy amplias (por ejemplo, coste nulo para llamadas salientes, por ejemplo, alguien nos llama a nuestra PBX a la operadora, y la operadora quiere transferir a uno de esos 30 telefonos de la empresa, al cursarse por uno de los 9 tracks, saldria gratuita la llamada, y podriamos aplicar FailOver). El unico problema: el contrario, en la llamada entrante, si el track esta ocupado no se me ocurre aplicar un metodo de failover al siguiente track puesto que la llamada se cursa contra la operadora, a no ser que se aplique un sistema de desvio de llamada “si comunica” rotativo entre todos las lineas del track. Curioso experimento