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!

Asterisk Advanced. Day 3

Hoy voy a hacer una prueba, escribir un articulo durante la clase a modo “Inline”. Seguramente salga un articulo demasiado extenso pero al menos, lo máximo completo.

– Teoría de Macros en el DialPlan

En primer lugar un tema que no hemos visto hasta la fecha y es crucial para configuraciones de dialplan repetitivas, las Macros.

Dos conceptos basicos

Las macros se componen del contexto del Macro [macro-<nombredelmacro>]

Solo tienen una extension, la “s”
exten => s,1,Answer()
same => n,Hangup

Por otro lado, las Macros se ejecutan desde el Plan de Marcacion, como una aplicación cualquiera con el formato Macro(<nombredelmacro>, <argumento1>, <argumento2>, etc)

Luego dentro del contexto Macro para poder utilizar esos argumentos llamados se utilizan las variables especificas de las macros ${ARG1}, ${ARG2}, etc

Ejemplo:

[extensiones]
exten => 100,1,Macro(prueba,SIP/mitelefono, 30)

[macro-prueba]
exten => s,1,Dial(${ARG1},${ARG2})

Aparte disponemos de variables especificas de las Macro. ${MACRO_CONTEXT}, ${MACRO_EXTEN} y ${MACRO_PRIORITY}. Sirven para saber dentro de la macro, que contexto, que extensión y que prioridad llamó a la Macro.

Un ejemplo, si utilizamos un Buzon de Voz, que coincide con el numero de extension pues podriamos utilizar ${MACRO_EXTEN}:

[extensiones]
exten => 100,1,Macro(prueba,SIP/mitelefono, 30)

[macro-prueba]
exten => s,1,Dial(${ARG1},${ARG2})
exten => n,VoiceMail(${MACRO_EXTEN})

A partir de aquí ya podemos dar “rienda suelta” a la imaginacion y poder simplificar nuestro trabajo de escritura de tareas repetitivas.

– Asterisk Realtime

Ya conocemos esto de artículos anteriores, como el uso del Web-MeetMe (configuraciones de salas de conferencia directamente desde la Web, a través de bases de datos en “tiempo real” (realtime).

Pero ahora una visión un poco mas práctica de como se trabaja con Realtime, ya que realmente el Web-Meetme siguiendo los pasos venia prácticamente preparado paso por paso y no podíamos entender que estaba haciendo realmente a nivel interno.

La utilidad de Realtime sobre configuraciones en ficheros de texto, es simplemente el hecho de poder introducir modificaciones constantes de una forma ultra-rapida (mediante un interfaz web por ejemplo que acceda a la base de datos).

Un ejemplo tipico: en la web vemos el listado de usuarios, con un boton para borrarlos cuando los damos de baja, y luego un mini formulario en el que ponemos el usuario y la contraseña y damos de alta una extensión inmediatamente. No habria que estar accediendo al servidor, accediendo al fichero de texto, editándolo, guardando, recargando el modulo, etc…

En configuraciones estáticas (situaciones en las que rara vez se cambia una extension por ejemplo), es poco practico por que puede salir mas caro el collar que el perro. Pero si un dia nos da por diseñar una interfaz web sencilla, y una base de datos (fichero .sql) que precargue nuestros valores default, podriamos implementar esto en tiempo record y podríamos tenerlo siempre presente en todas nuestras instalaciones (quizá algún día lo plantee esto como un articulo, muchos temas ya tengo pendientes conforme avanzamos en el mundo de Asterisk).

Un primer inconveniente que encontramos, es que Asterisk pretende centralizar todas las conexiones a bases de datos a traves de una capa de abstraccion como ODBC, es decir que los conectores directos nativos como MySQL y PostgreSQL tienden a su desaparicion. Para los no demasiado experimentados en el mundo ODBC esto podria ser un inconveniente a corto plazo.

Si recuerdan, el Web-Meetme lo hacia todo a traves de ODBC asi que este problema lo salvan (lo que no salvan que Meetme tiende a desaparcer tambien en favor de ConfBridge (nueva aplicación para conferencias sin necesidad de timing, tambien hablaremos de ella en un futuro).

Ahora sobre la configuración los ficheros involucrados

En primer lugar /etc/asterisk/extconfig.conf necesitamos añadir una linea del tipo
<nombredelaconfiguracion> => <driver>,<nombrebasededatos>,<nombretabla>

En el caso ejemplo del Web-Meetme era:
meetme => odbc,meetme, booking

El segundo fichero es el /etc/asterisk/res_config.conf

[nombrebasededatos]
enabled => yes // Esta activada la conexion
dsn => el Data Source Name del driver ODBC
pre-connect => yes // La conexión se ejecuta al arrancar Asterisk
username => usuario de la base de datos // En caso que conectemos por Puerto a la base de Datos, como en bases remotas
password => password de la base de datos // Lo mismo que lo anterior

En el ejemplo que estamos siguiendo:

[meetme]
dsn => meetme (este es el contexto que creamos antes en el sistema)
username => asterisk (supuestamente va a ser nuestro usuario para asuntos de Asterisk y servidor de base de datos)
password => asterisk (o la que le pusiéramos)
pre-connect => yes
enabled => yes

Ahora la configuracion del driver odbc en el sistema, /etc/odbc.ini

[meetme]
Description = ODBC para MySQL // Una descripcion cualquiera
Driver = MySQL // El driver ODBC que utilizamos, en este caso para MySQL por el tema ese que va a tender a desaparecer que comentábamos antes
Server = localhost // Servidor donde esta la base de datos
Database = meetme // Nombre de la base de datos con la que trabajaremos
Port = 3306 // Puerto de la base de datos
User = asterisk // En caso que conectemos por puerto en vez de por Socket
Password = asterisk // En caso que conectemos por Socket
Socket = /var/run/mysqld/mysqld.sock // Por aquí conectamos por Socket

Y finalmente /etc/odbcinst.ini

[MySQL]
Description = MySQL ODBC MyODBC Driver
Driver = /usr/lib/odbc/libmyodbc.so // librería ODBC del Driver MySQL
Setup = /usr/lib/odbc/libodbcmyS.so // librería ODBC de Configuración MySQL

Solo quedaria configurar la tabla y base de datos y ya preparado.

Algunas consideraciones adicionales: para reducir el numero de peticiones a cache, el fichero de configuracion del modulo que estamos convirtiendo en “RealTime” introducimos la siguiente variable: rtcachefriends=yes

De aquí pueden surgir multiples ideas prácticas que me gustaria probar personalmente y dedicar un articulo especifico con mis resultados, como por ejemplo, crear una funcion en func_odbc.conf para consultar algo especifico de una base de datos externa para tratarlo a traves del DialPlan, como por ejemplo consultar el telefono de un Cliente.

– CDR y CEL

Esta parte trata sobre como se gestiona CDR (Registro de Detalles de Llamada) y la nueva implementación mas detallada del registro CEL, en el que es posible ver a nivel de flujo de llamada de DialPlan, no solo a nivel de canal. La verdad es que es meramente informativa con informacion sobre los campos que se utilizan, y algunas aplicaciones de dialplan para edicion, pero realmente merece un articulo bastante amplio para poder entrar en detalle incluso algun mecanismo para extraer informacion como vimos en el articulo de CDR-Stats, una gran aplicación para poder visualizar los datos de forma bastante generica (y recuerdo que quede en montar un software para analizar llamadas pero mas en detalle para un proposito en concreto).

– El mundo de las Tarjetas Analogicas

Ya dedique varios articulos a este tema cuando empece a trabajar con la tarjeta TDM410P como el siguiente y la segunda parte del mismo.

Algunos conceptos novedosos y no vistos hasta la fecha:

Sobre la tecnologia Analogica, existen tres posibles de sistemas de señalizacion, (en el fichero chan_dahdi.conf) ground start (en desuso), loop start (tambien en desuso) y kewl start (sistema mas utilizado en la actualidad, 99% de los casos).

Otra novedad que trae la version 1.8 es la posibilidad de crear contextos en el chan_dahdi.conf y tener por ejemplo un contexto generico [channels] donde especificar ciertos argumentos especificos de la tecnologia analogica (que eran los que soliamos definir antes del channel => cuando utilizabamos un modulo FXO

Ejemplo:

[channnels]
usecallerid = yes
transfer = yes

[telefono-analogico]
callerid = “Telefono Analogico” <1001>
context= extensiones
signaling = fxo_ks
dahdichan = <el_canal_que_definimos_en_/etc/dahdi/system.conf>

[linea-analogica]
callerid=asreceived
context = llamadas_entrantes
signaling = fks_ks
dahdichan = <el_canal_que_definimos_en_/etc/dahdi/system.conf>

Pero luego, en el Dialplan tenemos que seguir definiendo en canal a la vieja usanza (DAHDI/1, DAHDI/2, etc…)

Dato importante de las lineas extrantes analogicas, es que hay que mandarlas a un contexto en el DialPlan (por ejemplo, llamadas_entrantes) y dentro de ese contexto, poner la extension “s” (start) ya que es imposible reconocer hacia donde pretende ir esa llamada por las limitaciones de la “analogia”.

Mañana parece que seguiremos con el tema de las conexiones de Tarjeteria, pero esta vez con una nueva que no hemos visto hasta la fecha, una tarjeta de Primarios.

Espero vuestros comentarios sobre como quedo esta “modalidad” de blogging inline. Para mi particularmente resulto mas comoda porque en los huecos libres podia ir escribiendo, y no tener que hacer todo el texto ya a deshoras y ademas tambien ha servido un poco con “apuntes personales” de lo visto para revisiones futuras (como realmente es el blog entero para mi personalmente).

MeetMe in a Box: Web-MeetMe: Conferencias de Audio de altos vuelos.

Hoy en día es muy común ver multitud de software web, capaz de ofrecer funcionalidades de conferencias online, webminars (seminarios web), y videoconferencias llevadas a reuniones. Llegaremos a eso algún día, pero como para ello se requiere el software, y el hardware especifico (y de calidad), y en estos momentos como todos sabemos, el horno no está para bollos (pese a que la gran mayoría sabemos a día de hoy lo que nos podríamos ahorrar, existen aún defensores, como George Clooney en “Up in the Air” que defienden “lo presencial”).

De momento no vamos a conformarnos con poco, y vamos a tratar de montar un sistemas de conferencias por Audio, de bajo coste, y si puede ser con Teléfonos de por medio, que hoy en día, las llamadas a fijos están muy baratas y dan una calidad de audio ““streaming”” excepcional.

Y a este sistema, Asterisk lo llamó MeetMe. Y realmente es tan simple como el tema de los buzones de voz (incluso más simple aun!) con su Aplicación con el mismo nombre, y su fichero de configuración meetme.conf. Pero voy a dar un paso más allá: Haciendo uso de esta base, poder obtener el potencial de un sistema de Gestión de Conferencias de Audio en tiempo real, a través de una Interfaz Web. Esto, realmente suena mucho mejor que “una conferencia a tres (o a cuatro)”, como quien dice. Vamos allá.

Para la Interfaz Web MeetMe van a hacer falta algunos elementos. Algunos ya los tendremos si hicimos la instalación de LAMP en su día.

En primera instancia vamos a ir descargando el paquete estrella, la interfaz Web-MeetMe. La página oficial seria: https://sourceforge.net/projects/web-meetme/

# tar –xvf web-meetme_(versión que sea)
# cd web-meetme

En primer lugar toca configurar el Driver ODBC para conectar con nuestra base de datos MySQL. Hay que instalar algunos detalles para el ODBC de nuestro sistema
# aptitude install unix-odbc
# aptitude install libmyodbc

Ahora configuramos el driver en condiciones. Primero editamos /etc/odbcinst.ini para crear un driver a MySQL:

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

Luego configuramos el fichero /etc/odbc.ini con la siguiente información.

[meetme]
Description = ODBC para MySQL
Driver = MySQL
Server = localhost (local, o servidor donde tengamos la base de datos con el driver ODBC)
Database = meetme (tenemos que crear una base de datos igual que la de Asterisk, pero con este nombre, para diferenciar un poco, en mysql,
Port = 3306
User            = asterisk
Password        = asterisk
Socket = /var/run/mysqld/mysqld.sock (puede que este fichero de socket este en otro sitio dependiendo la distribución donde tenemos nuestro sistema)
Stmt =
Trace = yes
TraceFile = /tmp/odbc.log

No entro en detalles, porque esto es configuración del conector ODBC para acceder a nuestra base de datos MySQL que supuestamente, ya tenemos instalada.

Para configurar la nueva base de datos meetme, simplemente podemos entrar en la consola mysql #mysql –u asterisk –p y poner el comando: CREATE DATABASE `meetme` ;

A partir de ahí generamos las tablas. Si no hemos salido del directorio web-meetme del paquete que descargamos antes ejecutamos:
# mysql –u asterisk –p < ./cbmysql/db-table-create-(version-que-sea).txt
# mysql –u asterisk –p < ./cbmysql/upgrade-db.txt

Ahora realizamos la configuración del conector ODBC de Asterisk, el fichero de configuración es /etc/asterisk/res_odbc.conf, creando un contexto específico para meetme.

[meetme]
dsn => meetme (este es el contexto que creamos antes en el sistema)
username => asterisk (supuestamente va a ser nuestro usuario para asuntos de Asterisk y servidor de base de datos)
password => asterisk (o la que le pusiéramos)
pre-connect => yes

Ahora en extconfig.conf (si tenemos el fichero de ejemplo, tan solo buscamos la línea meetme => y cambiamos lo que haya al completo por:
meetme => odbc,meetme,booking

Como todo lo hacemos a través del driver ODBC pues los Call Detail Records, los vamos a registrar de esta manera también. En el fichero cdr_adaptative_odbc.conf:

[wmm]
connection=meetme
// este es el context que utilizamos antes en res_odbc.conf)
table=cdr
// vamos a llamar a la tabla igual que la llamamos en la bbdd Asterisk. Realmente podríamos basarnos en la misma base de datos que ya tenemos, pero en este caso, para que no sea estrictamente necesario seguir el planteamiento de CDR-Stats vamos a independizarlo.

También hace falta introducir una pequeña opción en meetme.conf para evitar usar una columna del Asterisk RealTime para meetme que web-meetme no utiliza:

logmembercount=no

Después de esto tenemos una opción para acceder al sistema utilizando un servicio LDAP, o utilizando usuarios creados a mano en la base de datos. En nuestro caso de momento, vamos con esta opción, ya que a priori tampoco deberíamos tener tantos… o sí. Me apunto esto para en un futuro, actualizar con un sistema LDAP como ampliación del poder de Asterisk + LINUX. Para crear la estructura de la tabla “user”, como antes en el directorio web-meetme ejecutamos:
# mysql –u asterisk –p < ./cbmysql/db-admin-user-create.txt

Con esto ya tenemos creada la base del sistema.

Ahora vamos a configurar el sistema Web-Meetme en si.

En primer lugar tenemos que preparar la interfaz web dentro de nuestro directorio raíz donde se publican las web de nuestro servidor Apache. Por regla general y por defecto suele ser /var/www. Ahí podemos crear un nuevo directorio específico para Web-Meetme
#mkdir /var/www/web-meetme

Ahora vamos a copiar todo el tarball que descargamos al principio de Web-Meetme en este directorio recién creado:

#cp –r /ruta/donde/este/nuestro/tarball/descomprimido /var/www/web-meetme

Ahora toca configurar los parámetros de nuestra Interfaz Web en los ficheros de configuración de la misma, en primer lugar dentro del directorio raíz de web-meetme vamos /lib/defines.php de momento lo básico es configurar los datos de acceso a nuestra base de datos y algunos campos clave:

define (“WEBROOT”, “http://ip-nuestro-servidor/web-meetme/”);
// La dirección web relativa de nuestro
define (“FSROOT”, “/var/www/web-meetme/”);
// La ruta a la interfaz
define (“LIBDIR”, FSROOT.”lib/”);
// Esto tal cual

Finalmente editamos una más, para identificación de usuarios, en nuestro caso habíamos creado una tabla “user” (automáticamente durante el proceso de carga de datos SQL que hicimos antes) dentro de nuestra base de datos meetme para la administración de usuarios:

define (“AUTH_TYPE”, “sqldb”); // adLDAP or sqldb

Existe un usuario en la base de datos administrador creado por defecto. Que luego usaremos para acceder el sistema y poder crear usuarios adicionales personalizados.
Usuario: wmm@localhost
Password: wmmpw

También es necesario configurar los parámetros de la base de datos. En este caso se realiza desde el fichero dentro de /lib/database.php:

$database = ‘meetme’;
$host = ‘localhost’;
$username = ‘asterisk’;
$password = ‘asterisk’;

Si os fijáis este fichero hace referencia a un módulo DB.php. Para poder hacer uso de este también es necesario instalar un paquete, php-pear y su módulo db
# aptitude install php-pear
# pear install db
El caso es que al parecer el modulo db ha quedado obsoleto y lo sustituye mdb2
# pear install mdb2 (aunque con el primero ya es suficiente en el momento que escribo este artículo)

Por otro lado nos toca configurar la interfaz para comunicarse con el Asterisk Manager. Para ello debemos configurar primero el manager de Asterisk y añadir un usuario para esto específico. En el directorio /etc/asterisk, fichero manager.conf, creamos un nuevo contexto, que va a ser justamente el usuario que vamos a utilizar:

[meetme]
secret = meetme (la password que queramos)
read = call
write = command,originate
Y luego como siempre #asterisk –rx ‘manager reload’

Y ahora en el directorio de la interfaz web de Web-Meetme, dentro de /phpagi tenemos un fichero de configuración de ejemplo que vamos a utilizar
#cd /var/www/web-meetme/phpagi
#cp phpagi.example.conf /etc/asterisk/phpagi.conf

Y lo editamos asi:
# vim /etc/asterisk/phpagi.conf

Dentro de [asmanager]
server=localhost
port=5038
username=meetme
secret=meetme

También tenemos que editar el fichero index.html para adaptarlo a la ruta relativa de nuestra web. Algo así:

<META HTTP-EQUIV=”REFRESH” CONTENT=”0; URL=http://servidor_ip/web-meetme/meetme_control.php”>

Y ya está todo lo básico. Ahora podemos acceder a nuestro sistema Web MeetMe desde
http://ip_servidor/web-meetme

Lo último de todo sería configurar una marcación en el extensions.conf para poder acceder a nuestro sistema, sea desde un DID que tuviéramos configurado, o directamente a la extensión en concreto. Por ejemplo:

exten => 5000,1,NoOp()
exten => 5000,n,Answer
exten => 5000,n,MeetMe()

Y con esto marcando el 5000 si en la interfaz habíamos creado un número de conferencia, nos pedirá, el número de conferencia y el PIN asignado para acceder a la misma.

Lo más curioso de esto es que en este proyecto también está presente Areski Belaid, creador del CDR-Stats y también de A2Billing, uno de  “tarificadores” más reconocidos en Asterisk, y desde este Blog agradecemos sus contribuciones al mundo de la Interfaz web para Asterisk.

Otras curiosidades que he encontrado, php-agi no está diseñado para trabajar con una version PHP superior a 5.2. Es por esto por lo que aparece un error en el log de apache constante:

PHP Parse error:  syntax error, unexpected T_GOTO, expecting T_STRING

La solución a este problema es muy fácil, la function goto está obsoleta, por eso vamos a nuestro directorio de web-meetme /var/www/web-meetme/phpagi y dentro modificamos el fichero phpagi.php, vamos a la línea donde aparece:

“function goto”

Y la cambiamos por “function goto2”. Así de simple.

Así el sistema quedaría configurado como para poder crear una sala de conferencias, visualizar los usuarios, expulsarlos a voluntad, bloquearles el micrófono, gestiones simples de administración de conferencias… aunque todavía no he llegado a alcanzar el 100% de la funcionalidad. La documentación es muy pobre, y mis vanos intentos de conseguir resultados no han llegado a buen puerto. Por ejemplo la función de Invite, para poder ser aplicada a través de un Troncal SIP, no consigo hacer que el sistema se autentifique correctamente para lanzar la llamada a través del mismo. La mayor parte de la configuración se consigue editando las variables del fichero defines.php, aun así, he de reconocer que el software tiene un nivel de personalización bastante grande, ya entrare en detalles sobre esto en otro momento. Al menos con esto es posible tener en marcha lo básico para poder trabajar eficientemente.

Obteniendo un control exhaustivo de llamadas con CDR-Stats

Una de las funciones más interesantes que tiene Asterisk casi por defecto, es el hecho de guardar todo un registro completo de eventos acontecidos, todos aquellos movimientos a través del Plan de Marcación en tiempo real. Y estos eventos pueden quedar registrados de diversas formas, sea en ficheros CSV (comma separated values) formato muy común de almacenaje de datos en ficheros de texto planos, o registros en una base de datos SQL (Postgre SQL, MySQL, etc).

En mi caso, he mostrado un gran interés en registrar los eventos en una base de datos MySQL puesto que ha sido hasta la fecha, pese a ser propietaria de la todopoderosa Oracle (y porque no decirlo, Sun Microsystems me caía mejor como corporación), la que más he manejado en mi vida. Quizá algún día empiece a indagar en el mundo del elefantito Postgre, pero de momento la combinación MySQL y el gestor del gestor, valga la redundancia, phpMyAdmin, simplifica mi existencia.

Ahora, tras esta breve introducción, voy a explicar cómo combinar estos dos elementos, el registro detalle de llamadas (CDR, call detail record) con una base de datos MySQL, y poder obtener una interfaz genérica, ya preparada, y de gran utilidad para manipular estos registros de llamada: CDR-STATS (créditos a Areski Belaid por este excelente trabajo de integración)

Pues como siempre, empecemos manos a la obra.

En primer lugar, toca configurar el sistema Asterisk para que vaya almacenando de forma automática todo el registro de llamadas en la base de datos, y por ende, necesitamos la base de datos instalada en nuestro sistema. Para ello lo más sencillo, en el sistema en que nos encontramos (Ubuntu Server), es instalar LAMP (Linux + Apache + MySQL + PHP) ya que toda esta combinación nos servirá en un futuro cada una de sus partes (Apache y MySQL son requeridos por Cdr-stats y PHP por phpMyAdmin).

Existe un comando en Ubuntu Server muy sencillo que nos permitirá hacer la instalación de este sistema en cuestión de segundos: tasksel (veremos aquella pantalla que vimos en su día durante la instalación del sistema base). Ahí seleccionamos Servidor LAMP y validamos, instalándose automáticamente todo. Nos pedirá algunos detalles de instalación, como las contraseñas de acceso root a nuestra base de datos MySQL que necesitaremos para la posterior configuración.

A continuación instalamos phpMyAdmin para la gestión sencilla como comentaba antes: aptitude install phpmyadmin. Nos pedirá entre otros temas, la contraseña de administrador (root) de nuestra base de datos Mysql, se la proporcionamos. Una vez instalado, con un navegador apuntando a nuestro servidor Asterisk podemos acceder (o a la dirección donde este ubicado nuestro servidor web si lo tenemos independiente al servidor asterisk): http://servidorasterisk/phpmyadmin. Ahí podremos acceder de momento con el usuario “root” y la contraseña de administrador a nuestras bases de datos.

Ahora tenemos que empezar a diseñar la base de datos donde vamos a almacenar nuestros CDR de Asterisk.  De momento, creamos un archivo de texto que llamamos por ejemplo, dbasterisk.sql y dentro agregamos:

CREATE DATABASE asterisk;
GRANT INSERT
ON asterisk.*
TO asterisk@localhost
USE asterisk;

CREATE TABLE `cdr` (
`calldate` datetime NOT NULL default ‘0000-00-00 00:00:00’,
`clid` varchar(80) NOT NULL default ”,
`src` varchar(80) NOT NULL default ”,
`dst` varchar(80) NOT NULL default ”,
`dcontext` varchar(80) NOT NULL default ”,
`channel` varchar(80) NOT NULL default ”,
`dstchannel` varchar(80) NOT NULL default ”,
`lastapp` varchar(80) NOT NULL default ”,
`lastdata` varchar(80) NOT NULL default ”,
`duration` int(11) NOT NULL default ‘0’,
`billsec` int(11) NOT NULL default ‘0’,
`disposition` varchar(45) NOT NULL default ”,
`amaflags` int(11) NOT NULL default ‘0’,
`accountcode` varchar(20) NOT NULL default ”,
`userfield` varchar(255) NOT NULL default ”
);

ALTER TABLE `cdr` ADD `uniqueid` VARCHAR(32) NOT NULL default ”;
ALTER TABLE `cdr` ADD INDEX ( `calldate` );
ALTER TABLE `cdr` ADD INDEX ( `dst` );
ALTER TABLE `cdr` ADD INDEX ( `accountcode` );

De momento no interesa demasiado eliminar ningún campo porque si no luego podremos tener problemas con el CDRStats, que aun solucionables, no deseamos complicarnos la vida de momento.

Con esto lo introducimos en nuestra base de datos con el sencillo comando, que solo nos pedirá nuestra clave de administrador de MySQL
mysql –p  < dbasterisk.mysql

Lo segundo que necesitamos es instalar el módulo de Asterisk cdr_mysql. Seguramente durante la instalación del Asterisk-Addons (en caso de la versión 1.6.2) o directamente durante la instalación de Asterisk (versión 1.8), con la opción make menuconfig pudimos seleccionar el módulo cdr_mysql. En otro caso nos tocaría volver a recompilar Asterisk-Addons incluyendo este módulo. En caso que no, vamos a donde descomprimimos el tarball de Asterisk-addons, y realizamos la siguiente secuencia:

# make menuconfig (seleccionamos debajo del submenú Call Detail Recording cdr_msql)
# ./configure
# make
# make install

Y ya tendríamos preparado el modulo. Solo quedaría configurarlo para empezar a registrar llamadas en nuestra base de datos. Existe un fichero de configuración en /etc/asterisk llamado cdr_mysql.conf que retocaremos asi:

[global]
hostname=localhost
dbname=asterisk
table=cdr
user=asterisk
// A continuacion crearemos un usuario llamado asterisk desde la interfaz de phpmyadmin
password=contraseñadeasterisk
port=3306
// Puerto por defecto de MySQL y si lo cambiamos tendremos que cambiarlo aquí también

Aparte, bajo el contexto [columns] debemos eliminar todos los comentarios “;” que empiecen por alias y static.

Por otro lado nos toca configurar el nuevo usuario asterisk. Dentro de phpMyadmin accediendo por la interfaz web como comente antes, entramos en la opción Privilegios, seleccionamos el usuario asterisk que en teoría debería haberse creado junto a la base de datos y le damos al botón de edición, o creamos uno nuevo seleccionando “Agregar nuevo usuario”.

Aquí solo tenemos que darle permisos totales para acceder a la base de datos (si es que solo vamos a utilizar esta base de datos para Asterisk, sino, ya seleccionamos privilegios básicos de datos y no de estructura y menos de administración) y damos a Continuar (se actualizan los privilegios). Luego en la contraseña, le ponemos la contraseña que especificamos antes y le volvemos a dar a continuar para actualizar. Esto es todo.

Ahora simplemente accedemos a la CLI y cargamos el módulo mysql con el comando: reload cdr_addon_mysql.so

Aparte podemos comprobar que esta todo OK si ponemos el comando cdr show status en el apartado Registered Backends aparecerá uno que pone “mysql”.

Ya tenemos nuestro Asterisk “registrando” todas las llamadas en nuestra base de datos. Considerar que en función del espacio de nuestro sistema tendremos que purgar eventualmente el registro para no saturar la base de datos en función del uso que le demos a nuestra máquina. Aunque esto ya es administración de SQL y debería ir dedicado en otro capítulo.

Ahora viene la configuración de CDR-Stats para poder ver de forma “bonita” ese registro de llamadas, aunque realmente podríamos crear con lo que tenemos cualquier interfaz en php que acceda a esta tabla (cdr) de la base de datos (asterisk) en función de nuestras necesidades. Quiza algún día próximo haga alguna aproximación a esto para poder crear un sistema muy básico y así generar un informe concreto de rápido acceso desde una interfaz web, ya que he podido observar que CDR-Stats, aún siendo muy bonito, no llega a ser todo lo completo que uno podría llegar a necesitar en un momento determinado, dada su “genericidad” y para obtener información de alta calidad, requiere dar muchos pasos (crear muchos filtros, con la consiguiente pérdida de tiempo si especialmente se trata de un trabajo diario repetitivo), en vez de poder obtener un informe concreto de un solo golpe (por ejemplo número de llamadas atendidas por cada extensión, o número de llamadas salientes por cada extensión y tiempo total consumido). Incluso podríamos filtrar por tipo de llamadas por extensión y tiempo consumido (a móviles, a fijos y demás), al puro estilo “Facturador Telefónico”. Supuestamente existen software muy avanzados de facturación para Locutorios (Asterisk es un sistema ideal para este tipo de negocios de bajo coste) y otros Retailers que se dediquen a este mundillo (Expendedores de tarjetas de llamadas, etc). Este software se llama A2Billing (asterisk2billing), y ha sido creado por la misma empresa que pertenece Areski Belaid, creador de CDR-Stats como comente antes.

En la página web del creador existe documentación sobre su instalación, pero debo decir que es de muy baja calidad, y siguiéndola paso a paso yo no conseguí hacerlo funcionar. Y tengo constancia que muchos otros tampoco lo consiguieron.  Hay que considerar que CDR-Stats no está pensado originalmente, para ser integrado en una maquina Asterisk a modo “Standalone” sino como un módulo de sistemas completos Asterisk tipo FreePBX o Elastix. Pero siguiendo la filosofía de este blog, haciendo esto desde 0 estamos en contacto con la “naturaleza” del sistema Asterisk y estaremos más cubiertos ante la posibilidad de fallos o desastre sin la complejidad de un sistema prefabricado y preconfigurado.

En primer lugar nos toca instalar la última versión de Python, por los tiempos que corren ahora, se trata de la versión 2.6: aptitude install python2.6

Luego viene un modulo de Python utilizado por este sistema muy útil para la creación de sitios web con Python: Django en la web http://www.djangoproject.com/download/

La instalación de este es muy sencilla tras ser descargado:
# wget http://www.djangoproject.com/download/1.2.4/tarball/
// La versión puede variar con el momento también
# tar xzvf Django-1.2.4.tar.gz
// Igual lo que viene va en función de la versión
# cd Django-1.2.4
# pythong setup.py install

Luego necesitamos otro módulo de Python, Dateutils, lo podemos obtener de los repositorios de Python, pero para ello necesitamos la herramienta easy_intall:
# aptitude install python-setuptools
# easy_install DateUtils

Y a continuación, otro llamado South:

# easy_install South

Ahora viene un módulo de Django, llamado Uni Form. En este caso la última versión del módulo se puede descargar de la página del Autor: https://github.com/areski/django-uni-form/downloads

# wget https://github.com/areski/django-uni-form/tarball/0.8.0 –no-check-certificate
# tar xvf 0.8.0
// En estos casos como antes, estamos sujetos a la version, creo que es importante conocer commandos de Linux a la perfeccion para poder adaptarse con comodidad a estos commandos en function del tiempo en el que leamos este articulo
# cd areski-django-uniform-xxxxx…. (aquí viene el directorio recién descomprimido)
# python setup.py build
# python setup.py bdist_egg
# easy_install dist/django_uni_form-0.8.0-py2.6.egg (sujeto a versión de uniform y python también)

Ya tenemos el sistema listo, solo falta descargamos finalmente el personaje principal de tidi esto: CDR-Stats. Tenemos dos opciones, con el tarball, o con la última versión git subida por el autor. Para no complicarnos la vida nada, lo haremos con el Tarball y seguir en la tónica de hasta ahora, aunque invito fervientemente a aprender a utilizar git puesto que es un sistema de Control de Versiones excelente y con 4 comandos básicos, se vuelve muy sencillo de manejar.

# wget https://github.com/areski/cdr-stats/tarball/v1.1.0 –no-check-certificate
# tar xvf v1.1.0
// Y ahora preparamos ya lo descomprimido para ubicarlo en el lugar que sera ejecutado con nuestro Apache automáticamente justo en el ultimo paso
# mkdir /usr/share/django_app
# cp –r areski-cdr-stats-(directorio recién descomprmido)/cdr_stats /usr/share/django_app

Así tendremos preparado el sistema cdr_stats en su directorio de “instalación” como veremos mas adelante. Entramos en esa carpeta /usr/share/django_app/cdr_stats y editamos el fichero settings.py:

En la línea de ADMINS descomentamos y ponemos nuestro nombre y correo electrónico para figurarnos como administrador del sistema CDR-Stats

Luego en las sección Databases, tenemos que poner los parámetros de conexión de nuestro sistema MySQL:
‘ENGINE’:’mysql’,
‘NAME’:’asterisk’,
‘USER’:’asterisk’,
‘PASSWORD’:’contraseña_del_usuario_asterisk’

Seguimos adelante, en la sección LANGUAGE_CODE ponemos ‘es-es’, en TIMEZONE ‘Europe/Madrid’ (si somos de España)
Sino buscamos en http://en.wikipedia.org/wiki/List_of_tz_zones_by_name

Más abajo, en la sección: MEDIA_URL vamos a poner la dirección local de nuestro asterisk y el puerto 9000 quedando algo asi:
MEDIA_URL=’http://ip_del_servidor_web:9000/resources/’ (no dejar localhost porque podremos tener problemas si accedemos desde otro sitio que no sea el servidor con la carga de recursos)

Luego vamos a generar una clave privada única para cambiar la que viene por defecto en la sección SECRET_KEY con el siguiente comando de consola:
tr -dc A-Za-z0-9 < /dev/urandom | (head -c $1 > /dev/null 2>&1 ||head -c 50) && echo

Y finalmente en la parte de este fichero de configuración, en INSTALLED_APPS tenemos que comentar la línea  #’dilla’

Ahora crearemos un enlace simbolico para los elementos media de python que usaremos en nuestro entorno (supuestamente estamos en la carpeta /cdr_stats/admin de /django_app

ln -s  /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media/ /usr/share/django_app/cdr_stats/admin

Finalmente sincronizamos la base de datos con el sistema Python, necesitamos un módulo adicional para poder  trabajar con MySQL y Python conjuntamente:
#aptitude install python-mysqldb
# python manage.py syncdb

Ahora pedirá una serie de datos sobre el primer usuario de Administrador, los rellenamos, nombre de usuario, email, contraseña, etc. Con esto podremos acceder a la interfaz web de CDR-Stats por primera vez. Si queremos crear otros superusuarios basta con que ejecutemos el siguiente comando:
python manage.py createsuperuser –username=usuarioejemplo –email=usuarioejemplo@ejemplo.com

Con esto ya tendremos el sistema base de CDR_Stats configurado por completo. Ahora solo necesitamos probar que el sistema funciona bien, antes de “automatizarlo” en nuestro Apache para futuros usos:
python manage.py runserver 0.0.0.0:9000

Y entramos a la interfaz web http://ip_servidor_web:9000 nos redirigirá a la pagina de CDR-Stats nuestra, ahí accedemos con el usuario y contraseña creados antes. Si podemos verla sin problemas (Recordar que usa Flash asi que necesitaremos el plugin en nuestro navegador adecuado), entonces ya tendremos todo listo.

Finalmente vamos a configurar el servidor Apache para que ejecute el soft ware automáticamente al arrancar nuestro servidor. Necesitamos cargar un modulo de Apache para poder ejecutar programas en Python:
aptitude install libapache2-mod-python

Creamos un fichero llamado cdr_stats.conf dentro de la carpeta /etc/apache2/sites-available/ con la siguiente información:

Listen *:9000
<VirtualHost *:9000>
DocumentRoot /usr/share/django_app/cdr_stats/
ErrorLog /usr/share/django_app/err-cdr_stats.log
<Location “/”>
SetHandler mod_python
PythonHandler django.core.handlers.modpython
PythonPath “[‘/usr/share/django_app/cdr_stats/’,’/usr/share/django_app/’] + sys.path”
SetEnv DJANGO_SETTINGS_MODULE cdr_stats.settings
PythonDebug On
</Location>
<location “/media”>
SetHandler None
</location>
</VirtualHost>

Ahora creamos un enlace simbolico a este fichero, en la carpeta sites-enabled:
ln -s /etc/apache2/sites-available/cdr_stats.conf /etc/apache2/sites-enabled/

Reiniciamos el servidor Apache: service apache2 restart

Y aunque suene poco profesional, como diría nuestro amigo Porky, That’s all Folks! Deberíamos de ver, accediendo de nuevo a la dirección anterior en  nuestro navegador web, el sistema CDR-Stats en funcionamiento.

Si queda algún fleco o alguna duda sin resolver en este mensaje, no duden en ponerme un comentario y actualizare esto para dejarlo lo más completo posible.