Un cliente llama y se queja de la calidad de las llamadas “escucho entrecortado”, “tengo eco” y un largo etcétera. ¿Cómo podemos darle una respuesta fiable y anexarle un reporte de la calidad de sus llamadas? Trabajando con el modulo cdr_adaptive de Asterisk y creando una tabla personalizada donde guardar los datos que nos interesa.
Prerrequisitos: Haber compilado Asterisk con el soporte ODBC
El modulo cdr_adaptive permite crear tablas personalizadas de CDR y guardar los datos en una base de datos a través del conector ODBC. Pero ¿Qué datos vamos a guardar? En esto nos ayuda la función CHANNEL de Asterisk. Entre los distintos valores que podemos leer de un canal activo, están:
- peerip: la IP de origen del canal
- rtpqos: permite leer distintas informaciones acerca de la calidad de la llamada. Entre ellas:
- local_lostpackets: los paquetes audio/video perdidos a lo largo de la llamada
- local_count: numero total de paquetes audio/video recibidos
- local_jitter: Jitter local de la llamada
- remote_lostpackets: los paquetes audio/video perdidos entre los trasmitidos
- remote_count: numero total de paquetes audio/video trasmitidos
- remote_jitter: jitter remoto para la llamada
- useragent: el dispositivo utilizado para la llamada (telefono SIP; Softphone; PBX, etc)
- audioreadformat: codec audio del canal
- audiowriteformat: codec audio saliente
Además de estos valores, vamos a escribir en la tabla otros:
- accountcode: el código o cuenta del cliente
- hangupcause: variable generada por la aplicación Dial que contiene un código que nos dice como y porque ha terminado la llamada
- calldate: la fecha de la llamada
- dst: el numero de destino de la llamada
- billsec: duración de la llamada desde que ha sido contestada
Algunos de estos campos los escribe Asterisk en automático ya que son parte de las variables predefinidas del CDR (Call Data Record). Otros hay que declararlos en el dialplan. Con estos datos vamos a crear la base de datos (o utilizar una existente) y la tabla correspondiente.
mysql -u root -ppassword
mysql> create database asterisk;
mysql> use asterisk
mysql> CREATE TABLE `cdr2` (
`id` bigint(20) NOT NULL auto_increment,
`calldate` datetime NOT NULL default '0000-00-00 00:00:00',
`accountcode` varchar(20) default NULL,
`dst` varchar(80) NOT NULL default '0',
`billsec` varchar(80) NOT NULL default '0',
`peerip` varchar(80) NOT NULL default '',
`useragent` varchar(80) NOT NULL default '',
`codec1` varchar(80) NOT NULL default '',
`codec2` varchar(80) NOT NULL default '',
`tlp` int(15) NOT NULL default '0',
`llp` int(15) NOT NULL default '0',
`porlp` decimal(6,3) unsigned zerofill NOT NULL default '000.000',
`trp` int(15) NOT NULL default '0',
`rlp` int(15) NOT NULL default '0',
`porrp` decimal(6,3) unsigned zerofill NOT NULL default '000.000',
`ljitter` varchar(20) NOT NULL default '',
`rjitter` varchar(32) NOT NULL default '',
`hangupcause` varchar(80) NOT NULL default '',
PRIMARY KEY (`id`)
);
Si se fijan hay dos campos de que no hemos hablado:
- porlp: este campo contendrá el porcentaje de paquetes locales perdidos cuyo calculo se hará a través de una operación matemática muy sencilla
- porrp: este campo contendrá el porcentaje de paquetes remotos perdidos cuyo calculo se hará a través de una operación matemática muy sencilla
Ahora creamos los permisos para la base de datos asterisk, desde local:
mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo';
desde remoto:
mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo';
actualizamos los permisos:
mysql> flush privileges;
salimos del cliente MySQL:
mysql> quit
Ahora creamos una conexión a la base de datos MySQL con ODBC. Si es la primera vez que utilizan ODBC hay que seguir estos pasos:
nano /etc/odbcinst.ini
Para CentOS 5.7 32 bit debe contener:
[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/libmyodbc3.so
Setup = /usr/lib/libodbcmyS.so
FileUsage = 1
nano /odbc.ini
[cdr2]
Description = MySQL CDR2
Driver = MySQL
Database = asterisk
Server = localhost
User = asterisk
Password = sesamo
Port = 3306
Option = 3
El bloque de arriba crea una conexión a la base de datos MySQL “asterisk” utilizando como usuario asterisk y como contraseña sesamo. Terminada la configuración de ODBC falta la parte Asterisk donde hay que modificar tres archivos:
- res_odbc.conf
- cdr_adaptive_odbc.conf
- extensions.conf
El primer archivo es él que normalmente se utiliza para la configuración de Asterisk Realtime. Se abre:
nano /etc/asterisk/res_odbc.conf
y al final del archivo se copian las siguientes líneas:
[cdr2]
enabled => yes
dsn => cdr2
username => asterisk
password => sesamo
pre-connect => yes
sanitysql => select 1
idlecheck => 3600
connect_timeout => 10
En dsn hay que poner el nombre de la etiqueta que define el bloque creado en odbc.ini. Se guardan los cambios y se continua con cdr_adaptive.conf
nano /etc/asterisk/cdr_adaptive_odbc.conf
al final del archivo se pone;
[cdr2]
connection=cdr2
table=cdr2
alias start => calldate
los datos:
- [cdr2]: un nombre que se le asigna a la conexión
- connection=cdr2: en este parámetro hay que poner la etiqueta que define el bloque creado en res_odbc.conf
- table=cdr2: la tabla MySQL donde se guardarán los datos
- alias start => calldate: en cdr_adaptive hay tres campos donde se guardan diferentes momentos de la llamada: cuando inicia, cuando se contesta y cuando se termina. Los nombres de estos campos son respectivamente start, answer y end. El campo calldate no existe. Por este motivo para que este campo contenga un valor hay que escoger unos de los tres que crea cdr_adaptive. Esto se hace indicando un alias y definiendo que el campo calldate contendrá el valor del campo start de cdr_adaptive (cuando la llamada inicia).
Se guardan los cambios y se pasa al dialplan. Si queremos monitorear todas las llamadas salientes y para ellas utilizamos un proveedor SIP, en el contexto correspondiente ponemos:
[salientes]
exten => _00.,1,Noop(llamadas salientes)
same => n,Dial(SIP/ProveedorSIP/${FILTER(0-9,${EXTEN})})
same => n,Hangup()
exten => h,1,set(CDR(hangupcause)=${HANGUPCAUSE})
exten => h,n,set(CDR(accountcode)=${CDR(accountcode)})
exten => h,n,set(CDR(peerip)=${CHANNEL(peerip)})
exten => h,n,set(CDR(useragent)=${CHANNEL(useragent)})
exten => h,n,set(CDR(codec1)=${CHANNEL(audioreadformat)})
exten => h,n,set(CDR(codec2)=${CHANNEL(audiowriteformat)})
exten => h,n,set(CDR(tlp)=${CHANNEL(rtpqos,audio,local_count)})
exten => h,n,set(CDR(llp)=${CHANNEL(rtpqos,audio,local_lostpackets)})
exten => h,n,set(CDR(porlp)=$[{CHANNEL(rtpqos,audio,local_lostpackets)} / ${CHANNEL(rtpqos,audio,local_count)} * 100])
exten => h,n,set(CDR(trp)=${CHANNEL(rtpqos,audio,remote_count)})
exten => h,n,set(CDR(rlp)=${CHANNEL(rtpqos,audio,remote_lostpackets)})
exten => h,n,set(CDR(porrp)=$[{CHANNEL(rtpqos,audio,remote_lostpackets)} / ${CHANNEL(rtpqos,audio,remote_count)} * 100])
exten => h,n,set(CDR(ljitter)=${CHANNEL(rtpqos,audio,local_jitter)})
exten => h,n,set(CDR(rjitter)=${CHANNEL(rtpqos,audio,remote_jitter)})
exten => h,n,Hangup
Como Asterisk guarda los datos en el CDR cuando finaliza la llamada, podemos utilizar la extensión h para los nuestros. Si se fijan en porlp ý porrp la operación matemática es muy sencilla: se multiplican los paquetes perdidos por los paquetes totales y el resultado se divide por 100. De esta forma se saca el porcentaje de paquetes perdidos.
Se sacan unas cuantas llamadas y se mira que pasa en la tabla CDR2:
mysql -u root -ppassword
mysql> use asterisk
mysql> select calldate,useragent,codec1,codec2,tlp,llp,porlp,trp,rlp,porrp from cdr2;
mysql> quit
Fuente: Voztovoice.org
No hay comentarios.:
Publicar un comentario