La variable “rtcachefriends”

Asterisk, Desarrollo No Comments

Recientemente hemos tenido que montar una distribución de Asterisk sobre un Debian Lenny, y todo ha ido sobre ruedas hasta que nos hemos puesto a montar los clientes SIP en realtime: resulta que al agregar un usuario a la base de datos del RT y loguearnos en el softphone, nos aparecia en la consola de asterisk una y otra vez:

[Nov  3 09:12:45] NOTICE[7266]: chan_sip.c:12335 handle_response_peerpoke: Peer ‘104′ is now Reachable. (3ms / 2000ms)

[Nov  3 09:12:45] NOTICE[7266]: chan_sip.c:12335 handle_response_peerpoke: Peer ‘104′ is now Reachable. (2ms / 2000ms)

[Nov  3 09:12:46] NOTICE[7266]: chan_sip.c:12335 handle_response_peerpoke: Peer ‘104′ is now Reachable. (2ms / 2000ms)

Este mensaje se repite cada 2 o 3 ms, para avisarte que te has registrado correctamente en tu extensión saturando toda la pantalla, y dejando la consola inutilizada.

Despues de un par de horas tirandonos de los pelos, recompilando Asterisk, cambiando de base de datos, cambiando de sofphone,  y probando a poner servidor bocabajo (a punto estuvimos) dimos con el problema… ¡¡La variable “rtcachefriends” en el archivo sip.conf!!

Cuando la tenemos activa, es la que dice a Asterisk que debe meter a todos los usuarios creados en tiempo real en la caché interna donde se almacenan también los “friends” agregados por el archivo de configuración sip.conf. Digamos que cuando no está activa nuestro Asterisk es como el pececito Doris, solo ahora pierde la memoria cada 3 ms y vuelve a registrar una y otra vez al mismo usuario.

Así que ya sabeis niños, cuando trabajeis con usuarios en realtime, rtcachefriends=yes.

Configurando extensiones SIP en real time

Asterisk No Comments

Una de las ventajas de Asterisk es la arquitectura realtime. Este sistema permite almacenar la configuración de nuestro Asterisk en una base de datos, en lugar de hacerlo en los archivos de configuración que tenemos en etc/asterisk. De esta forma Asterisk puede leer los archivos de configuración en tiempo real, en lugar de tener que hacerlo al cargar los módulos.

Lo bueno de esto es que podemos hacer modificaciones en la configuración sin tener que reiniciar Asterisk o recargar módulos. Hoy vamos a mostrar aquí como podemos introducir los clientes SIP en la base de datos de forma que podamos crearlos y modificarlos sobre la marcha.

Lo primero que tenemos que hacer es configurar el acceso a la base de datos, para ello editaremos el archivo res_mysql.conf y introduciremos los datos de conexión:

[general]
dbhost = 127.0.0.1 ;en caso de que Asterisk y mySQL compartan el mismo servidor.
dbname = nombre_bd
dbuser = usuario_bd
dbpass = pass_bd
dbport = 3306 ;puerto por defecto en mySQL

A continuación crearemos una tabla en la base de datos donde alojaremos la información de las cuentas SIP, os pego aquí el choricete SQL para ahorraros el trabajo:

CREATE TABLE `sip_buddies` (
`id` int(20) NOT NULL auto_increment,
`name` varchar(80) NOT NULL default ”,
`host` varchar(31) NOT NULL default ‘dynamic’,
`callerid` varchar(80) default NULL,
`mailbox` varchar(50) default NULL,
`secret` varchar(80) default NULL,
`ipaddr` varchar(15) NOT NULL default ”,
`port` smallint(5) unsigned NOT NULL default ‘5060′,
`regseconds` int(11) NOT NULL default ‘0′,
`username` varchar(80) NOT NULL default ”,
`context` varchar(80) NOT NULL default ‘contexto_saliente’,
`fullcontact` varchar(80) NOT NULL,
`disallow` varchar(45) NOT NULL default ‘all’,
`allow` varchar(45) NOT NULL default ‘g729,gsm,ulaw,alaw,ilbc’,
`type` varchar(45) NOT NULL default ‘friend’,
`qualify` varchar(45) NOT NULL default ‘yes’,
`canreinvite` varchar(45) NOT NULL default ‘yes’,
`nat` varchar(45) NOT NULL default ‘yes’,
`dtmfmode` varchar(45) NOT NULL default ‘rfc2833′,
`record_out` varchar(45) NOT NULL default ‘Adhoc’,
`record_in` varchar(45) NOT NULL default ‘Adhoc’,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM;

Según las especificaciones del manual, podríamos declarar muchos mas campos en la tabla, pero con estos que hemos puesto es suficiente para nosotros.

NOTA: en “contexto” debemos poner el contexto que tengamos definido para llamadas salientes en nuestro dialplan.

Por último solo nos queda indicarle a Asterisk que la información SIP debe buscarla en la base de datos, en lugar de hacerlo en el archivo de configuración, sip.conf. Para esto editamos el archivo extconfig.conf e introduciremos las siguientes lineas:

sipusers => mysql,nombre_bd,sip_buddies
sippeers => mysql,nombre_bd,sip_buddies

Esto le indica que la información acerca de los sip users y los sip peers debe buscarla en el servidor mysql, en la base de datos nombre_bd, y en la tabla sip_buddies. Guardamos el archivo, reiniciamos Asterisk… y estamos preparados para empezar a registrar usuarios.

Desde ahora ya podemos meter nuestros usuarios SIP en tiempo real. Eso sí, hay que tener en cuenta que nuestro archivo sip.conf ya no sera cargado, por lo que si tenemos alguna configuración de usuarios aquí, debemos pasarla a la base de datos.

Ahora un caso práctico:

Llega a nuestra empresa el nuevo becario, al cual vamos a enmarronar con un monton de encuestas telefónicas. Necesita, claro está, que le creemos una cuenta SIP en asterisk. Los únicos campos requeridos serán name (su extension), callerid (su nombre genérico) y secret (password), así que directamente podemos introducir en MySQL:

INSERT INTO sip_buddies (name, callerid, secret) VALUES (105, ‘Becario Pringao’, 44322);

Ahora abrimos la configuración del softfone/telefono SIP, introducimos el usuario y la contraseña… ¡Y listo!

Becario

Un saludo desde aquí a todos los becarios que nos leen! xD

Una aplicación simple. Integración de Mantis en Asterisk.

Asterisk, Desarrollo No Comments

Integrar una aplicación en Asterisk no resulta dificil si tenemos unos conocimientos básicos del dialplan y sabemos como realizar consultas a bases de datos. En esta ocasión y a modo de sencillo ejemplo relizaremos una sencilla modificación en nuestro dialplan para enlazar asterisk con Mantis.

¿Que es Mantis?Mantis bug tracker

Para aquellos que no lo conozcais, Mantis es un completo sistema de seguimiento de incidencias, libre y funciona sobre php+mysql. No llevo mucho tiempo trabajando con Mantis, pero hasta ahora he descubierto bastantes posibilidades:

  • Las incidencias pueden pasar por diversos estados (abierta, asignada al ténico, cerrada…) facilmente reconocibles por colores, así como organizarlas por proyectos.
  • Permite la creación crear varios perfiles de usuario (técnico, desarrollador, coordinador…),
  • Es posible definir un flujo de trabajo (p. ej: el perfil X puede abrir incidencias, pero solo el perfil Y puede resolverlas y cerrarlas)
  • También nos permite mantener una comunicación directa via email con el cliente afectado, de forma que cada vez que editemos una incidencia le llegue un mensaje al usuario con los cambios realizados.

Captura mantis

Captura de Mantis.

Un caso práctico.

Bien, supongamos que la joven empresa Pepe Consulting S.L. se dedica a la reparación y mantenimiento de equipos informáticos.

Esta empresa tiene una central en la que reciben los pedidos de los clientes, llevan un registro de las incidencias y a coordinan a los técnicos que estan en la calle.

Resulta que Godofredo Cascajosa, uno de los técnicos de campo, se ha desplazado a un pueblo cercano, Villacabreros del Trabuco, para hacer una reparación y ahora necesita llamar a la central para saber cual es su próximo encargo.

Pues bien, ahí es donde entra Asterisk en acción, ¿por que tener a una operadora ocupada cuando el propio Asterisk puede darle esa información? Con el siguiente ejemplo veremos como Asterisk realiza una consulta a la base de datos de Mantis y facilita la información requerida al técnico.

Lo primero de todo es tener un buen plan, en nuestro caso hemos diseñado el diagrama de flujo que va a seguir nuestra aplicación:

Diagrama de flujo de la aplicación.

Al turróoooon!!!

Para que esto funcione tenemos que saber dónde almacena mantis la información sobre las incidencias dentro de la base de datos. En nuestro caso las incidencias son almacenadas en la tabla mantis_bug_table y los campos que nos interesan son:

  • id: número de incidencia
  • summary: titulo de la incidencia
  • status: estado de la incidencia (nos interesa el estado 10, incidencias abiertas

En la tabla mantis_bug_text_table encontraremos el campo description donde se almacenan la descripciones de las incidencias.
Comenzaremos creando la extension mantis, que se corresponderá con el número 101.

[mantis]
exten => 101,1,Answer()
 
;Conexion inicial a la base de datos
exten => 101,n,MYSQL(Connect CONNID host user pass dabase)
exten => 101,n,GotoIf($["${CONNID}" = ""]?errMysql)
 
exten => 101,n,NoOp(Menu inicial)
exten => 101,n(menu),Wait(1)
 
;Leemos las opciones del menu y esperamos la respuesta
exten => 101,n,Festival(Pulse UNO para listar las incidencias.)
exten => 101,n,Festival(Pulse DOS para ver detalles.)
exten => 101,n,Read(MENU,,1)  ;Recogemos la opcion pulsada
exten => 101,n,GotoIf($["${MENU}" = "1"]?opcion1)
exten => 101,n,GotoIf($["${MENU}" = "2"]?opcion2)
exten => 101,n,Goto(menu)

Con esto ya hemos conseguido crear la conexión a la base de datos y el menú inicial. Vamos con el primer apartado del menu:

; ==================================
; Opcion 1 (Listado de incidencias)
; ==================================
exten => 101,n(opcion1),NoOp(Opcion 1 seleccionada)
 
; Cuenta el número de incidencias abiertas
exten => 101,n,MYSQL(Query QCOUNT ${CONNID} SELECT\ COUNT(id)\ from\ mantis_bug_table\ WHERE\ status=10)
exten => 101,n,MYSQL(Fetch foundRow ${QCOUNT} BUG_COUNT) ; fetch row
 
; Si no existen incidencias salimos
exten => 101,n,GotoIf($["${BUG_COUNT}" = "0"]?infoNoHayBugs)
 
; Si existen incidencias indicamos el numero
exten => 101,n,Festival(Hay ${BUG_COUNT} incidencias abiertas:)
 
; Consultamos las incidencias abiertas
exten => 101,n,MYSQL(Query QBUGS ${CONNID} SELECT\ CONCAT(\'Incidencia número\ \'\,id\,\'\: \ \'\,summary)\ from\ mantis_bug_table\ WHERE\ status=10)
exten => 101,n(fetchrow),MYSQL(Fetch foundRow ${QBUGS} BUG_DESC) ; fetch row
exten => 101,n,GotoIf($["${foundRow}" = "0"]?done) ; Si no existen incidencias salimos
exten => 101,n,Wait(1)
exten => 101,n,Festival(${BUG_DESC})
exten => 101,n,Goto(fetchrow)
 
exten => 101,n,Goto(menu) ; Volvemos al menú

Fijaos que al construir la consulta debemos introducir el caracter de espacio debemos hacerlo con una barra invertida delante “\ “.
Ahora con el segundo:

; =================================
; Opcion 2 (Detalle de incidencias)
; =================================
exten => 101,n(opcion2),NoOp(Opcion 2 seleccionada)
exten => 101,n,Wait(1)
exten => 101,n,Festival(Introduzca el número de incidencia con 4 dígitos)
 
;Lectura del numero de incidencia
exten => 101,n,Read(ID,,4)
 
;Buscamos la incidencia introducida
exten => 101,n,MYSQL(Query QDESCRIPTION ${CONNID} SELECT\ description\ from\ mantis_bug_text_table\ WHERE\ id=${ID})
exten => 101,n,MYSQL(Fetch foundRow ${QDESCRIPTION} DESCRIPTION) ; fetch row
 
;Si no existe la incidencia avisamos saltamos a la subrutina que informa que la incidencia no existe
exten => 101,n,GotoIf($["${foundRow}" = "0"]?infoBugInexistente)
 
;Si existe la incidencia se lee su numero y su descripcion
exten => 101,n,Wait(1)
exten => 101,n,Festival(Incidencia numero ${ID}. Descripcion:)
exten => 101,n,Festival(${DESCRIPTION})
 
exten => 101,n,Goto(menu) ;Volvemos al menú

Y el código donde manejamos los mensajes de error:

; =======
; Errores
; =======
exten => 101,n(infoNoHayBugs),Festival(No hay incidencias abiertas.)
exten => 101,n,Goto(menu)
 
exten => 101,n(infoBugInexistente),Festival(La incidencia indicada no existe.)
exten => 101,n,Goto(menu)
 
exten => 101,n(errMysql),Festival(Se ha producido un error de conexión.)
exten => 101,n,Hangup

Un vez guardado este código en el archivo mantis.dialplan en /etc/asterisk/dialplan, tenemos que asegurarnos que lo estamos incluyendo en nuestro dialplan mediante la línea:

#include dialplan/mantis.dialplan

También nos aseguraremos de que la extension [mantis] esté habilitada para las llamadas entrantes poniendo esta linea en nuestro contexto de llamadas entrantes:

include => mantis

Reiniciamos nuestro Asterisk, y voilá! Cuando nuestro técnico llame a la central solo tendrá que marcar el 101 para acceder al menú de consulta de incidencias de Mantis.

Me gusta que los planes salgan bien

“Me gusta que los planes salgan bien…”

La entrada/salida de una aplicación asterisk

Asterisk 1 Comment

A la hora de pensar en una aplicación telefónica real en Asterisk, lo primero que como programador se me viene a la cabeza, es la forma en que se va a comunicar con el usuario. Esto es, la forma en que va a introducir los datos y va a obtener la información deseada.

asteriskEn una aplicación informática estándar, tenemos a disposición del usuario la pantalla del ordenador para mostrar información y un teclado y ratón con el que introducir los datos, sin embargo tenemos que tener en cuenta, que por muy potente que sea el programa que hemos desarrollado en asterisk, el usuario solo va a disponer de un pequeño auricular y un teclado numérico de 10 teclas (y en el peor de los casos, con los antiguos teléfonos analógicos, ni siquiera eso).

Actualmente, con el uso de los teléfonos móviles (y algunos fijos) tenemos la posibilidad de interactuar mediante mensajes SMS, lo cual ofrece una vía adicional de comunicación entre nuestra aplicación y el usuario, pero en este artículo nos centraremos mas en la comunicación basada en la telefonía tradicional.

La salida

El canal de salida estándar en nuestro caso el auricular del teléfono, mediante el cual podremos reproducir sonidos, grabaciones o incluso generar voces sintéticas mediante TTS (text to speech).

juegos de guerra

Una opción económica a la hora de elegir un motor TTS es Festival Speech Synthesis System (Festival para los amigos) una alternativa libre para generar voz sintética. Actualmente se encuentra en su versión 2.0 beta y soporta muchos idiomas y cuando digo muchos me refiero a bastantes. En cuanto a la calidad de la voz, no os voy a engañar, suena a máquina, os parecerá estar hablando con el ordenador de Juegos de Guerra (Que también tiene su encanto, oye!) pero las alternativas son aplicaciones comerciales de pago no asequibles a cualquier bolsillo. Entre las mas conocidas, Verbio y el famoso Loquendo.

La entrada

En cuanto al canal de entrada, la introducción de datos, la fórmula mas sencilla es la utilización del propio teclado del teléfono para introducir dígitos, esto nos limita a usar solo números y los caracteres especiales # y *. Por lo que nos vemos siempre obligados a utilizar códigos de usuario numéricos, contraseñas numéricas y menús organizados por números.

También existen actualmente sistemas de reconocimiento de voz aunque la mayoría aun no están muy depurados. Probablemente ya lo habréis sufrido alguna vez llamando al servicio técnico de alguna compañía (“Por favor, diga claramente el motivo de su llamada…”). El principal problema de estos sistemas es que no son fiables, requieren que el usuario hable claramente, vocalizando y sin ningún ruido de fondo, algo complicado si tenemos en cuenta la gran riqueza dialéctica de nuestro país.

gañan

“No le he entendido, por favor, repita el motivo de su llamada”

Mas adelante ya veremos como montar una aplicación básica en Asterisk usando Festival y el teclado numérico como entrada de datos. Así como la instalación y configuración del servicio Festival.

« Previous Entries