lunes, 12 de marzo de 2012

ODBC Connector para MySQL en Asterisk

¿Como configurar ODBC para MySQL en Asterisk?
En las versiones de Asterisk 1.2 y 1.4 teníamos los módulos:

app_mysql.so: implementaba la aplicación MySQL en Asterisk y que permitía poder conectarnos directamente desde el dialplan de Asterisk a una base de Datos MySQL.

cdr_mysql.so: implementa el módulo que se encarga de pasar todo lo que esta en el CDR(/var/log/asterisk/cdr-csv/Master.csv) a una Base de Dados MySQL.

res_config_mysql.so: implementado para poder trabajarlo con Asterisk Real Time.

Pero en las versiones de Asterisk 1.8 y 10, estos módulos estan obsoletos(deprecated) a excepcion de res_config_mysql.son que es útil
Entonces si queremos conectarnos directamente desde el dialplan hacia una base de datos(sin usar AGI :-P) o si queremos pasar el log del CDR a una base de datos o si queremos trabajar con Real Time, quien podrá ayudarnos???

Yooooo!! el ODBC Connector, no contaban con mi astucia :-P

Vamos a explicar como configurar y como trabaja ODBC Connector con MySQL en Asterisk.

El conector ODBC es una capa de abstracción de base de datos que hace posible que Asterisk pueda comunicarse con una amplia gama de bases de datos sin necesidad de hacer desarrollos para crear un conector de base de datos independiente para cada base de datos. Esto ahorra una gran cantidad de esfuerzo de desarrollo y mantenimiento del código. Cabe indicar que hay un costo ligeramente en el rendimiento, porque se esta añadiendo otra capa de aplicación entre el asterisk y la base de datos, pero esto puede ser mitigado con un diseño adecuado y bien vale la pena cuando se necesita una capacidad de gran alcance y base de datos flexible compatibles con Asterisk.

Podrias configurar: ODBC para MySQL, ODBC para PostgreSQL y ODBC para Microsoft SQL

En esta ocación voy a focalizarme en ODBC para MySQL:

Ingredientes de la abuela Laberiana:

1.-Instalamos el motor de Base de Daots MySQL en Centos:
#yum install mysql mysql-server mysql-devel

2.-Instalar los drivers ODBC en Linux y los paquetes UnixODBC antes de compilar Asterisk porque el modulo ODBC en asterisk lo requiere como dependencia para construir sus modulos de ODBC.
#yum install unixODBC unixODBC-devel libtool-ltdl libtool-ltdl-devel

3.-Instalamos los drivers ODBC para MySQL
#yum install mysql-connector-odbc

4.-Creamos una base de datos de nombre asterisk y dentro creamos la tabla usuarios:
donde como registro tendremos los nombres de los usuarios, la clave y la categoría de permiso que tendran para hacer llamadas.


5.- Crear una contraseña de root para MySQL
#mysqladmin -u root password s3kr3t

6.- Creamos el usuario asterisk para que administre la base con la que vamos a trabajar:
#mysql -u root -ps3kr3t
mysql>CREATE USER 'asterisk'@'%' IDENTIFIED BY 'mys3kr3t'
Query OK, 0 rows affected (0.00 sec)

7.-Creamos la base de datos de nombre asterisk:
mysql>create database asterisk;

8.- Una vez creado la base de datos necesitamos asignar permisos para el usuario asterisk para que acceda que acceda a la base de datos con la que vamos a trabajar.
mysql>GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'%';
Query OK, 0 rows affected (0.00 sec)

9.-Creamos la tabla de nombre usuarios:
mysql>USE asterisk;
mysql>CREATE TABLE `usuarios` (
`id` int(11) NOT NULL auto_increment,
`nombre` varchar(20) NOT NULL,
`clave` int(1) NOT NULL,
`loc` int(1) NOT NULL,
`cel` int(1) NOT NULL,
`ldn` int(1) NOT NULL,
`ldi` int(1) NOT NULL,
PRIMARY KEY (`nombre`),
KEY `id` (`id`)
) TYPE=MyISAM;
INSERT INTO usuarios (nombre,clave,loc,cel,ldn,ldi) VALUES (
'ohumala','2781','1','1','1','1'),
('agarcia','9847','1','0','1','0'),
('atoledo','1789','1','0','0','0');


10.- Procedemos a compilar o recompilar asterisk según sea el caso, para que se implemente el conector ODBC.

#cd /usr/src/asterisk-1.8.10.0/
#make clean
#./configure
#make
#make menuselect
; validar si los módulos relacionados a ODBC están habilitados




#make
#make install
#make samples
#make config


11.- Iniciamos asterisk e ingresamos al CLI> y validamos si los modulos ODBC estan implementados
#asterisk
#rasterisk -vvvvvvvvvv
*CLI> module show like odbc




Hasta este punto ya tenemos los módulos ODBC implementados en Asterisk y tenemos creado la base de datos asterisk con la tabla usuarios.

12.- Ahora mos a ver los archivos de configuración involucrados:

#/etc/odbcinst.ini
#/etc/odbc.ini
#/etc/asterisk/res_odbc.conf
#/etc/asterisk/func_odbc.conf
#/etc/asterisk/extensions.conf

13.-Procedemos a configurar el driver ODBC para MySQL esto es en el fichero /etc/odbcinst.ini
Para sistemas de 32 bits
#vim /etc/odbcinst.ini
--------------------------------------------------------


[MySQL]
Description = ODBC para MySQL
Driver = /usr/lib/libmyodbc3.so
Setup = /usr/lib/libodbcmyS.so
FileUsage = 1

---------------------------------------------------------

Para sistemas de 64 bits
#vim /etc/odbcinst.ini
---------------------------------------------------------

[MySQL]
Description = ODBC para MySQL
Driver64 = /usr/lib64/libmyodbc5.so
Setup64 = /usr/lib64/libodbcmyS.so
FileUsage = 1

---------------------------------------------------------

Para validar el sistema es capaz de reconocer el driver, ejecutamos el siguiente comando:
#odbcinst -q -d
[MySQL]
debería devolvernos el nombre de la etiqueta [MySQL]

14.- Ahora procedemos configurar el fichero /etc/odbc.ini este fichero es configurado para crear el identificador que asterisk utilizará para hacer referencia a esta configuración, para controlar como conectarse a la base de datos.

#vim /etc/odbc.ini
----------------------------------------------------------

[asterisk-conect]
Description = MySQL Asterisk
Driver = MySQL
Database = asterisk
Server = localhost
User = asterisk
Password = mys3kr3t
Port = 3306
Option = 3

------------------------------------------------------------

Validar si el conector ODBC se puede conectar a la base de datos, para utilizamos la aplicación isql:
#echo "select 1" | isql -v asterisk-conect
no debe mostrar un resutado come este:


15.- Procedemos a configurar el fichero res_odbc para permitir a Asterisk conectarse a través de ODBC.
#vim /etc/asterisk/res_odbc.conf
--------------------------------------
[ENV]
[asterisk]
enabled => yes
dsn => asterisk-conect
username => asterisk
password => mys3kr3t
pre-connect => yes
sanitysql => select 1
idlecheck => 3600
connect_timeout => 10

---------------------------------------

Guardamos los cambios y reiniciamos el servicio

#asterisk -r>core stop now
#asterisk
#rasterisk -vvvvvvvvvvvv


ver si ODBC esta activo:


16.-Funcion ODBC “func_odbc”
La función func_odbc permite hacer consultas a la base de datos directamente desde el
dialplan. Al mismo tiempo es posible actualizar o modificar campos específicos de la base
de datos. El archivo que se utiliza para este tipo de configuración es el func_odbc.conf.
En este caso vamos a configurar para consultar si se tiene permiso para hacer llamadas

Ingresamos al fichero:
#vim /etc/asterisk/func_odbc.conf
-----------------------------------------------------------------------------------------------
[usuariosLoc]
dsn=asterisk
readsql=SELECT loc FROM usuarios WHERE clave='${SQL_ESC(${ARG1})}'

[usuariosCel]
dsn=asterisk
readsql=SELECT cel FROM usuarios WHERE clave='${SQL_ESC(${ARG1})}'

[usuariosLdn]
dsn=asterisk
readsql=SELECT ldn FROM usuarios WHERE clave='${SQL_ESC(${ARG1})}'

[usuariosLdi]
dsn=asterisk
readsql=SELECT ldi FROM usuarios WHERE clave='${SQL_ESC(${ARG1})}'
-------------------------------------------------------------------------------------------------

Guardamos los cambios:
#rasterisk -vvvvvvvvv
*CLI>module reload func_odbc.so


Para validar si se crearon nuestra funciones:
*CLI>core show function ODBC_usuariosLoc


17.- Procedemos a configurar nuestro dialplan donde haremos uso de las funciones creadas para consultar a la base de datos antes de rutear la llamada hacia la PSTN:

#vim /etc/asterisk/extensions.conf

---------------------------------------------------------------------------------
[Fijo-SIP]
exten=>_[2-7]XXXXXX,1,NoOp(Fijo Local)
same=>n,Read(pass,agent-pass,4)
same=>n,Set(PERMISO=${ODBC_usuariosLoc(${pass})})
same=>n,GotoIf($[${PERMISO}=1]?ok:off)
same=>n(ok),Dial(SIP/TroncalSIP/${EXTEN})
same=>n,Hangup()
same=>n(off),NoOp(NO TIENE PERMISO PARA LLAMAR)
same=>n,Hangup()

[Celular-SIP]
exten=>_9XXXXXXXX,1,NoOp(Celular)
same=>n,Read(pass,agent-pass,4)
same=>n,Set(PERMISO=${ODBC_usuariosCel(${pass})})
same=>n,GotoIf($[${PERMISO}=1]?ok:off)
same=>n(ok),Dial(SIP/TroncalSIP/${EXTEN})
same=>n,Hangup()
same=>n(off),NoOp(NO TIENE PERMISO PARA LLAMAR)
same=>n,Hangup()

[LDN-SIP]
exten=> _0NX[2-7]XXXXX,1,NoOp(Larga Distancia Local)
same=>n,Read(pass,agent-pass,4)
same=>n,Set(PERMISO=${ODBC_usuariosLdn(${pass})})
same=>n,GotoIf($[${PERMISO}=1]?ok:off)
same=>n(ok),Dial(SIP/TroncalSIP/${EXTEN})
same=>n,Hangup()
same=>n(off),NoOp(NO TIENE PERMISO PARA LLAMAR)
same=>n,Hangup()

[LDI-SIP]
exten=>_00XXX.,1,NoOp(Larga Distancia Internacional)
same=>n,Read(pass,agent-pass,4)
same=>n,Set(PERMISO=${ODBC_usuariosLdi(${pass})})
same=>n,GotoIf($[${PERMISO}=1]?ok:off)
same=>n(ok),Dial(SIP/TroncalSIP/${EXTEN})
same=>n,Hangup()
same=>n(off),NoOp(NO TIENE PERMISO PARA LLAMAR)
same=>n,Hangup()


-------------------------------------------------------------------------------------------
18.-Interactúan con la tabla usuarios de la base de datos asterisk:



19.- Este seria el esquema de la relación que hay entre extensions.conf, func_odbc.conf,res_odbc.conf,odbc.ini y la Base de Datos:



El próximo post veremos como pasar el CDR(desde el Log) a una base de datos MySQL utilizando el módulo cdr_adaptive_odbc.so

Fuentes de ayuda:
http://ofps.oreilly.com/titles/9780596517342/asterisk-DB.html
http://www.voztovoice.org/?q=node/187