Convenciones tipográficas.
Negrita = comandos que el usuario tiene que teclear en la consola de Linux
NegritaCursiva: Lineas que hay que añadir/modificar en los archivos de configuración
Nombreprograma = Indica el nombre de un programa o librería
Cursiva: respuesta del servidor Linux a los comandos
CLI> indica que estamos trabajando en la consola de Asterisk
mysql> indica que estamos trabajando en el cliente MySQL
Si encuentran alguna incorrección o errata pueden escribir al autor: [email protected].
i
Este documento se publica bajo la GNU Free Documentation License, versión 1.3 o sucesivas, publicadas por la Free Software Foundation. Está permitido copiar, distribuir y/o modificar este documento bajo los términos indicados en la licencia. Una copia integral de la licencia es presente en la apéndice D de este libro.
Copyright (C) 2010-2015 Andrea Sannucci Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
ii
INDICE
Capitulo I - Instalación de Asterisk ….......................................................................................... 1
1.1 Utilidades, librerías, dependencias 11.2 DAHDi 6 1.2.1 DAHDi en Linode 6 1.2.2 DAHDi en un servidor CentOS 81.3 FAX, GoogleTalk, Asterisk 91.4 Asterisk Addons – MySQL, MP3, Chan_mobile 12 1.4.1 Chan_mobile 15
Capitulo II - Configuración de Asterisk …................................................................................. 19
2.1 Instalar y configurar un cortafuego 192.2 Carpetas y archivos 222.3 Música en espera y MP3 242.4 Sip.conf (protocolo SIP) 272.5 Extensions.conf (plan de llamadas) 34 2.5.1 El contexto subscribe 39 2.5.2 X-lite y el plan de llamadas 40 2.5.3 Llamadas entre extensiones 42 2.5.4 Las Macros 432.6 Voicemail.conf – buzón de voz 462.7 Iax.conf – Protocolo IAX2 532.8 Features.conf 56 2.8.1 Integración de features.conf con la aplicación Dial 632.9 Logger.conf 682.10 Followme.conf (sigueme) 712.11 ENUM 752.12 Las conferencias (meetme.conf) 782.13 Asterisk GUI 822.14 La gestión de las colas 85 2.14.1 Los agentes 86 2.14.2 queues.conf 87
Capitulo III - Asterisk y la PSTN ….......................................................................................... 91
3.1 Instalación dispositivo X100P 923.2 Configuración X100P en Asterisk 93
Capitulo IV – IVR …................................................................................................................... 97
4.1 Grabación de las locuciones 974.2 Plan de llamadas y IVR 99
iii
Capitulo V - Asterisk y FAX ….................................................................................................. 102
5.1 Asterisk con IAXmodem y Hylafax 1025.2 Asterisk y el protocolo T38 1125.3 Envío de FAX 118
Capitulo VI - Asterisk Realtime …............................................................................................. 121
6.1 Voicemail y ODBC 121 6.2 ODBC y CDR 1346.3 MeetMe Realtime 136
Capitulo VII - Asterisk y TTS (text to speech) …...................................................................... 140
7.1 Festival 140 7.2 Cepstral 142
Capitulo VIII - Conexiones entre servidores Asterisk ….......................................................... 146
8.1 Conectar dos servidores Asterisk con el protocolo SIP 1468.2 Conectar dos Servidor Asterisk con el protocolo IAX2 1488.3 DUNDi 151
Capitulo IX - Openfire y Asterisk ….......................................................................................... 162
9.1 Instalacion de Openfire 1629.2 Instalar el Plugin SIPPhone en Openfire 1709.3 El Plugin Asterisk-IM 1769.4 Asterisk como cliente en Openfire 1829.5 Conectar dos servidores Openfire 1859.6 Openfire Connection Manager 188
Capitulo X - Potpourri …............................................................................................................ 192
10.1 Func_odbc.conf - ODBC y Base de datos 19210.2 Asterisk y GoogleTalk 19410.3 AGI y despertador 19810.4 Fail2ban 199
Apéndice A – Asterisk Aplicaciones 202
Apéndice B – Asterisk Funciones 213
Apéndice C – Plan de llamadas 221
Apéndice D – GNU Free Documentation License 227
iv
Capitulo I
Instalación de Asterisk
1.1 Utilidades, librerías y dependencias
Asterisk es el programa más usado y conocido para manejar una PBX1. Para una lista completa de las funcionalidades brindadas visiten la página de los desarrolladores2. Entre ellas:
• Registro de llamadas• Desvío de llamadas• Trasferencia de llamadas• Conferencias• ENUM3
• Música en espera• Gestión de colas (call center)• Soporte para tarjetas FXO4, FXS5 y digitales
Este manual abarca la instalación de Asterisk en un VPS (Servidor Virtual Privado) y es valida para cualquier Servidor Linux CentOS. Con el VPS la ventaja es tener una PBX siempre activa, independiente de la banda ancha disponible en la casa/oficina y evita tener una computadora dedicada y siempre encendida.
Hay empresas que ofrecen VPS a costos relativamente bajos. Entre todas hay dos que tienen una óptima relación calidad/precio.
La primera es SliceHost6 que con 20 dólares mensuales brinda un VPS de 256 Megabyte de memoria RAM, 10 Gigabyte de disco duro, 100 Gigabyte de trafico.
La segunda empresa es Linode7 que con 19,95 dólares mensuales brinda una VPS de 360 Megabyte de memoria RAM, 16 Gigabyte de disco duro y 200 Gigabyte de trafico.
La distribución Linux que se utilizará para la instalación de Asterisk es CentOS8, porque es la más conocida, utilizada y funcional para los fines de este manual.1 Un PBX o PABX (siglas en inglés de Private Branch Exchange y Private Automatic Branch Exchange para PABX)
cuya traducción al español sería Central secundaria privada automática, es cualquier central telefónica conectada directamente a la red pública de teléfono por medio de líneas troncales para gestionar, además de las llamadas internas, las entrantes y/o salientes con autonomía sobre cualquier otra central telefónica. Este dispositivo generalmente pertenece a la empresa que lo tiene instalado y no a la compañía telefónica, de aquí el adjetivo privado a su denominación. (Wikipedia)
2 www.asterisk.org/features 3 http://en.wikipedia.org/wiki/Telephone_Number_Mapping4 FXO (Foreign Exchange Office) es un dispositivo de computador que permite conectar éste a la red telefónica
conmutada y mediante un software especial, realizar y recibir llamadas de teléfono.5 FXS (Foreign Exchange Station) es el conector en una central telefónica o en la pared de nuestro hogar, que permite
conectar un teléfono analógico estándar.6 www.slicehost.com 7 www.linode.com 8 www.centos.org
Para manejar el servidor Linux desde una computadora con sistema operativo Microsoft Windows se debe utilizar el programa Putty9. Se descarga y se abre dando clic dos veces en el icono del programa. Aparecerá la siguiente ventana:
Se coloca la dirección IP del VPS en la casilla “Host name, or IPaddress”, se deja en Port el numero 22 y se presiona el botón Open. Aparecerá una nueva ventana:
9 Es un cliente SSH, Telnet, rlogin y TCP raw distribuido bajo una licencia libre.
2
Se introducen las credenciales para acceder al servidor remoto. Se digita root y se presiona la tecla envío. Cuando el sistema lo pide, se digita la contraseña.
Para la conexión desde un servidor Linux el comando es:
ssh root@ipservidorremoto
Si no se usa el puerto estándar (22) habrá que indicarlo de la siguiente forma:
ssh -p 20000 root@ipservidorremoto
Una vez dentro del servidor Linux se puede empezar con la instalación de Asterisk.
Antes que nada se necesita instalar un buen editor de textos como NANO, indispensable para modificar los archivos de configuración de Asterisk y en general para crear/modificar cualquier archivo de texto.
Para instalar NANO el comando es:
yum install nano
YUM es un programa que permite gestionar todos los paquetes precompilados para la distribución Linux CentOS. Para una lista de las opciones disponibles se usa el siguiente comando:
yum --help
Una buena practica es actualizar el sistema:
yum update
Se continua con la instalación de Vorbis (un codificador/decodificador de archivos audio) y las relativas
3
librerías: yum install libvorbis libvorbis-devel vorbis-tools libogg libogg-devel
Para instalar la función CURL:
yum install curl curl-devel libidn-devel
Se sigue con unas cuantas utilidades y librerías necesarias para la compilación de las fuentes:
yum install gcc ncurses ncurses-devel make gcc-c++ libtermcap libtermcap-devel zlib zlib-devel libtool bison bison-devel openssl-devel bzip2 bzip2-devel wget newt newt-devel
Si se quiere utilizar MySQL10 como base de datos predefinida:
yum install mysql mysql-server mysql-devel
ODBC11 para crear conexiones a bases de datos:
yum install unixODBC unixODBC-devel mysql-connector-odbc libtool-ltdl-devel
Un sintetizador vocal (festival):
yum install festival festival-devel
Speex12 es un codificador decodificador específicamente diseñado para la compresión de la voz. Se instalará partiendo de las fuentes:
cd /usr/src
wget http://downloads.xiph.org/releases/speex/speex-1.2rc1.tar.gz
Para descomprimirlo:
tar -xf speex-1.2rc1.tar.gz
Se entra en la carpeta creada y se compila:
cd speex-1.2rc1
./configure --prefix=/usrmakemake install
10 MySQL es un sistema de gestión de base de datos relacional, multihilo y multiusuario. (Wikipedia). La pagina principal del programa: http://www.mysql.com/
11 http://es.wikipedia.org/wiki/Open_Database_Connectivity 12 http://speex.org/
4
Para terminar se actualizan las librerías:
ldconfig -v
Se continua con un decodificador/codificador MP3 - Lame. Útil para usar música en espera en formato MP3.
cd /usr/src
wget http://ufpr.dl.sourceforge.net/sourceforge/lame/lame-398-2.tar.gz
Se descomprime:
tar -xf lame-398-2.tar.gz
Se entra en la capeta de Lame:
cd lame-398-2
Se compilan las fuentes:
./configure --prefix=/usrmakemake install
Se termina con el comando:
ldconfig -v
para actualizar las librerías.
Para “manipular” los archivos MP3 (por ejemplo para bajar la calidad del sampling) antes de compilar SOX se necesita la librería libmad.
Para instalarla:
cd /usr/src
wget http://prdownloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz
tar -xf libmad-0.15.1b.tar.gz
cd libmad-0.15.1b
./configure --prefix=/usrmakemake install
5
Actualizar las librerías:
ldconfig -v
Para terminar esta primera parte se instalará el programa SOX13 (Sound eXchange) muy útil para convertir archivos audio de un formato a otro.
cd /usr/src
wget http://ufpr.dl.sourceforge.net/sourceforge/sox/sox-14.3.0.tar.gz
se descomprime:
tar -xf sox-14.3.0.tar.gz
Se Entra en la carpeta:
cd sox-14.3.0
y se compila:
./configure --prefix=/usrmake make install
Se actualizan las librerías:
ldconfig -v
1.2 DAHDI
El paquete DADHI (Digium Asterisk Hardware Device Interface) permite cargar los drivers y configurar distintos tipos de tarjetas en Asterisk (analógicas, digitales, RDSI/ISDN, cancelador de ECHO). Asterisk, además, se apoya en DAHDI para la generación del “timing” indispensable para las conferencias y el trunking IAX2. 1.2.1 DAHDI en Linode
Los VPS alquilados en Linode utilizan como sistema de virtualización XEN14. Por eso para una correcta instalación de DAHDI se tendrá que seguir el procedimiento que sigue.
Primero se averigua la versión del kernel que se está usando:
uname -r13 http://sox.sourceforge.net/Main/HomePage 14 http://xen.org/
6
Un ejemplo del resultado del comando es:2.6.18.8-linode22
Se crea la carpeta donde se guardarán las fuentes del kernel:
mkdir /usr/src/kernel
se entra en la carpeta
cd /usr/src/kernel
Se descargan las fuentes desde la pagina dedicada de Linode15.
Para el ejemplo arriba mencionado sería:
wget http://www.linode.com/src/2.6.18.8-linode22.tar.bz2
Se descomprime:
tar -xf 2.6.18.8-linode22.tar.bz2
Se crea un link simbólico a las fuentes descargadas:
cd /lib/modules/2.6.18.8-linode22/ln -s /usr/src/kernel/2.6.18.8-linode22/ build
Se preparan las fuentes para la instalación de DAHDI:
cd /usr/src/kernel/2.6.18.8-linode22
make -f Makefile cleanmake -f Makefile oldconfigmake -f Makefile scripts/genksyms/make -f Makefile prepare
Terminada esta operación empieza el proceso de instalación de DAHDI:
cd /usr/src
wget http://downloads.asterisk.org/pub/telephony/dahdi-linux/dahdi-linux-current.tar.gz
tar -xf dahdi-linux-current.tar.gzcd dahdi-linux-2.2.1makemake install
15 http://www.linode.com/src
7
DAHDI Tools:
cd /usr/src
wget http://downloads.asterisk.org/pub/telephony/dahdi-tools/dahdi-tools-current.tar.gz
tar -xf dahdi-tools-current.tar.gzcd dahdi-tools-2.2.1./configuremake make installmake config
Se modifican dos parámetros en el script de arranque de DAHDI
nano /etc/init.d/dahdi
estas dos líneas:
modprobe dahdimodprobe dahdi_dummy 2> /dev/null
para que queden:
modprobe -f dahdi modprobe -f dahdi_dummy 2> /dev/null
1.2.2 DAHDI en CentOS Server
Si se está utilizando un servidor CentOS en lugar de un VPS (Linode) los pasos a seguir son:
cd /usr/src
yum install kernel-devel kernel-headers
wget http://downloads.asterisk.org/pub/telephony/dahdi-linux/releases/dahdi-linux-2.2.0.2.tar.gz
tar -xf dahdi-linux-2.2.0.2.tar.gzcd dahdi-linux-2.2.0.2makemake install
Se Sigue con dadhi-tools:
cd /usr/src
8
wget http://downloads.asterisk.org/pub/telephony/dahdi-tools/releases/dahdi-tools-2.2.0.tar.gz
tar -xf dahdi-tools-2.2.0.tar.gzcd dahdi-tools-2.2.0./configuremakemake install
Para que arranque en automático:
make config
1.3 FAX, GoogleTalk, Asterisk
Para el soporte fax hay que instalar SpanDSP16. SpanDSP es un procesador de señales digitales y en Asterisk su función es permitir el envío y la recepción de faxes. Trabaja con archivos Tiff y para compilarlo hay que instalar esas librerías:
yum install libtiff libtiff-devel
Se puede continuar con la descarga y instalación de SpanDSP
cd /usr/src
wget http://www.soft-switch.org/downloads/spandsp/spandsp-0.0.6pre17.tgz
tar -xf spandsp-0.0.6pre17.tgz
cd spandsp-0.0.6
./configure --prefix=/usrmakemake install
Se termina actualizando las librerias:
ldconfig -v
Asterisk tiene la posibilidad de conectarse a GoogleTalk17 o a otro servidor de tipo Jabber18 como cliente. Para que sea posible se debe instalar Gnutls y Iksemel. Gnutls permite crear conexiones basadas en el protocolo TLS19. En CentOS están disponibles los paquetes precompilados:
16 http://www.soft-switch.org/ 17 http://www.google.com/talk/intl/es/18 http://www.jabberes.org/19 http://es.wikipedia.org/wiki/Transport_Layer_Security
9
yum install gnutls gnutls-devel gnutls-utils
Ahora se puede instalar iksemel:
cd /usr/src
wget http://iksemel.googlecode.com/files/iksemel-1.4.tar.gz
tar -xf iksemel-1.4.tar.gz
cd iksemel-1.4
./configure --prefix=/usrmakemake check
Con make check se verifica que la compilación esté sin errores. El comando ejecuta una serie de test y devuelve el resultado.
Para completar la instalación:
make install
Se actualizan las librerías:
ldconfig -v
Instalamos Sendmail, un servidor de correo electrónico. Asterisk lo utiliza para enviar correos de notificación cada vez que llegue un correo de voz a las casillas configuradas en el buzón de voz.
yum install sendmail sendmail-devel sendmail-cf
OpenLDAP es la versión open source del protocolo Lightweight Directory Access. Normalmente se utiliza para crear un directorio de usuarios que puede ser consultado y/o modificado desde remoto. Muchos programas implementan la posibilidad de conectarse a un servidor OpenLDAP y Asterisk, desde la versión 1.6.X, presenta esta posibilidad:
yum install compat-openldap openldap openldap-clients openldap-devel openldap-servers
SNMP es el Protocolo Simple de Administración de Red y sirve para controlar y monitorear el desempeño de nuestro servidor Linux. En Asterisk permite monitorear, entre otras cosas, los canales y las llamadas.
yum install net-snmp net-snmp-devel net-snmp-libs net-snmp-perl net-snmp-utils php-snmp
10
Ahora se puede empezar con la instalación de Asterisk (versión 1.6.X). Primero se descargan las fuentes:
cd /usr/src
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-1.6.0-current.tar.gz
se descomprime:
tar -xf asterisk-1.6.0-current.tar.gz
Se entra en la carpeta:
cd asterisk-1.6.0.25
Se compila:
./configuremake menuselect
Aparecerá:
Desde este menú se pueden configurar todos los módulos que se quiere que Asterisk instale. Se averigua si el modulo Jabber está seleccionado. Bajar con los cursores del teclado hasta “Resource Modules” y averiguar que a lado de res_jabber haya un asterisco. Si no lo hay y aparecen tres XXX significa que no se puede instalar (hubo seguramente algún problema con la instalación de iksemel).
11
Se puede navegar entre los varios menús para seleccionar/deseleccionar los módulos. Para guardar los cambios desde el menú principal hundir el botón “Save & Exit”.
Ahora se compila e instala Asterisk:
makemake install
Para los archivos de configuración de muestra:
make samples
Para el arranque automático al boot de Linux:
make config
1.4 Asterisk Addons – MySQL, MP3, Chan_mobile
Asterisk Addons es un paquete que añade cuatro funcionalidades principales a la centralita Asterisk:
1. La posibilidad de tener un registro de las llamadas en una base de datos MySQL;2. Utilizar archivos MP320 para la música en espera3. Añadir el protocolo H32321 (versión propietaria)4. El canal chan_mobile que permite conectar, via bluetooth, un celular a la centralita y usarlo
como Gateway GSM y, si el celular lo soporta, envío de SMS.
Antes de empezar arrancar el servidor MySQL
El comando es:
/etc/init.d/mysqld start
Para que arranque cada vez que se inicia el servidor Linux:
chkconfig mysqld on
Se crea una contraseña para el usuario root:
20 MPEG-1 Audio Layer 3, más conocido como MP3, es un formato de audio digital comprimido con pérdida desarrollado por el Moving Picture Experts Group (MPEG) para formar parte de la versión 1 (y posteriormente ampliado en la versión 2) del formato de vídeo MPEG. El mp3 estándar es de 44 kHz y un bitrate de 128 kbps por la relación de calidad/tamaño. Su nombre es el acrónimo de MPEG-1 Audio Layer 3 y el término no se debe confundir con el de reproductor MP3.
21 H.323 es una recomendación del ITU-T (International Telecommunication Union), que define los protocolos para proveer sesiones de comunicación audiovisual sobre paquetes de red.
12
mysqladmin -u root password sesamo
Si el servidor Linux tiene un dispositivo bluetooth hay que instalar estos paquetes:
yum install bluez-utils bluez-libs bluez-libs-devel bluez-hcidump
Se descarga el paquete de Asterisk addons en la carpeta /usr/src:
cd /usr/src
wget http://downloads.asterisk.org/pub/telephony/asterisk/asterisk-addons-1.6.0-current.tar.gz
Se descomprime:
tar -xf asterisk-addons-1.6.0-current.tar.gz
Se entra la carpeta recién creada:
cd asterisk-addons-1.6.0.4
Se compila:
./configuremakemake install
Para los archivos de muestra:
make samples
Ahora para que la centralita tenga un registro de todas las llamadas en MySQL hay que seguir este procedimiento. Crear una base de datos:
mysqladmin create asteriskcdr -u root -psesamo
Entrar en el cliente MySQL como usuario root y la contraseña que se ha creado anteriormente:
mysql -u root -psesamo
Crear la tabla para registrar las llamadas en la base de datos:
mysql> use asteriskcdr
mysql> 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 '',
13
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 '', uniqueid varchar(32) NOT NULL default '', userfield varchar(255) NOT NULL default '');
Crear un nuevo usuario y darle todos los privilegios para manejar la base de datos desde local y remoto:
mysql> GRANT ALL PRIVILEGES ON asteriskcdr.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo';
mysql> GRANT ALL PRIVILEGES ON asteriskcdr.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo';
mysql> flush privileges;
mysql> quit
Lo único que falta es añadir unas líneas en el archivo de configuración de Asterisk que se encarga de conectarse a la base de datos creada. Se abre el siguiente archivo de texto con nano:
nano /etc/asterisk/cdr_mysql.conf
y se modifican estas líneas:
[global]hostname=localhostdbname=asteriskcdrtable=cdrpassword=sesamouser=asteriskport=3306sock=/var/lib/mysql/mysql.sock
Se guardan los cambios (CTRL-O CTRL-X).
Ahora se vuelve a arrancar el servidor Linux.
14
rebootTerminada la operación de arranque se entra en el servidor y se verifica que todo esté funcionando:
Para Dahdi:
/etc/init.d/dahdi status### Span 1: DAHDI_DUMMY/1 "DAHDI_DUMMY/1 (source: Linux26) 1" (MASTER)Para Asterisk:
asterisk (pid 2403) is running...Para la base de datos:
asterisk -rvvvvv
CLI> cdr mysql status
Debe aparecer:
Connected to asteriskcdr@localhost, port 3306 using table cdr for 45 seconds.Wrote 0 records since last restart.CLI> quitExecuting last minute cleanups
1.4.1 Chan_mobile
Para conectar nuestro celular a Asterisk primero hay que modificar el archivo hcid.conf:
mv /etc/bluetooth/hcid.conf hcid.conf.old
nano /etc/bluetooth/hcid.conf
Pegar las siguientes líneas:
## HCI daemon configuration file.## HCId optionsoptions { autoinit yes; security auto; pairing multi; passkey "1234";}
# Default settings for HCI devices
15
device { name "%h-%d"; class 0x120104; iscan enable; pscan enable; lm accept; lp rswitch,hold,sniff,park;}
Se guardan los cambios y se arranca el servicio:
/etc/init.d/bluetooth start
Iniciando los servicios de Bluetooth: [ OK ]
Una vez que el servicio esté activo se vuelve el computador visible a otros dispositivos bluetooth:
dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/hci0 org.bluez.Adapter.SetMode string:discoverable
Desde el celular (dependiendo de la marca y modelo) se buscan otros dispositivos bluetooth y cuando aparece el nombre del computador se selecciona y se hacee el “pairing” (se asocia). A lo largo del procedo de asociacion preguntará por la clave. Se deberá digitar “1234” y configurar esta asociación como automática.
Ahora se busca el MACaddress22 del dispositivo bluetooth del computador:
hcitool dev
hci0 00:1F:E2:ED:5E:E9
Se abre el archivo de configuración de Asterisk para el chan_mobile y configura este dispositivo:nano /etc/asterisk/mobile.conf
Se copia el MAC address en esta línea:
[adapter]id=blueaddress=00:1F:E2:ED:5E:E9
Se guardan los cambios y se vuelve a arrancar Asterisk:
/etc/init.d/asterisk restart
22 La dirección MAC (siglas en inglés de Media Access Control o control de acceso al medio) es un identificador de 48 bits (6 octetos) que corresponde de forma única a una ethernet de red. Es individual, cada dispositivo tiene su propia dirección MAC determinada y configurada por el IEEE (los últimos 24 bits) y el fabricante (los primeros 24 bits). Wikipedia
16
Desde la consola de Asterisk se busca el celular:
asterisk -rvvvvvvvvvvvvvvvvvv
CLI> mobile search
El resultado será:
Address Name Usable Type Port00:25:48:6F:F1:00 Nokia E71 Yes Phone 1
El comando devuelve el MAC Address del celular, indicando si es utilizable en Asterisk y el puerto que hay que usar para la configuración.
Se vuelve a entrar en el archivo chan_mobile:
nano /etc/asterisk/mobile.conf
Se añaden las siguientes líneas:
[Nokia E71]address=00:25:48:6F:F1:00port=1context=incoming-celularadapter=bluegroup=1
Se guardan los cambios y se arranca Asterisk otra vez:
/etc/init.d/asterisk restart
Desde la consola se mira si el celular está conectado:asterisk -rvvvvvvvvvvvvvvv
CLI> mobile show devices
ID Address Group Adapter Connected State SMSNokia E71 00:25:48:6F:F1:00 1 blue Yes Free No
El Nokia E71 está conectado al servidor Asterisk. Ya se puede usar para hacer llamadas pero no para el envío de SMS.
Para efectuar llamadas usando como gateway el celular hay que modificar el Dialplan (plan de llamadas):
nano /etc/asterisk/extensions.conf
17
En el contexto externas se ponen estas lineas:
[externas]; Llamadas via Nokia E71exten => _3XXXXXXXXX,1,Dial(Mobile/NokiaE71/${EXTEN},45)exten => _3XXXXXXXXX,n,Hangup
Esta configuracion es para los celulares de Colombia que empiezan todos con el numero 3.
18
Capitulo II
Configuración de Asterisk
2.1 Instalar y configurar un cortafuegos
Para proteger el servidor Linux de accesos no autorizados hay que instalar un firewall (cortafuegos23) y abrir los puertos que Asterisk necesita para aceptar conexiones externas. Esta es la parte más delicada de la configuración del servidor porque es donde se definen los puertos y los servicios que son accesibles desde Internet. En el caso del VPS Linode se instalará y Configurará IPtables.
Si Asterisk se encuentra instalado en un computador conectado a Internet a través de un router hay dos opciones:
• Abrir los puertos desde la pagina de administración del router.• Configurar una DMZ en el router y luego gestionar los puertos directamente con IPtables
Para instalar iptables:
yum install iptables
Iptables se encarga de gestionar todos los paquetes que entren y salgan del servidor Linux. Para eso se utilizan tres tipos de tablas:
• la tabla filter donde pasan todos los paquetes en entrada y salida. La tabla filter acepta tres tipos de opciones (cadenas)
• INPUT para los paquetes en entrada• OUTPUT para los paquetes en salida• FORWARD para redireccionar los paquetes
• la tabla NAT se utiliza para rescribir las direcciones o los puertos de los paquetes• la tabla MANGLE se utiliza para modificar algunos parámetros de los paquetes (un ejemplo es
marcar los paquetes para que vengan procesados y enviados con una prioridad más alta)
Las reglas se definen una por linea y serán procesadas por iptables siguiendo la misma secuencia.
Cuando no se especifica diversamente, todas las reglas se aplicarán a la tabla filter:
Se acepta todo el trafico en entrada direccionado a la interfaz lookpack
iptables -A INPUT -i lo -j ACCEPT
Se rechaza (REJECT) todo el trafico entrante direccionado a las IP 127.0.0.0/127.255.255.255 menos que para la interfaz -lo
iptables -A INPUT -i ! lo -d 127.0.0.0/8 -j REJECT
23 http://es.wikipedia.org/wiki/Cortafuegos_%28inform%C3%A1tica%29
Se aceptan todos los paquetes en entrada de conexiones ya establecidas, o relacionados con conexiones establecidas. Véase protocolo TCP
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Se deja pasar todos los paquetes salientes.
iptables -A OUTPUT -j ACCEPT
Se deja pasar todo el trafico en entrada para el protocolo SSH (puerto 22 tcp)
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
Se deja pasar todo el trafico en entrada destinado al puerto udp 4569 (protocolo IAX2)
iptables -A INPUT -p udp --dport 4569 -j ACCEPT
Se deja pasar todo el trafico en entrada destinado al puerto udp 5060 (protocolo SIP)
iptables -A INPUT -p udp --dport 5060 -j ACCEPT
Se deja pasar todo el trafico en entrada destinado a los puertos udp que van de 10000 a 20000 (protocolo RTP)
iptables -A INPUT -p udp --dport 10000:20000 -j ACCEPT
Se dejan pasar las solicitudes de ping
iptables -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
A este punto, que se han definido los puertos base que se necesitan abiertos, se bloquea todo el trafico restante.
iptables -A INPUT -j REJECTiptables -A FORWARD -j REJECT
Se averigua el estado de las reglas definidas con el comando:
iptables -L
Aparecerá:
Chain INPUT (policy ACCEPT)target prot opt source destinationACCEPT all -- anywhere anywhereREJECT all -- anywhere 127.0.0.0/8 reject-with icmp-port-unreachableACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
20
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:sshACCEPT udp -- anywhere anywhere udp dpt:iaxACCEPT udp -- anywhere anywhere udp dpt:sipACCEPT udp -- anywhere anywhere udp dpts:ndmp:dnpACCEPT icmp -- anywhere anywhere icmp echo-requestREJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)target prot opt source destinationREJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain OUTPUT (policy ACCEPT)target prot opt source destinationACCEPT all -- anywhere anywhere
Para guardar los cambios:
service iptables saveSaving firewall rules to /etc/sysconfig/iptables: [ OK ]
Se arranca el servicio:
service iptables start
Si aparece este error:
Loading additional iptables modules: ip_conntrack_netbios_ns [FAILED]
Se comenta esta linea:
IPTABLES_MODULES="ip_conntrack_netbios_ns"
en el archivo /etc/sysconfig/iptables-config
Para que quede:
#IPTABLES_MODULES="ip_conntrack_netbios_ns"
Se vuelve a arrancar iptables:
service iptables restart
Para arrancar iptables automáticamente:
chkconfig iptables on
Para terminar hay que configurar Asterisk para que use los puertos UDP desde 10000 hasta 20000 para
21
el protocolo RTP24 (es el que se encarga, una vez establecida la conexión entre dos canales, del flujo audio/video)
Se edita el archivo:
nano /etc/asterisk/rtp.conf
En los archivos de configuración de Asterisk, los parámetros pueden estar comentados con un punto y coma por delante. Si se quiere utilizarlos hay que quitar el punto y coma.
Se quita el punto y coma antes de [general]
En rtpstart se pone 10000 y en rtpend 20000:
rtpstart=10000rtpend=20000
Se guardan los cambios efectuados y se recarga la configuración de Asterisk:
/etc/init.d/asterisk restart
2.2 Carpetas y archivos
Al terminar la instalación de Asterisk unas cuantas carpetas nuevas serán creadas.
/etc/asterisk
Contiene todos los archivos de configuración de Asterisk.
/usr/lib/asterisk/modules
Contiene todos los módulos compilados y utilizables en Asterisk.
/var/lib/asterisk
Que a su vez contiene las siguientes carpetas:
agi-bin/ donde poner los script AGI.
firmware/
Donde se guardan los firmware de las tarjetas en uso.
images/
24 http://es.wikipedia.org/wiki/Real-time_Transport_Protocol
22
Donde las aplicaciones irán a buscar las imágenes cuando se comuniquen con teléfonos que suportan esta función.
keys/
Claves publicas y privadas que Asterisk necesita para autenticarse con otros servidores o servicios (Ej: DUNDi).
mohmp3/
Carpeta con archivos mp3 que se pueden usar como música en espera si se tienen instalados los asterisk-addons.
sounds/
Contiene todas las locuciones que se pueden usar en el plan de llamadas (dialplan).
moh/
La música en espera que viene con la instalación de Asterisk (no mp3).
licences/
Las licencias de uso que se han adquirido (Ej: para el codec audio g729)./var/spool/asterisk
Que contiene:
dictate/
Donde se guardarán los archivos audio creados con la aplicación Dictate().
meetme/
Donde se guardarán las grabaciones de las conferencias.
monitor/
Si se graba una llamada, esta es la carpeta donde se guardarán los archivos audio.
outgoing/
Donde hay que mover los archivo de llamadas (call files). Véase el archivo callfiles.txt en la carpeta doc de las fuentes de Asterisk para una explicación del funcionamiento de estos archivos.
system/
23
Carpeta para archivos temporales creados por la aplicación System().
tmp/
Carpeta donde se guardan los archivos temporales creados por algunas aplicaciones (Ej. contestador).
voicemail/
Donde se guardarán los archivos audio de los mensajes de voz dejados en el contestador y los mensajes audio personalizados de cada usuario.
/var/run
Contiene la ID del proceso de Asterisk cuando esté corriendo.
/var/log/asterisk
Donde se guardarán todos los registros de Asterisk (llamadas, mensajes y eventos). De revisar cuando se tengan problemas con Asterisk.
2.3 Música en espera y MP3
Una de las funcionalidades de Asterisk es la música en espera. En muchos servicios de asistencia al cliente es típico escucharla mientras se espera que algún operador nos atienda. En este párrafo se mostrará la configuración de la música en espera con archivos MP3. Al usar archivos MP3 hay que tener en cuenta los problemas relacionados con el derecho de autor.
Primero se crea, sino existe, la carpeta donde guardar los archivos MP3:
mkdir /var/lib/asterisk/mohmp3
Ahora hay que copiar un archivo mp3 en la carpeta creada.
Desde Linux:
Si lo hacemos desde un sistema con Linux utilizaremos el comando:
scp archivo.mp3 [email protected]:/var/lib/asterisk/mohmp3
scp - El comando que permite copiar archivos de un servidor Linux a otro.archivo.mp3 - El nombre del [email protected] - El nombre de usuario y nombre de dominio del servidor remoto.var/lib/asterisk/mohmp3 - La carpeta donde se copiará el archivo en el servidor remoto.
Si el puerto predefino para el protocolo SSH no es el 22, habrá que indicarlo en el comando. En el caso
24
que sea, por ejemplo, el 25000:
scp -P 25000 archivo.mp3 root@miodominio:/var/lib/asterisk/mohmp3
Desde Windows:
Se descarga el programa Winscp25, se instala, se configura para la conexión al servidor Linux y se abre la conexión. Esta es la ventana de trabajo de Winscp:
Terminada la copia del fichero MP3, el paso que sigue es configurar el archivo musiconhold.conf.
Lo editamos de la siguiente manera:
nano /etc/asterisk/musiconhold.conf
Se añaden las siguientes líneas al final del archivo:
[mp3]mode=filesdirectory=/var/lib/asterisk/mohmp3random=yes
25 http://winscp.net/eng/docs/lang:es
25
Se accede a la consola de Asterisk:
asterisk -rvvvvvvvvvvvvv
Se escribe:
CLI> moh reload
Para recargar la configuración de la música en espera.
CLI> moh show classes
Para ver las clases de música en espera configuradas. Aparecerá:
Class: default localhosMode: files localhosDirectory: /var/lib/asterisk/moh
Class: mp3Mode: filesDirectory: /var/lib/asterisk/mohmp3
CLI> quit
Usando archivos MP3 para la música de espera hay que tener en cuenta que el sistema necesitará utilizar bastante recursos de la CPU. Esto porque los archivo MP3 tendrán que ser convertidos en el formato audio (codec) requerido por el canal que está accediendo al servicio.
Considerando que los teléfonos IP no tienen un sistema de audio de alta calidad se puede bajar la frecuencia de sampling de los archivos MP3 sin perder en calidad del audio escuchado. El programa que permite este tipo de operación es SOX.
Ejemplo:
cd /var/lib/asterisk/mohmp3
sox archivo.mp3 -V -r 22050 -c 1 archivo1.mp3
• -c 1 pasamos el archivo de estéreo a mono (un canal).• -r 22050 frecuencia de sampling de 44100 H/z a 22050 Hz.• archivo1.mp3 - el resultado del sampling.
Usando la opción -V aparecerá en la pantalla todo el proceso:
sox: SoX v14.3.0Input File : ‘fichero.mp3’
26
Channels : 2Sample Rate : 44100Precision : 16-bitDuration : 00:05:01.38 = 13290858 samples = 22603.5 CDDA sectorsFile Size : 7.24MBit Rate : 192kSample Encoding: MPEG audio (layer I, II or III)Output File : ‘fichero1.mp3’Channels : 1Sample Rate : 22050Precision : 16-bitDuration : 00:05:01.38 = 6645429 samples ~ 22603.5 CDDA sectorsSample Encoding: MPEG audio (layer I, II or III)Comment : ‘Processed by SoX’
sox INFO sox: effects chain: input 44100Hz 2 channelssox INFO sox: effects chain: channels 44100Hz 1 channelssox INFO sox: effects chain: rate 22050Hz 1 channelssox INFO sox: effects chain: dither 22050Hz 1 channelssox INFO sox: effects chain: output 22050Hz 1 channels
Para probar la nueva configuración se necesita crear una extensión en el archivo extensions.conf (el dialplan o plan de llamadas) que se presentará en el parrafo 2.4:
Importante: cada vez que se modifican o añaden nuevo archivos en la carpeta hay que recargar la configuración de la música en espera.
2.4 Sip.conf (protocolo SIP)
El archivo sip.conf es donde se definen las extensiones SIP, los proveedores SIP y, en general, todo lo relacionado con el protocolo SIP26. El archivo sip.conf está estructurado en tres bloques. Una parte general donde se define la configuración global del protocolo SIP, el bloque central donde se configura el registro a los proveedores VoIP y/o otros servidores Asterisk, y la parte final donde se configuran las extensiones internas y externas.
Hay que pensar en Asterisk como un conmutador que quizás algún día hemos visto en la recepción de un Hotel o una empresa. Asterisk tiene las mismas funcionalidades y muchas más. Con las extensiones configuradas se podrán llamar una con otra, se podrán enrutar las llamadas a teléfonos fijos, celulares, hacia nuestros proveedores SIP y utilizar los típicos servicios de estos como llamadas en espera, desvío de llamadas, llamada a tres, contestador automático.
La configuración que sigue abarca los parámetros más importantes del sip.conf; cada línea del archivo viene acompañada de una breve explicación. Si delante del parámetro hay un punto y coma significa que el parámetro no será tomado en consideración al momento en que el sip.conf será cargado al
26 http://es.wikipedia.org/wiki/Session_Initiation_Protocol
27
arrancar Asterisk.
nano /etc/asterisk/sip.conf
[general]; etiqueta que introduce la parte general de la configuración.
allowguest=no ; No permite llamadas entrantes de extensiones SIP remotas no autentificadas. Un parámetro que aumenta la seguridad de Asterisk.
bindport=5060 ; El puerto utilizado para conectarse al servidor Asterisk (protocolo UDP).
bindaddr=0.0.0.0 ; La dirección IP para conectarse al servidor Asterisk (en este caso cualquier dirección IP de la computadora donde está instalado Asterisk sea tarjeta de red local o wan o VPN).
;tcpenable=yes ; Desde la versión 1.6 es posible configurar el servidor para que permita también conexiones con protocolo TCP.
;tcpbindaddr=0.0.0.0:5059 ; Dirección y puerto para las conexiones SIP con protocolo TCP.
callevents=yes ; Si está en yes cuando el estado de una extensión cambia, el Asterisk Manager genera el correspondiente evento27 (útil para programas externos tipo FOP).
context=default; El contexto predefinido que todas las extensiones utilizarán si no viene especificado diversamente en cada extensión.
domain=sip.miodominio.com ; el dominio local para el servidor Asterisk.
domain=192.168.1.32 ; Si queremos conectarnos a Asterisk usando un segundo dominio (ejemplo una red local). Si tenemos distintos dominios que apuntan a la misma dirección IP podemos especificarlos con este parámetro indicándolos uno por linea.
subscribecontext = subscribe; Este parámetro define el contexto que se utilizará para permitir a las extensiones acceder al estado de otras.
27 http://www.voip-info.org/wiki/view/Asterisk+manager+API
28
allowsubscribe=yes ; Esto permite suscribirse desde una extensión a otra para tener acceso a su estado (disponible, timbrando, hablando, etc…).
notifyringing=yes ; Notifica si la extensión está timbrando.
notifyhold=yes ; Notifica si la extensión está en espera.
callcounter = yes ; Cuenta el numero de llamadas simultaneas que está efectuando una extensión.
counteronpeer = yes ; Cuenta el numero de llamadas simultaneas en las extensiones de tipo peer o en la parte peer de una extensión tipo friend (una extensión de tipo friend es al mismo tiempo user y peer). De este modo en una extensión de tipo friend, si se ha definido un limite de 2 llamadas simultaneas, se diferenciarán según sean salientes o entrantes.
disallow=all ; Deshabilita todos los codecs (audio y vídeo).
allow=ulaw ; Habilita el codec audio ulaw para todas las extensiones.
allow=alaw ; Habilita el codec alaw para todas las extensiones.
useragent=X-Lite; Asterisk se presentará con este nombre al momento de comunicarse con otros servidores ó proveedores SIP. A veces algunos proveedores SIP no permiten conexiones directas de servidores Asterisk. En este modo nos presentamos como si fuéramos el softphone X-Lite.
realm=sip.voztovoice.com ; Este parámetro representa el nombre que se utilizará para la “autenticación codificada” que es parte del proceso de autenticación de una extensión presente en las especificaciones del protocolo SIP. Se usa también para crear las contraseñas de las extensiones usando algoritmo de reducción criptográfico MD5
t38pt_udptl=yes ; Permite el uso del protocolo T38 (fax sobre IP) pero solo en modo pasarela, es decir, entre dos extensiones que soporten el protocolo. Desde la versión 1.6.0.21, Asterisk “negocia” directamente los parámetros para la recepción de los faxes y ya no actúa solamente como pasarela. Ademas, desde la misma versión es posible indicar directamente en la misma linea el tipo de corrección de error utilizado y el tamaño de los paquetes que contienen el fax. La misma linea se puede escribir también de esta forma:
29
t38pt_udptl = yes,fec,maxdatagram=400
faxdetect=yes; permite la detección de faxes en canales SIP. Permite diferenciar el tratamiento de las llamadas entrantes según sea un fax o una llamada de voz
videosupport=yes ; Para permitir vídeo llamadas.
srvlookup=yes ; Permite hacer búsquedas de registros DNS SRV basadas en los nombres de dominio para llamadas SIP salientes del tipo: SIP/usuario@dominio.
alwaysauthreject = yes ; Cuando un INVITE o REGISTER entrante es rechazado, Asterisk enviará siempre como respuesta que el usuario o la contraseña no son validas y no la razón verdadera del rechazo. Aumenta la seguridad.
Ahora viene la parte del registro con nuestros proveedores de llamadas. Si los vamos a usar solo para las llamadas salientes no hace falta configurar esta parte. Siguen algunos ejemplos a modo de explicación.
register => fulano:[email protected]
Para el registro con el proveedor el username será fulano, la contraseña sesamo y el dominio sip.provider1.com. Si el proveedor usa un puerto que no es el 5060 hay que especificarlo al final de la línea de esta forma:
register => fulano:[email protected]:5061
En los casos descritos arriba las llamadas entrantes llegaran a la extensión s y al contexto que se define en la configuración de la extension. Si queremos que las llamadas entre a una extensión definida, tenemos que añadir al final de la linea el numero. Este numero puede ser arbitrario siempre y cuando los proveedores SIP no especifiquen diversamente.
register => fulano:contraseñ[email protected]/1234
La ultima parte es dedicada a la configuración de las extensiones:
[1000] ; Numero de la extensión.
accountcode=1000 ; El código que aparecerá en el registro de llamadas para esta extensión.
language=es ; Si hemos instalado las locuciones en más de un idioma, aquí se puede definir el idioma para la
30
extension.
type=friend ; Tipo de extensión. Puede ser friend, user o peer.
• User: una extensión que se registra al servidor Asterisk usando el campo From para hacer llamadas.
• Peer: una extensión que usamos para hacer y recibir llamadas y que reconocemos a través del campo Host.
• Friend: es a la vez user + peer.
secret=contraseña ; La contraseña que la extensión usará para autenticarse al servidor Asterisk.
qualify=yes ; Este parámetro se utiliza para mantener activa la conexión de una extensión que se conecta al servidor Asterisk detrás de una NAT (Network Address Translation)28
mailbox=1000@default ; Si este parámetro es configurado, cuando la extensión se conecte al servidor Asterisk, éste controlará si hay mensajes de voz pendientes y en caso positivo se lo comunicará usando MWI = Message Waiting Indicator.; es una señal audio o vídeo que puede ser recibida por la mayoría de los teléfonos IP o Softphone.
host=dynamic; Si la extensión se conecta remotamente cambiando continuamente su dirección IP se pone este parámetro a dynamic. En caso contrario se indica la dirección IP.
dtmfmode=rfc2833 ; El protocolo para enviar los tonos DTMF.29
context=phones ; El contexto que usará la extensión.
canreinvite=no ; Normalmente Asterisk actúa como B2BUA30 entre las extensiones y esto permite usar toda una series de funcionalidades cuando Asterisk quede en el medio de las llamadas. Con este parámetro en “no” este es el comportamiento normal. Se pone “yes” si se quiere que flujo audio/video vaya directamente de una extensión a otra. En los casos que la extensiones estén detrás de un NAT, canreinvite=yes no
28 Su uso más común es permitir utilizar direcciones privadas (definidas en el RFC 1918) y aún así proveer conectividad con el resto de Internet. Existen rangos de direcciones privadas que pueden usarse libremente y en la cantidad que se quiera dentro de una red privada (Wikipedia)
29 En telefonía, el sistema de marcación por tonos, también llamado sistema multifrecuencial o DTMF (Dual-Tone Multi-Frequency), consiste en lo siguiente: Cuando el usuario pulsa en el teclado de su teléfono la tecla correspondiente al dígito que quiere marcar, se envían dos tonos, de distinta frecuencia: uno por columna y otro por fila en la que esté la tecla, que la central descodifica a través de filtros especiales, detectando instantáneamente que dígito se marcó.
30 El B2BUA es una aplicación para controlar llamadas entre usuarios SIP.
31
funciona.
nat=yes ; Si la extensión se encuentra detrás de un NAT hay que poner “yes”.
callerid=Fulano <1000> ; El nombre y el numero de identificación de la extensión.
disallow=all ; Deshabilitar todos los codecs.
allow=gsm ; Habilita el codec audio GSM (el primero que se intentará utilizar durante la negociación de la llamada).
allow=ulaw ; Habilita el codec audio ulaw.
allow=alaw ; Habilita el codec audio alaw.
allow=g729 ; Habilita el codec audio g729.
allow=h263 ; Habilita el codec vídeo h263.
call-limit=2 ; Con este parámetro definimos que la extensión puede usar solamente dos canales a la vez. Este parámetro desde la versión 1.6.X.X de Asterisk es “deprecated”, eso significa que se puede utilizar pero que pronto será tachado de las nuevas versiones de Asterisk. En su lugar, para limitar el numero de llamadas para una extensión, se usan las funciónes GROUP y GROUP_COUNT
Configuramos una segunda extensión:
[1001]type=friendaccountcode=1001language=essecret=contraeñaqualify=yesmailbox=1001@defaulthost=dynamicdtmfmode=rfc2833context=phonescanreinvite=nonat=yes
32
callerid=Sutano <1001>disallow=allallow=gsm ;allow=ulawallow=alawallow=g729allow=h263call-limit=2
Ahora un ejemplo para un proveedor de llamadas SIP.
[justvoip] ; Nombre que le asignamos al proveedor.
type=peer ; Lo vamos a utilizar solo para llamadas salientes (peer).
host=sip.justvoip.com ; El nombre del dominio del proveedor.
fromdomain=sip.justvoip.comEste parametro permite definir el nombre de dominio que aparecerá en la campo From: de la cabecera SIP. Mucho proveedores lo exigen para autenticarse
fromuser=fulano; Los datos que nos pide el proveedor para conectarnos (usuario y contraseña).
defaultuser=fulano
secret=contraseña
qualify=yes
canreinvite=no
dtmfmode=rfc2833
context=from-justvoip ; El contexto de utilizar en extensions.conf si usamos el proveedor también para las llamadas entrantes.
call-limit=2 ; Numero de canales que brinda el proveedor.
language=esdisallow=allallow=ulawallow=alaw
33
allow=g729
Cada vez que se modifica la configuración del sip.conf hay que recargarla. Se entra en la consola de Asterisk:
asterisk -rvvvvvvvvvv
Se escribe el comando:
CLI> sip reload
Reloading SIP
La lista de los comandos disponibles en la consola para las extensiones SIP se obtiene escribiendo:
CLI> help sip
sip notify Send a notify packet to a SIP peersip prune realtime [peer|user| Prune cached Realtime users/peers
sip reload Reload SIP configurationsip set debug {on|off|ip|peer} Enable/Disable SIP debugging
sip set history {on|off} Enable/Disable SIP historysip show {channels|subscriptio List active SIP channels/subscriptions
sip show channel Show detailed SIP channel info sip show domains List our local SIP domains
sip show history Show SIP dialog history sip show inuse List all inuse/limits
sip show objects List all SIP object allocations sip show peers List defined SIP peers
sip show peer Show details on specific SIP peer sip show registry List SIP registration status sip show settings Show SIP global settings
sip show tcp List TCP Connections sip show users List defined SIP users
sip show user Show details on specific SIP user sip unregister Unregister (force expiration) a SIP peer from the registry
Con el comando sip show settings se tendrá una vista más completa de todos los valores asignados a los parámetros presentes en el archivo de configuración sip.conf.
2.5 Extensions.conf (plan de llamadas)
El archivo de configuración estensions.conf es el más importante para la puesta en marcha de Asterisk. En él se define el plan de llamadas. Cualquier número marcado desde una extensión será procesado dentro de este archivo. Al igual que el archivo sip.conf está dividido en tres bloques:
34
• La parte general donde se configuran algunos parámetros generales.• La parte globals donde se definen las variables globales que se van a utilizar en Asterisk y que
son validas para todos los canales.• Una ultima parte donde queda toda las configuración del plan de llamada.
nano /etc/asterisk/extensions.conf
La parte general:
[general]
static=yes ; Si static es “yes” y writeprotect es “no”, para guardar los cambios hechos en el plan de llamadas, desde la consola de Asterisk habrá que escribir el comando dialplan reload.
writeprotect=no ; En caso contrario se actualizará automáticamente pero se perderán todos los comentarios presentes en el archivo.
autofallthrough=yes ; Si es “yes” cuando alguna llamada se sale del plan de llamadas se terminará.
priorityjumping=yes ; Algunas aplicaciones y/o funciones tienen la capacidad, bajo algunas circunstancias, de “saltar” desde la prioridad donde se encuentran a una prioridad que normalmente es n= +101 donde n es el numero de la prioridad que se está ejecutando. Si está en “yes” hará ese salto sino no.
[globals] SOP = SIP/1000 FUL = SIP/0057310000000 JUST = SIP/justvoip
En Globals se configuran las variables globales que queremos usar en el dialplan, Si se efectúan llamadas frecuentes a un numero y se quiere configurar con una sigla o un nombre, en esta parte del archivo se puede hacer. Las tres líneas muestran tres casos distintos. Para llamar la extensión 1000 (configurada en sip.conf) se podrá usar la variable SOP, para llamar el numero de celular de mi amigo fulano en vez de poner el numero por extenso podré indicar la variable FUL; para concluir si para las llamadas uso el proveedor SIP Justvoip se podrá usar la variable JUST.
En la tercera parte es donde se configura el verdadero dialplan o plan de marcado. El dialplan se compone de contextos y dentro de cada contexto van las extensiones y prioridades. Cada extensión y prioridad puede contener una aplicación o una función (para una lista completa de las aplicaciones y funciones disponibles véase el apéndice A y B). Para empezar, se definirán dos contextos, uno para las llamadas internas y otro para las llamadas externas.
[internas]
35
; Esta etiqueta indica que todo lo que aparece a partir de esta línea se considerará perteneciente al contexto internas.
exten => 123,1,Answer()
Todas las líneas de configuración están estructuradas de la siguiente manera:• exten => en cada línea. • 123 es el numero de extensión (cuando se marcará este numero desde un teléfono IP, hardware
o software, Asterisk procesará la llamada empezando por esta línea). • 1 es la prioridad. Asterisk procesa las líneas secuencialmente, del numero más bajo al más alto. • Answer es la aplicación que permite contestar la llamada.
exten => 123, 2,Playback(hello-world)
Esta es la segunda línea que será procesada. 123 la misma extensión de la primera línea, 2 es la prioridad (progresiva). Playback es la aplicación que le permite a Asterisk usar las voces; en este caso el archivo audio es hello-world que hace parte de las voces que vienen con la instalación de Asterisk.
exten => 123,3,Hangup
Esta es la tercera línea. 123 la extensión, 3 la prioridad, Hangup la aplicación que sirve para colgar una llamada.
Si se efectúa una llamada al número 123, Asterisk abrirá un canal para la llamada (Answer), escucharemos la locución Hello World y luego la llamada se terminará.
[internas] exten => 123,1,Answer() exten => 123,2,Playback(hello-world) exten => 123,3,Hangup()
Otra forma de es:
[internas] exten => 123,1,Answer() exten => 123,n,Playback(hello-world) exten => 123,n,Hangup()En la segunda y tercera línea en el numero de la prioridad aparece una “n”; la “n” significa next y sirve para no tener que escribir en cada línea el numero progresivo de la prioridad. Esto es muy cómodo cuando se modifica el dialplan porque al insertar una nueva línea no se tendrá que volver a numerar todas las demás.
Ahora se definirá un contexto muy sencillo para las llamadas externas.
[externas]exten => _0057.,1,Dial(${JUST}/${EXTEN})
36
La primera línea le dice a Asterisk que para todos los números marcados que empiecen por 0057 deberá usar esta parte del dialplan. El signo _ (guion bajo) se pone cuando no se indica el numero exacto sino solamente una parte. El . (punto) indica que después del 0057 pueden haber cualquier numero de cifras. Dial es la aplicación que se utiliza para hacer una llamada. En otro párrafo (2.8.1) se explicará de forma más detallada las variables y opciones que usa esta aplicación. Por ahora es importante saber que ${JUST} es la variable configurada en el bloque globals y corresponde a SIP/justvoip, es decir el proveedor de llamadas SIP. ${EXTEN} es una variable interna de Asterisk donde se almacena el numero que se está marcando.
exten => _0057.,n,Playback(all-outgoing-lines-unavailable)
Si por algún motivo la llamada no tiene exito, se procesará la segunda línea donde se escuchará una voz que avisará que todas las líneas están ocupadas o no disponibles.
exten => _0057.,n,Hangup()
Con la tercera línea la llamada se terminará.
Ahora se definirán dos contextos más, uno para las extensiones que tienen acceso a las líneas externas y uno para aquellas que solo pueden hacer llamadas internas. Estos contextos hay que definirlos en la configuración de cada extensión (vease sip.conf) para definir cuales extensiones tienes acceso a determinados contextos.
[solo-internas]include => internas
Con esto se define que todas las extensiones configuradas en sip.conf bajo el contexto solo-internas tendrán acceso solo a la parte del dialplan contenido bajo la etiqueta [internas]
[phones]include => internasinclude => externas
Con estas líneas se define que todas las extensiones configuradas con el contexto phones tendrán acceso a los contextos del dialplan [internas] y [externas].
En la configuración del sip.conf (parrafo 2.4) las dos extensiones que se han configurado les hemos asignado el contexto phones.
A través de los contextos podemos crear grupos distintos de extensiones y hasta grupos cerrados de usuarios, es decir grupos donde las extensiones solo se puedan llamarse entre ellas.
Añadiendo las líneas para escuchar la música en espera en formato MP3 el dialplan será:
[general] static=yes
37
writeprotect=noautofallthrough=yespriorityjumping=yes
[globals] SUP = SIP/1000 FUL = SIP/0057310000000 JUST = SIP/justvoip
[internas] exten => 123,1,Answer() exten => 123,2,Playback(hello-world) exten => 123,3,Hangup()
exten => 100,1,Answerexten => 100,n,MusicOnHold(mp3,60)exten => 100,n,Hangup
[externas] exten => _0057.,1,Dial(${JUST}/${EXTEN}) exten => _0057.,n,Playback(all-outgoing-lines-unavailable) exten => _0057.,n,Hangup()
[solo-internas] include => internas
[phones] include => internas include => externas
Para actualizar la configuración desde la consola de Asterisk:
asterisk -rvvvvvvvvvv
Se escribe el comando:
CLI> dialplan reload
La lista de los comando relacionados con el dialplan se obtiene:
CLI> help dialplan
dialplan add extension Add new extension into context dialplan add ignorepat Add new ignore pattern dialplan add include Include context in other context dialplan reload Reload extensions and only extensions dialplan remove extension Remove a specified extension
38
dialplan remove ignorepat Remove ignore pattern from context dialplan remove include Remove a specified include from context dialplan set extenpatternmatch Use the Old extension pattern matching algorithm. dialplan set extenpatternmatch Use the New extension pattern matching algorithm. dialplan show Show dialplan
2.5.1 El contexto subscribe
Como se ha indicado a lo largo de la configuración del archivo sip.conf hay la posibilidad de suscribirse a una extensión para conocer su estado. Esto es posible configurando el contexto subscribe en el plan de llamadas:
nano /etc/asterisk/extensions.conf
Se añaden las siguientes líneas (usando la prioridad hint):
[subscribe]exten => 1000,hint,SIP/1000exten => 1001,hint,SIP/1001
Ahora se incluye este contexto en los dos contextos que creados:
[solo-internas] include => internasinclude => subscribe
[phones] include => internas include => externasinclude => subscribe
Se guardan los cambios y desde la consola de Asterisk se actualiza el plan de llamadas:
asterisk -rvvvvvvvvvvvv
CLI> dialplan reload
Con el comando:
CLI> core show hints
-= Registered Asterisk Dial Plan Hints =- 1001@subscribe : SIP/1001 State:Idle Watchers 0 1000@subscribe : SIP/1000 State:Idle Watchers 0
39
2.5.2 X-Lite y el plan de llamadas
Una vez configurado un plan de llamadas básico se puede empezar haciendo algunas pruebas. Primero se configurará un SoftPhone (X-Lite) para conectarlo a nuestro Asterisk para hacer las primeras llamadas.
Se descarga el Softphone X-Lite desde la página Web de la empresa que lo desarrolla31 y se instala. Para Linux podemos usar el SoftPhone Ekiga32.
Una vez instalado se abre el programa y se configura (menu “Sip account settings”):
Se usan los datos que de configuración puestos en el sip.conf. En domain se pone la dirección IP del servidor Asterisk. Cuando se ha terminado, se presiona el botón Aplicar y luego Aceptar. El SoftPhone se registrará en nuestro Asterisk:
Una vez finalizado con éxito el registro de nuestra extensión se puede hacer la primera llamada. Desde el teclado numérico del X-Lite marcamos la extensión 123. Se escuchará la locución hello-world y la llamada terminará.
Llamando la extensión 100 se escuchará la música en espera basada en el archivo mp3 que se ha cargado en el servidor Asterisk.
31 http://www.counterpath.com/ 32 http://ekiga.org/
40
Para subscribir la extensión configurada en el X-Lite al estado de otra extensión se abre el panel lateral derecho, y se añade la extensión 1001 en contactos de esta forma:
Si la extensión se encuentra registrada al servidor Asterisk veremos su estado:
41
2.5.3 Llamadas entre extensiones y aplicación Echo
En Asterisk se han configurado dos extensiones (1000 y 1001). Para hacer llamadas de una a otra hay que modificar el plan de llamadas:
nano /etc/asterisk/extensions.conf
Dentro del contexto internas se añaden las siguientes líneas:
exten => _100X,1,Dial(SIP/${EXTEN},45)exten => _100X,n,HangupAnalizando las dos líneas:
_100X estos caracteres indican el número de la extensión a llamar: El primer carácter y el último en Asterisk se llaman Pattern Matching y juntos a otros tienen este significado:
• X: Puede ser un número de 0 a 9.• Z: Puede ser un número de 1 a 9.• N: Puede ser un número de 2 a 9.• _ : Si el numero de extensión que se indica no es exacto se pone delante del numero mismo este
signo.• .: El punto representa cualquier numero de cifras.• !: el punto exclamativo representa cualquier numero de cifras (incluyendo 0 cifras)
Dial es la aplicación que se usa en Asterisk para iniciar una llamada.
42
${EXTEN} es el nombre de la variable de canal donde se almacena el numero que se marca.
45 es el número de segundos que timbrará la extensión llamada.
Si dentro de este tiempo nadie contesta, Asterisk procesará la siguiente línea, es decir, colgará la llamada (aplicación Hangup).
Ahora se añadirán otras líneas para configurar la aplicación Echo en el dialplan. Esta aplicación se usa para probar el audio de una extensión y averiguar si hay problemas de configuración.
Estas son las líneas que hay que añadir al contexto internas:
exten => 150,1,Answerexten => 150,n,Playback(echo-test)exten => 150,n,Echoexten => 150,n,Hangup
Se guardan los cambios en el plan de llamadas y se recarga la configuración:
asterisk -rvvvvvvvvvvvvvvvvvvvv
CLI> dialplan reload
Ahora desde el SoftPhone se marca el numero 150 y se procede con el test de Echo.
2.5.4 Las Macros
Si en el plan de llamadas algunas acciones se repiten muy a menudo, Asterisk brinda la posibilidad de crear una Macro que permite simplificar estas operaciones. La sintaxis de la aplicación Macro:
asterisk -rvvvvvvvvvvvv
CLI> core show application Macro
-= Info about application ‘Macro’ =-[Synopsis]Macro Implementation
[Description]Macro(macroname,arg1,arg2...): Executes a macro using the context‘macro-<macroname>’, jumping to the ‘s’ extension of that context andexecuting each step, then returning when the steps end.The calling extension, context, and priority are stored in ${MACRO_EXTEN},${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. Arguments become${ARG1}, ${ARG2}, etc in the macro context.
43
If you Goto out of the Macro context, the Macro will terminate and controlwill be returned at the location of the Goto.If ${MACRO_OFFSET} is set at termination, Macro will attempt to continueat priority MACRO_OFFSET + N + 1 if such a step exists, and N + 1 otherwise.WARNING: Because of the way Macro is implemented (it executes the prioritiescontained within it via sub-engine), and a fixed per-thread memorystack allowance, macros are limited to 7 levels of nesting (macrocalling macro calling macro, etc.). It may be possible thatstack-intensive applications in deeply nested macros could causeAsterisk to crash earlier than this limit. It is advised that if youneed to deeply nest macro calls, that you use the Gosub application(now allows arguments like a Macro) with explict Return() callsinstead.Use of the application WaitExten within a macro will not function as expected.Please use the Read application in order to read DTMF from a channel currentlyexecuting a macro.
El comando seria:
Macro(nombre_de_la_macro, argumento1,argumento2,argumentoN)
ArgumentoN es un valor o una variable que se pasa a la macro al momento de llamarla desde el plan de llamadas.
Se crearán las siguientes variables:
• ${MACRO_EXTEN} contendrá el numero marcado.• ${MACRO_CONTEXT} contendrá el contexto de donde se ha llamado la Macro.• ${MACRO_PRIORITY} contendrá la prioridad de la línea de donde se ha llamado la Macro• ${ARG1}, ${ARG2}, ${ARGN) son las variables que contienen los argumentos que se han
enviado a la Macro.
Para empezar a utilizar la aplicación Macro se creará una muy sencilla que antes de marcar una extensión controle que ésta esté disponible:
Primero hay que salir de la consola y modificar el plan de llamadas:
CLI> quit
nano /etc/asterisk/extensions.conf
Al final del archivo se añaden estas líneas:
[macro-disponible]exten => s,1,ChanIsAvail(SIP/${MACRO_EXTEN})exten => s,n,Gotoif($[${AVAILSTATUS} = 4]?4:3)
44
exten => s,n,MacroExitexten => s,n,Playback(all-circuits-busy-now)exten => s,n,Hangup
Una explicación de las aplicaciones nueva que aparecen en las lineas de la Macro:
ChanIsAvail: controla si una extensión está disponible y retorna la variable ${AVAILSTATUS} que puede contener estos valores:
• 0 AST_DEVICE_UNKNOWN – El canal es valido pero su estado no es conocido”. • 1 AST_DEVICE_NOT_INUSE - “No se está usando”.• 2 AST_DEVICE IN USE - “El canal está en uso”.• 3 AST_DEVICE_BUSY - “El canal está ocupado”. • 4 AST_DEVICE_INVALID - “El canal es invalido”. • 5 AST_DEVICE_UNAVAILABLE - “El canal no está disponible (no está registrado a
Asterisk)”. • 6 AST_DEVICE_RINGING - “El canal está timbrando”.
Gotoif: literalmente es “ve a la prioridad indicada si se presenta una determinada condición”, de otra forma ve a otra prioridad.
MacroExit: sale de la macro y vuelve al mismo contexto, extensión prioridad + 1 de donde se llamó.
Para insertar la Macro en el plan de llamadas creado modificamos la parte utilizada para llamar una extensión:
exten => _100X,1,Dial(SIP/${EXTEN},45)exten => _100X,n,Hangup
Para que quede:
exten => _100X,1,Macro(disponible)exten => _100X,n,Dial(SIP/${EXTEN},45)exten => _100X,n,Hangup
Se guardan los cambios y se actualiza el plan de llamadas:
asterisk -rvvvvvvvvvvvvvvv
CLI> dialplan reload
Ahora se marca de una extensión a otra y se controla lo que aparece en la consola de Asterisk para controlar el comportamiento de la Macro.
45
2.6 Voicemail.conf – Buzón de voz
En el archivo voicemail.conf es donde se configura todo lo relacionado con el buzón de voz. Si se recibe una llamada y no se contesta o la línea está ocupada, siempre y cuando se configura el plan de llamadas oportunamente, entrará en función el contestador, grabará el mensaje de voz dejado por quien llama y enviará un correo electrónico de aviso al llamado. Es posible anexar el archivo audio al correo electrónico en distintos formatos audio. El voicemail.conf se encuentra en la carpeta /etc/asterisk.
nano /etc/asterisk/voicemail.conf
[general]; Empieza la parte general.
format=gsm|wav ; El codec audio utilizado para grabar los mensajes de voz dejados en el contestador.
serveremail= [email protected]; El remitente del correo electrónico que avisa de una nuevo mensaje de voz.
attach=yes ; Si attach está en “yes” el mensaje de voz se enviará como anexo al correo electrónico.
maxmsg=100 ; Numero máximo de mensajes de voz para cada buzón de voz configurado.
maxsecs=300 ; Numero máximo de segundos de durada de un mensaje de voz.
minsecs=3 ; Numero mínimo de segundos para que un mensaje de voz sea reconocido como tal y sea enviado al buzón de voz del destinatario.
maxgreet=60 ; Se puede grabar un mensaje de bienvenida para nuestro buzón de voz personal. Este parámetro define la duración máxima del mensaje (en segundos).
skipms=3000 ; Cuando se escuchan los mensaje de voz, si lo hemos configurado previamente, podemos usar el teclado numérico del teléfono para adelantar o devolver el mensaje mismo. Ejemplo: presionando el número 8 se adelantará de 3000 milisegundos, es decir 3 segundos, con el 9 nos devolvemos de 3 segundos.
maxsilence=10 ; Si mientras se graba un mensaje de voz hay un silencio de 10 segundos, la llamada se termina y también la grabación.
silencethreshold=128
46
; Este numero representa el nivel de audio y sirve para definir que se considera silencio. Más bajo el número, más sensible al ruido .
maxlogins=3 ; Numero máximo de intentos permitidos cuando se marca la contraseña asociada al buzón de voz personal. moveheard=yes ; Una vez escuchados los mensajes de voz se mueven a la carpeta OLD (viejos) en automático si se configura en no, hay que hacerlo desde el menú del contestador.
userscontext=default ; El contexto predefinido para los usuarios del buzón de voz. ;externnotify=/usr/bin/myapp ; Si cada vez que se recibe un mensaje de voz se quiere arrancar un programa hay que configurarlo usando este parámetro.
;externpass=/usr/bin/myapp ; Si se desea que un programa arranque cada vez que se cambia la contraseña de nuestro buzón de voz hay que configurarlo usando este parámetro.
;externpassnotify=/usr/bin/myapp ; Si externpass está configurado y queremos que la contraseña se actualice también en voicemail.conf hay que configurar este parámetro.
directoryintro=dir-intro ; El mensaje de introducción de la aplicación directory (para buscar las extensiones configuradas en Asterisk).
charset=ISO-8859-1 ; El estándar ISO para los mensajes de texto que se enviaran para notificar la llegada de un nuevo mensaje de voz.
pbxskip=yes ; Quitar la la abreviación [PBX] en el asunto del mensaje.
fromstring=VozToVoice ; El nombre que aparecerá como remitente del correo electrónico.
usedirectory=yes ; Los mensajes de voz que se reciben se pueden reenviar a otros usuarios/extensiones del servidor Asterisk. También se pueden dejar directamente mensajes de voz en determinados buzones. Este parámetro permite buscar en el directorio la persona a la que queremos dejar o reenviar el mensaje de voz.
;odbcstorage=asterisk
47
; Se pueden guardar los mensajes de voz en un base de datos usando el conector ODBC. Aquí es donde hay que configurar el nombre de la base de datos.
;odbctable=voicemessages; El nombre de la tabla de la base de datos donde guardar los mensajes de voz. ; Change the from, body and/or subject, variables: ; VM_NAME, VM_DUR, VM_MSGNUM, VM_MAILBOX, VM_CALLERID, VM_CIDNUM, ; VM_CIDNAME, VM_DATE ; ; Note: The emailbody config row can only be up to 512 characters due to a ; limitation in the Asterisk configuration subsystem. ;emailsubject=[PBX]: New message ${VM_MSGNUM} in mailbox ${VM_MAILBOX} ; The following definition is very close to the default, but the default shows ; just the CIDNAME, if it is not null, otherwise just the CIDNUM, or “an unknown ; caller”, if they are both null. ;emailbody=Dear ${VM_NAME}:\n\n\tjust wanted to let you know you were just left a ${VM_DUR} long message (number ${VM_MSGNUM})\nin mailbox ${VM_MAILBOX} from ${VM_CALLERID}, on ${VM_DATE}, so you might\nwant to check it when you get a chance. Thanks!\n\n\t\t\t\t—Asterisk\n
Todo el bloque de arriba representa las variables y el texto del correo electrónico que se enviará para notificar la llegada de un nuevo mensaje de voz. Se puede modificar para adaptarlo a las exigencias especificas de cada instalación.
pagerfromstring=VozToVoice ; Si se envía una notifica también a un localizador ó Pager esta línea define el remitente del mensaje. pagersubject=Nuevo VM ; El objeto del mensaje al Pager.
pagerbody=Nuevo mensaje de ${VM_DUR} de duración en la casilla ${VM_MAILBOX}\nde ${VM_CALLERID}, en ${VM_DATE} ; El cuerpo del mensaje.
emaildateformat=%A, %d %B %Y at %H:%M:%S ; Con este parámetro se configura la hora de llegada del correo en el formato 24H.
mailcmd=/usr/sbin/sendmail -t ; Sendmail es el programa predefinido para enviar los correos electrónicos.
Si en lugar ODBC se quiere usar el protocolo IMAP33 para guardar los mensajes de voz, aquí va indicada su configuración.
;imapgreetings=no
33 IMAP Wikipedia
48
; Para guardar el mensaje de bienvenida en la carpeta de IMAP. Igual a no si no se usa IMAP. ;greetingsfolder=INBOX ; Si imapgreetings es igual a “yes” aquí es donde se define la carpeta donde guardar el mensaje audio de bienvenida.
;imapparentfolder=INBOX ; Si se quiere crear una carpeta dentro de la carpeta INBOX para cada buzón de voz.
tz=central ; Uso horario predefinido para indicar la fecha y la hora del correo de voz recibido.
attach=yes; Si es “yes” el mensaje de voz se anexará al correo electrónico de notifica.
attachfmt=wav ; El formato audio definido para el envío del mensaje audio anexo al correo electrónico.
saycid=yes; Si es a “yes” antes de escuchar el correo de voz se anunciará el identificativos (numero de teléfono o extensión) de quien lo dejó.
sayduration=no; Anunciar o no la duración del correo de voz.
saydurationm=2; Definir la duración mínima del correo de voz para que sea anunciada (en minutos).
dialout=phones; Contexto de utilizar para efectuar llamadas desde el menú del contestador [opción 4 del menú avanzado].
sendvoicemail=yes ; Permitir o no de enviar un correo de voz a otra extensión [opción 5 del menú avanzado].
; callback=fromvm; Contexto para llamar desde el menú del buzón de voz al remitente de un mensaje de voz.
; exitcontext=fromvm ; Contexto donde enviar el usuario si mientras usa los menú del buzón presiona la tecla * o 0.
review=yes; Si es “yes” permite a quien está dejando un correo de voz de escucharlo antes de enviarlo.
; operator=yes; Permite a quien llama de presionar 0 (cero) antes/después/mientras está dejando un correo de voz para buscar una operadora.
49
; envelope=no ; Antes de reproducir el mensaje audio, reproduce los datos del mensaje.
; delete=yes; Si es “yes” una vez que se notifique la llegada de un correo de voz, éste se borrará del servidor.
; volgain=0.0; Si el correo de voz se grabó con un volumen muy bajo con esta opción podemos mejorar su calidad. Para que se pueda utilizar se debe haber instalado SOX.
; nextaftercmd=yes; Ir al correo de voz que sigue si se presiona las teclas 7 o 9 (borrar/guardar el mensaje que se esta escuchando).
forcename=yes; Obliga cada usuario con buzón de voz configurado a grabar su nombre la primera vez que accede. Un usuario se considera nuevo si su contraseña coincide con el número de su extensión.
forcegreetings=no; Obliga el nuevo usuario a grabar un mensaje de bienvenida.
hidefromdir=no; El usuario no aparecerá en el directorio.
tempgreetwarn=yes; Recuerda al usuario que el mensaje de bienvenida que esta usando es temporal.
;vm-password=custom_sound ; Configurar una locución alternativa para pedir la contraseña del buzón.
; vm-newpassword=custom_sound ; Configurar una locución alternativa cuando se avisa de insertar una nueva contraseña para el buzón de voz.
; vm-passchanged=custom_sound ; locución alternativa para decir “Tu contraseña ha sido cambiada”.
; vm-reenterpassword=custom_sound ; locución alternativa para decir “Introduce nuevamente tu contraseña seguida del botón numeral o gato.
; vm-mismatch=custom_sound; locución alternativa de “la contraseña insertada y repetida no son iguales”.
listen-control-forward-key=# ; Tecla numérica para adelantar el mensaje que se está escuchando.
50
listen-control-reverse-key=*; Tecla numérica para ir atrás en el mensaje que se está escuchando.
listen-control-pause-key=0; Tecla numérica para poner en pausa el mensaje.
listen-control-restart-key=2; Tecla numérica para volver a escuchar el mensaje desde el inicio.
listen-control-stop-key=13456789; Teclas numéricas para parar el mensaje y volver al menú del contestador.
backupdeleted=100; Numero máximo de mensajes en la carpeta “borrados”.
[zonemessages]colombia=America/Bogota|'vm-received' aebY 'digits/at' HMeastern=America/New_York|'vm-received' Q 'digits/at' IMpcentral=America/Chicago|'vm-received' Q 'digits/at' IMpcentral24=America/Chicago|'vm-received' q 'digits/at' H N 'hours'military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p'european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM
En el bloque de arriba se definen las zonas horarias que podemos usar en el contestador. Si por ejemplo hay usuarios de distintos continentes, se pueden definir por cada uno de ellos su huso horario y de esta forma configurar la fecha y hora en que recibieron los mensajes de voz.
[default] ; Aquí empieza la configuración de los buzones de voz para los usuarios pertenecientes al contexto default.
;maxmsg=50 ; Define el numero máximo de correos de voz por cada carpeta de un determinado contexto (en este caso el contexto es default).
; Cada buzón de voz sigue estas reglas
Numero extensión => contraseña, nombre apellido, correo electrónico, correo pager,opciones separadas por el signo coma.
Sigue la configuración de los buzones de voz para la extensiones configuradas en el sip.conf.
1000 => 1000,Fulano,[email protected],,tz=Colombia1001 => 1001,Sutano,[email protected],,tz=Colombia
51
Algunos ejemplos más:
;4200 => 9855,Mark Spencer,[email protected],[email protected],attach=no|[email protected]|tz=central|maxmsg=10 ;4300 => 3456,Ben Rigas,[email protected] ;4310 => -5432,Sales,[email protected],,tz=colombia ;4069 => 6522,Matt Brooks,[email protected],,|tz=central|attach=yes|saycid=yes|operator=yes|moveheard=yes|sayduration=yes|saydurationm=1 ;4073 => 1099,Bianca Paige,[email protected],,delete=1 ;4110 => 3443,Rob Flynn,[email protected] ;4235 => 1234,Jim Holmes,[email protected],,Tz=european[other] ;other es otro contexto con sus opciones y sus usuarios (por ejemplo si el mismo servidor está siendo utilizado por dos empresas distintas ).;directoryintro=dir-company2; mensaje de bienvenida del directorio de la empresa 2 ;1234 => 5678,Company2 User,root@localhost;[acme] ; tercero contexto para otra empresa ;tz=eastern ;111 => 7383,Pete,[email protected],,tz=central ;112 => 6262,Nancy,[email protected]
Se guardan los cambios y se vuelve a arrancar Asterisk:
/etc/init.d/asterisk restart
Una vez configurado el contestador hay que modificar el archivo extensions.conf y añadir algunos bloques que permiten acceder al buzón de voz y dejar un mensaje en el mismo.
nano /etc/asterisk/extensions.conf
[internas]exten => 97,1,Answer; abre el canal (contesta). exten => 97,n,VoiceMailMain(${CALLERID(num)}@default); envía la llamada directamente al buzón de voz de la extensión que está llamando en el contexto default. exten => 97,n,Hangup; termina la llamada.
97 es el número que desde el teléfono IP o Softphone hay que marcar para acceder al buzón de voz personal.
Se añade otro bloque en el plan de llamadas de modo que si una extensión no está disponible o ocupada la llamada entre directamente al buzón de voz de la extensión llamada:
exten => _100X,1,Macro(disponible)exten => _100X,n,Dial(SIP/${EXTEN},45)exten => _100X,n,GotoIf($[“${DIALSTATUS}” = “BUSY”]?busy:unavail); según si la extensión esté ocupada o nadie contesta se continuará en el dialplan en las prioridades definidas con las etiquetas unavail, (no disponible), o busy, (ocupado).exten => _100X,n(unavail),Voicemail(${EXTEN}@default,u); se activará el buzón de voz
52
anunciando que la extensión llamada no está disponible (opción u) y después del tono se podrá dejar un mensaje.exten => _100X,n,Hangup; se terminará la llamada.exten => _100X,n(busy),VoiceMail(${EXTEN}@default,b); se activará el buzón de voz anunciando que la extensión llamada está ocupada (opción b) y que después del tono se podrá dejar un mensaje.exten => _100X,n,Hangup; se terminará la llamada.
Se guardan los cambios y se actualiza el plan de llamadas:
asterisk -rvvvvvvvvvvvvvv
CLI> dialplan reload
Ahora desde el X-lite se llama la extensión 97 para probar el menú del VoiceMail (buzón de voz).
2.7 Iax.conf – protocolo IAX
Ya se ha presentado la parte relacionada con la configuración de las extensiones SIP (párrafo 2.4). En este párrafo se verá como configurar otras extensiones usando el protocolo IAX234. El archivo que hay que modificar es el iax.conf y se encuentra, en la carpeta /etc/asterisk.
nano /etc/asterisk/iax.conf
[general]
bindport=4569 ; El puerto UDP usado por este protocolo. Este parámetro va configurado antes del bindaddr.
bindaddr=0.0.0.0 ; IP que Asterisk usará para “escuchar” los pedidos de conexiones. 0.0.0.0 para todos los IP del computador.
delayreject=yes ; Mejora la seguridad contra “brute force password attacks” retrasando el envío de los rechazos de autenticación.
srvlookup=yes ; Permite hacer búsquedas de registros DNS SRV basadas en los nombres de dominio para llamadas IAX salientes del tipo IAX2/usuario@dominio.
accountcode=lss0101 ; Genera una cuenta general con la cual grabar las llamadas.
34 IAX (Inter-Asterisk eXchange protocol) es uno de los protocolos utilizado por Asterisk, un servidor PBX (central telefónica) de código abierto patrocinado por Digium. Es utilizado para manejar conexiones VoIP entre servidores Asterisk, y entre servidores y clientes que también utilizan protocolo IAX. Wikipedia
53
language=en ; Lenguaje predefinido para las locuciones (ingles).
disallow=all ; Desactivamos todos los codecs (audio y video).
allow=alaw allow=gsm
; minregexpire = 60; maxregexpire = 60;tiempo mínimo y máximo de expiración de la registración de las peers
A partir de esta parte del archivo se definen los proveedores IAX2 u otros PBX Asterisk con los que nos queremos registrar.
;register => marko:[email protected] ; Registro con nombre usuario, contraseña y dominio.
;register => joe@remotehost:5656 ; Registo con nombre, dominio y puerto remoto (sin contraseña).
;register => marko:[torkey]@tormenta.linux-support.net ; Registro con nombre, clave RSA35 (torkey) y dominio.
Ahora inicia la configuración de las extensiones IAX2
[guest] ; Dejamos esta parte si queremos configurar un usuario huésped (sin contraseña).
type=user ; Puede solo recibir llamadas.
context=default ; El contexto que usará en extensions.conf.
callerid=”Guest IAX User” ; el identificador del usuario huésped.
Se configura una extensión de prueba para luego usarla para una conexión desde desde un cliente IAX2.
[marko]; Nombre de la extensión.
35 El sistema criptográfico con clave pública RSA es un algoritmo asimétrico cifrador de bloques, que utiliza una clave pública, la cual se distribuye (en forma autenticada preferentemente), y otra privada, la cual es guardada en secreto por su propietario.
54
type=friend ; Tipo friend es peer y user a la vez.
host=dynamic ; Si el cliente no se conecta siempre desde un IP determinado hay que indicar dynamic.
secret=password ; Contraseña.
context=phones ; Contexto asociado a este usuario en extensions.conf.
mailbox=1234@default; Buzón de los correo de voz del usuario.
qualify=yes; Para averiguar periódicamente con un NOTIFY si el usuario está conectado al servidor Asterisk.
callerid = “marko” ; Identificador de llamada del usuario.
requirecalltoken=auto; En septiembre del 2009 hubo una actualización del protocolo IAX2 para mejorar la seguridad. Muchos Softphone y teléfonos IAX2 todavía no soportan los cambios. En este caso para tener la certeza de que sea posible conectarlos a Asterisk hay que configurar este parámetro en NO o AUTO.
Se guardan los cambios y se actualiza la configuración de Asterisk:
asterisk -rvvvvvvvvvvvvvvv
CLI> iax2 reload
Para conectar a la extensión recién creada en el archivo iax.conf se utilizará el softphone Zoiper36. Una vez instalado se abre y se entra en la ventana de opciones. Se elige “Cuenta nueva de iax” y se pone el nombre de la cuenta.
36 www.zoiper.com
55
En la siguiente pantalla se insertan los datos de la cuenta como definidos en iax.conf.
En la barra de la cuenta aparecerá: marko (Registrado) (IAX)
Ahora se puede hacer llamadas a extensiones internas y números externos. Aunque todavía no haya muchos proveedores VoIP que brindan conexiones IAX2, es un protocolo destinado a crecer en los próximos años siempre y cuando resuelvan alguno bugs que parece padecer.
2.8 Features.conf
El archivo features.conf es donde se configura el parqueo de las llamadas y se asigna una función a una determinada combinación de teclas. Es aquí, por ejemplo, donde se definen cuales son las teclas que tenemos que presionar para transferir una llamada, grabarla, lanzar una aplicación
56
nano /etc/asterisk/features.conf
; ; Features.conf ;[general]
parkext => 700; La extensión donde transferir las llamadas para parquearlas.
parkpos => 701-710; El numero de extensiones reservadas para parquear las llamadas.
parkinghints = no; si está en yes podemos controlar el estado de las extensiones donde se parquean las llamadas sino tenemos que añadir las extensiones reservadas para el parqueo de las llamadas en el dialplan, contexto subscribe
parkingtime => 45; Numero de segundos después de los cuales la llamada parqueada viene transferida a la extensión definida por el próximo parámetro
comebacktoorigin = yes; si está en yes la llamada parqueada, después del parkingtime, vuelve a la extensión que la parqueó; si está en no la llamada será transferida al contexto parkedcallstimeout, extensión ‘s’,prioridad ‘1’ que habrá que crear en extensions.conf
courtesytone = beep; El sonido que será enviado a la llamada parqueada cuando alguien la llama o cuando empieza y termina la grabación de la misma
parkedplay = both; Define a quien enviar el beep cuando se llama la extensión parqueada. Puede ser:
• parked(canal parqueado)• caller(llamante) • both(ambos)
parkedcalltransfers = caller; Habilita o deshabilita la secuencia de tonos para transferir la llamada cuando es una llamada parqueada. Puede ser:
• callee(llamado)• caller (llamante)• both (ambos)• no
57
parkedcallreparking = caller; Habilita o deshabilita la secuencia de tonos para parquear una llamada cuando era ya una llamada parqueada. Puede ser:
• callee(llamado)• caller (llamante)• both(ambos)• no.
;parkedcallhangup = caller; Habilita o deshabilita la secuencia de tonos para terminar una llamada cuando es una llamada parqueada. Puede ser:
• callee(llamado)• caller (llamante)• both(ambos)• no.
;parkedcallrecording = caller; Habilita o deshabilita la secuencia de tonos para grabar una llamada cuando es una llamada parqueada. Puede ser:
• callee(llamado)• caller (llamante)• both(ambos)• no.
parkedmusicclass=default; La clase de música en espera que escuchará la extensión que ha sido parqueada
transferdigittimeout => 5; Numero de segundos de espera entre cada dígito cuando se esta transfiriendo una llamada
xfersound = beep; El sonido que indicará que la transferencia de la llamada “asistida” se completó
xferfailsound = beeperr; El sonido que indicará que la transferencia de la llamada no se pudo completar
pickupexten = *8; En la configuración de las extensiones SIP se pueden configurar dos parámetros: callgroup y pickupgroup. Cuando dos o más extensiones pertenecen al mismo callgroup y una de ellas timbra, se puede contestar la llamada desde una de las extensiones que en pickupgroup tienen configurado el callgroup de la extension.
featuredigittimeout = 2000; numero de milisegundos entre cada dígito cuando se activan le funcionalidades definidas más adelante
58
atxfernoanswertimeout = 15 ; Tiempo máximo disponible para contestar una llamada transferida con el método “asistido” (en segundos)
atxferdropcall = no; Si quien transfiere una llamada con el método “asistido” cuelga antes que la llamada sea transferida completamente, Asterisk devuelve la llamada a quien la estaba transfiriendo. Si está en yes la llamada no se devuelve y se considera terminada.
atxferloopdelay = 10; Numero de segundos de espera antes de devolver la llamada (si atxferdropcall = no)
atxfercallbackretries = 2; Las veces que se intentará devolver la llamada
La mapa de las funcionalidades que aparecen aquí abajo solo funcionan si Asterisk hace de puente entre las llamadas. Si por ejemplo en la configuración de las extensiones en sip.conf se configura canreinvite=yes es probable que estas funcionalidades no resulten
[featuremap]
blindxfer => #; la tecla que hay que presionar para empezar la transferencia de una llamada
disconnect => *0; la secuencia de teclas que hay que presionar para terminar la llamada
automon => *1; La secuencia de teclas que hay que presionar para grabar la llamada (en dos archivos audio, uno para cada canal)
atxfer => *2; La secuencia de teclas que hay que presionar para una transferencia de llamada “asistida”. ¿Que diferencia hay entre blindxfer y atxfer? Al terminar este bloque la explicación.
parkcall => *7; La secuencia de teclas que hay que presionar para parquear la llamada. Podemos usar esta secuencia o transferir directamente la llamada a la extensión 700
automixmon => *3; La secuencia de teclas que hay que presionar para grabar la llamada en un único archivo audio mezclando las voces de los dos interlocutores
• blinxferA lo largo de una conversación se quiere transferir la llamada a otra extensión. Hay que presionar la tecla # y luego el numero de la extensión. La llamada será transferida y nuestra llamada terminará
59
• atxferA lo largo de una conversación queremos transferir la llamada a otra extensión. Presionamos la secuencia *2 y luego el numero de la extensión donde se quiere transferir la llamada. Se escuchará timbrar la extension y una vez que el interlocutor descuelgue se podrá hablar con él (por ejemplo para anunciar la llamada que se va a transferir). Solamente cuando colgaremos las dos extensiones serán conectadas entre ellas.
[applicationmap] ; en esta parte del archivo se pueden añadir funcionalidades personalizadas que luego serán disponibles en el plan de llamadas. La sintaxis para estas funcionalidades es:
<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>[,<AppArguments>[,MOH_Class]]
• FeatureName: El nombre de la funcionalidad;• DTMF_sequence: la secuencia de teclas para activar la funcionalidad;• ActivateOn: aquí se define para quien activar la funcionalidad. Los valores son self y peer. Con
self la funcionalidad se activa para quien la activa, con peer para el otro canal• ActivatedBy: Este parámetro define quien tiene acceso a la funcionalidad. Las opciones son:
caller (llamante), callee (llamado), both (ambos)• Application: La aplicación que se va a ejecutar• AppArguments: Las opciones asociadas a la aplicación• MOH_Class: la clase de música en espera que escuchará el canal libre mientras se ejecuta la
funcionalidad
Ejemplo:test1 => *9,peer,Playback,tt-monkeys,default; Presionando la secuencia *9 desde un canal, el otro escuchará la locución tt-monkeys mientras el canal que activó la funcionalidad, escuchará música en espera.
Se guardan los cambios. Para volver disponibles estas funciones hay que modificar el plan de llamadas. Se va a recoger la configuración del archivo así como se dejó en el párrafo 2.5 En negrita aparecen las partes que hay que añadir.
nano /etc/asterisk/extensions.conf
[general] static=yeswriteprotect=noautofallthrough=yespriorityjumping=yes
[globals] SUP = SIP/1000 FUL = SIP/0057310000000 JUST = SIP/justvoip DYNAMIC_FEATURES=test1#blindxfer#automon#disconnect#atxfer#parkcall#automixmon
60
[internas]exten => 97,1,Answer()exten => 97,n,VoiceMailMain(${CALLERID(num)}@default)exten => 97,n,Hangup()
exten => 123,1,Answer()exten => 123,2,Playback(hello-world)exten => 123,3,Hangup()
exten => 100,1,Answerexten => 100,n,MusicOnHold(mp3,300)exten => 100,n,Hangup
exten => 150,1,Answerexten => 150,n,Playback(echo-test)exten => 150,n,Echo(15)exten => 150,n,Hangup
exten => _100X,1,Macro(disponible)exten => _100X,n,Dial(SIP/${EXTEN},45)exten => _100X,n,GotoIf($[${DIALSTATUS} = BUSY]?busy:unavail)exten => _100X,n(unavail),Voicemail(${EXTEN}@default,u)exten => _100X,n,Hangupexten => _100X,n(busy),VoiceMail(${EXTEN}@default,b)exten => _100X,n,Hangup
[externas]exten => _3XXXXXXXXX,1,Dial(Mobile/NokiaE71/${EXTEN},45)exten => _3XXXXXXXXX,n,Hangup
exten => _00573.,1,Dial(${JUST}/${EXTEN})exten => _00573.,n,Playback(all-outgoing-lines-unavailable)exten => _00573.,n,Hangup()
[subscribe]exten => 1000,hint,SIP/1000exten => 1001,hint,SIP/1001exten => 701,hint,park:701@parkedcallsexten => 702,hint,park:702@parkedcallsexten => 703,hint,park:703@parkedcallsexten => 704,hint,park:704@parkedcallsexten => 705,hint,park:705@parkedcallsexten => 706,hint,park:706@parkedcallsexten => 707,hint,park:707@parkedcallsexten => 708,hint,park:708@parkedcallsexten => 709,hint,park:709@parkedcalls
61
exten => 710,hint,park:710@parkedcalls
[solo-internas]include => internasinclude => subscribeinclude => parkedcalls
[phones]include => internasinclude => externasinclude => subscribeinclude => parkedcalls
[macro-disponible]exten => s,1,ChanIsAvail(SIP/${MACRO_EXTEN})exten => s,n,Gotoif($[${AVAILSTATUS} = 4]?4:3)exten => s,n,MacroExitexten => s,n,Playback(all-circuits-busy-now)exten => s,n,Hangup
Para que las funcionalidades configuradas en features.conf sean activas hay que definir la variable DYNAMIC_FEAUTURES y añadirle todas las funcionalidades que se han configurado. Después de la etiqueta [subscribe] se han añadido diez líneas para poder controlar el estado de las extensiones usadas para parquear las llamadas. De esta forma siempre se podrá saber cuantas llamadas están parqueadas (en los teléfonos IP software y hardware que prevén esta posibilidad).Para terminar en las etiquetas [phones] y [solo-internas] se ha añadido el contexto parkedcalls. Todos la extensiones que tengan acceso al contexto phones, además de tener acceso al contexto internas, externas y subscribe, tendrán acceso al contexto parkedcalls es decir podrán llamar una extension parqueada.
Hay tres aplicaciones relacionadas con el parqueo de llamadas que se pueden utilizar en el plan de llamadas:
• Park• ParkAndAnnounce • ParkedCall
Se guardan los cambios y se reinicia Asterisk:
/etc/init.d/asterisk restart
Desde la consola de Asterisk podemos ver las funcionalidades activadas.
asterisk -rvvvvvvvvvvvv
CLI> features show
62
Builtin Feature Default Current--------------- ------- -------Pickup *8 *8Blind Transfer # #Attended Transfer *2One Touch Monitor *1Disconnect Call * *0Park Call *7One Touch MixMonitor *3Dynamic Feature Default Current--------------- ------- -------test1 no def *9Call parking------------Parking extension: 700Parking context: parkedcallsParked call extensions: 701-710
2.8.1 Integración de features.conf con la aplicación DIAL
Ya se ha presentado (Párrafo 2.8) la configuración del archivo features conf y como se definen el parqueo de las llamadas y otras aplicaciones. En este párrafo se verá como integrar esas funcionalidades en el dialplan de Asterisk usando la aplicación Dial.
La sintaxis de la aplicación Dial:
Dial(Technology/resource[&Tech2/resource2...][,timeout][,options][,URL]):
• Dial: el nombre de la aplicación que nos permite en el dialplan hacer una llamada• Technology: el protocolo o la tecnología usada para hacer la llamada (ej: SIP, IAX2)• resource: el recurso usado para hacer la llamada o el numero de extensión a llamar• timeout: define los segundos dentro de los cuales la llamada tiene que ser contestada.• options: son las opciones que podemos añadir a la aplicación• URL: para enviar una dirección Web a la extensión llamada (si dicha extensión tiene la
capacidad para recibirla)
Algunos ejemplos:exten => 1000,1,Dial(SIP/1000,45)exten => 1000,2,Hangup
Si se marca la extensión 1000 Asterisk llamará dicha extensión usando el protocolo SIP, esperará 30 segundos. Si la extensión 1000 no contesta dentro de los treinta segundos, Asterisk procesará la línea siguiente del dialplan, es decir terminará la llamada.
63
exten => 00573001000000,1,Dial(SIP/justvoip/00573001000000,45)exten => 00573001000000,2,Hangup
En este caso si desde un SoftPhone o IP Phone conectados a la centralita se marca el numero 0057300100000, Asterisk llamará dicho numero usando un proveedor VoIP (en este caso especifico Justvoip). Esperará una respuesta por 45 segundos y si nadie contesta terminará la llamada. Como tecnología se ha indicado SIP porque justvoip usa solo este tipo de protocolo. En el caso de proveedores que utilicen el protocolo IAX2 sería:
exten => 00573001000000,1,Dial(IAX2/justvoip/00573001000000,45)exten => 00573001000000,2,Hangup
Para configurar las funcionalidades definidas en el archivo features.conf se tendrá que utilizar unas opciones de la aplicación Dial.
exten => 1000,1,Dial(SIP/2000,30,hH)
Las opciones presentes en la linea aquí presentada son dos:
• h: permite al llamado colgar la llamada usando la tecla *0• H: permite al llamante colgar la llamada usando la tecla *0
exten => 1000,1,Dial(SIP/2000,30,kK)
• k: permite al llamado parquear la llamada presionando la secuencia de teclas definida en features.conf
• K: permite al llamante parquear la llamada presionando la secuencia de teclas definida en features.conf
exten => 1000,1,Dial(SIP/2000,30,tT)
• t: permite al llamado transferir la llamada presionando la secuencia de teclas definida en features.conf
• T: permite al llamante transferir la llamada presionando la secuencia de teclas definida en features.conf
exten => 1000,1,Dial(SIP/2000,30,wW)
• w: permite al llamado empezar la grabación de la llamada presionando la secuencia de teclas definida en features.conf. Asterisk, en este caso, creará dos archivos audio, uno por cada interlocutor.
• W: permite al llamante empezar la grabación de la llamada presionando la secuencia de teclas definida en features.conf. Asterisk, en este caso, creará dos archivos audio, uno por cada interlocutor.
exten => 1000,1,Dial(SIP/2000,30,xX)
64
• x: permite al llamado empezar la grabación de la llamada presionando la secuencia de teclas definida en features.conf. La diferencia con las opciones w y W es que en este caso los dos canales (llamante y llamado) se grabaran en un único archivo audio
• X: lo mismo de arriba pero para el llamante.
Si se quiere, por ejemplo, activar todas estas opciones a la vez, la aplicación Dial aparecerá de esta forma:
exten => _100X,1,Dial(SIP/ ${EXTEN},45,hHkKtTwWxX)
A seguir se presentarán algunos registros como aparecen en la consola de Asterisk al activar o desactivar las funcionalidades descritas.
asterisk -rvvvvvvvvvvvvvvv
CLI>• SIP1000-0091d880 answered SIP1001-009292e0 -- Stopped music on hold on SIP/1001-009292e0 == Extension Changed 2100[internal] new state InUse for Notify User 1000 [Nov 6 10:44:28] DTMF[30238]: channel.c:2628 __ast_read: DTMF begin ‘#’ received on SIP/2100-0091d880 [Nov 6 10:44:28] DTMF[30238]: channel.c:2638 __ast_read: DTMF begin passthrough ‘#’ on SIP/2100-0091d880 [Nov 6 10:44:28] DTMF[30238]: channel.c:2546 __ast_read: DTMF end ‘#’ received on SIP/2100-0091d880, duration 100 ms [Nov 6 10:44:28] DTMF[30238]: channel.c:2596 __ast_read: DTMF end accepted with begin ‘#’ on SIP/2100-0091d880 [Nov 6 10:44:28] DTMF[30238]: channel.c:2612 __ast_read: DTMF end passthrough ‘#’ on SIP/2100-0091d880 -- Started music on hold, class ‘default’, on SIP/2300-009292e0 -- <SIP/1000-0091d880> Playing ‘pbx-transfer.gsm’ (language ‘it’) [Nov 6 10:44:30] DTMF[30238]: channel.c:2628 __ast_read: DTMF begin ‘7’ received on SIP/1000-0091d880 [Nov 6 10:44:30] DTMF[30238]: channel.c:2632 __ast_read: DTMF begin ignored ‘7’ on SIP/1000-0091d880 [Nov 6 10:44:30] DTMF[30238]: channel.c:2546 __ast_read: DTMF end ‘7’ received on SIP/1000-0091d880, duration 100 ms [Nov 6 10:44:30] DTMF[30238]: channel.c:2612 __ast_read: DTMF end passthrough ‘7’ on SIP/1000-0091d880 [Nov 6 10:44:31] DTMF[30238]: channel.c:2628 __ast_read: DTMF begin ‘0’ received on SIP/1000-0091d880 [Nov 6 10:44:31] DTMF[30238]: channel.c:2632 __ast_read: DTMF begin ignored ‘0’ on SIP/1000-0091d880 [Nov 6 10:44:31] DTMF[30238]: channel.c:2546 __ast_read: DTMF end ‘0’ received on SIP/1000-0091d880, duration 120 ms
65
[Nov 6 10:44:31] DTMF[30238]: channel.c:2612 __ast_read: DTMF end passthrough ‘0’ on SIP/1000-0091d880 [Nov 6 10:44:32] DTMF[30238]: channel.c:2628 __ast_read: DTMF begin ‘0’ received on SIP/1000-0091d880 [Nov 6 10:44:32] DTMF[30238]: channel.c:2632 __ast_read: DTMF begin ignored ‘0’ on SIP/1000-0091d880 [Nov 6 10:44:32] DTMF[30238]: channel.c:2546 __ast_read: DTMF end ‘0’ received on SIP/1000-0091d880, duration 120 ms [Nov 6 10:44:32] DTMF[30238]: channel.c:2612 __ast_read: DTMF end passthrough ‘0’ on SIP/1000-0091d880 -- Stopped music on hold on SIP/1001-009292e0 -- Started music on hold, class ‘default’, on SIP/1000-009292e0 == Parked SIP/1001-009292e0 on 701@parkedcalls. Will timeout back to extension [phones] 1000, 1 in 45 seconds -- <SIP/1000-0091d880> Playing ‘digits/7.gsm’ (language ‘it’) -- <SIP/1000-0091d880> Playing ‘digits/0.gsm’ (language ‘it’) -- <SIP/1000-0091d880> Playing ‘digits/1.gsm’ (language ‘it’) -- Added extension ‘701’ priority 1 to parkedcalls (0x8230a0) == Extension Changed 701[internal] new state InUse for Notify User 1001 == Extension Changed 701[internal] new state InUse for Notify User 1000
En este ejemplo la llamada de la extensión 1000 a la extensión 1001 viene contestada. Desde la extensión 1000 se presiona la tecla numeral # y luego se parquea la llamada presionando la secuencia 700 (como configurado en el archivo features.conf. La locución de Asterisk nos dirá en que posición ha sido parqueada la llamada (en este caso la extensión 701). La llamada quedará en espera para 45 segundos y luego Asterisk devolverá la llamada a la extensión 1000. Como se puede ver en las dos ultimas líneas, Asterisk notificará también a las extensiones 1000 y 1001 que la extensión 701 está en uso. Esto porque en los softphone de estas dos extensiones se han añadido, en la lista de contactos, dicha extensión.
• SIP/1000-008e3990 answered SIP/1001-009292e0 -- Stopped music on hold on SIP/1001-009292e0 == Extension Changed 1000[internal] new state InUse for Notify User 1000 [Nov 6 10:55:22] DTMF[30249]: channel.c:2628 __ast_read: DTMF begin ‘*’ received on SIP/1001-009292e0 [Nov 6 10:55:22] DTMF[30249]: channel.c:2638 __ast_read: DTMF begin passthrough ‘*’ on SIP/1001-009292e0 [Nov 6 10:55:22] DTMF[30249]: channel.c:2546 __ast_read: DTMF end ‘*’ received on SIP/1001-009292e0, duration 100 ms [Nov 6 10:55:22] DTMF[30249]: channel.c:2596 __ast_read: DTMF end accepted with begin ‘*’ on SIP/2300-009292e0 [Nov 6 10:55:22] DTMF[30249]: channel.c:2612 __ast_read: DTMF end passthrough ‘*’ on SIP/1001-009292e0 [Nov 6 10:55:22] DTMF[30249]: channel.c:2628 __ast_read: DTMF begin ‘2’ received on SIP/1001-009292e0 [Nov 6 10:55:22] DTMF[30249]: channel.c:2638 __ast_read: DTMF begin passthrough ‘2’ on SIP/1001-009292e0
66
[Nov 6 10:55:23] DTMF[30249]: channel.c:2546 __ast_read: DTMF end ‘2’ received on SIP/1001-009292e0, duration 100 ms [Nov 6 10:55:23] DTMF[30249]: channel.c:2596 __ast_read: DTMF end accepted with begin ‘2’ on SIP/1001-009292e0 [Nov 6 10:55:23] DTMF[30249]: channel.c:2612 __ast_read: DTMF end passthrough ‘2’ on SIP/1001-009292e0 -- <SIP/1001-009292e0> Playing ‘beep.ulaw’ (language ‘it’) -- User hit ‘*3’ to record call. filename: auto-1225986923-2300-2100 == Begin MixMonitor Recording SIP/1000-008e3990 [Nov 6 10:55:26] DTMF[30249]: channel.c:2628 __ast_read: DTMF begin ‘*’ received on SIP/1001-009292e0 [Nov 6 10:55:26] DTMF[30249]: channel.c:2638 __ast_read: DTMF begin passthrough ‘*’ on SIP/1001-009292e0 [Nov 6 10:55:26] DTMF[30249]: channel.c:2546 __ast_read: DTMF end ‘*’ received on SIP/1001-009292e0, duration 100 ms [Nov 6 10:55:26] DTMF[30249]: channel.c:2596 __ast_read: DTMF end accepted with begin ‘*’ on SIP/1001-009292e0 [Nov 6 10:55:26] DTMF[30249]: channel.c:2612 __ast_read: DTMF end passthrough ‘*’ on SIP/1001-009292e0 [Nov 6 10:55:27] DTMF[30249]: channel.c:2628 __ast_read: DTMF begin ‘2’ received on SIP/1001-009292e0 [Nov 6 10:55:27] DTMF[30249]: channel.c:2638 __ast_read: DTMF begin passthrough ‘2’ on SIP/1001-009292e0 [Nov 6 10:55:27] DTMF[30249]: channel.c:2546 __ast_read: DTMF end ‘2’ received on SIP/1001-009292e0, duration 120 ms [Nov 6 10:55:27] DTMF[30249]: channel.c:2596 __ast_read: DTMF end accepted with begin ‘2’ on SIP/1001-009292e0 [Nov 6 10:55:27] DTMF[30249]: channel.c:2612 __ast_read: DTMF end passthrough ‘2’ on SIP/1001-009292e0 -- <SIP/1001-009292e0> Playing ‘beep.ulaw’ (language ‘it’) -- User hit ‘*3’ to stop recording call. == End MixMonitor Recording SIP/1000-008e3990
En este ejemplo la extensión 1001 llama la extensión 1000. La llamada viene contestada. Presionando la secuencia *3 desde la extensión 1001 se empezá a grabar la llamada en la modalidad MixMonitor, es decir en un único archivo audio. Presionando *3 otra vez la grabación terminará.
Para terminar se modificará el plan de llamadas para incluir estas funciones en las llamadas entre extensiones. (en negrita los cambios):
exten => _100X,1,Macro(disponible)exten => _100X,n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)exten => _100X,n,GotoIf($[${DIALSTATUS} = BUSY]?busy:unavail)exten => _100X,n(unavail),Voicemail(${EXTEN}@default,u)exten => _100X,n,Hangupexten => _100X,n(busy),VoiceMail(${EXTEN}@default,b)exten => _100X,n,Hangup
67
2.9 Logger.conf
En el archivo logger.conf es donde se configuran todos los registros de las actividades de Asterisk.
Se abre el archivo:
nano /etc/asterisk/logger.conf
[general]
dateformat=%F %T; formato ISO 8601 para las fechas
appendhostname = yes ; si se quiere que el nombre de cada archivo de registro termine con el nombre del dominio hay que activar este parametro
queue_log = yes ; con queue_log se indica si se quiere tener un registro de las colas de espera (predefinido es yes)
queue_log_name = queue_log; El nombre del archivo donde se guardará los registros de las colas en espera (predefinido queue_log) ; Los archivos de registros se pueden volver de un tamaño bastante grande volviendo un poco incómoda su consulta. Para evitar esto se puede usar el programa logrotate. En esta parte del archivo se indica como se quiere “rotar” los archivos
rotatestrategy = rotate; de este modo el archivo más viejo tendrá el numero secuencial más alto.
event_log = yes; De manera predefinida asterisk registra en un archivo los eventos genéricos
;aquí abajo empieza la parte dedicada a la definición de lo que se quiere registrar en cada archivo (incluida la consola)
[logfiles] ; ; Se puede registrar en cada archivo y consola los siguientes eventos: ; debug ; notice ; warning ; error; verbose ; dtmf ;
68
; Esta es una buena configuración:debug> debugconsole => notice,warning,error,dtmf,debugmessages => notice,warningfull => error
; en la consola aparecerán las noticias, los avisos, los errores, el debug y los tonos dtmf presionados.; en el archivo messages las noticias, los avisos y el debug; en el archivo full solamente los errores
Se guardan los cambios y se pasa a la definición de las política de rotación de los archivos de registro. Para definir esta políticas hay que instalar el programa Logrotate que se encarga de este tipo de tarea.
yum install logrotate
Una vez instalado se crea un nuevo archivo donde se van a definir la rotación de los archivos
nano /etc/logrotate.d/asterisk
Se pegan las siguientes líneas:
/var/log/asterisk/messages /var/log/asterisk/full { missingok rotate 7 daily postrotate /usr/sbin/asterisk -rx 'logger reload' > /dev/null 2> /dev/null endscript } /var/log/asterisk/queue_log { missingok rotate 5 size=100k postrotate /usr/sbin/asterisk -rx 'logger reload'> /dev/null 2> /dev/null endscript }
El primer bloque define la rotación para el archivo messages y el archivo full. La rotación será diaria y se crearán un máximo de 7 archivos secuenciales (messages.1 messages.2 , etc.). El más antiguo tendrá el numero secuencial más alto. Después de la rotación (postrotate) se actualiza la configuración del archivo logger.conf en asterisk.
El segundo bloque define la política de rotación del archivo de registro queue_log. En este caso el archivo rotará cuando alcanzará un tamaño de 100 Kbyte y se creerán un máximo de 5 archivos secuenciales.
69
Para testar el archivo de configuración creado el procedimiento es:
cd /etc/logrotate.d
logrotate -fv asterisk
La respuesta será:
reading config file asteriskreading config info for /var/log/asterisk/messages/var/log/asterisk/fullreading config info for /var/log/asterisk/queue_logHandling 2 logsrotating pattern: /var/log/asterisk/messages/var/log/asterisk/full forced from command line (7 rotations)empty log files are rotated, old logs are removedconsidering log /var/log/asterisk/messages log /var/log/asterisk/messages does not exist—skippingconsidering log /var/log/asterisk/full log /var/log/asterisk/full does not exist—skippingnot running postrotate script, since no logs were rotatednot running postrotate script, since no logs were rotatedrotating pattern: /var/log/asterisk/queue_log forced from command line (5 rotations)empty log files are rotated, old logs are removedconsidering log /var/log/asterisk/queue_log log needs rotatingrotating log /var/log/asterisk/queue_log, log->rotateCount is 5renaming /var/log/asterisk/queue_log.5 to /var/log/asterisk/queue_log.6 (rotatecount 5, logstart 1, i 5),old log /var/log/asterisk/queue_log.5 does not existrenaming /var/log/asterisk/queue_log.4 to /var/log/asterisk/queue_log.5 (rotatecount 5, logstart 1, i 4),old log /var/log/asterisk/queue_log.4 does not existrenaming /var/log/asterisk/queue_log.3 to /var/log/asterisk/queue_log.4 (rotatecount 5, logstart 1, i 3),old log /var/log/asterisk/queue_log.3 does not existrenaming /var/log/asterisk/queue_log.2 to /var/log/asterisk/queue_log.3 (rotatecount 5, logstart 1, i 2),old log /var/log/asterisk/queue_log.2 does not existrenaming /var/log/asterisk/queue_log.1 to /var/log/asterisk/queue_log.2 (rotatecount 5, logstart 1, i 1),renaming /var/log/asterisk/queue_log.0 to /var/log/asterisk/queue_log.1 (rotatecount 5, logstart 1, i 0),old log /var/log/asterisk/queue_log.0 does not existlog /var/log/asterisk/queue_log.6 doesn’t exist—won’t try to dispose of itrenaming /var/log/asterisk/queue_log to /var/log/asterisk/queue_log.1running postrotate script
Para aplicar los cambios desde la consola de Asterisk:
asterisk -rvvvvvvvvvvvvvv
70
se escribe:
CLI> logger reload
2.10 Followme.conf (sígueme)
El archivo followme permite hacer una cosa muy sencilla: definir una serie de números (extensiones internas, fijos o celulares) donde desviar la llamada si en la extensión predefinida nadie contesta o si ha sido activada esta opción. Si el desvío es hacia otras extensiones internas no tendrá ningún costo, si se hace hacia números fijos y/o celulares para hacer la llamada habrá que utilizar proveedores VoIP y pagar la relativa tarifa.
Como se ha visto para el desvío de llamada sencillo (párrafo 2.8), se podrá activar y desactivar la aplicación según como se necesite.
Se modifica el archivo de configuración:
nano /etc/asterisk/followme.conf
El archivo empieza con una parte general que es igual para todas las extensiones configuradas. Luego, se personaliza la configuración para cada extensión.
[general]
featuredigittimeout=>5000 ; numero de milisegundos disponibles para el llamado para aceptar o rechazar la llamada
takecall=>1 ; para aceptar la llamada, el llamado, después de descolgar, tendrá que hundir la tecla 1 del teléfono
declinecall=>2 ; para rechazarla la tecla 2
call-from-prompt=>followme/call-from ; este es la locución predefinida que escuchará el llamado anunciándole quien lo está llamando
norecording-prompt=>followme/no-recording ; la locución predefinida si el llamante no ha registrado el propio nombre o si la opción para registrarlo no ha sido acticvada
options-prompt=>followme/options; esta locución anunciará al llamado que tendrá que digitar 1 para aceptar la llamada y dos para rechazarla
pls-hold-prompt=>followme/pls-hold-while-try ; El llamante escuchará esta locución que le dirá que espere en línea mientras se intentará localizar el
71
llamado
status-prompt=>followme/status ; Esta locución anunciará al llamante que la persona llamada no se encuentra al momento en su oficina/casa/etc.
sorry-prompt=>followme/sorry ; si al final de todos los desvíos nadie contestará la llamada, esta locución anunciará al llamante que no se ha podido localizar la persona buscada
Ahora empieza la configuración especifica de cada extensión que se quiere incluir en este archivo. En este ejemplo se definirá los números que se llamarán si la extensión 1000 no contesta
[1000] ; numero de la extensión a configurar
musicclass=>default ; tipo de música en espera que escuchará el llamante mientras se intentará localizar el destinatario de la llamada
context=>phones ; el contexto que usará la aplicación followme para localizar el llamado. Si se han incluido números fijos y celulares este contexto debe tener acceso a las llamadas externas.
number=>1001,15 ; Aquí empieza la lista de números que se intentará llamar para localizar el destinatario de la llamada. En este ejemplo si el destinatario no contesta a la extensión 1000 se llamará como segunda opción la extensión 1001 por 15 segundos.
number=> 0057510000000,15; si a la extensión 1001 nadie contesta se intentará llamar el numero fijo que aparece en esta línea por otros 15 segundos
number=> 0057310000000,15; si al numero fijo tampoco contestan se intentará llamar al celular takecall=>1 ; ahora siguen los mismo parámetros que se han configurado en la parte general. Se pueden personalizar para cada extensión
declinecall=>2 call-from-prompt=>followme/call-from followme-norecording-prompt=>followme/no-recording followme-options-prompt=>followme/options followme-pls-hold-prompt=>followme/pls-hold-while-try followme-status-prompt=>followme/status followme-sorry-prompt=>followme/sorry
72
Una vez terminada la configuración para la extensión 1000 se puede seguir con la 1001 y así siguiendo.
[1001]…….Se guardan los cambios y se recarga la configuración de Asterisk:
/etc/init.d/asterisk reload
Para más información se puede mirar la sintaxis de la aplicación followme. Desde la consola:
asterisk -rvvvvvvvvvvvvvvvvvvvvv
Se escribe el comando:
CLI> core show application followme
-= Info about application ‘FollowMe’ =- [Synopsis] Find-Me/Follow-Me application [Description] FollowMe(followmeid[,options]): This application performs Find-Me/Follow-Me functionality for the caller as defined in the profile matching the <followmeid> parameter in followme.conf. If the specified <followmeid> profile doesn’t exist in followme.conf, execution will be returned to the dialplan and call execution will continue at the next priority. Options: s - Playback the incoming status message prior to starting the follow-me step(s) a - Record the caller’s name so it can be announced to the callee on each step n - Playback the unreachable status message if we’ve run out of steps to reach the or the callee has elected not to be reachable. Returns -1 on hangup
El uso de la aplicación es muy sencillo. En el plan de llamadas bajo el contexto internas se añaden la linea en negrita:
CLI> quit
nano /etc/asterisk/extensions.conf
exten => _100X,1,Macro(disponible)exten => _100X,n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)exten => _100X,n,Followme(${EXTEN},san)exten => _100X,n,GotoIf($[${DIALSTATUS} = BUSY]?busy:unavail)exten => _100X,n(unavail),Voicemail(${EXTEN}@default,u)
73
exten => _100X,n,Hangupexten => _100X,n(busy),VoiceMail(${EXTEN}@default,b)exten => _100X,n,Hangup
Si alguien, por ejemplo, llama la extensión 1000 y nadie contesta dentro de 45 segundos se activará la aplicación Followme que empezará a llamar todos los números configurados para la extensión 1000 para localizar el destinatario de la llamada.
Las tres opciones configuradas significan:
• s – se anunciará al llamante el estado de la extensión 1000 antes de empezar los distintos pasos configurados en el archivo followme.conf
• a – el llamante podrá grabar su propio nombre para que sea anunciado al llamado cuando conteste y de esta forma tenga la posibilidad de decidir si quiere o no aceptar la llamada
• n – Una vez que se hayan llamados todos los números y no se logre localizar la persona buscada, el llamante escuchará una locución que le dirá que no ha sido posible localizar el destinatario de la llamada.
¿Como podemos hacer para que el Followme se active solamente cuando el “dueño” de la extensión 1000 quiere activarla?
Con unas lineas que permitan al usuario decidir cuando activar el followme. En el dialplan, contexto internas, añadimos:
Con unas lineas que permitan al usuario decidir cuando activar el followme. En el dialplan, contexto internas, añadimos:
exten => 101,1,Answer exten => 101,n,Set(DB(${CALLERID(num)}/FOLLOWME)=1) exten => 101,n,Hangup
Con estas tres líneas, usando la base de datos internas de Asterisk, asociamos a la variable ${CALLERID(num)}/FOLLOWME) el valor uno. En el caso de la extensión 1000 seria:
1000/FOLLOWME=1
Luego cada vez que llamamos la extensión 1000 se controlará si esta variable tiene asociado el valor uno (es decir el followme activado)
[macro-followme]exten => s,1,Set(FM=${DB(${MACRO_EXTEN}/FOLLOWME)}) exten => s,n,NoOp(${FM}) exten => s,n,GotoIf($["${FM}" = "1"]?followme:exit) exten => s,n(followme),Followme(${MACRO_EXTEN},san)exten => s,n(exit),Macroexit
Se añade la linea en negrita al siguiente bloque y se quita la linea exten => _100X,n,Followme($
74
{EXTEN},san) :
exten => _100X,1,Macro(followme)exten => _100X,n,Macro(disponible)exten => _100X,n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)exten => _100X,n,GotoIf($[${DIALSTATUS} = BUSY]?busy:unavail)exten => _100X,n(unavail),Voicemail(${EXTEN}@default,u)exten => _100X,n,Hangupexten => _100X,n(busy),VoiceMail(${EXTEN}@default,b)exten => _100X,n,Hangup
Para desactivar el followme la extensión 1000 tendrá que llamar la extensión 102
exten => 102,1,Answer exten => 102,n,Set(DB(${CALLERID(num)}/FOLLOWME)=0) exten => 102,n,Hangup
Se actualiza el plan de llamadas:
asterisk -rvvvvvvvvv
CLI> dialplan reload
Este es solamente un ejemplo. Hay distintas formas de configurar el followme según las necesidades.
2.11 ENUM
ENUM o mapeo de números telefónicos, está constituido por una serie de protocolos que permiten crear una convergencia entre la red telefónica tradicional y Internet. Permite asociar (utilizando el protocolo DNS37) un numero telefónico a una serie de servicios típicos de la red internet (VoIP, correo electrónico, pagina web, etc.).
¿Cómo funciona?
Se ha creado una nueva jerarquía de dominios bajo el DNS e164.ARPA donde se almacenan los servicios asociados a un determinado numero telefónico.
Un ejemplo:
Tenemos un número telefónico: +5712345678
Este se almacenará bajo la jerarquía e164.ARPA siguiendo un orden inverso y poniendo entre cada digito un punto:
37 Un servidor DNS permite conectarse con la máquina sin necesidad de usar su dirección IP; basta con ingresar el dominio para que el servidor DNS resuelva y establezca una conexión. Wikipedia
75
8.7.6.5.4.3.2.1.7.5.e164.arpa
Este número estará asociado a unos registros DNS específicos (Name Authority Pointer o NAPTR) que podrán conocerse a través de una consulta:
$ORIGIN 8.7.6.5.4.3.2.1.7.5.e164.arpa.IN NAPTR 100 10 “u” “E2U+sip” “!^.*$!sip:[email protected]!” IN NAPTR 102 10 “u” “E2U+mailto” “!^.*$!mailto:[email protected]!”
En este caso dos:
• una SIP URI38
• un correo electrónico
Queda claro que una vez que se tengan estos datos será posible usarlos en Asterisk; llamando directamente la SIP URI en lugar del número telefónico (ahorrando los costos de llamadas) o enviar un correo electrónico.
Para hacer una prueeba se registra un numero telefónico y se asocia a distintos servicios Internet a través de E164.org39, un directorio ENUM publico.
ENUM y Asterisk
Primero tenemos que modificar el fichero enum.conf
nano /etc/asterisk/enum.conf
[general] search => e164.arpa search => e164.org h323driver => H323
Se ponen estas líneas que nos permitirán hacer búsqueda en la jerarquía DNS e164.arpa y e164.orgSe guardan los cambios y se vuelve a arrancar Asterisk:
/etc/init.d/asterisk restart
Esta es una lista de las funciones disponibles en Asterisk para hacer consultas ENUM:
• ENUMLOOKUP permite hacer una consulta de los registros NAPTR asociados a un determinado numero telefónico
• ENUMQUERY permite hacer una consulta de los registros NAPTR pero, al contrario de ENUMLOOKUP generará como resultado un ID que luego se podrá usar con la función ENUMRESULT
38 http://www.3cx.es/voip-sip/sip-uri.php 39 https://www.e164.org/index.php
76
• ENUMRESULT permite consultar los resultados generados por ENUMQUERY usando el ID creado por ENUMQUERY
ENUMLOOKUP
Sintaxis:
ENUMLOOKUP(number[,Method-type[,options[,record#[,zone-suffix]]]])
Ejemplos:
exten => _00.,1,Set(Enum1=${ENUMLOOKUP(+${EXTEN:2},SIP,c,,e164.org)})
El ejemplo funciona si para marcar un numero se usa el formato internacional: 00 + código país + código ciudad + numero.
• Se asigna el resultado de la consulta a la variable Enum1• ENUMLOOKUP el nombre de la función de Asterisk• +${EXTEN:2} se quitan del numero marcado los primeros dos dígitos (00) y se pone al frente
un + (el resultado será: +5712345678 que es el formato requerido para hacer consultas ENUM)• SIP los resultados serán solamente SIP URI• c: con esta opción se recibirá como respuesta el numero de SIP URI asociadas al numero
telefónico indicado• Hacemos la consulta en la jerarquía DNS e164.org
El resultado de la consulta será un número entero que indicará cuantos SIP URI están asociados al número telefónico indicado
exten => _00.,1,Set(Enum1=${ENUMLOOKUP(+${EXTEN:2},ALL,c,,e164.org)})
parecido al ejemplo precedente con la única diferencia que la consulta restituirá todos los NAPTRs asociados al numero telefónico indicado.
ENUMQUERY
Sintaxis:
ENUMQUERY(number[,Method-type[,zone-suffix]])
Ejemplos:
exten => _00.,1,Set(Enum1=${ENUMQUERY(+${EXTEN:2},SIP,e164.org)})
El resultado de la consulta será un numero (ID) que se utilizará con la función ENUMRESULT
ENUMRESULT
77
Sintaxis:
ENUMRESULT(id,resultnum)
Ejemplos:
exten => _00.,1,Set(NUM=${ENUMRESULT(${Enum1},1)})
Con esta línea se mira el primer NAPTR resultado de la consulta hecha con ENUMQUERY. La variable ${Enum1} es la que contiene el ID de la consulta y es la misma que hay que indicar como ID en la función ENUMRESULT
DIALPLAN (Plan de llamadas)
A continuación se presenta como construir el plan de llamadas de modo que antes de llamar cualquier número (nacional o internacional) haga una consulta en ENUM para ver si es posible usar una SIP URI en lugar del número telefónico:
exten => _00.,1,Set(Enum1=${ENUMLOOKUP(+${EXTEN:2},sip,c)}|counter=0) exten => _00.,2,GotoIf($[”${counter}”<”${Enum1}”]?3:6) exten => _00.,3,Set(counter=$[${counter}+1]) exten => _00.,4,Dial(SIP/${ENUMLOOKUP(+${EXTEN:2},sip,,${counter})}) exten => _00.,5,GotoIf($[”${counter}”<”${sipcount}”]?3:6) exten => _00.,6,Dial(SIP/MyproveedorVoIP/${EXTEN}) exten => _00.,7,Hangup
Lo mismo se puede hacer para el protocolo IAX:
exten => _00.,1,Set(Enum1=${ENUMLOOKUP(+${EXTEN:2},iax2,c)}|counter=0) exten => _00.,2,GotoIf($[”${counter}”<”${Enum1}”]?3:6) exten => _00.,3,Set(counter=$[${counter}+1]) exten => _00.,4,Dial(IAX2/${ENUMLOOKUP(+${EXTEN:2},sip,,${counter})}) exten => _00.,5,GotoIf($[”${counter}”<”${sipcount}”]?3:6) exten => _00.,6,Dial(SIP/MyproveedorVoIP/${EXTEN}) exten => _00.,7,Hangup
Se puede construir una macro que se ocupe de las consultas ENUM y si no hubiera resultados volver al dialplan y efectuar la llamada vía proveedor SIP o a través de la línea telefónica tradicional.
2.12 Las conferencias (Meetme.conf)
Quizás una de las características más interesantes de Asterisk es la posibilidad de crear conferencias audio. En este párrafo se verá como configurar el archivo meetme.conf y algunos ejemplos de como usar una conferencia.
78
Hay que empezar con la configuración del archivo meetme.conf:
nano /etc/asterisk/meetme.conf
[general]
audiobuffers=32 ; Numero de paquetes audio de 20ms que serán guardados en un buffer de memoria cuando pertenecen a canales que no son DADHI. Esto permite sincronizar el audio de los distintos participantes y evitar retrasos. Puede ser un valor entre 2 y 32
schedule=yes ; este parámetro va configurado con yes solamente si se usan las conferencias en realtime40. En caso contrario hay que dejarlo en no
logmembercount=yes ; este parámetro se utiliza para tener una cuenta de los usuarios presenten en una conferencia actualizando la base de datos usada (realtime)
fuzzystart=300 ; Hay una conferencia programada a las 8 de la mañana. Este parámetro se utiliza para definir si un usuario puede o no entrar en la conferencia si esta no ha empezado. 300 es el número de segundos. Ejemplo. Si el usuario entra a la 7:55 será aceptado porque puede entrar hasta 5 minutos (300 segundos) antes del comienzo de la conferencia. Si entra a las 7:50 será rechazado.
earlyalert=3600 ; Este valor (siempre en segundos) define si al usuario que intenta entrar en una conferencia programada le será anunciado o no que la conferencia todavía no ha empezado. Si entra cuando falta menos de una hora recibirá este aviso. Si entra más de una hora antes se le anunciará que la conferencia no existe.
endalert=120 ; cuando faltarán 120 segundos para terminar la conferencia programada, se le anunciará a todos los participantes.
[rooms] ; desde esta etiqueta empieza la configuración de las conferencias ; ; la sintaxis es conf => confno[,pin][,adminpin] ; conf => 3500 conf => 3501,1234 conf => 3502,1234,5678
Una explicación de los tres ejemplos.
40Asterisk Realtime
79
En el primero se define un cuarto de conferencias cuya extensión es 3500 y todos los usuarios tienen el permiso para entrar.
En el segundo la extensión es la 3501 y para entrar los usuarios tendrán que digitar el PIN 1234.
En la tercero la extensión es la 3502. Los usuarios tendrán que usar el PIN 1234 y los administradores el PIN 5678.
Se guardan los cambios y se vuelve a arrancar Asterisk:
/etc/init.d/asterisk restart
Una lista de las aplicaciones disponibles para gestionar las conferencias.
Desde la consola:
asterisk -rvvvvvvvvvvvvvvv
Se escribe
CLI> core show application meetme (más la tecla tab)
MeetMe MeetMeAdmin MeetMeChannelAdmin MeetMeCount
Las aplicaciones disponibles son cuatro. La primera es para entrar en una conferencia, la segunda para administrarla, la tercera es para controlar un canal de la conferencia y la tercera para conocer el numero de usuarios presentes en una conferencia.
Se sigue con la configuración del plan de llamadas. Se define un contexto dedicado a las conferencias y ahí se configuran los cuartos
nano /etc/asterisk/extensions.conf
[conferencias]exten => _350[012],1,Meetme(${EXTEN},scM(default)) exten => _350[012],n,Hangup
Llamando la extensión 3500 se entrará en el cuarto de conferencia 3500 (como configurado en meetme.conf)
Las tres opciones:
• s - Con esta opción se activa el menú del cuarto de conferencias para usuarios y administradores. Marcando la tecla asterisco se escuchará el menú.
• c - Al entrar en un cuarto de conferencia se le anunciará al usuario el número de personas presentes.
80
• M(default) - Cuando en el cuarto está solamente una persona, ésta escuchara la música en espera de la clase default”
Existe la posibilidad de crear cuartos de conferencias de forma dinámica (sin tener que configurarlos en el archivo meetme.conf). para hacerlo hay que crear estas líneas en el extensions.conf
exten => 3510,1,Meetme(,DM(default)) exten => 3510,n,Hangup
Primero no se indica el número del cuarto de conferencias y se usa la opción D que permite definir la extensión 3510 como cuarto de la conferencia y un PIN para entrar a ella. Si en lugar de la opción D se pone la opción d no se necesitará definir un PIN para el cuarto de conferencia.
Para tener una lista completa de las opciones disponibles desde la consola de Asterisk:
CLI> core show application MeetMe
Si se quiere definir un número máximo de usuarios que pueden participar en una conferencia podemos usar esta macro (con la aplicación MeetMeCount):
exten => 3520,1,Set(confmax=10) exten => 3520,2,Macro(meetme)exten => 3520,3,Hangup
[macro-meetme] exten => s,1,MeetMeCount(${MACRO_EXTEN},count) exten => s,2,Gotoif($[${count} > ${confmax}]?103) exten => s,3,MeetMe(${MACRO_EXTEN},D) exten => s,4,Hangup exten => s,103,Playback(conf-invalid) exten => s,104,Hangup
Primero se asocia a la variable confmax el numero 10 (el numero máximo de participantes permitidos en la conferencia) y luego se llama la macro meetme. Con la primera línea de la macro controlamos cuantos usuarios están en la conferencia 3520 y se asocia ese número a la variable count. Si el numero contenido en la variable count es mayor del numero contenido en la variable confmax (10) vamos a la línea con prioridad 103 donde se comunicará que la conferencia no es valida y se colgará la llamada; si es menor el usuario entrará al cuarto de conferencias.Con este comando:
CLI> help meetme
Usage: meetme (un)lock|(un)mute|kick|list [concise] <confno> <usernumber> Executes a command for the conference or on a conference
se maneja desde la consola de Asterisk muchas de las opciones disponibles para una conferencia.
81
CLI> meetme list 3500
meetme list 3500 User #: 01 1000 Fulano Channel: SIP/1100-b7835e20 (unmonitored) 00:00:33 User #: 02 1001 Sutano Channel: SIP/1000-b7847ce0 (unmonitored) 00:00:22
Aparecerá la lista de usuarios presentes en el cuarto de conferencia 3500. Se recarga la configuración de Asterisk:
/etc/init.d/asterisk reload
La lineas modificadas en el dialplan (en negrita los cambios):
[conferencias]exten => _350[012],1,Meetme(${EXTEN},scM(default))exten => _350[012],n,Hangup
exten => 3510,1,Meetme(,DM(default))exten => 3510,n,Hangup
[phones]include => internasinclude => externasinclude => subscribeinclude => parkedcallsinclude => conferencias
Desde la consola de Asterisk:
asterisk -rvvvvvvvvvvvvv
Se actualiza el dialplan:
CLI> dialplan reload
2.13 Asterisk GUI
Asterisk GUI es una interfaz gráfica desarrollada para la gestión y la configuración de Asterisk desde un navegador Web. Simplifica el manejo de Asterisk siempre y cuando se tenga un conocimiento básico del funcionamiento de la PBX. Al arrancar la GUI, ésta añade macros y extensiones al plan de llamadas; para evitar de perder el trabajo que se ha hecho es buena practica hacer una copia de todos los archivo de configuración de Asterisk presentes en la carpeta /etc/asterisk:
mkdir /tmp/asterisk
cp /etc/asterisk/* /tmp/asterisk
82
Para descargar la ultima versión disponible hay que instalar el programa Subversion.
yum install subversion
cd /usr/src
Se descargan los archivos de la GUI
svn co http://svn.asterisk.org/svn/asterisk-gui/branches/2.0
Se entra en la carpeta:
cd 2.0/
Se compila y instala:
./configuremakemake install
Para terminar con la instalación hay que modificar dos archivos de configuración de Asterisk. Primero el manager.conf
nano /etc/asterisk/manager.conf
[general] enabled = yes webenabled = yes port = 5038 httptimeout = 60 bindaddr = 0.0.0.0displayconnects = yes
Se crea un usuario que sera él que se usará para entrar en la pagina de administración de la GUI de Asterisk
[admin] secret = sesamo read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan write = system,call,agent,user,config,command,reporting,originate
Se guardan los cambios y se sigue con el archivo http.conf
nano /etc/asterisk/http.conf
[general]
83
enabled = yes enablestatic = yes bindaddr=0.0.0.0 bindport=8088
Se guardan los cambios y se reinicia Asterisk
/etc/init.d/asterisk restart
Ahora hay que abrir los puertos 5038 TCP y 8088 TCP en el cortafuegos
nano /etc/sysconfig/iptables
Se añaden estas líneas en la sección *filter:
# Asterisk Manager -A INPUT -p tcp -m tcp --dport 5038 -j ACCEPT # Asterisk http -A INPUT -p tcp -m tcp --dport 8088 -j ACCEPT
Se reinicia el cortafuegos:
service iptables restart
Ahora se averigua que todo esté bien configurado
make checkconfig
--- Checking Asterisk configuration to see if it will support the GUI --- * Checking for http.conf: OK * Checking for manager.conf: OK * Checking if HTTP is enabled: OK * Checking if HTTP static support is enabled: OK * Checking if manager is enabled: OK * Checking if manager over HTTP is enabled: OK --- Everything looks good ---
• GUI should be available at http://www.example.com:8088/asterisk/static/config/cfgbasic.html•
Desde un navegador Web se visita la pagina de configuración de la GUI de Asterisk (cambiar example.com con la dirección IP del servidor asterisk).
http://www.example.com:8088/static/config/cfgbasic.html
Si esta no funciona prueben:
84
Aquí van algunas imágenes de la interfaz gráfica
2.14 La gestión de las colas
Asterisk, entre sus funcionalidades, permite crear y administrar colas de espera. Normalmente este tipo de configuración se usa en los call center y permite redirigir las llamadas entrantes a los agentes que se encargarán de atenderlas.
¿Como se configura en Asterisk la gestión de las colas? A través de dos archivos:
• agents.conf• queues.conf
85
En el primero configuramos, definiendo algunas variables y parámetros, los agentes que atenderán las colas.En el queues.conf se configuran las colas (pueden ser una o más), cuales agentes y/o grupos son miembros de una determinada cola y que tipo de estrategia se utilizarán para enrutar las llamadas a los distintos agentes.
2.14.1 Los Agentes
Para configurar los agentes que atenderán las llamadas entrantes a las distintas colas hay que modificar el archivo agents.conf
nano /etc/asterisk/agents.conf
[general] ; empieza la parte general
persistentagents=yes ; define si el callbacklogin tiene que ser almacenado en la base de datos interna de Asterisk. De esta forma cuando se vuelve a arrancar Asterisk estos datos serán recargados
multiplelogin=yes ; define si está permitido a una misma extensión conectarse como agente múltiple
[agents] ; desde aquí comienza la configuración de los agentes
maxlogintries=3 ; numero máximo de intentos que tiene un agente para conectarse
autologoff=15 ; si un agente no contesta una llamada dentro de 15 segundos será automáticamente desconectado
autologoffunavail=yes ; si la extensión desde la cual el agente se conecta se vuelve no disponible, automáticamente el agente será desconectado
endcall=yes ; un agente puede terminar una llamada presionando la tecla *
musiconhold => default ; la clase de musica en espera que escuchará el agente cuando esté conectado
Se define un grupo para los agentes que se configurarán:
group=1
La última parte es dedicada a la configuración de los agentes siguiendo la sintaxis:
86
agent => IDagente,contraseñaagente,nombre
Dos ejemplos:
agent => 2000,1234,Fulanoagent => 2001,2345,Sutano
Se guardan los cambios.
Para que un agente se pueda loguear hay que escribir estas líneas en el plan de llamadas (contexto internas):
nano /etc/asterisk/extensions.conf
exten => _200[01],1,Agentlogin(${EXTEN})exten => _200[01],n,Hangup
Se recarga la configuración de Asterisk:
/etc/init.d/asterisk reload
Desde la consola
asterisk -rvvvvvvvvvvvvv
CLI> agent show
2000 (Fulano) not logged in (musiconhold is ‘default’)2001 (Sutano) not logged in (musiconhold is ‘default’)2 agents configured [0 online , 2 offline]
Los dos agentes están configurados pero no conectados.
2.14.2 Queues.conf
Para terminar la configuración dedicada a las colas hay que modificar el archivo queues.conf
nano /etc/asterisk/queues.conf
[general] ; empieza la parte general
persistentmembers = yes ; si se usan agentes dinámicos su configuración se guardará en la base de datos de Asterisk. De esta forma si Asterisk se vuelve a arrancar, cada agente será enrutado a su correspondiente cola.
87
keepstats = no ; mantiene las estadísticas de la cola durante un “reload” de asterisk
autofill = yes ; normalmente una cola funciona de la siguiente manera. Hay unos cuantos usuarios esperando por ser atendidos por los agentes. Cuando el usuario que está de primero en la cola viene atendido el segundo se vuelve primero e será atendido por el primer agente disponible. Este comportamiento no tiene en cuenta que pueden haber muchos agentes disponibles pero que cada usuario tendrá que esperar de volverse el primero de la lista para ser atendido. Con este parámetro definimos otro tipo de comportamiento. Los usuarios serán atendidos de manera paralela hasta que haya agentes disponibles. De esta forma se reducen considerablemente los tiempos de espera.
monitor-type = MixMonitor ; si se elige grabar las conversaciones, con este parámetro los archivos audios de los dos canales serán mezclados en uno solo
shared_lastcall=yes ; en el caso de agentes que pertenecen a más de una cola poniendo a yes este parámetro se respetarán los tiempos de espera entre las distintas colas
[ventas] ; el nombre de una cola de espera. Desde esta línea empieza su configuración
musicclass = default ; la clase de la música en espera
;announce = queue-ventas ; se puede crear un anuncio para indicar a los agentes (cuando contestan una llamada) a que cola pertenece el usuario que están atendiendo (útil en el caso de agentes que atienden más de una cola a la vez).
strategy = ringall ; con strategy se define que tipo de estrategia hay que utilizar para atender las colas.
Posibles opciones son:
• Leastrecent: Asigna la siguiente llamada al agente que más tiempo lleve sin atender una llamada.
• Fewestcalls: Asigna la siguiente llamada al agente que menos llamadas haya atendido. • Random: Asigna la siguiente llamada aleatoriamente a cualquier agente disponible. • Ringall: Llama a todos los agentes a la vez y el primero que descuelgue será quien atienda la
llamada. • RRMemory: Distribuye las llamadas “por turnos” entre los agentes disponibles y “recuerda” el
último agente al que intentó llamar. • Linear: contacto los agentes siguiendo el orden definido en este archivo de configuración.
88
• Wrandom: asigna la llamada aleatoriamente usando una métrica basada en penalidades.
timeout = 15 ; este el tiempo, en segundos, pasado el cual la llamada se considerará no contestada por el agente.
retry = 5 ; tiempo, en segundos, antes de volver a llamar todos los agentes
weight=0 ; cada cola puede tener un peso. Las colas con un valor alto tendrán prioridad respecto a aquellas con un peso más bajo
autopause=no ; si un agente non contesta una llamada será puesto en pausa
maxlen = 0 ; con este parámetro se define el numero máximo de usuarios que pueden entrar en la cola de espera (0 = ningún limite)
announce-frequency = 90; Cada cuantos segundos se anunciará al usuario en la cola su posición y/o tiempo estimado de espera
min-announce-frequency = 15 ; para evitar que cada vez que la posición y/o el tiempo estimado de un usuario cambie se le presente un anuncio, este parámetro define un tiempo (en segundos) que se esperará antes de comunicarle su nueva posición/tiempo estimado.
;periodic-announce-frequency=60 ; este parámetro representa cada cuantos segundos a un usuarios en la cola se le presentará un anuncio (por ejemplo relacionado con algún producto de la empresa).
announce-holdtime = once ; anunciar junto a la posición en la cola el tiempo estimado de espera. Puede ser yes, no, u once (una sola vez)
announce-position = yes ; periódicamente se le anunciará al usuario en la cola, su posición en la misma
announce-round-seconds = 10 ; el tiempo de espera estimado será redondeado a las decenas
reportholdtime = yes ; Antes que el agente conteste una llamada se le anunciará el tiempo de espera del usuario que va a atender
joinempty = yes ; permite a los usuarios acceder a la cola aunque no haya agentes disponibles
89
ringinuse = no ; con este parámetro en no, no se timbrarán las extensiones de los agentes que están en uso (solo protocolo SIP)
Para terminar la configuración de esta cola se definen los agentes que son parte de ella. Se puede hacer de dos formas:
• Indicando un agente por línea • Indicando un grupo de agentes
Un agente por línea:
member => Agent/2000member => Agent/2001 Un grupo de agentes:
; member => Agent/@1
Una vez terminada la configuración del archivo, se guardan los cambios y se añaden unas líneas al archivo extensions.conf para configurar la cola en el plan de llamadas:
nano /etc/asterisk/extensions.conf
En el contexto internas se pone:
exten => 3000,1,Queue(ventas) exten => 3000,n,Hangup
Se guardan los cambios y se actualiza la configuración de Asterisk:
/etc/init.d/asterisk reload
Desde un SoftPhone conectado a Asterisk, se marca la extensión 3000 para ver el resultado de la configuración de la cola en espera.
90
Capitulo III
Asterisk y la PSTN
Una de las posibilidades brindadas por Asterisk es la de conectarlo, a través de dispositivos Hardware, a la red telefónica conmutada (RTB)41. Los dispositivos pueden ser de distintos tipos:
• Dispositivos FXO• Dispositivos FXS• Dispositivos Mixtas (FXO/FXS)• Dispositivos BRI (ISDN)• Dispositivos PRI (E1, T1, J1)
FXO (Foreign Exchange Office) es un dispositivo de computador que permite conectar éste a la RTB, y mediante un software especial, realizar y recibir llamadas de teléfono.
FXS (Foreign Exchange Station) es el conector en una central telefónica o en la pared de nuestro hogar, que permite conectar un teléfono analógico estándar.
Los dispositivos Mixtos FXO/FXS combinan los dos tipos de conexiones según las necesidades del adquirente. Un ejemplo de dispositivo FXO/FXS es la tarjeta Digium42 TDM400P que permite instalar un total 4 módulos, sean FXO o FXS.
Los dispositivos BRI (Basic rate interface) permiten conectar una linea ISDN (Integrated Services Digital Network) al servidor Linux. Las lineas ISDN están compuestas de dos canales audio (de 64Kbit/s cada uno) y un canal D que se utiliza para la señalizacion con la central telefónica (de 16 Kbit/s).
Los dispositivos E1, T1, J1, que también se pueden denominar primarios, son lineas digitales que según el tipo brindan de 24 (T1) a 34 (E1) canales de voz. La diversa nomenclatura de estas lineas está relacionada con los países donde se usan. T1 son la lineas disponibles en Estados Unidos, E1 en Europa y J1 en Japón.
41 Red Telefónica Conmutada 42 Digium
El tipo de dispositivos a utilizar estará relacionado con el tipo de instalación que se está haciendo (casa, oficina, pequeña empresa, etc.)
En este capitulo se verá como instalar un dispositivo FXO en el computador y como configurarlo en Asterisk para efectuar y recibir llamadas.
3.1 Instalación dispositivo X100P
El dispositivo X100P es una tarjeta PCI43 con un canal FXO disponible.
Para la instalación de la tarjeta en un servidor Linux, distribución CentOS estos son los pasos a seguir:
1. Apagar el computador2. Desconectar el cable de alimentación3. Abrir el chasis del Computador4. Insertar la tarjeta en una ranura PCI disponible5. Volver a poner el chasis del computador6. Conectar el cable de alimentación al computador7. Conectar la linea telefónica al puerto FXO de la tarjeta a través de un normal cable telefónico8. Prender el computador
Normalmente CentOS reconoce automáticamente la nueva tarjeta instalada y le asigna un IRQ44 para que pueda comunicarse con el procesador del computador.
Una vez arrancado el sistema comprobamos que efectivamente la tarjeta ha sido reconocida por el sistema:
lspci -v
Según el modelo y marca en la pantalla tendremos una salida de este tipo:
02:08.0 Communication controller: Tiger Jet Network Inc. Tiger3XX Modem/ISDN interface Subsystem: Intel Corporation Digium X100P/X101P analogue PSTN FXO interface Flags: bus master, medium devsel, latency 64, IRQ 201
43 PCI 44 IRQ
92
I/O ports at d800 [size=256] Memory at fdc00000 (32-bit, non-prefetchable) [size=4K] Capabilities: [40] Power Management version 2
Se comprueba el IRQ
cat /proc/interrrupts
201: 330596875 IO-APIC-level wcfxo
3.2 Configuración X100P en Asterisk
El programa/librería que se encarga de detectar y configurar el puerto FXO en Asterisk es DAHDI. DAHDI trabaja “encima” de Asterisk y por eso hay que arrancarlo siempre antes de Asterisk. Para la configuración de la tarjeta se usarán algunas utilidades presentes en el paquete DAHDI-tools.
La primera utilidad que se usará es dahdi_genconf que reconoce el tipo de tarjeta instalado y crea/modifica dos archivos:
/etc/dahdi/system.conf
/etc/asterisk/dahdi-channels.conf
dahdi_genconf -v
El resultado:
Default parameters from /etc/dahdi/genconf_parametersGenerating /etc/dahdi/system.confGenerating /etc/asterisk/dahdi-channels.conf
Ahora se abren los dos archivos para ver que cambios hizo esta utilidad:
nano /etc/dahdi/system.conf
# Autogenerated by /usr/sbin/dahdi_genconf on Mon Nov 30 09:19:08 2009# If you edit this file and execute /usr/sbin/dahdi_genconf again,# your manual changes will be LOST.# Dahdi Configuration File## This file is parsed by the Dahdi Configurator, dahdi_cfg## Span 1: WCFXO/0 "Generic Clone Board 1" (MASTER) RED
fxsks=1;el tipo de señalizacion utilizada por el canal. En este caso protocolo FXS Koolstart
93
echocanceller=mg2,1;el tipo de cancelación del echo software (mg2) y el canal (en este caso existe solamente el 1)
loadzone =usdefaultzone=us; zona predefinida para la señalizacion (tono de llamada, tono de ocupado, etc..)
El único cambio que hay que hacer es modificar los dos últimos parámetros con el código de su propio país, siempre y cuando los parámetro de señalización estén presentes en el archivo indications.conf
Se guardan los cambios.
El segundo archivo:
nano /etc/asterisk/dahdi-channels.conf
; Span 1: WCFXO/0 "Generic Clone Board 1" (MASTER) RED;;; line="1 WCFXO/0/0 FXSKS (In use) (SWEC: MG2)"signalling=fxs_ks; el tipo de señalizacion del canal. Normalmente es el contrario del puerto instalado. Si el puerto es FXO la señalizacion es FXS y viceversa.
callerid=asreceived; aquí se puede configurar el callerid completo para la linea telefónica conectada al puerto FXO. Si se deja el parámetro en “asreceived” se presentará al llamante el numero telefónico asignado a la linea por la compañía telefónica.
group=1; si se disponen de muchos canales se pueden crear grupos. Este tipo de parámetro será útil al momento de configurar el dialplan context=from-pstn; es el contexto en donde entrarán las llamadas procedentes de la linea telefónica.
channel => 1; numero de canales disponibles en la tarjeta (en este caso 1)
Para que el archivo dahdi-channels sea leído por Asterisk tenemos que poner un include en el archivo chan_dahdi.conf
nano /etc/asterisk/chan_dahdi.conf
el fondo del archivo se añade la linea:
#include dahdi-channels.conf
94
Se guardan los cambios.
Desde la consola de Asterisk recargamos la configuración de DAHDI
asterisk -rvvvvvvvvvvvvvvvvvvv
CLI> dahdi restart
Si no sale ningún error significa que la configuración es correcta.
El estado de los canales DAHDI
CLI> dahdi show status
Description Alarms IRQ bpviol CRC4 Fra Codi Options LBOGeneric Clone Board 1 OK 0 0 0 CAS Unk YEL 0 db (CSU)/0-133 feet (DSX-1)
Una serie de informaciones acerca del canal configurado:
CLI> dahdi show channel 1
Channel: 1File Descriptor: 15Span: 1stExtension: Dialing: noContext: from-pstnCaller ID: Calling TON: 0Caller ID name:Mailbox: none>Destroy: 0InAlarm: 0Signalling Type: FXS KewlstartRadio: 0tOwner: <None>>Real: <None>Callwait: <None>Threeway: <None>Confno: -1Propagated Conference: -1Real in conference: 0DSP: nostBusy Detection: noTDD: nostRelax DTMF: noDialing/CallwaitCAS: 0/0
95
Default law: ulawFax Handled: noPulse phone: noDND: nostEcho Cancellation:localhos128 tapslocalhoscurrently OFFActual Confinfo: Num/0, Mode/0x0000Actual Confmute: NoHookstate (FXS only): Onhook
Ultima parte de la configuración es crear en el plan de llamadas un contexto para las llamadas entrantes de la linea telefónica y unas lineas en el contexto externas:
• Para hacer llamadas desde una extensión conectada a Asterisk en el contexto externas se pone:
exten => _9.,1,Dial(DAHDI/g1/${EXTEN:1},45)exten => _9.,n,Hangup
Para todas las llamadas locales y nacionales se usará la linea telefónica. Para diferenciar estas llamadas de las internacionales se ha puesto el numero 9 que representa el valor a marcar antes de cualquier numero local o nacional. Con g1 se indica el grupo (el puerto FXO pertenece al grupo 1).
Otra forma puede ser:
exten => _9.,1,Dial(DAHDI/1/${EXTEN:1},45)exten => _9.,n,Hangup
En lugar de g1 se pone 1 que es el canal del puerto FXO
Para las llamadas en entrada desde la linea telefónica:
[from-pstn]exten => s,1,Dial(SIP/1000,45)exten => s,n,Hangup
Todas las llamadas que entran a través de la linea telefónica se desvían a la extensión 1000.
Se guardan los cambios y se reinicia Asterisk
/etc/init.d/asterisk restart
Para más puertos FXO el procedimiento es casi idéntico.
96
Capitulo IV
IVR
IVR es la sigla de Interactive Voice Response, que se traduce del inglés como Respuesta de Voz Interactiva. Consiste en un sistema telefónico que es capaz de recibir una llamada e interactuar con el usuario a través de grabaciones de voz y el reconocimiento de respuestas a través del uso de la tecla del teléfono. Es un sistema automatizado de respuesta interactiva, orientado a entregar y/o capturar información a través del teléfono, permitiendo el acceso a servicios de información u otras operaciones.
Asterisk permite configurar cualquier tipo de IVR y en este capitulo se mostrará come crear un IVR básico.
4.1 Grabación de las locuciones:
En Asterisk existe la aplicación Record que nos permite grabar archivos audios para luego utilizarlos en la creación de un IVR. Para implementarla hay que modificar el plan de llamadas.
nano /etc/asterisk/extensions.conf
En el contexto internas se pone:
exten => _66XX,1,Answer() exten => _66XX,n,Wait(2)exten => _66XX,n,Record(/tmp/prompt${EXTEN:2}:wav) exten => _66XX,n,Wait(2) exten => _66XX,n,Playback(/tmp/prompt${EXTEN:2}) exten => _66XX,n,Wait(2) exten => _66XX,n,Hangup()
• Línea 1: contesta la llamada• Línea 2: espera 2 segundos• Línea 3: Graba el archivo audio en la carpeta /tmp con nombre promptXX donde XX son los
últimos dos dígitos de la extensión que hemos llamado desde nuestro softphone. Ej. Si llamamos la extensión 6650 el archivo audio tendrá el nombre prompt50.waw
• Línea 4: espera 2 segundos• Línea 5: devuelve el archivo recién grabado• Línea 6: espera 2 segundos• Línea 7: cuelga la llamada
Si la grabación no nos satisface, se vuelve a grabar marcando el mismo numero. La nueva grabación remplazará la vieja.
Se actualiza el dialplan y se graban las locuciones:
asterisk -rvvvvvvvvvvvvvvvv
CLI> dialplan reload
CLI> quit
Esta solución permite grabar hasta 99 archivos audio. Una vez que se tengan los archivos listos vamos a copiarlos en la carpeta de las locuciones de Asterisk.
mkdir /var/lib/asterisk/sounds/custom
cd /tmp
mv prompt* /var/lib/asterisk/sounds/custom
La sinopsis de la aplicación:
-= Info about application ‘Record’ =-
[Synopsis] Record to a file [Description] Record(filename.format,silence[,maxduration][,options]) Records from the channel into a given filename. If the file exists it will be overwritten. - ‘format’ is the format of the file type to be recorded (wav, gsm, etc). - ‘silence’ is the number of seconds of silence to allow before returning. - ‘maxduration’ is the maximum recording duration in seconds. If missing or 0 there is no maximum. - ‘options’ may contain any of the following letters: ‘a’ : append to existing recording rather than replacing ‘n’ : do not answer, but record anyway if line not yet answered ‘q’ : quiet (do not play a beep tone) ‘s’ : skip recording if the line is not yet answered ‘t’ : use alternate ‘*’ terminator key (DTMF) instead of default ‘#’ ‘x’ : ignore all terminator keys (DTMF) and keep recording until hangup If filename contains ‘%d’, these characters will be replaced with a number incremented by one each time the file is recorded. A channel variable named RECORDED_FILE will also be set, which contains the final filemname. Use ‘core show file formats’ to see the available formats on your system User can press ‘#’ to terminate the recording and continue to the next priority. If the user should hangup during a recording, all data will be lost and the application will teminate.
98
4.2 Plan de llamadas e IVR
En el párrafo precedente se ha mostrado como grabar los archivos audio para la creación de un IVR. Para el ejemplo a seguir se han registrados tres archivos que contienen las siguientes frases:
• espeng.wav - “for english press one, para español marque dos”• espmenu.wav - “para efectuar un test de echo marque 1, para escuchar la música en espera
marque 2, para la oficina de ventas marque 3)• engmenu.wav - “for echo test press 1, for music on hold press 2, for sales office, press 3)
Lo archivos se han copiado en la carpeta /var/lib/asterisk/sounds/custom. Ahora se puede empezar con la construcción del dialplan para la creación del IVR:
nano /etc/asterisk/IVR
[IVR] exten => s,1,Wait(1) ;espera un segundo exten => s,2,Set(CHANNEL(language)=es) ; pone como predefinidas las locuciones en español exten => s,3,Set(TIMEOUT(digit)=7) ; 7 segundos es el tiempo que espera entre el primer dígito y los sucesivos exten => s,4,Set(TIMEOUT(response)=10) ; 10 segundos es el tiempo que espera para que el llamante presione una tecla exten => s,5,BackGround(custom/espeng) ; presenta el menú vocal y al mismo tiempo escucha si el llamante presiona alguna tecla exten => s,6,WaitExten() ; espera que el llamante presione alguna tecla exten => 1,1,goto(IVR1,s,1) ; si presiona 1 va al contexto IVR1, extensión s, prioridad 1 exten => 2,1,goto(IVR2,s,1) ; si presiona 2 va al contexto IVR2, extensión s, prioridad 1 exten => i,1,Playback(invalid) ; si el numero digitado no es valido (ni 1 ni 2) comunica el error exten => i,2,Playback(goodbye) ; se despide exten => i,3,Hangup ; cuelga la llamada exten => t,1,goto(IVR,s,2) ; si dentro de 10 segundo el llamante no presiona ninguna tecla vuelve a presentar el menu vocal exten => h,1,Hangup ; si el llamante cuelga ejecuta la extensión h
[IVR1] exten => s,1,Set(TIMEOUT(digit)=7) ; exten => s,2,Set(TIMEOUT(response)=10) exten => s,3,Set(CHANNEL(language)=en) ; define como idioma predefinido el ingles y usas las locuciones en este idioma exten => s,4,BackGround(custom/engmenu) ; presenta en menú en ingles exten => s,5,WaitExten() ; Espera que el llamante presione una tecla exten => 1,1,Playback(demo-echotest) ; Si presiona 1 efectuá el test de echo exten => 1,2,Echo() exten => 2,1,MusicOnHold ; Si presiona 2 escuchará la música en espera predefinida exten => 3,1,Playback(pls-wait-connect-call) ; Si presiona 3 lo pone en comunicación con la oficina de ventas (extensión 3000)
99
exten => 3,2,Goto(internas,3000,1) exten => i,1,Playback(invalid) exten => i,2,Playback(goodbye) exten => i,3,hangup exten => t,1,goto(IVR1,s,1) exten => h,1,Hangup
[IVR2] exten => s,1,Set(TIMEOUT(digit)=7) exten => s,2,Set(TIMEOUT(response)=10) exten => s,3,Set(CHANNEL(language)=es) exten => s,4,BackGround(custom/espmenu) exten => s,5,WaitExten() exten => 1,1,Playback(demo-echotest) exten => 1,2,Echo() exten => 2,1,MusicOnHold exten => 3,1,Playback(pls-wait-connect-call) exten => 3,2,Goto(internas,3000,1) exten => i,1,Playback(invalid) exten => i,2,Playback(goodbye) exten => i,3,hangup exten => t,1,goto(IVR1,s,1) exten => h,1,Hangup
El menú IVR2 es totalmente igual al IVR1 solamente que es en español.
Para incluir este archivo en el diaplan (plan de llamadas):
nano /etc/asterisk/extensions.conf
Si se quieres que todas las llamadas externas sean atendidas por el IVR, en el contexto donde entran las llamadas externas se pone:
[from-PSTN]exten => s,1,Answer exten => s,n,Wait(1) exten => s,n,Goto(IVR,s,1)
Para probarlo se añaden estas lineas en el contexto internas:
exten => 50,1,Answer exten => 50,n,Wait(1) exten => 50,n,Goto(IVR,s,1)
y al final del archivo añadimos
#include "IVR"
100
El comando #include en el archivo extensions.conf toma un archivo de texto y lo engloba al plan de llamadas.
Se guardan los cambios y desde la consola de Asterisk:
CLI> dialplan reload
Al momento de crear un IVR, las posibilidades son prácticamente infinitas.
Ejemplos:
• un IVR que gestione colas de espera diferenciadas por departamento (ventas, compras, asistencia técnica, etc.)
• un IVR que permita marcar directamente una extensión o, en el caso que no se marque ninguna, envíe la llamada a una operadora.
101
Capitulo V
Asterisk y FAX
Desde la versión 1.6.X, Asterisk soporta la recepción y trasmisión de FAX a través del modulo app_fax. Este modulo se apoya en las librerías SpanDSP que hay que instalar antes de compilar Asterisk. En este capitulo se presentará una solución basada en el modulo app_fax y una basada en la combinación del programa IAXmodem con el servidor de FAX Hylafax.
5.1 Asterisk con IAXmodem y Hylafax
Esta solución se basa en el uso de IAXmodem como extensión IAX2 y Hylafax como servidor de FAX.
IAXmodem
IAXmodem es un modem software, escrito en lenguaje C que utiliza un canal IAX2 (uno de los protocolos presentes en Asterisk) en lugar de una línea telefónica y utiliza un DSP software en lugar de un chip DSP (Digital Signal Processing)45. Se descargan las fuentes de IAXmodem:
cd /usr/src
wget http://switch.dl.sourceforge.net/sourceforge/iaxmodem/iaxmodem-1.2.0.tar.gz
Se descomprime el archivo
tar -xf iaxmodem-1.2.0.tar.gz
Se entra en la carpeta:
cd iaxmodem-1.2.0
Se compila:
./configuremake
Se copia el programa compilado en la siguiente carpeta:
cp iaxmodem /usr/local/sbin
Se crean algunas carpetas y archivos para IAXmodem:
mkdir /etc/iaxmodem
mkdir /var/log/iaxmodem
45 DSP Wikipedia
touch /var/log/iaxmodem/ttyIAX
touch /var/log/iaxmodem/iaxmodemSe modifica el archivo de configuración predefinido que viene con las fuentes:
nano iaxmodem-cfg.ttyIAX
Este es un ejemplo de configuración:
device /dev/ttyIAXowner uucp:uucpmode 660port 4570refresh 300server 127.0.0.1peername iaxmodemsecret passwordcidname VozToVoicecidnumber XXXXXXXXXXcodec ulaw
Esta configuración es valida si IAXmodem está instalado en el mismo computador donde se instaló Asterisk. En el caso de dos computadores distintos hay que indicar en la línea server la dirección IP del servidor Asterisk. Pongan la contraseña en secret y en cidname y cidnumber nombre y numero telefónico que usará IAXmodem para presentarse a Asterisk. Se pueden configurar cuantos IAXmodem se quieran cambiando en la primera línea el nombre del device, en port el puerto y en peername el nombre. Cada archivo tendrá un nombre distinto, ttyIAX2 ttyIAX3, etc.
Se guardan los cambios y se copia el archivo en la carpeta /etc/iaxmodem que se ha creado:
cp iaxmodem-cfg.ttyIAX /etc/iaxmodem/ttyIAX
Ahora se modifica la configuración de Asterisk para insertar la nueva extensión IAX:
nano /etc/asterisk/iax.conf
[iaxmodem]type=friendcontext=faxdisallow=allallow=ulawusername=iaxmodemsecret=passwordqualify=yesnotransfer=yeshost=dynamic
103
requirecalltoken=auto
Se guardan los cambios y se actualiza la configuración de IAX2 en Asterisk
asterisk -rvvvvvvvvvvvvvvvvvvv
Se escribe
CLI> iax2 reload
Se sale de la consola
CLI> quit
Ahora se puede hacer una prueba para ver si la conexión entre IAXmodem y Asterisk funciona:
cd /usr/local/sbin
./iaxmodem ttyIAX
debería aparecer:
[2009-06-08 12:03:39] Modem started[2009-06-08 12:03:39] Setting device = '/dev/ttyIAX'[2009-06-08 12:03:39] Setting owner = 'uucp:uucp'[2009-06-08 12:03:39] Setting mode = '660'[2009-06-08 12:03:39] Setting port = 4570[2009-06-08 12:03:39] Setting refresh = 300[2009-06-08 12:03:39] Setting server = '127.0.0.1'[2009-06-08 12:03:39] Setting peername = 'iaxmodem'[2009-06-08 12:03:39] Setting secret = 'password'[2009-06-08 12:03:39] Setting cidname = 'VozToVoice’[2009-06-08 12:03:39] Setting cidnumber = 'XXXXXXXXX'[2009-06-08 12:03:39] Setting codec = ulaw[2009-06-08 12:03:39] Opened pty, slave device: /dev/pts/4[2009-06-08 12:03:39] Created /dev/ttyIAX symbolic link
Per salir presionamos CTRL-C
[2009-06-08 12:03:45] Terminating on signal 2...
Antes de hacerlo se controla que en la consola de Asterisk aparezca la conexión de IAXmodem (en otra ventana Terminal)
104
Para arrancar IAXmodem en automático se instala el script presente en la carpeta de las fuentes de IAXmodem:
cd /usr/src/iaxmodem-1.2.0
mv iaxmodem.init.fedora /etc/init.d/iaxmodem
se vuelve ejecutable:
chmod +x /etc/init.d/iaxmodem
e se configura para el arranque automático:
chkconfig --add iaxmodemchkconfig iaxmodem on
Se arranca el programa:
/etc/init.d/iaxmodem start
Hylafax
Hylafax es un servidor FAX diseñado para sistemas Linux que usa un sistema cliente-servidor. Un cliente (FAX) se conecta al servidor (Hylafax) y a través de el envía el FAX
Hay que empezar instalando algunas (dependencias) requeridas por Hylafax:
yum install ghostscript ghostscript-devel sharutils ghostscript-fonts
En la pagina de Hylafax están presentes los paquetes para las distintas distribuciones de Linux:
Se descargan los paquetes para Centos 5 (cliente y servidor):
cd /usr/src
wget ftp://ftp.hylafax.org/binary/linux/redhat/6.0.4/hylafax-server-6.0.4-1rhel5.i386.rpm
wget ftp://ftp.hylafax.org/binary/linux/redhat/6.0.4/hylafax-client-6.0.4-1rhel5.i386.rpm
Se instalan:
rpm -iv hylafax*.rpm
Se añade el faxgetty (faxgetty es el programa que realmente contesta las llamadas) al inittab (El fichero inittab describe que procesos se inician al arrancar el Servidor Linux)
105
nano /etc/inittab
Se añade esta línea:
fax:2345:respawn:/usr/sbin/faxgetty ttyIAX
Se guardan los cambios y se vuelve a a arrancar inittab:
init q
Se empieza con la configuración de Hylafax:
faxsetup
Update /var/spool/hylafax/status/any.info. HylaFAX configuration parameters are: [1] Init script starts faxq: yes [2] Init script starts hfaxd yes [3] Start old protocol: no [4] Start paging protocol: no
Are these ok [yes]?
Se contesta yes
Modem support functions written to /var/spool/hylafax/etc/setup.modem.Configuration parameters written to /var/spool/hylafax/etc/setup.cache.No scheduler config file exists, creating one from scratch.
Country code [1]? 57Area code []? 1Long distance dialing prefix [1]? 0International dialing prefix [011]? 00Dial string rules file (relative to /var/spool/hylafax) ["etc/dialrules"]?Tracing during normal server operation [1]?Default tracing during send and receive sessions [0xffffffff]?Continuation cover page (relative to /var/spool/hylafax) []?Timeout when converting PostScript documents (secs) [180]?Maximum number of concurrent jobs to a destination [1]?Define a group of modems []?Time of day restrictions for outbound jobs ["Any"]?Pathname of destination controls file (relative to /var/spool/hylafax) []?Timeout before purging a stale UUCP lock file (secs) [30]?Max number of pages to permit in an outbound job [0xffffffff]?Syslog facility name for ServerTracing messages [daemon]?The non-default scheduler parameters are:
106
CountryCode: 57AreaCode: 1LongDistancePrefix: 0InternationalPrefix: 00Are these ok [yes]? yes
Creating new configuration file /var/spool/hylafax/etc/config...Restarting HylaFAX server processes.Should I restart the HylaFAX server processes [yes]?
/etc/rc.d/init.d/hylafax startStarting HylaFAX queue manager (faxq): [ OK ]Starting HylaFAX server (hfaxd): [ OK ]Restarting HylaFAX modem manager (faxgetty): [ OK ]
Do you want to run faxaddmodem to configure a modem [yes]?
Serial port that modem is connected to []? ttyIAX
Ok, time to setup a configuration file for the modem. The manualpage config(5F) may be useful during this process. Also be awarethat at any time you can safely interrupt this procedure.Reading scheduler config file /var/spool/hylafax/etc/config.No existing configuration, let's do this from scratch.
Country code [1]? 57Area code [415]? 1Phone number of fax modem [+1.999.555.1212]? +571XXXXXXXXLocal identification string (for TSI/CIG) ["NothingSetup"]? VozToVoiceLong distance dialing prefix [1]? 0International dialing prefix [011]? 00Dial string rules file (relative to /var/spool/hylafax) [etc/dialrules]?Tracing during normal server operation [1]?Tracing during send and receive sessions [11]?Protection mode for received facsimile [0600]?Protection mode for session logs [0600]?Protection mode for ttyIAX [0600]?Rings to wait before answering [1]? 2Modem speaker volume [off]?Command line arguments to getty program ["-h %l dx_%s"]?Pathname of TSI access control list file (relative to /var/spool/hylafax) [""]?Pathname of Caller-ID access control list file (relative to /var/spool/hylafax) [""]?Tag line font file (relative to /var/spool/hylafax) [etc/lutRS18.pcf]?Tag line format string ["From %%l|%c|Page %%P of %%T"]?Time before purging a stale UUCP lock file (secs) [30]?Hold UUCP lockfile during inbound data calls [Yes]?Hold UUCP lockfile during inbound voice calls [Yes]?
107
Percent good lines to accept during copy quality checking [95]?Max consecutive bad lines to accept during copy quality checking [5]?Max number of pages to accept in a received facsimile [25]?Syslog facility name for ServerTracing messages [daemon]?Set UID to 0 to manipulate CLOCAL [""]?Use available priority job scheduling mechanism [""]?
CountryCode: 57AreaCode: 1FAXNumber: +571XXXXXXXXLongDistancePrefix: 0InternationalPrefix: 00DialStringRules: etc/dialrulesSessionTracing: 11RingsBeforeAnswer: 2SpeakerVolume: offGettyArgs: "-h %l dx_%s"LocalIdentifier: "VozToVoice"TagLineFont: etc/lutRS18.pcfTagLineFormat: "From %%l|%c|Page %%P of %%T"MaxRecvPages: 25Are these ok [yes]?
Now we are going to probe the tty port to figure out the typeof modem that is attached. This takes a few seconds, so be patient.Note that if you do not have the modem cabled to the port, or themodem is turned off, this may hang (just go and cable up the modemor turn it on, or whatever).
Probing for best speed to talk to modem: 38400 OK.
About fax classes:The difference between fax classes has to do with how HylaFAX interactswith the modem and the fax protocol features that are used when sendingor receiving faxes. One class isn't inherently better than another;however, one probably will suit a user's needs better than others.Class 1 relies on HylaFAX to perform the bulk of the fax protocol.Class 2 relies on the modem to perform the bulk of the fax protocol.Class 2.0 is similar to Class 2 but may include more features.Class 1.0 is similar to Class 1 but may add V.34-fax capability.Class 2.1 is similar to Class 2.0 but adds V.34-fax capability.
HylaFAX generally will have more features when using Class 1/1.0 thanwhen using most modems' Class 2 or Class 2.0 implementations. Generallyany problems encountered in Class 1/1.0 can be resolved by modificationsto HylaFAX, but usually any problems encountered in Class 2/2.0/2.1 willrequire the modem manufacturer to resolve it.
108
Use Class 1 unless you have a good reason not to.This modem looks to have support for Class 1 and 1.0.How should it be configured [1]?Hmm, this looks like a Class 1 modem.Product code (ATI0) is "spandsp".Other information (ATI3) is "www.soft-switch.org".DTE-DCE flow control scheme [default]?Modem manufacturer is "spandsp".Modem model is "IAXmodem".Using prototype configuration file iaxmodem...The modem configuration parameters are:ModemResetCmds: "ATH1\nAT+VCID=1"Are these ok [yes]?
Creating new configuration file /var/spool/hylafax/etc/config.ttyIAX...Done setting up the modem configuration.Checking /var/spool/hylafax/etc/config for consistency......some parameters are different.
The non-default scheduler parameters are:
CountryCode: 57AreaCode: 1LongDistancePrefix: 0InternationalPrefix: 00DialStringRules: etc/dialrulesAre these ok [yes]?
Creating new configuration file /var/spool/hylafax/etc/config......saving current file as /var/spool/hylafax/etc/config.sav.
Don't forget to run faxmodem(8C) (if you have a send-only environment)or configure init to run faxgetty on ttyIAX.
Do you want to run faxaddmodem to configure another modem [yes]? no
Looks like you have some faxgetty processes running (PIDs are): 13236It is usually a good idea to restart these processes after runningfaxsetup; especially if have just installed new software. If theseprocesses are being started by init(8C) then sending each of them aQUIT message with the faxquit command should cause them to be restarted.Is it ok to send a QUIT command to each process [yes]?
/usr/sbin/faxquit ttyIAX
Se vuelve a arrancar Hylafax
109
/etc/init.d/hylafax restart
Shutting down HylaFAX queue manager (faxq): [ OK ]Shutting down HylaFAX server (hfaxd): [ OK ]Starting HylaFAX queue manager (faxq): [ OK ]Starting HylaFAX server (hfaxd): [ OK ]Restarting HylaFAX modem manager (faxgetty): [ OK ]
Todos los archivos de configuración que se crearan a lo largo del proceso de configuración de Hylafax se guardaran en la carpeta /var/spool/hylafax/etc
Prueba
Se tiene un numero geográfico de EuteliaVoIP y la posibilidad de enviar faxes desde internet con otro operador.
El trunk Eutelia para las llamadas entrantes está configurado con el contexto from-euteliaEn la configuración del extensions.conf para este contexto se han añadido estas líneas:
[from-eutelia]exten => s,1,NoOp( Call from Eutelia )exten => s,n,Answerexten => s,n,Wait(3)exten => s,n,Dial(SIP/1000,45)exten => s,n,Hangupexten => fax,1,Dial(IAX2/iaxmodem)exten => fax,n,Hangup
Si Asterisk reconoce que está llamando un fax saltará a la extensión fax sino llamará la extensión SIP/1000.
Se guardan los cambios y se reinicia Asterisk
/etc/init.d/asterisk restart
Desde la pagina web de un proveedor que permita enviar fax se envía un fax al numero geográfico configurado de EuteliaVoIP. Este es el resultado del envío.
Lado Asterisk:
110
Correo electrónico recibido:
FaxMaster es el usuario predefinido que Hylafax usa para enviar el fax a un correo electrónico. Si se quiere, se puede cambiar modificando el archivo FaxDispatch que se encuentra en la carpeta /var/spool/hylafax/etc
Si se quiere recibir el correo electrónico con el texto en español siempre en el mismo archivo se añade esta línea:
TEMPLATE=es
Para el envío de los faxes se crea en extension.conf un contesto [fax] (El mismo que se ha configurado para la extension iaxmodem en iax.conf) con las siguientes líneas:
111
[fax]exten => _X.,1,Dial(SIP/justvoip/${EXTEN})exten => _X.,n,Hangup Se Actualiza el dialplan:
/etc/init.d/asterisk reload
Desde el terminal de Linux se escribe:
sendfax -n -d <faxnumber> <file.txt>
Ejemplo:
sendfax -n -d 0057XXXXXXXX /tmp/fulano.pdf
Si se quieres usar un cliente con interfaz gráfica para el envío de fax, una buena solucion es YajHFC46 (Yet another Java HylaFAX Client) que siendo escrito completamente en JAVA funciona en sistemas operativos Linux y Windows.
El caso que se utilice un cliente remoto en el cortafuegos hay que abrir el puerto 4559 TCP (usado por Hylafax) y los puertos desde el 30000 hasta el 65000 TCP para los datos.
5.2 Asterisk y el protocolo T38
Se pone una hoja en la “maquina”, se marca el numero de teléfono de destino y se espera que salga un OK por algún lado. Esta sencilla operación es la que se hace cuando se quiere enviar un FAX. Todo lo que pasa en el “mientras” es totalmente transparente. Los dos Faxes negocian todos los pasajes y para hacer eso usan un protocolo. Este protocolo ha sido definido por la “International Telecommunication Union” y tomó como sigla T.30
En 1998 la misma organización define un nuevo protocolo que permite recibir y enviar faxes usando una red a paquetes (Internet). La sigla de este protocolo es T.38.
¿Cómo funciona el protocolo T.38?
Quizás la imagen que sigue ayuda para entender:
46 YajHFC
112
El FAX, conectado a la línea telefónica está también conectado a un Gateway con soporte T.38. Este Gateway se encarga de transformar el FAX en el formato requerido para luego ser enviado a través de la red Internet. En el lado opuesto otro Gateway T.38 se encarga de “decodificar” los paquetes que lleguen para luego pasar el resultado al fax de destinación. Un Gateway T.38 clásico funciona como se muestra en la imagen que sigue:
Los datos del FAX T.30 vienen analizados y manipulados para luego ser transformados en paquetes (IFP). Se pueden enviar usando tres protocolos de transporte: UDPTL, TCP o RTP. Será tarea de los Gateway T.38 negociar el protocolo de trasporte. En el caso de Asterisk el único protocolo de trasporte permitido es UDPTL que funciona de la siguiente forma:
113
Cada paquete UDPTL contiene encapsulado el paquete IFP (que contiene los datos del fax que se está enviando y un sistema de corrección de errores – FEC [forward error correction]). Para repetir los paquetes perdidos y controlar que lleguen en el justo orden hay a disposición dos sistemas:
• Con el primero se repite el ultimo paquete enviado como FEC para el paquete que se está enviando
• Con el segundo se crea un paquete de paridad para un numero determinado de paquetes IFP y se incluye esta información en el paquete UDPTL corriente.
El paquete UDPTL está encapsulado en un paquete UDP (protocolo de trasporte) que a su vez está encapsulado en un paquete IP (protocolo que permite al paquete llegar a destinación).
Asterisk soporta el protocolo T.38 solamente como pasarela, es decir que no está “en el medio” a lo largo del envío del fax. A un lado y al otro de la trasmisión deberán estar dos Gateway T.38 que se hagan cargo de la tarea de enviar/recibir el fax. En Asterisk el envío y recepción de faxes es posible a través de la librería SpanDSP y el modulo app_fax.
Desde la consola
asterisk –rvvvvvvvvvvvvvvvv
Se controla la sintaxis de las dos aplicaciones contenidas en el modulo app_fax
CLI> core show application ReceiveFax
-= Info about application 'ReceiveFAX' =-
[Synopsis]Receive a FAX
[Description]
114
ReceiveFAX(filename[|options]):Receives a fax from the channel into the given filename overwritingthe file if it already exists. File created will have TIFF format.The option string may contain zero or more of the following characters: 'c' -- makes the application behave as a calling machine The default behaviour is to behave as an answering machine.
This application uses following variables: LOCALSTATIONID to identify itself to the remote end. LOCALHEADERINFO to generate a header line on each page.
This application sets the following channel variables upon completion: FAXSTATUS - status of operation: SUCCESS | FAILED FAXERROR - Error when FAILED FAXMODE - Mode used: audio | T38 REMOTESTATIONID - CSID of the remote side. FAXPAGES - number of pages sent. FAXBITRATE - transmition rate. FAXRESOLUTION - resolution.
Returns -1 in case of user hang up or any channel error.Returns 0 on success.
CLI> core show application SendFax
-= Info about application 'SendFAX' =-
[Synopsis]Send a FAX
[Description] SendFAX(filename[|options]):Send a given TIFF file to the channel as a FAX.The option string may contain zero or more of the following characters: 'a' - makes the application behave as an answering machine The default behaviour is to behave as a calling machine.
This application uses following variables: LOCALSTATIONID to identify itself to the remote end. LOCALHEADERINFO to generate a header line on each page.
This application sets the following channel variables upon completion: FAXSTATUS - status of operation: SUCCESS | FAILED FAXERROR - Error when FAILED
115
FAXMODE - Mode used: audio | T38 REMOTESTATIONID - CSID of the remote side. FAXPAGES - number of pages sent. FAXBITRATE - transmition rate. FAXRESOLUTION - resolution.
Returns -1 in case of user hang up or any channel error.Returns 0 on success.
Algunos ATA comercializados soportan el protocolo T.38. En Voip-info47 aparece una lista (aunque no muy actualizada).
Para el soporte T.38 en Asterisk hay que modificar dos archivos:
nano /etc/asterisk/sip.conf
en la parte general se busca la línea que sigue y si está comentada se quita el punto y coma por delante:
t38pt_udptl = yes,FEC,maxdatagram=400
Se guardan los cambios y se continua con el segundo archivo:
nano /etc/asterisk/udptl.conf
Se pone:
[general]udptlstart=4000udptlend=4099udptlchecksums=yesudptlfecentries = 3udptlfecspan = 3use_even_ports = no
Se guardan los cambios y se vuelve a arrancar Asterisk:
/etc/init.d/asterisk restart
Para el test que se va a presentar se ha configurado un numero geográfico de Eutelia VoIP (que soporta el protocolo T.38 a través de un Gateway Server Cisco) y se ha modificado el plan de llamadas de la siguiente forma
nano /etc/asterisk/extensions.conf
47 Asterisk T38
116
[from-eutelia]exten => s,1,Answerexten => s,n,Wait(2)exten => s,n,Receivefax(/tmp/${UNIQUEID}.tif)exten => s,n,Noop(FAXSTATUS ${FAXSTATUS}, FAXERROR ${FAXERROR}, FAXMODE ${FAXMODE})exten => s,n,Hangup
Se guardan los cambios y se actualiza el dialplan:
asterisk –rvvvvvvvvvvvvvv
CLI> dialplan reload
En el primer test se ha usado para la llamada saliente Justvoip y se ha enviado el fax a través de la combinación Hylafax/IAXmodem:
Executing [003907331870559@fax-out:1] Dial("IAX2/iaxmodem2-901", "SIP/justvoip/003907331870559") in new stack -- Called justvoip/003907331870559 -- SIP/justvoip-082e0b38 is making progress passing it to IAX2/iaxmodem2-901 -- Executing [07331870559@from-eutelia:1] Answer("SIP/eutelia3-b6156d00", "") in new stack -- Executing [07331870559@from-eutelia:2] Wait("SIP/eutelia3-b6156d00", "2") in new stack -- SIP/justvoip-082e0b38 answered IAX2/iaxmodem2-901 -- Executing [07331870559@from-eutelia:3] ReceiveFAX("SIP/eutelia3-b6156d00", "/tmp/1255656629.101.tif") in new stack -- Executing [07331870559@from-eutelia:4] NoOp("SIP/eutelia3-b6156d00", "FAXSTATUS SUCCESS, FAXERROR , FAXMODE T38,REMOTESTATIONID VozToVoice") in new stack -- Executing [07331870559@from-eutelia:5] Hangup("SIP/eutelia3-b6156d00", "") in new stack== Spawn extension (from-eutelia, 07331870559, 5) exited non-zero on 'SIP/eutelia3-b6156d00'== Spawn extension (fax-out, 003907331870559, 1) exited non-zero on 'IAX2/iaxmodem2-901' -- Hungup 'IAX2/iaxmodem2-901'
Como se puede notar el fax ha llegado sin problemas y se ha usado el protocolo T.38
En la segundo test se ha usado para la llamada justvoip con Hylafax/IAXmodem y como numero geográfico en recepción un DID de Cheapnet
Executing [6554451618@from-cheapnet:1] Answer("SIP/cheapnet-b5a268e0", "") in new stack -- Executing [6554451618@from-cheapnet:2] Wait("SIP/cheapnet-b5a268e0", "2") in new stack[Oct 17 00:17:55] NOTICE[26474]: channel.c:2926 __ast_read: Dropping incompatible voice frame on SIP/cheapnet-b5a268e0 of format ulaw since our native format has changed to 0x8 (alaw) -- SIP/justvoip-082f2838 answered IAX2/iaxmodem2-293 -- Executing [6554451618@from-cheapnet:3] ReceiveFAX("SIP/cheapnet-b5a268e0", "/tmp/1255756675.129.tif") in new stack[Oct 17 00:17:57] WARNING[26474]: app_fax.c:383 transmit_audio: channel 'SIP/cheapnet-b5a268e0' refused to negotiate T.38
117
[Oct 17 00:18:02] NOTICE[2684]: chan_iax2.c:10099 socket_process: Peer 'iaxmodem2' is now REACHABLE! Time: 3 -- ast_get_srv: SRV lookup for '_sip._UDP.sip.cheapnet.it' mapped to host sip.cheapnet.it, port 5060 -- Executing [6554451618@from-cheapnet:4] NoOp("SIP/cheapnet-b5a268e0", "FAXSTATUS SUCCESS, FAXERROR , FAXMODE audio,REMOTESTATIONID VozToVoice") in new stack -- Executing [6554451618@from-cheapnet:5] Hangup("SIP/cheapnet-b5a268e0", "") in new stack
En este caso el “modo” ha sido audio, es decir T.30
Los dos test indican que en Asterisk es posible enviar faxes T.30 (hylafax) –> Asterisk –> Eutelia T.38 y no se necesita tener en ambos lados un Gateway T.38 La misma aplicación Receivefax sirve también para un escenario de este tipo: T.30 (hylafax) –> Asterisk –> Cheapnet T.30
5.3 Envío de FAX
Como se ha visto en el párrafo 8.2 la aplicación para enviar FAX en Asterisk es SendFax. La sintaxis es muy sencilla:
SendFAX(filename[|options]):
El problema es que con esta aplicación no podemos llamar directamente un FAX en cuanto no hay posibilidad de indicar el numero a marcar.
Para solucionar el problema hay que hacer uso de un callfile. Un callfile es un archivo de texto donde se definen unas cuantas acciones que Asterisk tiene que ejecutar; una vez que esté completado se mueve en la carpeta /var/spool/asterisk/outgoing. Asterisk controla periódicamente esta carpeta y si hay un archivo de este tipo lo procesa.
En el escenario que se va a presentar se llamará el numero de destino (un servicio que permite recibir FAX y luego los envía a un correo electrónico definido) usando come proveedor para la llamada justvoip. Una vez que el destinatario conteste se enviará el archivo prueba.tif (solo funciona con archivos tiff) presente en la carpeta /tmp.
cd /tmp
nano enviofax
Se añaden las siguientes lineas:
Channel: SIP/justvoip/0039XXXXXXXXXXX;el canal que se va a usar para efectuar la llamada
Callerid: "FAX"; el identificativo del llamante
WaitTime: 30
118
;Se espera un respuesta por 30 segundos
Maxretries:3:se intentará llamar el numero per tres veces
RetryTime: 300; entre un intento y otro se esperarán 300 segundos
Account: 1000; en el registro de las llamadas (CDR) cobramos la llamada a la extensión 1000
Application: SendFax; una vez que el destinatario conteste se ejecuta la aplicación sendfax
Data: /tmp/prueba.tif;el nombre del archivo que se enviará
El resultado del archivo sin los comentarios será:
Channel: SIP/justvoip/0039XXXXXXXXXXXCallerid: "FAX"WaitTime: 30Maxretries:3RetryTime: 300Account: 1000Application: SendFaxData: /tmp/prueba.tif
Se guardan los cambios y se mueve el archivo en la carpeta /var/spool/asteisk/outgoning
mv enviofax /var/spool/asterisk/outgoing
Este es el resultado en la consola de Asterisk:
Attempting call on SIP/justvoip/003907334445023 for application SendFax(/tmp/prueba.tif) (Retry 1) > Channel SIP/justvoip-084c82d0 was answered. > Launching SendFax(/tmp/prueba.tif) on SIP/justvoip2-084c82d0 [Nov 26 15:45:32] NOTICE[7630]: pbx_spool.c:357 attempt_thread: Call completed to SIP/justvoip2/003907334445023
Este es el correo electrónico recibido:
119
120
Capitulo VI
Asterisk Realtime
ARA (The Asterisk Realtime Architecture) es un método para almacenar los archivos de configuración de Asterisk en una base de datos. Existen dos tipos de realtime:
• Estático;• Dinámico;
El realtime estático se usa para guardar los archivos de configuración de Asterisk en una base de datos que Asterisk leerá al momento de iniciarse. El realtime dinámico se utiliza para guardar en la base de datos, “objetos” que se necesitan modificar y actualizar al instante: usuarios SIP o IAX2, las colas de espera y los agentes, los correo de voz. Los cambios se actualizarán en tiempo real en la base de datos y esta es la gran diferencia entre la versión estática y la dinámica. En la primera si se modifican los datos hay que recargar la configuración de Asterisk, en la segunda se leen, se escriben y se actualizan en tiempo real.
En este capitulo se presentarán algunos ejemplos de utilización del realtime en Asterisk.
6.1 Voicemail y ODBC
En Asterisk es posible almacenar los mensajes de voz en realtime dinámico usando una base de datos MySQL y el conector ODBC. Una vez configurada la base de datos se podrán hacer consulta desde cualquier tipo de programa que soporte ODBC.
Para averiguar si los módulos estén compilados y cargados en Asterisk desde la consola:
asterisk -rvvvvvvvvvvvvv
CLI> module show like odbc
Module Description Use Count res_config_odbc.so Realtime ODBC configuration 0 res_odbc.so ODBC resource 0 func_odbc.so ODBC lookups 0 cdr_adaptive_odbc.so Adaptive ODBC CDR backend 0 cdr_odbc.so ODBC CDR Backend 0 5 modules loaded
CLI> quit
La respuesta de Asterisk indica que todos los módulos están instalados. Si no fuera así hay que seguir este procedimiento:
Parar Asterisk y volver a compilarlo con el soporte ODBC de Voicemail
/etc/init.d/asterisk stop
Volver a compilar e instalar Asterisk
cd /usr/src/asterisk-1.6.0.22
make distclean./configuremake menuselect
Seleccionar la opción ODBC_STORAGE en el menú Voicemail
salir presionando la tecla X para guardar la configuración.
make make install
Volver a arrancar Asterisk y averiguar, a través de la consola, que aparezcan los módulos como mostrado arriba
/etc/init.d/asterisk start
Se crea la base de datos en MySQL y la tabla para guardar los mensajes de voz. Se crea la base de datos:
mysqladmin -u root -p create asteriskvoicela tabla voicemessages:
mysql -u root -psesamo
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 81
122
Server version: 5.0.45 Source distribution Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.
mysql> use asteriskvoice
Database changed
mysql> CREATE TABLE `voicemessages` ( `id` int(11) NOT NULL auto_increment, `msgnum` int(11) NOT NULL default '0', `dir` varchar(80) default '', `context` varchar(80) default '', `macrocontext` varchar(80) default '', `callerid` varchar(40) default '', `origtime` varchar(40) default '', `duration` varchar(20) default '', `mailboxuser` varchar(80) default '', `mailboxcontext` varchar(80) default'', `recording` longblob, PRIMARY KEY (`id`), KEY `dir` (`dir`) );
Query OK, 0 rows affected (0.13 sec)
Se crea un nuevo usuario y se le otorgan todos los privilegios para manejar la base de datos voicemail. Desde local:
Mysql> GRANT ALL PRIVILEGES ON asteriskvoice.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON asteriskvoice.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo'; Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
mysql> quit
ByeUna vez creada la base de datos, la tabla y el usuario que tiene los privilegios para administrarla, hay que configurar ODBC para que pueda conectarse a MySQL y a la base de datos recién creada. Para este efecto hay que crear dos archivo en la carpeta /etc:
nano /etc/odbcinst.ini
123
y se añaden estas líneas:
[MySQL] Description = ODBC for MySQL Driver = /usr/lib/libmyodbc3.so Setup = /usr/lib/libodbcmyS.so FileUsage = 1
nano /etc/odbc.ini
[asteriskvoice] Description = MySQL voicemail Driver = MySQL Database = asteriskvoiceServer = localhost User = asteriskPassword = sesamo Port = 3306 Option = 3
El archivo extconfig.conf es donde se configura el Realtime en Asterisk (estático y dinámico). Hay que modificarlo para indicar que los mensajes de voz se guardarán en una base de datos:
nano /etc/asterisk/extconfig.conf
Se añade en la parte final del archivo esta línea:
voicemail => odbc,asterisk,voicemessages
Se guardan los cambios y se sigue con la modifica del archivo voicemail.conf
nano /etc/asterisk/voicemail.conf
Hay que buscar las dos líneas que aparecen abajo y quitar el punto y coma que tienen por delante:
odbcstorage=asterisk odbctable=voicemessages
El valor del parámetros odbcstorace es el que se ha indicado en extconfig.conf y voicemessages es la tabla de la base de datos donde se guardarán los mensajes de voz.
Se guardan los cambios y se termina momificando el archivo res_odbc.conf que es el que se encarga de hacer la conexión entre Asterisk y ODBC:
nano /etc/asterisk/res_odbc.conf
124
Se añaden las siguientes lineas:
[asterisk] enabled => yes dsn => asteriskvoiceusername => asteriskpassword => sesamo pre-connect => yes
En dsn aparece la etiqueta que se ha configurado en el archivo odbc.ini.
Se vuelve a arrancar Asterisk:
/etc/init.d/asterisk restart
y se averigua que la conexión esté funcionando:
asterisk -rvvvvvvvvvvvvvvvv
CLI> odbc show
ODBC DSN Settings ----------------- Name: asterisk DSN: asteriskvoice Pooled: No Connected: Yes
Para probar configuración se llama una extensión y se deja un mensaje en el contestador.
Ahora en un computador con Windows XP/2000/Vista y Microsoft Excel o Microsoft Access se va a crear una conexión a la base de datos.
Primero hay que abrir el puerto 3306 TCP en el cortafuego de Linux añadiendo la siguiente linea en la seccion *filter:
nano /etc/sysconfig/iptables
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
Se reinicia iptables:
service iptables restart
Luego hay que instalar el conector mysql para ODBC versión Windows. Se descarga, según la versión de Windows, desde esta pagina:
125
http://dev.mysql.com/downloads/connector/odbc/3.51.html
Terminada la descarga se instala.
Microsoft Excel
Se abre el Excel y en el menú datos se selecciona Obtener datos externos > Nueva consulta de base de datos:
Se selecciona <Nuevo origen de datos> y se presiona el botón Aceptar:
Se escoge un nombre para la origen de datos y se escoge el tipo:
126
Se indican los datos necesarios (host del servidor Mysql - usuario, contraseña y nombre de la base de datos)
127
Se regresa a la ventana precedente y se selecciona la tabla > voicemessages y Aceptar
En la ventana que aparece se escoge Asterisk-voicemail y se presiona Aceptar
Se escogen las columnas que se quieren incluir en la consulta:
128
y si se quiere se puede filtrar los datos:
Se ordenan los datos:
129
Se devuelven a Microsoft Excel:
Ahora los registros de la base de datos aparecerán en Excel:
130
Microsoft Access
Se arranca Microsoft Access y se crea un nuevo archivo > base de datos en blanco
Obtener datos externos > Importar
131
Se escoge en la lista “base de datos ODBC”
132
Asterisk-Voicemal.dsn (que encontramos ahí porque ya la hemos creada con Excel)
Se ponen los mismos datos de conexión usados por Excel:
133
Se escoge la tabla voicemessages:
Este es el resultado:
6.2 ODBC y CDR
En este párrafo se mostrará como guardar los registros de las llamadas (que ya hemos almacenado en una base de datos MySQL) utilizando ODBC. No es propiamente una configuración realtime pero puede ser útil para luego consultar los datos desde otras aplicaciones.
Se modifica el archivo odbc.ini:
134
nano /etc/odbc.ini
y se añaden estas líneas:
[asteriskcdr] Description = MySQL ODBC Driver Testing Driver = MySQL Database = asteriskcdrServer = localhost User = asterisk Password = sesamoOption = 3 Port = 3306
Se guardan los cambios y se continua con el archivo res_odbc.conf:
nano /etc/asterisk/res_odbc.conf
[asterisk2] enabled = yes dsn = asteriskcdr username = asterisk password = sesamologuniqueid = yes pre-connect = yes
Se termina con:
nano /etc/asterisk/cdr_odbc.conf
[global] dsn=asterisk2 username=asterisk password=sesamologuniqueid=yes table=cdr usegmtime=no
Se guardan los cambios y se reinicia Asterisk
/etc/init.d/asterisk restart
En el archivo de registro se encontrarán estas líneas:
[Dec 9 15:09:09] NOTICE[3976] res_odbc.c: Connecting asterisk2 [Dec 9 15:09:09] NOTICE[3976] res_odbc.c: res_odbc: Connected to asterisk2 [asterisk-cdr]
135
[Dec 9 15:09:09] NOTICE[3976] res_odbc.c: Registered ODBC class ‘asterisk2’ dsn->[asterisk-cdr]
y desde la consola de Asterisk se averigua que haya conexión
asterisk -rvvvvvvvvvvvvvvvvvvv
CLI> odbc show
ODBC DSN Settings ----------------- Name: asterisk2 DSN: asteriskcdr Pooled: No Connected: Yes Name: asterisk DSN: asteriskvoice Pooled: No Connected: Yes
Ahora se pueden hacer consultas a la base de datos (desde microsoft access, por ejemplo) y sacar todas las estadísticas y/o reportes que queramos.
6.3 MeetME Realtime
Para la configuración de las conferencias se puede usar el archivo de configuración que se ha visto en el parrafo 2.12 o se puede optar para la solución en Realtime. En Realtime la ventaja es poder programar las conferencias con fecha y hora directamente en la base de datos. En el caso del Realtime hay que crear una base de datos:
mysqladmin create asteriskmeetme -u root -psesamo
Desde en el cliente mysql:
mysql -u root -psesamo
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 47897 Server version: 5.1.37 MySQL Community Server (GPL) by Remi Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.
mysql> use asteriskmeetme
Database changed
Se crea la tabla meetme:
136
mysql> CREATE TABLE `meetme` ( `confno` char(80) NOT NULL default '0', `starttime` datetime NOT NULL default '0000-00-00 00:00:00', `endtime` datetime default NULL, `pin` char(20) default NULL, `opts` char(100) default NULL, `adminpin` char(20) default NULL, `adminopts` char(100) default NULL, `members` int(11) NOT NULL default '0', `maxusers` int(11) NOT NULL default '0', PRIMARY KEY (`confno`,`starttime`) );
Query OK, 0 rows affected (0.01 sec)
Se configuran los privilegios para la base de datos asteriskmeetme:
mysql> GRANT ALL PRIVILEGES ON asteriskmeetme.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo';
mysql> GRANT ALL PRIVILEGES ON asteriskmeetme.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Se introducen algunos datos de prueba en la tabla:
mysql> INSERT INTO meetme (confno,pin,adminpin,members,starttime,endtime) VALUES ("5000","1234","2345","0","2009-09-24 19:00","2009-09-24 20:00");
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO meetme (confno,pin,adminpin,members,starttime,endtime) VALUES ("5001","1234","2345","0","2009-09-25 19:00","2009-09-25 20:00");
Query OK, 1 row affected (0.00 sec)
y se sale del cliente MySQL
mysql> quit
Bye
Con estos datos se han programado dos conferencias:
137
• la 5000 que iniciará a las 7 de la tarde del 24 de septiembre del 2009 y terminará a las 8 de la tarde del mismo día;
• la 5000 que iniciará a las 7 de la tarde del 25 de septiembre del 2009 y terminará a las 8 de la tarde del mismo día;
Ahora la configuración de ODBC y Asterisk
nano /etc/odbc.ini
se añaden estas líneas:
[asteriskmeetme] Description = MySQL connection to ‘asteriskmeetme’ database Driver = MySQL Database = asteriskmeetme Server = localhost User =asterisk Password = sesamo Port = 3306 Option = 3
Se guardan los cambios y se modifica el archivo res_odbc.conf
nano /etc/asterisk/res_odbc.conf
[asterisk3] enabled = yes dsn = asteriskmeetme username = asterisk password = sesamologuniqueid = yes pre-connect = yes
Se guardan los cambios y se pasa al archivo extconfig.conf
nano /etc/asterisk/extconfig.conf
se añade esta línea en el bloque realtime:
meetme => odbc,asterisk3,meetme
Se modifica el dialplan para dar acceso a las dos conferencias creadas en la base de datos:
nano /etc/asterisk/extensions.conf
en el contexto conferencias ponemos:
138
exten => _500[01],1,Meetme(${EXTEN},M) exten => _500[01],n,Hangup
Para usar las conferencias en realtime hay que modificar el archivo meetme.conf
nano /etc/asterisk/meetme.conf
modificar este parámetro:
shedule= no
para ponerlo en yes
schedule=yesSe guardan los cambios y reinicia Asterisk:
/etc/init.d/asterisk restart
Algunas locuciones relacionadas con las conferencias programadas no están disponibles con la instalación de Asterisk. Hay que descargarlas (en inglés) de este enlace:
http://www.voztovoice.org/tmp/confprompts.tar
Se descomprime el archivo y se copian las locuciones en la carpeta /var/lib/asterisk/sounds/en
En el campo “members” de la tabla meetme se almacenarán dinámicamente los usuarios presentes en la conferencia.
139
Capitulo VII
Asterisk y TTS (text to speech)
7.1 Festival
Festival en un TTS48, es decir un sistema de síntesis de voz. ¿Para que lo necesitamos en Asterisk? Si se quiere crear un menú de voz usando lineas de texto, leer archivos de texto, Festival es la solución.
Para averiguar que el modulo de festival esté correctamente cargado en Asterisk, desde la consola de la centralita:
asterisk -rvvvvvvvvvvvvvvv
CLI> module unload app_festival
== Unregistered application ‘Festival’
CLI> module load app_festival
== Parsing ‘/etc/asterisk/festival.conf’: == Found == Registered application ‘Festival’ Loaded app_festival => (Simple Festival Interface)
CLI> quit
Si aparece algún tipo de error significa que el modulo no ha sido compilado y hay que volver a la compilación de Asterisk.
Festival tiene como idioma predefinido el inglés. Para agregarle el idioma español hay que seguir estos pasos:
cd /usr/share/festival/voices
wget http://www.voztovoice.org/tmp/festival-spanish.zip
yum install unzip
unzip festival-spanish.zip
Ahora se modifica el archivo de configuración de festival
nano /usr/share/festival/festival.scm
48 Festival es un sistema de síntesis de voz de propósito general para múltiples lenguajes desarrollado originalmente por el Centro de Investigación de Tecnologías del Lenguaje de la Universidad de Edinburgo, la Universidad Carnegie Mellon así como otros centros de enseñanza han realizado contribuciones substanciales al proyecto.
se añaden estas líneas antes de la ultima linea del archivo
;(language__spanish)(set! voice_default 'voice_el_diphone)
(define (tts_textasterisk string mode) "(tts_textasterisk STRING MODE) Apply tts to STRING. This function is specifically designed for use in server mode so a single function call may synthesize the string. This function name may be added to the server safe functions." (let ((wholeutt (utt.synth (eval (list 'Utterance 'Text string))))) (utt.wave.resample wholeutt 8000) (utt.wave.rescale wholeutt 5) (utt.send.wave.client wholeutt)))
Se guardan los cambios en el archivo y se modifica el archivo de configuración de festival en Asterisk:
nano /etc/asterisk/festival.conf
estas son la líneas que hay que modificar/activar
[general] host=localhost port=1314 festivalcommand=(tts_textasterisk "%s" 'file)(quit)\n
Se guarda el archivo con Ctrl-O Ctrl-X
Se reinicia Asterisk
/etc/init.d/asterisk reload
Para arrancar el servidor de Festival en automático se pone esta línea en el archivo rc.local:
nano /etc/rc.local
/usr/bin/festival_server > /dev/null &
Se inicia el servidor festival;
/usr/bin/festival_server > /dev/null &
Se controla que esté corriendo:
ps aux | grep festival
141
Se modifica el Dialplan para crear una extensión que permita hacer una prueba del servidor Festival (en el contexto internas):
nano /etc/asterisk/extensions.conf
exten => 650,1,Answer() exten => 650,n,Festival(Asterisk y Festival trabajan junto. Chevere!!!) exten => 650,n,Hangup()
Se actualiza el dialplan desde la consola
asterisk -rvvvvvvvvvvvvvvvvv
CLI> dialplan reload
Desde un softphone conectado a Asterisk se marca la extensión 650 para escuchar la frase que se acaba de configurar en el dialplan.
7.2 Cepstral
Cepstral49 es otro sistema TTS que se puede integrar en Asterisk (versión 1.4.X y 1.6.X) gracias a un modulo dedicado. Cepstral no es un programa gratuito y cada voz cuesta 29,99 dólares por canal.
Se descarga una voz de prueba desde el sitio de Cepstral
cd /opt
wget http://downloads.cepstral.com/cepstral/i386-linux/Cepstral_Marta-8kHz_i386-linux_5.1.0.tar.gz
Se descomprime
tar -xf Cepstral_Marta-8kHz_i386-linux_5.1.0.tar.gz
y se instala
cd Cepstral_Marta-8kHz_i386-linux_5.1.0
./install.sh
Se aceptan los términos de la licencia, se escoge la carpeta /opt/swift para la instalación y se confirman los datos.
Para que Linux sepa donde ir a buscar las librerías de Cepstral hay que indicarselo modificando el
49 Cepstral
142
archivo ld.so.conf
nano /etc/ld.so.conf
se añade esta línea:
/opt/swift/lib
Se guardan los cambios y se actualizan las librerías:
ldconfig -v
Una vez instalada la voz de Cepstral hay que compilar y instalar el modulo para Asterisk:
cd /usr/src
wget http://www.voztovoice.org/tmp/app_swift-1.6.2.tar.gz
se descomprime:
tar -xf app_swift-1.6.2.tar.gz
Se entra en la carpeta:
cd app_swift-1.6.2
Se compila e instala:
makemake install
Se reinicia Asterisk:
/etc/init.d/asterisk restart
y se averiguas que el modulo esté cargado:
asterisk -rvvvvvvvvvvv
CLI> module show like app_swift
Module Description Use Count app_swift.so Cepstral Swift TTS Application 0 1 module loaded
La sinopsis del comando
143
CLI> core show application swift
-= Info about application ‘Swift’ =-
[Synopsis] Speak text through Swift text-to-speech engine. [Description] Syntax: Swift(text[|timeout in ms|maximum digits]) Example: Swift(Hello World|5000|5) = 5 second delay between 5 digits This application operates in two modes. One is processing text-to-speech while listening for DTMF and the other just processes the text-to-speech while ignoring DTMF entirely. Unless the timeout and maximum digits options are BOTH specified, the application will automatically ignore DTMF. Returns -1 on hangup or 0 otherwise.
Se sale de la consola de Asterisk:
CLI> quit
En la carpeta donde están los archivos de configuración de Asterisk se habrá creado un nuevo archivo: swift.conf. Hay que modificarlo para terminar la integración de Cepstral en Asterisk:
nano /etc/asterisk/swift.conf
[general]buffer_size=65535goto_exten=yesvoice=Marta-8kHz
Se guardan los cambios y se actualiza Asterisk:
/etc/init.d/asterisk restart
Para probar la instalación, hay que crear algunas lineas en en el dialplan, contexto internas:
nano /etc/asterisk/extensions.conf
exten => 660,1,Answer() exten => 660,n,Playback(welcome) exten => 660,n,Swift(En el centro de comunicaciones de VoztoVoice. Espere mientras lo conectamos con una operadora)exten => 660,n,Wait(2) exten => 660,n,Hangup
Se actualiza el dialplan:
144
asterisk -rvvvvvvvv
CLI> dialplan reload
Desde un softphone se marca el numero 660.
145
Capitulo VIII
Conexiones entre servidores Asterisk
8.1 Conectar dos servidores Asterisk con el protocolo SIP
Hay dos servidores Asterisk, A y B, y se quieren conectar entre ellos usando el protocolo SIP para llamar desde A las extensiones de B y desde B las extensiones de A; además en el servidor A está configurado un proveedor de llamadas VoIP para Colombia y desde B se quiere redirigir todas las llamadas para Colombia hacia ese proveedor. Las extensiones del servidor A y del servidor B no pueden ser iguales porque sino no sería posible transferir las llamadas de un servidor a otro. En este escenario en el servidor A las extensiones son de 4 cifras y empiezan por 1, en el servidor B son de 4 cifras y empiezan por 4.
Servidor A (vozcom)
nano /etc/asterisk/sip.conf
Se añade:
register => vozcom:[email protected]/voznet
[voznet] type=friend secret=contraseña context=phones qualify=yes host=dynamic language=es disallow=all allow=gsm allow=ulaw allow=alaw
Con la línea de register, se conecta el servidor vozcom al servidor voznet. Con las líneas que están después de la etiqueta [voznet] se define una extensión SIP que será aquella usada por el servidor B para conectarse al servidor A.
Servidor B (voznet)
nano /etc/asterisk/sip.conf
Se añade::
register => voznet:[email protected]/vozcom
[vozcom]
type=friend secret=contraseña context=phones host=dynamic language=es qualify=yes disallow=all allow=gsm allow=ulaw allow=alaw
Ahora que los dos servidores están configurados hay que reiniciarlos. En los dos se escribe el comando:
/etc/init.d/asterisk restart
Desde la consola se averigua que haya conexión entre los dos servidores:
para el servidor A (vozcom):
CLI> sip show registry
sip.voztovoice.net:5060 vozcom 105 Registered Mon, 15 Dec 2008 09:57:39
CLI> sip show peers
voznet/vozcom 67.18.186.202 D 5060 OK (34 ms)
para el servidor B (voznet)
CLI> sip show registry
sip.voztovoice.com:5060 Y voznet 105 Registered Mon, 15 Dec 2008 10:00:32
CLI> sip show peers
vozcom/voznet 209.20.72.171 D 5060 OK (34 ms)
Ahora lo único que hace falta es modificar el archivo extensions.conf de ambos servidores.
Servidor AEn el contexto internas (para las llamadas a extensiones del servidor B) se añade:
exten => _4XXX,1,NoOp() exten => _4XXX,n,Dial(SIP/voznet/${EXTEN},30) exten => _4XXX,n,Hangup()
Con estas líneas se configura Asterisk para que todas las llamadas con destino las extensiones cuyo
147
numero empiece por 4 y sea de 4 cifras sean redirigidas hacia voznet (servidor B)
Servidor BEn el contexto internas (para las llamadas a extensiones del servidor A) se añade:
exten => _1XXX,1,NoOp() exten => _1XXX,n,Dial(SIP/vozcom/${EXTEN},30) exten => _1XXX,n,Hangup()
Para las llamadas a Colombia (en el contexto externas) se pone:
exten => _0057.,1,Dial(SIP/vozcom/${EXTEN},30)exten => _0057.,n,Hangup
Con estas dos línea se define que todas las llamadas para Colombia sean direccionadas hacia al servidor A
Actualizamos la configuración en los dos servidores:
asterisk -rvvvvvvvvvvvvvvv
CLI> dialplan reload
Esta configuración es una buena solución si no tenemos muchos servidores Asterisk que conectar entre ellos. En caso contrario es más conveniente usar el protocolo DUNDi que se verá en el párrafo 8.3
8.2 Conectar dos Servidor Asterisk con el protocolo IAX2
En este párrafo se mostrará como conectar dos servidor Asterisk a través del protocolo IAX2. La ventaja de IAX2 está en su característica, llamada trunking, que utiliza el mismo encabezado (header) para el envío del audio de todas las llamadas. De esta forma cuando hay un numero considerable de llamadas que estén pasando por el trunk, hay un notable ahorro de banda. Otra ventaja es que la señalización y los datos audio/video pasan por el mismo puerto (UDP 4569), anulando en la practica los típicos problemas de NAT que “padece” el protocolo SIP.
Se usarán dos VPS alquilados con la empresa Linode. Es importante que los dos estén en el mismo centro de datos porque de esta forma hay la posibilidad de conectarlos como si estuvieran en la misma red local. Los datos que pasan a través de la LAN no vienen contabilizados para el calculo del consumo de banda.
Desde la pagina de administración de Linode se verán los VPS alquilados:
148
Es importante que en “location” aparezca el mismo centro de datos (en este ejemplo Dallas). Se selecciona el primer VPS y se va al menú Network. En private IP settings se activa la dirección IP de la red local. Ahora hay que crear una tarjeta de red virtual para la dirección IP asignada (192.168.142.246). Se abre una conexión ssh con el VPS y se siguen estos pasos:
nano /etc/sysconfig/network-scripts/ifcfg-eth0:1
Se añaden estas lineas:
DEVICE=eth0:1BOOTPROTO=noneONBOOT=yesIPADDR=192.168.142.246NETMASK=255.255.128.0
Se guardan los cambios y se vuelve a arrancar la red:
service network restart
Con el comando ifconfig debe aparecer:
Ahora se sigue el mismo procedimiento para el segundo VPS. Al terminar se empieza con la configuración de los dos servidores Asterisk.
Servidor A:Version Asterisk: 1.6.0.17IP: 192.168.142.248usuario: vozcomExtensiones: 3000-3099
149
Servidor B:Version Asterisk: 1.4.26.2IP: 192.168.142.246usuario: vozorgExtensiones: 6000-6099
Configuración del servidor A
nano /etc/asterisk/iax.conf
En el bloque register:
register => vozcom:[email protected]
El usuario:
[vozorg]type=friendhost=dynamictrunk=yessecret=passwordBcontext=phonesdeny=0.0.0.0/0.0.0.0permit=192.168.142.246/255.255.255.255qualify=yes
nano /etc/asterisk/extensions.conf
en el contexto internas:
[internas]exten => _60XX,1,Dial(IAX2/vozorg/${EXTEN})exten => _60XX,n,Hangup
asterisk –rvvvvvvvvvvvvvvv
CLI> iax2 reload
CLI> dialplan reload Servidor B:
nano /etc/asterisk/iax.conf
En el bloque register:
register => vozorg:[email protected]
150
El usuario:
[vozcom]type=friendhost=dynamictrunk=yessecret=passwordAcontext=phonesdeny=0.0.0.0/0.0.0.0permit=192.168.142.248/255.255.255.255qualify=yes
nano /etc/asterisk/extensions.conf
en nuestro contexto internas:
[internas]exten => _30XX,1,Dial(IAX2/vozcom/${EXTEN})exten => _30XX,n,Hangup
asterisk –rvvvvvvvvvvvvvvv
CLI> iax2 reload
CLI> dialplan reload
Ya se pueden hacer pruebas llamando del servidor A las extensiones del servidor B y viceversa.
8.3 DUNDi
Cuando hay que conectar un numero considerable de servidores Asterisk y compartir las rutas y las extensiones configuradas en cada uno de ellos, la solución más funcional es el protocolo DUNDi. DUNDi (Distributed Universal Number Discovery) es un protocolo que permite buscar y compartir plan de llamadas entre servidores Asterisk. Esto por medio de una red Peer-to-peer (punto-a-punto) en la cual no existen roles fijos de clientes y servidores, sino que los servidores pueden asumir uno u otro rol según el contexto.
A lo largo de la configuración se puede decidir si compartir contextos ya configurados en el Dialplan (plan de llamadas) o crear contextos nuevos donde se indican las rutas que se quieren compartir. Aunque la configuración y puesta en marcha pueda parecer algo complicado, con un poco de practica se irán aclarando las ideas y los conceptos claves.
El puerto predefido para el protocolo DUNDi es el 4520 UDP. Hay que abrirlo en el cortafuegos:
nano /etc/sysconfig/iptables
151
en la seccion *filter
-A INPUT -p udp -m udp --dport 4520 -j ACCEPT
Se guardan los cambios y se reinicia Iptables:
service iptables restart
En el escenario que se presenta en este párrafo hay dos servidores Asterisk con estas características:
Servidor A:Version Asterisk: 1.6.0.17IP: 192.168.142.248usuario: vozcomExtensiones: 2000-2999
Servidor B:Version Asterisk: 1.4.26.2IP: 192.168.142.246usuario: vozorgExtensiones: 6000-6099
Los dos servidores están en la misma LAN pero pueden estar ubicados en cualquier parte del mundo.
Con la configuración del archivo dundi.conf se definen los parámetros de conexión entre los servidores Asterisk y los contextos que se van a compartir. En el mismo archivo se define el tipo de protocolo que los dos servidores usarán para efectuar y recibir llamadas una vez que se haya encontrado la ruta (puede ser IAX2, SIP o H323). Por ultimo se modifica el Dialplan (plan de llamadas) para definir en los contextos configurados en dundi.conf, cuales son las rutas o contextos que se quiere compartir.
Servidor A
nano /etc/asterisk/dundi.conf
[general] ; desde esta etiqueta empieza la configuración general de DUNDi
department=VozComorganization=VozComlocality=Santa Martastateprov=Magdalenacountry=Colombiaemail=admin@servidorA.comphone=+57XXXXXXXXXX; se indican los datos de la empresa y de contacto
bindaddr=0.0.0.0
152
; direccion IP del servidor Asterisk o si se deja en 0.0.0.0 todos los IP disponibles en el servidor
port=4520; puerto predefinido usado por el protocolo DUNDi.
entityid=FE:FD:45:A4:C5:68; el MAC address de la tarjeta de red que se va a usar para la conexión
cachetime=3600; cuando se envía un solicitud para conocer la disponibilidad de una ruta y se encuentra una disponible, el resultado se guardará por el tiempo definido en este parámetro (en segundos) en la base de datos interna de Asterisk.
ttl=32;Time to Live es un numero que representa el tiempo de vida de la solicitud. Más alto el numero más nodos se alcanzará a consultar.
autokill=yes; si no se recibe una respuesta dentro de 2000 ms de un servidor conectado a la red DUNDi se anulará la solicitud. Esto permite evitar que las solicitudes queden colgadas en algún punto de la red.
secretpath=dundi; el modulo pbx_dundi crea una clave que rotará de manera automática y que se guardará en la base de datos interna de Asterisk.
storehistory=yes; mantiene un registro de las ultimas solicitudes efectuadas con los tiempos de respuesta de cada una. De esta forma es posible averiguar cuales son los nodos lentos dentro de la red DUNDi
[mappings]; desde esta etiqueta empieza el mapeo de los contextos DUNDi con los contextos presentes en el servidor Asterisk. Las sintaxis para definir los contextos es:
; dundi_context => local_context,weight,tech,dest[,options]]
• dundi_context – el contexto DUNDi que se quiere compartir con los demás nodos de la red DUNDi
• local_context – el contexto local definido en el plan de llamadas donde se configuran las rutas o extensiones que se quieren compartir
• weight – el peso que damos a las rutas que compartimos. Si son extensiones locales se pone 0, si son rutas por la cuales no tenemos una conexión directa o de alta calidad ponemos un numero más alto. Al momento de hacer una solicitud si para el mismo numero requerido existen distintas rutas, se escogerá la ruta con menor peso
• tech – protocolo usado para la conexión entre servidores Asterisk (se usará IAX2)• dest – cuando se hace una solicitud desde el servidor B y se encuentra una ruta en el Servidor
A, el Servidor A usará esta destinación para recibir la llamada. Simplificando: se crea un user en
153
el iax.conf del servidor Asterisk A y dest representa los paramentos para conectarse a ese user y a través de la conexión recibir las llamadas del servidor B
• options – son las distintas opciones que se pueden añadir por cada contexto DUNDi
• nounsolicited – llamadas de cualquier tipo que no sean solicitadas no son permitidas en esta ruta
• nocomunsolicit – llamadas comerciales no solicitadas no son permitidas en esta ruta• residential – el numero es de una residencia• commercial – el numero es de una empresa• mobile – el numero es un celular• nopartial – no se harán búsquedas por números que no sean completos
la ruta definida para el servidor A será:
vozcom => vozcom-local,0,IAX2,vozcom:${SECRET}@192.168.142.248/${NUMBER}
• vozcom: el contexto DUNDi que se va a compartir• vozcom-local: el contexto definido en el plan de llamadas que contendrá todas las rutas que se
van a compartir• IAX2: la tecnología usada (protocolo) para las llamadas• vozcom: usuario que se configurará en el el archivo iax.conf• ${SECRET}: es la variable que contiene la clave que el modulo DUNDi crea en automático y
que se usará para autenticar el usuario vozcom• 192.168.142.248: dirección IP del Servidor A• ${NUMBER}: la variable que contendrá el numero que ha sido solicitado.
Para terminar con la configuración del archivo dundi.conf se definen los servidores Asterisk con los se va a tener una conexión directa:
[FE:FD:45:A4:C4:49]model = symmetrichost = 192.168.142.246inkey = vozorgoutkey = vozcominclude = allpermit = vozcomqualify = yes
• FE:FD:45:A4:C4:48: MAC address de la tarjeta de red de Servidor Asterisk B con el que se crea la conexión
• model: puede ser:• inbound: recibe solamente solicitudes• outbound: solo efectúa solicitudes pero no las recibe• symmetric: recibe y efectúa solicitudes
• host: direccion IP o nombre de dominio del servidor Asterisk B
154
• inkey: clave RSA usada para autenticarse con el servidor Asterisk B• outkey: clave RSA usada por el Servidor Asterisk B para autenticarse con el Servidor Asterisk
A• include: incluye esta conexión para todas las solicitudes efectuadas en Servidor Asterisk A• permit: se definen los contextos DUNDi a los que tendrá acceso este nodo• qualify: se controlará periódicamente que la conexión con el nodo esté activa
Se guardan los cambios y se crea la clave RSA para autenticar el Servidor Asterisk B. Para crear la clave se usará una utilidad que viene con la instalación de asterisk. Primero entramos en la carpeta donde se guardan las claves:
cd /var/lib/asterisk/keys
Se crea la clave:
astgenkey -n vozcom
This script generates an RSA private and public key pairin PEM format for use by Asterisk. You will be asked toenter a passcode for your key multiple times. Pleaseenter the same code each time. The resulting files willneed to be moved to /var/lib/asterisk/keys if you wantto use them, and any private keys (.key files) willneed to be initialized at runtime either by runningAsterisk with the '-i' option, or with the 'init keys'command once Asterisk is running.
Press ENTER to continue or ^C to cancel.
Presionamos la tecla envío:
Generating SSL key 'vozcom':Generating RSA private key, 1024 bit long modulus.....................................++++++.............++++++e is 65537 (0x10001)writing RSA keyKey creation successful.Public key: vozcom.pubPrivate key: vozcom.key
Se crearán dos claves, una publica y una privada. La publica se copia en el Servidor Asterisk B:
scp vozcom.pub [email protected]:/var/lib/asterisk/keys
Ahora se puede añadir el usuario vozcom al archivo iax.conf
155
nano /etc/asterisk/iax.conf
Se añaden las siguientes lineas en el bloque dedicado a la configuración de las extensiones:
[vozcom]type=userdbsecret=dundi/secretcontext=vozcom-localqualify=yesdisallow=allallow=ulawallow=alaw
Importante definir el parámetro context con el valor del contexto que hemos definido en nuestra ruta (vozcom-local)
El ultimo archivo que hay que modificar es el plan de llamadas:
nano /etc/asterisk/extensions.conf
Se crea el contexto vozcom-local y se incluyen en él las rutas que se quieren compartir (las extensiones locales y una ruta para las llamadas a Colombia)
[vozcom-local]exten => _0057.,1,Dial(SIP/justvoip/${EXTEN})exten => _2XXX,1,Dial(SIP/${EXTEN},15)exten => _2XXX,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)exten => _2XXX,n(busy),Voicemail(${EXTEN}@default,b)exten => _2XXX,n,Hangupexten => _2XXX,n(unavail),Voicemail(${EXTEN}@default,u)exten => _2XXX,n,Hangup
Para las solicitudes remotas creamos otro contexto:
[dundi-remoto]switch => DUNDi/vozorg
el nombre vozorg es el contexto DUNDi que luego se creará en el Servidor Asterisk B
Añadimos el contexto dundi-remoto a la lista de contextos disponibles para la extensiones configuradas en el Servidor Asterisk A:
[phones]include => internasinclude => externasinclude => subscribe
156
include => parkedcallsinclude => conferenciasinclude => dundi-remoto
Se guardan los cambios y se continúa con la configuración del Servidor Asterisk B
Servidor B
nano /etc/asterisk/dundi.conf
[general]
department=VozOrgorganization=VozOrglocality=Santa Martastateprov=Magdalenacountry=Colombiaemail=admin@servidorB.comphone=+57XXXXXXXXbindaddr=0.0.0.0port=4520entityid=FE:FD:45:A4:C4:48cachetime=3600ttl=32autokill=yessecretpath=dundistorehistory=yes
[mappings]vozorg => vozorg-local,0,IAX2,vozorg:${SECRET}@192.168.142.246/${NUMBER}
[FE:FD:45:A4:C5:68]model = symmetrichost = 192.168.142.248inkey = vozcomoutkey = vozorginclude = allpermit = vozorgqualify = yes
Se crea la clave RSA:
cd /var/lib/asterisk/keys
astgenkey -n vozorg
This script generates an RSA private and public key pair
157
in PEM format for use by Asterisk. You will be asked toenter a passcode for your key multiple times. Pleaseenter the same code each time. The resulting files willneed to be moved to /var/lib/asterisk/keys if you wantto use them, and any private keys (.key files) willneed to be initialized at runtime either by runningAsterisk with the '-i' option, or with the 'init keys'command once Asterisk is running.
Press ENTER to continue or ^C to cancel.
Presionamos la tecla envío:
Generating SSL key 'vozorg':Generating RSA private key, 1024 bit long modulus.....................................++++++.............++++++e is 65537 (0x10001)writing RSA keyKey creation successful.Public key: vozorg.pubPrivate key: vozorg.key
Se copia en el Servidor Asterisk A
scp vozorg.pub [email protected]:/var/lib/asterisk/keys
nano /etc/asterisk/iax.conf
[vozorg]type=userqualify=yesdbsecret=dundi/secretcontext=vozorg-localdisallow=allallow=ulawallow=alaw
Para terminar se modifica el plan de llamadas:
nano /etc/asterisk/extensions.conf
[vozorg-local]exten => _60XX,1,Dial(SIP/${EXTEN})
[dundi-remoto]switch => DUNDi/vozcom
158
Se incluye el contexto dundi-remoto de forma que sea accesible a las extensiones
Una vez terminada la configuración del Servidor Asterisk B en ambos se reinicia la PBX:
/etc/init.d/asterisk restart
Se entra en la consola del servidor Asterisk A:
asterisk -rvvvvvvvvvvvv
miramos la lista de comandos disponibles para DUNDi
CLI> help dundi
dundi flush [stats] Flush DUNDi cache dundi lookup Lookup a number in DUNDi dundi precache Precache a number in DUNDi dundi query Query a DUNDi EID dundi set debug {on|off} Enable/Disable DUNDi debugging dundi show entityid Display Global Entity ID dundi show mappings Show DUNDi mappingsdundi show peers [registered|i Show defined DUNDi peers dundi show peer Show info on a specific DUNDi peer dundi show precache Show DUNDi precache dundi show requests Show DUNDi requests dundi show trans Show active DUNDi transactions dundi store history {on|off} Enable/Disable DUNDi historic records Primero se controla que haya conexión entre los dos servidores:
CLI> dundi show peers
EID Host Model AvgTime Statusfe:fd:45:a4:c4:48 192.168.142.246 (S) Symmetric Unavail OK (1 ms)
Con el comando:
CLI> database show
/dundi/secret : qotQe+Vp1B2G7S9yoizlPA==;3obGb1QtvkUeciZs7rH5CA==/dundi/secretexpiry : 1259212403
aparecerá la clave creada por el modulo pbx_dundi y el tiempo que falta para que caduque.
Ahora se puede hacer la primera consulta para controlar que efectivamente las rutas se están compartiendo:
159
CLI> dundi lookup 6099@vozorg
1. 0 IAX2/vozorg:[email protected]/6099 (EXISTS|CANMATCH) from fe:fd:45:a4:c4:49, expires in 2982 sDUNDi lookup completed in 0 ms
En el servidor Asterisk B las extensiones compartidas van de 6000 a 6099 y efectivamente enviando la solicitud la respuesta es que la extensión existe. En el comando ademas de la extensión va indicado el contexto como lo hemos definido en el bloque mappings del dundi.conf del servidor Asterisk B.
Si se envía una solicitud para una ruta que no existe la respuesta será:
CLI> dundi lookup 6100@vozorg
DUNDi lookup returned no results.DUNDi lookup completed in 2 ms
Se hace otra solicitud de prueba desde el Servidor Asterisk B
CLI> dundi lookup 2100@vozcom
1. 0 IAX2/vozcom:[email protected]/2100 (EXISTS) from fe:fd:45:a4:c5:69, expires in 2624 sDUNDi lookup completed in 0 ms
Solicitud para un numero colombiano:
CLI> dundi lookup 0057123456789@vozcom 1. 0 IAX2/vozcom:[email protected]/0057123456789 (EXISTS|MATCHMORE|CANMATCH) from fe:fd:45:a4:c5:69, expires in 3600 sDUNDi lookup completed in 39 ms
Para terminar las pruebas se conecta un softphone al servidor Asterisk B y se intenta llamar la extesion 2100 (que es presente en el servidor Asterisk A)
Esto es lo que aparece en la consola de Asterisk del servidor A:
Accepting AUTHENTICATED call from 192.168.142.246: > requested format = ulaw, > requested prefs = (ulaw|alaw), > actual format = ulaw, > host prefs = (ulaw|alaw), > priority = mine -- Executing [2100@vozcom-local:1] Dial("IAX2/vozcom-1213", "SIP/2100,15") in new stack == Using SIP RTP TOS bits 184
160
== Using SIP RTP CoS mark 5 == Using SIP VRTP TOS bits 136 == Using SIP VRTP CoS mark 4 == Using UDPTL TOS bits 184 == Using UDPTL CoS mark 5[Nov 26 00:06:39] WARNING[6087]: app_dial.c:1499 dial_exec_full: Unable to create channel of type 'SIP' (cause 20 - Unknown) == Everyone is busy/congested at this time (1:0/0/1) -- Executing [2100@vozcom-local:2] GotoIf("IAX2/vozcom-1213", "0?busy:unavail") in new stack -- Goto (vozcom-local,2100,5) -- Executing [2100@vozcom-local:5] VoiceMail("IAX2/vozcom-1213", "2100@default,u") in new stack
La llamada llega desde la IP del servidor Asterisk B y va al contexto vozcom-local (las rutas compartidas). Como la extensión 2100 no está disponible la llamada entra el contestador.
Las potencialidades del protocolo DUNDi son prácticamente infinitas y este párrafo se han presentado las herramientas básicas para empezar a utilizar.
161
Capitulo IX
Openfire y Asterisk
9.1 Instalación de Openfire
Openfire es un servidor jabber50. Con Openfire instalado se tendrá un nuestro servidor de mensajería instantánea sin tener que acudir a servicios de terceros. Esto implica tener una red de mensajería instantánea segura, fácilmente manejable y segura gracias al uso del protocolo TLS51. ¿Porque Openfire?. Entre tantos servidores con protocolo XMMP Openfire se destaca por la sencillez de la instalación, la administración desde una página Web, su multiplicidad de funciones y la posibilidad de ser integrado con Asterisk. Openfire es escrito en java y, para que funcione, hay que instalar la JDK (Java SE Development Kit) o instalar (la opción que se usará) la versión OpenSource del java development Kit
yum install java-1.6.0-openjdk*
Terminada la instalación se controla la versión instalada:
java -versionjava version "1.6.0"OpenJDK Runtime Environment (build 1.6.0-b09)OpenJDK Client VM (build 1.6.0-b09, mixed mode)
Se descarga el servidor jabber Openfire:
cd /opt
wget http://www.igniterealtime.org/downloadServlet?filename=openfire/openfire_3_6_4.tar.gz
se descomprime
tar -xf openfire_3_6_4.tar.gz
Se entra en la carpeta bin
cd /opt/openfire/bin
Se modifica el script de inicio modificando esta linea:
INSTALL4J_JAVA_HOME_OVERRIDE=
50 Jabber es un protocolo libre para mensajería instantánea, basado en el estándar XML y gestionado por XMPP Standards Foundation. (Wikipedia)
51 Secure Sockets Layer -Protocolo de Capa de Conexión Segura- (SSL) y Transport Layer Security -Seguridad de la Capa de Transporte- (TLS), su sucesor, son protocolos criptográficos que proporcionan comunicaciones seguras por una red, comúnmente Internet. (Wikipedia)
para que quede:
INSTALL4J_JAVA_HOME_OVERRIDE=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0
y se inicia:
./openfire start
Se averigua que esté corriendo
./openfire status
Si aparece
The daemon is running.
El servidor está funcionando.
Ahora hay que configurarlo. Openfire para registrar los datos puede utilizar una base de datos interna o externa. En este caso se usará MySQL.
Se crea la base de datos en MySQL
mysqladmin create openfire -u root -psesamo
Se entra en el cliente de mysql
mysql -u root -psesamo
Se crea un usuario y se le otorgan todos los permisos para manejar la base de datos Openfire
mysql> GRANT ALL PRIVILEGES ON openfire.* TO openfire IDENTIFIED BY 'sesamo';
mysql> GRANT ALL PRIVILEGES ON openfire.* TO 'openfire'@'localhost' IDENTIFIED BY 'sesamo';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> quit
Bye
sesamo es la contraseña del usuario openfire
163
Ahora se importan las tablas para la base de datos
mysql openfire < /opt/openfire/resources/database/openfire_mysql.sql -u root -psesamo
Para que openfire sea accesible desde afuera de la red local hay que abrir unos puertos en el cortafuegos.
nano /etc/sysconfig/iptables
En la sección *filter se añaden estas lineas:
-A INPUT -p tcp -m tcp --dport 5222:5223 -j ACCEPT-A INPUT -p tcp -m tcp --dport 5269 -j ACCEPT-A INPUT -p tcp -m tcp --dport 5275 -j ACCEPT-A INPUT -p tcp -m tcp --dport 7070 -j ACCEPT-A INPUT -p tcp -m tcp --dport 5443 -j ACCEPT-A INPUT -p tcp -m tcp --dport 9090 -j ACCEPT-A INPUT -p tcp -m tcp --dport 9091 -j ACCEPT
Se guardan los cambios y se reinicia iptables:
service iptables restart
Una vez configurado el firewall se accede a la pagina de configuración de Openfire. En la barra de la direcciones de nuestro navegador se escribe:
http://mioipodominio:9090
en lugar de mioipodominio se pone la dirección IP del servidor Linux o, si se tiene un dominio registrado, el nombre (Ej. www.ejemplo.com)
aparecerá una pagina de configuración:
164
se elige el idioma
Se configura el nombre del dominio o la dirección IP:
Se elige el tipo de base de datos que se utilizará:
165
Se configura el acceso a MySQL y la base de datos:
En seteos de perfil se elige la opción “por defecto”
Se configura el correo electrónico y la cuenta del administrador:
166
El servidor está listo para funcionar.
Antes de entrar en la página de administración de Openfire hay que parar y volver a arrancar el servidor:
/opt/openfire/bin/openfire stop/opt/openfire/bin/openfire start
167
Ahora se puede configurar el servidor; crear usuarios, instalar plugins, crear conferencias y otras cuantas funciones.
Para probar la conexión el cliente predefinido de Openfire es Spark52 (en mi caso para Windows). Hay que descargarlo, instalarlo y abrirlo. Se pone come usuario admin, que es el que se ha creado a lo largo de la configuración de Openfire, y se presiona ingresar.
52 Spark Client
168
Se pueden configurar más usuarios y grupos desde la pagina de administración
Si se quiere iniciar Openfire en automático:
cd /opt/openfire/bin/extra
nano openfired
Se cambian estas tres lineas
export OPENFIRE_HOME=/opt/openfireexport OPENFIRE_USER=rootCMD=”./openfire $1”
Se guardan los cambios y se vuelve ejecutable el archivo:
chmod +x openfired
169
Se copia en la carpeta de los demonios:
cp openfired /etc/init.d/openfired
y se añade a los servicios:chkconfig --add openfiredchkconfig openfired on
Para averiguar si Openfire arranca en automático se hace un un reboot de la maquina Linux.
reboot
9.2 Instalar el Plugin SIPPhone en Openfire
En este párrafo se verá come instalar el plugin SIPPhone para Openfire. Este plugin permite asociar a un usuario registrado en Openfire una cuenta SIP o extensión Asterisk. Luego se instala el mismo plugin en el cliente Spark y desde éste se podrán efectuar llamadas usando el dialplan configurado en Asterisk.
Desde un navegador Web entramos en la pagina de administración.
En el menú Plugins y se escoge Available Plugins en el menú de la izquierda. Dependiendo de los plugins que ya se instalaron, aparecerá una lista parecida a esta:
170
Se presionba el botón a la derecha del plugin para instalarlo. Se presiona el botón Server en la barra del menú. En la segunda línea del menú habrá un nuevo menú: Phone. Lo presionamos para entrar en el menú de configuración del plugin.
Se escoge “Add new Phone Mapping” y se rellenan los campos:
171
• XMMP username : el nombre del usuario openfire• SIP username : el numero o nombre de la extensión• Authorization Username : el numero o nombre de la extensión• Display Phone Number : el numero que aparecerá al llamado• Password: la contraseña asociada a la extensión• Server: el nombre del dominio o IP de nuestro servidor Asterisk• Outbound Proxy : si usamos un proxy para conectarnos al servidor Asterisk hay que indicarlo
aquí sino se pone la dirección IP o el nombre de dominio del servidor Asterisk• Voice Mail Number : si en extension.conf hemos configurado una extensión para entrar en
nuestro contestador tenemos que indicarlo aquí (ejemplo 97)
Se presionas el botón Create para guardar la configuración. Se repite la misma operación para todos los usuarios que se quiere asociar a una extensión de Asterisk. Una vez terminado hay que configurar el cliente Spark que es el único que funciona con este plugin.
Se abre el cliente Spark y se abre una conexión con el nombre de usuario configurado arriba (en este caso admin).
En la versión Linux de Spark el plugin se instala correctamente solamente si el cliente y el plugin se compilan desde las fuentes53.
En el menú del cliente Spark se elige la voz Plugins y en Plugins disponibles Phone client y se instala
53 SipPhone para Linux
172
173
Cuando se termina de descargar el plugin, se cierra el cliente y se vuelve a iniciar. En el menú acciones se elige Phone Enabled
174
Aparecerá el cliente SIP en una nueva línea del menú de Spark y se podrá empezar a usarlo para hacer llamadas.
175
Si se quiere usar un único programa para chatear, monitorear nuestros servidores Asterisk y además hacer llamadas VoIP esta es una buena solución.
9.3 El Plugin Asterisk-IM
Asterisk-IM permite asociar a cada usuario Openfire una extensión SIP configurada en sip.conf. De este modo cuando esa extensión está hablando, en el cliente jabber Spark el estado del usuario Openfire asociado con la extensión cambiará de disponible a “on the phone”.
Requisitos:
• haber instalado openfire con una base de datos externa (Mysql)• haber puesto el parámetro callevents=yes en la parte general del archivo sip.conf• haber configurado un usuario en el archivo manager.conf
Se modifica el archivo manager.conf:
176
nano /etc/asterisk/manager.conf
La parte general debe aparecer así:
[general] enabled = yes webenabled = yes port = 5038 httptimeout = 60 bindaddr = 0.0.0.0 allowmultiplelogin = yes displayconnects = yes timestampevents = yes
luego se añade un nuevo usuario:
[openfire] secret = sesamodisplayconnects = yes read = system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplanwrite = system,call,agent,user,config,command,reporting,originate
Se actualiza la configuración de Asterisk:
/etc/init.d/asterisk reload
En el caso que el servidor jabber y el servidor Asterisk estén en dos servidores distintos, en en la configuración del cortafuegos, hay que abrir el puerto 5038 TCP.
nano /etc/sysconfig/iptables
En la seccion *filter se añade esta línea
-A INPUT -p tcp—dport 5038 -j ACCEPT
Se guardan los cambios y se reinicia IPtables:
service iptables restart
Ahora el archivo sip.conf
nano /etc/asterisk/sip.conf
Se modifica la siguiente línea en la parte general:
callevents=yes
177
Desde la consola de Asterisk:
asterisk -rvvvvvvvvvvvvvv
CLI> sip reload
Se instala el plugin en Openfire. Desde un navegador Web se abre la pagina de administración de Openfire y se va al menú Plugins. Presionamos el menú “Available Plugins”
Para instalarlo se presiona el botón que aparece al fondo de la línea del plugin. Una vez instalado en el barra de menú una nueva voz, Asterisk IM.
Se escoge el menú Asterisk-IM y luego General Settings. Se configura siguiendo las pautas indicadas en la imagen que sigue:
178
Se presiona el botón SAVE. En la misma ventana se escoge el menú Add Server y se configura la conexión al Asterisk Manager
Se presiona el botón Create Server. La bolita verde a la izquierda indica che hay conexión con Asterisk.
179
Para averiguar que efectivamente el usuario Openfire esté conectado al Asterisk Manager se entra en la consola de Asterisk:
asterisk -rvvvvvvvvvvvvvv
se digita el comando:
CLI> manager show connected
Username IP Address Start Elapsed FileDes HttpCnt Read Write openfire 67.18.186.202 1229776886 349 30 0 04079 04851 1 users connected.
Se guardan los cambios y se entra en el menu Phone Mappings:
Se configuran todos los usuarios de Openfire que se quiere asociar con una extensión SIP presente en el servidor Asterisk.
Desde el cliente Spark se abre una conexión con el usuario admin que se ha configurado en Phone Mappings.
Cuando la extensión 2000 esté hablando, el estado de del usuario admin cambiará como aparece en la imagen que sigue:
180
En el caso de otro usuario:
181
9.4 Asterisk como cliente en Openfire
La configuración de Asterisk como cliente jabber en Openfire es parecida a la de GoogleTalk (párrafo 10.2). Para que el modulo res_jabber funcione, hay que asegurarse de haber seguido todos los pasos necesarios contenidos en el párrafo 1.3.
Se empieza con la modifica del archivo jabber.conf presente en la carpeta /etc/asterisk.
nano /etc/asterisk/jabber.conf
[general] debug=yes; activamos el debug
autoprune=yes
182
; remueve automáticamente los usuarios de la lista de amigos
autoregister=yes ; registra automáticamente los nuevos usuarios en lista de amigos
[vozcom] ; etiqueta que define la conexión (importante para las funciones Jabberstatus y Jabbersend de Asterisk)
type=client ; Asterisk actuará como un cliente (las opciones son cliente, componente y server)
serverhost=voztovoice.net ; el nombre de dominio o IP del servidor Openfire
[email protected]/openfire ; Nombre del usuario Openfire del servidor asterisk
secret=contraseña ; la contraseña
priority=10; el nivel de prioridad que tiene en cliente en caso de conflictos (ej: dos conexiones simultaneas del mismo usuario)
port=5222 ; el puerto TCP del servidor Openfire usado para conectarse
usetls=yes ; Usar el protocolo TLS
usesasl=yes; Usar el protocolo SASL
[email protected] ; la lista de amigos, uno por línea
[email protected] [email protected]
statusmessage=Asterisk server ; un mensaje personalizado del usuario
timeout=100 ;
Se guardan los cambios y antes de actualizar la configuración de Asterisk se configurar este usuario en Openfire. Desde un navegador Web se entra en la pagina de adminsitracion de Opnefire
183
En la barra de menú se escoge “Usuarios/Grupos” y luego en el menú vertical en la izquierda “crear nuevo usuario”
Se rellena el formulario y luego se presiona el botón crear usuario. Ahora se puede actualizar la configuración de Asterisk:
/etc/init.d/asterisk reload
Se averigua el resultado desde la consola de Asterisk
asterisk -rvvvvvvvvvvvv
184
CLI> jabber show connected
Jabber Users and their status: User: [email protected]/openfire – Connected
Para ver la lista de amigos:
CLI> jabber show buddies
Jabber buddy lists Client: [email protected]/openfire Buddy: [email protected] Resource: None Buddy: [email protected] Resource: None Buddy: [email protected] Resource: openfire node: http://www.asterisk.org/xmpp/client/caps version: asterisk-xmpp
9.5 Conectar dos servidores Openfire
Si se conectan dos servidores Openfire entre ellos, los usuarios de uno podrán agregar en su lista de amigos usuarios del otro servidor. Para lograr este tipo de comportamiento hay que modificar la configuración en los dos servidor:
Los dos servidores están instalados en dos computadores de la misma LAN:
Openfire A IP: 192.168.1.100Openfire B IP: 192.168.1.200
• Primero: si hay un cortafuegos por el medio, hay que abrir el puerto 5269 TCP en ambos• Segundo: se entra en la pagina de administración del servidor A y se escoge el menú Server >
Server Settings > Server to Server
Se configura la página como sigue:
185
Luego se pasa al menú Server > Server settings > Security settings y bajo el cuadro Server Connection Security se selecciona la casilla:
186
Se guardan los cambios y se sigue el mismo procedimiento en el servidor B indicando la IP: 192.168.1.100 en la White List
Se guardan los cambios y se verifica que la conexión esté activa:Se entra en el menú Sessions > Server Session donde debería aparecer:
Si no aparece ninguna conexión se puede usar el programa Telnet para averiguar si el puerto 5269 TCP esté efectivamente abierto. Desde la consola de Linux del servidor A se escribe:
telnet
telnet> o -a 192.168.1.200 5269
Trying 192.168.1.200... Connected to 192.168.1.200 Escape character is ‘^]’. </stream:stream>Connection closed by foreign host.
Si aparece la expresión en negrita todo está bien.
Se abre el cliente Spark, se abre una conexión con un nombre de usuario del Servidor Openfire A y se añade a la lista de amigos un usuario registrado en el servidor Openfire B:
187
Para tres o más servidores Openfire, que queremos conectar entre ellos, se sigue el mismo procedimiento.
9.6 Openfire Connection Manager
Si hay que manejar un numero considerable de usuarios (más de 1000 en linea a la vez), hay que recurrir al Connection Manager. Este programa se configura delante del servidor Openfire y gestiona las conexiones y las autenticaciones de los usuarios. Se pueden instalar uno o más Connection Manager según el numero de usuarios. Cada Connection Manager es capaz de manejar cinco mil usuarios. El esquema de funcionamiento es el que aparece en la imagen aquí abajo:
188
En ese ejemplo hay tres Connection Managers instalados que reciben las registraciones de los usuarios y a su vez están conectados con el servidor Openfire.
Se descarga el programa:
cd /opt
wget http://www.igniterealtime.org/downloadServlet?filename=connectionmanager/connection_manager_3_6_3.tar.gz
Se descomprime:
tar –xf connection_manager_3_6_3.tar.gz
Ahora solo falta configurar el programa. Se entra en la carpeta de configuración y se modifica el archivo manager.xml
cd /opt/connection_manager/conf
nano manager.xml
Las líneas que hay que modificar son:
• domain: el nombre de dominio del servidor Openfire (ej: miodominio.org)
• hostname: la dirección IP del servidor Openfire
• port: el puerto configurado en el servidor Openfire para aceptar las conexiones del Connection Manager (5262 predefinido)
• password: la contraseña que se ha definido en el servidor Openfire para aceptar las conexiones del Connection Manager
• name: un nombre que queremos asignar a el Connection Manager (muy útil si se tiene planeado instalar más de uno).
• interface: dirección IP o nombre de dominio donde el Connection Manager aceptará las conexiones.
Se guardan los cambios. Ahora hay que abrir los puertos 5222 y 5223 en el cortafuegos del computador donde esté instalado el Connection Manager.
Para terminar se instala el “script” para arrancar Connection Manager en automático:
cd /opt/connection_manager/bin/extra
nano cmanagerd
189
Se modifican las siguientes líneas:
export CMANAGER_HOME=/opt/connection_manager
export CMANAGER_USER=root
CMD="./cmanager.sh $1"
Se guardan los cambios y se termina:
cp cmanagerd /etc/init.d/
chmod +x /etc/init.d/cmanagerd
chkconfig –add cmanagerd
chkconfig cmanagerd on
Antes de arrancar el Connection Manager hay que modificar la configuración del servidor Openfire. Desde la pagina di administración del servidor Openfire bajo el menú “Server settings” se elige “Connection Manager”. En la pagina que aparece se activa el servicio, se escoge el puerto y se define una contraseña.
Se presiona el botón “Save Settings”. Se abre el puerto 5262 TCP en el cortafuegos.
Ahora se puede arrancar el Connection Manager. En el servidor Linux donde se instaló se escribe:
/etc/init.d/cmanagerd start
Se averigua que esté corriendo:
/etc/init.d/cmanagerd statusrunning pid is 5747
190
Connection Manager 3.6.3 [Feb 6, 2010 5:02:17 AM]
y en la pagina de administración de Openfire se verifica que está conectado:
Desde un cliente XMPP se abre una conexión usando como dirección IP o nombre de Dominio la que se ha configurado en la linea “interface” del archivo manager.xml
191
Capitulo X
Potpourri
10.1 Func_odbc.conf - ODBC y Base de datos
En este párrafo se verá como usar el conector ODBC y el archivo de configuración de Asterisk func_odbc.conf para hacer consultas en una base de datos MySQL y devolver los resultados al plan de llamadas.
Se crea una base de datos de prueba en MySQL:
cd /usr/src
wget http://www.voztovoice.org/tmp/timeclock.txt
mysql -u root -psesamo < timeclock.txt
La base de datos viene con dos registros insertados
mysql -u root -psesamo
mysql> use timeclock
mysql> SELECT * FROM users;
+----+--------+----------+----------+------------+ id | empnum | lastin | lastout | comments | +----+--------+----------+----------+------------+ | 1 | 12345 | 00:00:00 | 00:00:00 | Fulano | | 2 | 23456 | 00:00:00 | 00:00:00 | Sutano | +----+--------+----------+----------+------------+2 rows in set (0.00 sec)
Se asigna a un usuario los privilegios para conectarse a la base de datos:
mysql> GRANT ALL PRIVILEGES ON timeclock.* TO ‘timeclock’@’localhost’ IDENTIFIED BY ‘sesamo’;
Se actualizan los privilegios:
mysql> flush privileges;
Se sale del cliente MySQL:
mysql> quit
Ahora hay que modificar algunos archivos de Asterisk para que todo funcione:
nano /etc/asterisk/res_odbc.conf
Se añaden las siguientes líneas:
[timeclock] enable=yes dsn=timeclock username=timeclock password=sesamologuniqueid=yes pre-connect=yes
en el campo password se pone la contraseña configurada en MySQL para el usuario timeclock
nano /etc/asterisk/func_odbc.conf
se añaden las líneas:
[TIMECLOCK] dsn=timeclock readsql=SELECT comments FROM users WHERE empnum=’${SQL_ESC(${ARG1})}’ writesql=UPDATE users SET empnum=’${SQL_ESC(${VAL1})}’ WHERE empnum=’${SQL_ESC(${ARG1})}’
se continúa con:
nano /etc/odbc.ini
[timeclock] Description = MySQL ODBC TIMECLOCK Driver = MySQL Server = localhost User = timeclock Password = sesamoDatabase = timeclock Port = 3306 Option = 3
Para terminar falta crear la parte del dialplan que se encargará de hacer las consultas a la base de datos que hemos creado:
nano /etc/asterisk/extensions.conf
exten => 222,1,Answer exten => 222,n,Wait(2)
193
exten => 222,n,Festival(Por favor ingrese los 5 digitos del numero del empleado.”) exten => 222,n,Read(EMPNUM,beep,5) exten => 222,n,NoOp(EMPNUM: ${EMPNUM}) exten => 222,n,Set(EMPNAME=${ODBC_TIMECLOCK(${EMPNUM})}) exten => 222,n,GotoIf($[”${EMPNAME}foo” = “foo”]?notfound) exten => 222,n,Festival(El nombre del empleado es ${EMPNAME}. Hasta luego.”) exten => 222,n,NoOp(Employee: ${EMPNAME}) exten => 222,n,Hangup exten => 222,n(notfound),Festival(Ningun empleado corresponde al numero ingresado. Hasta luego.) exten => 222,n,Hangup
Se vuelve a arrancar Asterisk:
/etc/init.d/asterisk reload
o
/etc/init.d/asterisk restart
Flujo del dialplan:
• se contesta la llamada, • se usa un programa de síntesis de voz (Festival) para solicitar el llamante para que digite los 5
numero del empleado que está buscando• se espera que el llamante digite una serie de 5 números y a través de la aplicación Read se
almacenan los digitos en una variable• se consulta la base de datos para averiguar si el numero existe. • si no existe el dialplan sigue desde la etiqueta (notfound) • si existe continúa con la linea siguiente• se escuchará el nombre del empleado asociado a los 5 dígitos que se han enviado.
10.2 Asterisk y GoogleTalk
Asterisk incluye la funcionalidad de conectarse, como cliente, al servidor de googletalk. Una vez configurado Asterisk como cliente GoogleTalk se podrán recibir y efectuar llamadas de esta forma:
• Asterisk -> Gtalk • Gtalk -> Asterisk
Primero se averigua que el modulo res_jabber esté funcionando. Desde la consola:
asterisk -rvvvvvvvvvvv
Se escribe el comando:
194
*CLI> help jabber
Debe aparecer como respuesta una lista de comandos que se pueden utilizar con este modulo:
jabber reload Reload Jabber configuration jabber set debug {on|off} Enable/Disable Jabber debug jabber show buddies Show buddy lists of our clients jabber show connected Show state of clients and components jabber test Shows roster, but is generally used for mog’s debugging.
Si así no fuera, no se ha compilado Asterisk con el soporte Jabber o el modulo no viene cargado cuando Asterisk arranca.
Una primera prueba es intentar cargar el modulo:
CLI> module load res_jabber
si no se recibe ningún error significa que la operación ha tenido éxito. Se sale de la consola:
CLI> quit
Para configurar GoogleTalk en Asterisk hay que modifica dos archivos:
• jabber.conf• gtalk.conf
Se empieza con el jabber.conf
nano /etc/asterisk/jabber.conf
[general]debug=yes autoprune=yes ; remueve automáticamente los usuarios de la lista de amigos
autoregister=yes ; Autoregistra los nuevos usuarios en la lista de amigos
[gtalk]type=client serverhost=talk.google.com ; dominio del server GoogleTalk
[email protected] ; usuario que vamos a registrar en GoogleTalk
195
secret=XXXXXX ; contraseña
port=5222 ; puerto para la conexión a GoogleTalk
usetls=yes ; activa el protocolo TLS
usesasl=yes ; se activa el protocolo sasl
[email protected] ; desde este punto empieza la lista de amigos que se quiere añadir
statusmessage=Asterisk Server ; mensaje de estado que se visualizará junto al nombre de usuario
timeout=100
En el caso que se quiera conectar más de un usuario GoogleTalk desde el servidor Asterisk hay que repetir una segunda vez todo el bloque cambiando los parámetros relacionados con el nuevo usuario
Configuración de gtalk.conf:
nano /etc/asterisk/gtalk.conf
[general]context=google-in;contexto donde entrarán las llamadas de los usuarios GoogleTalk
allowguest=yes; se permiten llamadas de usuario GoogleTalk que no estén en la lista de amigos
bindaddr=IPAsterisk;direccion IP del servidor Asterisk
[guest]disallow=allallow=ulawcontext=google-in; configuración para los usuarios huéspedes (que no están en la lista de amigos
[fulano][email protected]=allallow=ulaw
196
connection=gtalkcontext=google-in
Este bloque que empieza con la etiqueta [fulano] es la configuración de uno de los amigos presentes en la lista de amigos de GoogleTalk. Si se quiere configurar más de uno hay que repetir todo el bloque cambiando la [etiqueta] y el correo electrónico.
Terminada la configuración hay que modificar el Dialplan para permitir las llamadas a usuarios GoogleTalk y al usuario GoogleTalk configurado en el servidor Asterisk.
nano /etc/asterisk/extensions.conf
Para las llamadas entrantes se añaden las lineas:
[google-in]exten => s,1,NoOp( Call from Gtalk )exten => s,n,Set(CALLERID(name)=”From Google Talk”)exten => s,n,Dial(SIP/1000,30)exten => s,n,GotoIf($[”${DIALSTATUS}” = “BUSY”]?busy:unavail)exten => s,n(unavail),Voicemail(1000@default,u)exten => s,n,Hangup()exten => s,n(busy),VoiceMail(1000@default,b)exten => s,n,Hangup()
Todas las llamadas que entren desde GoogleTalk la giramos a la extensión 1000. Si dentro de treinta segundos no se contesta, la llamadas se transfiere al buzón de voz. Importante notar que la etiqueta [google-in] es la misma que se configuró en el archivo gtalk.conf bajo el parametro “context”.
Para las llamadas salientes se pone en el contexto internas:
exten => 10000,1,Dial(gtalk/gtalk/[email protected])exten => 10000,n,Congestion(3)exten => 10000,n,Hangup
Una explicación de las tres lineas:
• Se dice a Asterisk de llamar a través de gtalk bajo la configuración que en jabber.conf se definió gtalk (vease etiqueta [gtalk]) a [email protected];
• si la llamada no tiene éxito o el servidor está congestionado recibiremos una señal de ocupado por 3 segundos
• se cuelga la llamada/canal•
Se actualiza la configuración de Asterisk con el comando:
/etc/init.d/asterisk reload
197
Ahora se puede desde la extensión 1000 hacer y recibir llamadas con GoogleTalk.
10.3 AGI y despertador
Para configurar un despertador en Asterisk se usará uno script escrito en PHP. Asterisk permite a través de la aplicación AGI (Asterisk Gateway Interface) interactuar con la PBX a través de distintos lenguajes de programación (PHP, Perl, Pyton, Java, etc.).
Se descarga el archivo:
cd /usr/src
wget http://qod.com/wakeup.2.0.tar
Se descomprime:
tar -xf wakeup.2.0.tar
Se entra en la carpeta:
cd wakeup.2.0
Se vuelve ejecutable el archivo wakeup.php:
chmod +x wakeup.php
se copia en la carpeta agi-bin de asterisk
cp wakeup.php /var/lib/asterisk/agi-bin/
Terminada esta primera parte se modifica el Dialplan para crear una nueva extensión que se usará para programar el despertador
nano /etc/asterisk/extensions.conf
Se añaden las siguientes dos líneas en el contexto internas:
exten => 77,1,agi(wakeup.php) exten => 77,n,Hangup
Se guarda el archivo y se reinicia Asterisk
/etc/init.d/asterisk reload
Ahora desde un Softphone se marca el numero 77 y se siguen las instrucciones para programar el despertador. Una vez programado si desde la misma extensión se marca otra vez la extensión 77 se
198
tendrá la opción de poder modificar la hora del despertador.
10.4 Fail2ban
Fail2ban es un programa que lee los registros (por ejemplo /var/log/asterisk/messages) y si hay un numero determinado de intentos de conexión sin éxito, banea (bloquea) las IP de donde se han originados los intentos interactuando con iptables (cortafuegos).
Fail2ban está escrito en Python y para que funcione hay que instalar este lenguaje de programación:
yum install python
luego se descarga el programa:
cd /usr/src
wget http://downloads.sourceforge.net/project/fail2ban/fail2ban-stable/fail2ban-0.8.4/fail2ban-0.8.4.tar.bz2
se descomprime:
tar -xf fail2ban-0.8.4.tar.bz2
se entra en la carpeta:
cd fail2ban-0.8.4
y se instala:
python setup.py install
Se activa el script para arrancarlo como un servicio (para CentOS)
cp /usr/src/fail2ban-0.8.4/files/redhat-initd /etc/init.d/fail2ban
chkconfig add fail2banchkconfig fail2ban on
Se configura para que lea los registros de Asterisk:
cd /etc/fail2ban/filter.d
nano asterisk.conf
y se añaden estas líneas
199
# Fail2Ban configuration file # # # $Revision: 250 $ # [INCLUDES] # Read common prefixes. If any customizations available—read them from # common.local #before = common.conf [Definition] #_daemon = asterisk # Option: failregex # Notes.: regex to match the password failures messages in the logfile. The # host must be matched by a group named “host”. The tag “<HOST>” can # be used for standard IP/hostname matching and is only an alias for # (?:::f{4,6}:)?(?P<host>\S+) # Values: TEXT # failregex = NOTICE.* .*: Registration from ‘.*’ failed for ‘<HOST>’ - Wrong password NOTICE.* .*: Registration from ‘.*’ failed for ‘<HOST>’ - No matching peer found NOTICE.* .*: Registration from ‘.*’ failed for ‘<HOST>’ - Username/auth name mismatch NOTICE.* <HOST> failed to authenticate as ‘.*’$ NOTICE.* .*: No registration for peer ‘.*’ (from <HOST>) NOTICE.* .*: Host <HOST> failed MD5 authentication for ‘.*’ (.*) # Option: ignoreregex # Notes.: regex to ignore. If this regex matches, the line is ignored. # Values: TEXT # ignoreregex =
con estas líneas se configura fail2ban para que controle eventuales accesos indeseados que aparecen en el archivo de registro de Asterisk.
Se termina modificando el archivo de configuración general de fail2ban:
cd /etc/fail2ban
nano jail.conf
al final del archivo se añaden las lineas que siguen:
[asterisk-iptables] enabled = true filter = asterisk action = iptables-allports[name=ASTERISK, protocol=all] sendmail-whois[name=ASTERISK, dest=root@localhost, [email protected]] logpath = /var/log/asterisk/messages
200
maxretry = 5 bantime = 1800
En la línea logpath aparece el archivo de registros que fail2ban leerá para averiguar intentos frustrados de conexión a Asterisk. En la configuración hay que modificar la dirección de correo electrónico. En lugar de root@localhost se pone la dirección de correo electrónico donde se quiere recibir los avisos. Para enviar los correos, fail2ban está configurado con Sendmail.
Para que funcione hay que modificar la configuración del los archivos de registro de Asterisk:
nano /etc/asterisk/logger.conf
y averiguar que la línea messages tenga el parámetro que aparece en negrita
messages => notice,debug
Se arranca fail2ban:
/etc/init.d/fail2ban start
Starting fail2ban: [ OK ]
Desde ahora el servidor Asterisk tiene algo más de seguridad y se podrá monitorear los intentos de acceso no autorizados.
201
Apendice A
Asterisk Aplicaciones
AddQueueMember: Dynamically adds queue members
ADSIProg: Load Asterisk ADSI Scripts into phone
AgentLogin: Call agent login
AgentMonitorOutgoing: Record agent’s outgoing call
AGI: Executes an AGI compliant application
AlarmReceiver: Provide support for receiving alarm reports from a burglar or fire alarm panel
AMD: Attempts to detect answering machines
Answer: Answer a channel if ringing
Authenticate: Authenticate a user
BackGround: Play an audio file while waiting for digits of an extension to go to.
BackgroundDetect: Background a file with talk detect
Bridge: Bridge two channels
Busy: Indicate the Busy condition
ChangeMonitor: Change monitoring filename of a channel
ChanIsAvail: Check channel availability
ChannelRedirect: Redirects given channel to a dialplan target.
ChanSpy: Listen to a channel, and optionally whisper into it
ClearHash: Clear the keys from a specified hashname
Congestion: Indicate the Congestion condition
ContinueWhile: Restart a While loop
ControlPlayback: Play a file with fast forward and rewind
DAHDIBarge: Barge in (monitor) DAHDI channel
DAHDIRAS: Executes DAHDI ISDN RAS application
DAHDIScan: Scan DAHDI channels to monitor calls
DateTime: Says a specified time in a custom format
DBdel: Delete a key from the database
DBdeltree: Delete a family or keytree from the database
DeadAGI: Executes AGI on a hungup channel
Dial: Place a call and connect to the current channel
Dictate: Virtual Dictation Machine
203
Directory: Provide directory of voicemail extensions
DISA: DISA (Direct Inward System Access)
DumpChan: Dump Info About The Calling Channel
EAGI: Executes an EAGI compliant application
Echo: Echo audio, video, or DTMF back to the calling party
EndWhile: End a while loop
Exec: Executes dialplan application
ExecIf: Executes dialplan application, conditionally
ExecIfTime: Conditional application execution based on the current time
ExitWhile: End a While loop
ExtenSpy: Listen to a channel, and optionally whisper into it
ExternalIVR: Interfaces with an external IVR application
Festival: Say text to the user
Flash: Flashes a DAHDI Trunk
FollowMe: Find-Me/Follow-Me application
ForkCDR: Forks the Call Data Record
204
GetCPEID: Get ADSI CPE ID
Gosub: Jump to label, saving return address
GosubIf: Conditionally jump to label, saving return address
Goto: Jump to a particular priority, extension, or context
GotoIf: Conditional goto
GotoIfTime: Conditional Goto based on the current time
Hangup: Hang up the calling channel
IAX2Provision: Provision a calling IAXy with a given template
ICES: Encode and stream using ‘ices’
ImportVar: Import a variable from a channel into a new variable
JabberSend: JabberSend(jabber,screenname,message)
JabberStatus: JabberStatus(Jabber,ScreenName,Variable)
Log: Send arbitrary text to a selected log level
Macro: Macro Implementation
MacroExclusive: Exclusive Macro Implementation
MacroExit: Exit From Macro
205
MacroIf: Conditional Macro Implementation
MailboxExists: Check to see if Voicemail mailbox exists
MeetMe: MeetMe conference bridge
MeetMeAdmin: MeetMe conference Administration
MeetMeChannelAdmin: MeetMe conference Administration (channel specific)
MeetMeCount: MeetMe participant count
Milliwatt: Generate a Constant 1004Hz tone at 0dbm (mu-law)
MinivmAccMess: Record account specific messages
MinivmDelete: Delete Mini-Voicemail voicemail messages
MinivmGreet: Play Mini-Voicemail prompts
MinivmNotify: Notify voicemail owner about new messages.
MinivmRecord: Receive Mini-Voicemail and forward via e-mail
MixMonitor: Record a call and mix the audio during the recording
Monitor: Monitor a channel
Morsecode: Plays morse code
MP3Player: Play an MP3 file or stream
206
MSet: Set channel variable(s) or function value(s)
MusicOnHold: Play Music On Hold indefinitely
MYSQL: Do several mySQLy things
NBScat: Play an NBS local stream
NoCDR: Tell Asterisk to not maintain a CDR for the current call
NoOp: Do Nothing (No Operation)
ODBCFinish: Clear the resultset of a successful multirow query
Page: Pages phones
Park: Park yourself
ParkAndAnnounce: Park and Announce
ParkedCall: Answer a parked call
PauseMonitor: Pause monitoring of a channel
PauseQueueMember: Pauses a queue member
Pickup: Directed Call Pickup
PickupChan: Pickup a ringing channel
Playback: Play a file
207
PlayTones: Play a tone list
PrivacyManager: Require phone number to be entered, if no CallerID sent
Proceeding: Indicate proceeding
Progress: Indicate progress
Queue: Queue a call for a call queue
QueueLog: Writes to the queue_log
RaiseException: Handle an exceptional condition
Read: Read a variable
ReadExten: Read an extension into a variable
ReadFile: Read the contents of a text file into a channel variable
ReceiveFAX: Receive a FAX
Record: Record to a file
RemoveQueueMember: Dynamically removes queue members
ResetCDR: Resets the Call Data Record
RetryDial: Place a call, retrying on failure allowing optional exit extension.
Return: Return from gosub routine
208
Ringing: Indicate ringing tone
SayAlpha: Say Alpha
SayCountPL: Say Polish counting words
SayDigits: Say Digits
SayNumber: Say Number
SayPhonetic: Say Phonetic
SayUnixTime: Says a specified time in a custom format
SendDTMF: Sends arbitrary DTMF digits
SendFAX: Send a FAX
SendImage: Send an image file
SendText: Send a Text Message
SendURL: Send a URL
Set: Set channel variable or function value
SetAMAFlags: Set the AMA Flags
SetCallerPres: Set CallerID Presentation
SetMusicOnHold: Set default Music On Hold class
209
SIPAddHeader: Add a SIP header to the outbound call
SIPDtmfMode: Change the dtmfmode for a SIP call
SLAStation: Shared Line Appearance Station
SLATrunk: Shared Line Appearance Trunk
SMS: Communicates with SMS service centres and SMS capable analogue phones
SoftHangup: Soft Hangup Application
SpeechActivateGrammar: Activate a Grammar
SpeechBackground: Play a sound file and wait for speech to be recognized
SpeechCreate: Create a Speech Structure
SpeechDeactivateGrammar: Deactivate a Grammar
SpeechDestroy: End speech recognition
SpeechLoadGrammar: Load a Grammar
SpeechProcessingSound: Change background processing sound
SpeechStart: Start recognizing voice in the audio stream
SpeechUnloadGrammar: Unload a Grammar
StackPop: Remove one address from gosub stack
210
StartMusicOnHold: Play Music On Hold
StopMixMonitor: Stop recording a call through MixMonitor
StopMonitor: Stop monitoring a channel
StopMusicOnHold: Stop Playing Music On Hold
StopPlayTones: Stop playing a tone list
System: Execute a system command
TestClient: Execute Interface Test Client
TestServer: Execute Interface Test Server
Transfer: Transfer caller to remote extension
TryExec: Executes dialplan application, always returning
TrySystem: Try executing a system command
UnpauseMonitor: Unpause monitoring of a channel
UnpauseQueueMember: Unpauses a queue member
UserEvent: Send an arbitrary event to the manager interface
Verbose: Send arbitrary text to verbose output
VMAuthenticate: Authenticate with Voicemail passwords
211
VoiceMail: Leave a Voicemail message
VoiceMailMain: Check Voicemail messages
Wait: Waits for some time
WaitExten: Waits for an extension to be entered
WaitForRing: Wait for Ring Application
WaitForSilence: Waits for a specified amount of silence
WaitMusicOnHold: Wait, playing Music On Hold
WaitUntil: Wait (sleep) until the current time is the given epoch
While: Start a while loop
Zapateller: Block telemarketers with SIT
212
Apendice B
Asterisk Funciones
AGENT Gets information about an Agent
ARRAY Allows setting multiple variables at once
AUDIOHOOK_INHERIT Set whether an audiohook may be inherited to another channel
BASE64_DECODE Decode a base64 string
BASE64_ENCODE Encode a string in base64
BLACKLIST Check if the callerid is on the blacklist
CALLERID Gets or sets Caller*ID data on the channel.
CALLERPRES Gets or sets Caller*ID presentation on the channel.
CDR Gets or sets a CDR variable
CHANNEL Gets/sets various pieces of information about the channel.
CHECKSIPDOMAIN Checks if domain is a local domain
CURL Retrieves the contents of a URL
CUT Slices and dices strings, based upon a named delimiter.
DB Read from or write to the Asterisk database
DB_DELETE Return a value from the database and delete it
DB_EXISTS Check to see if a key exists in the Asterisk database
DEVICE_STATE Get or Set a device state
DIALGROUP Manages a group of users for dialing
DIALPLAN_EXISTS Checks the existence of a dialplan target.
DUNDILOOKUP Do a DUNDi lookup of a phone number
DUNDIQUERY Initiate a DUNDi query.
DUNDIRESULT Retrieve results from a DUNDIQUERY
ENUMLOOKUP General or specific querying of NAPTR records for ENUM or ENUM-like DNS pointers
ENUMQUERY Initiate an ENUM query
ENUMRESULT Retrieve results from a ENUMQUERY
ENV Gets or sets the environment variable specified
EVAL Evaluate stored variables.
EXCEPTION Retrieve the details of the current dialplan exception
EXISTS Existence Test: Returns 1 if exists, 0 otherwise
214
EXTENSION_STATE Get an extension’s state
FIELDQTY Count the fields, with an arbitrary delimiter
FILE Obtains the contents of a file
FILTER Filter the string to include only the allowed characters
GLOBAL Gets or sets the global variable specified
GROUP Gets or sets the channel group.
GROUP_COUNT Counts the number of channels in the specified group
GROUP_LIST Gets a list of the groups set on a channel.
GROUP_MATCH_COUNT Counts the number of channels in the groups matching the specified pattern
HASH Implementation of a dialplan associative array
HASHKEYS Retrieve the keys of a HASH()
HINT Get the devices set for a dialplan hint
IAXPEER IAX peer information
IAXVAR Sets or retrieves a remote variable
ICONV Converts charsets of strings.
215
IF Conditional: Returns the data following ‘?’ if true, else the data following ‘:’
IFMODULE Checks if an Asterisk module is loaded in memory
IFTIME Temporal Conditional: Returns the data following ‘?’ if true, else the data following ‘:’
IMPORT Retrieve the value of a variable from another channel
ISNULL NULL Test: Returns 1 if NULL or 0 otherwise
JABBER_STATUS Retrieve buddy status
KEYPADHASH Hash the letters in the string into the equivalent keypad numbers.
LEN Returns the length of the argument given
LOCAL Variables local to the gosub stack frame
LOCK Attempt to obtain a named mutex
MAILBOX_EXISTS Tell if a mailbox is configured
MATH Performs Mathematical Functions
MD5 Computes an MD5 digest
MINIVMACCOUNT Gets MiniVoicemail account information
MINIVMCOUNTER Reads or sets counters for MiniVoicemail message
216
ODBC_ANTIGF Runs the referenced query with the specified arguments
ODBC_FETCH Fetch a row from a multirow query
ODBC_PRESENCE Runs the referenced query with the specified arguments
ODBC_SQL Runs the referenced query with the specified arguments
PP_EACH_USER Generate a string for each phoneprov user
QUEUE_MEMBER Count number of members answering a queue
QUEUE_MEMBER_COUNT Count number of members answering a queue
QUEUE_MEMBER_LIST Returns a list of interfaces on a queue
QUEUE_MEMBER_PENALTY Gets or sets queue members penalty.
QUEUE_VARIABLES Return Queue information in variables
QUEUE_WAITING_COUNT Count number of calls currently waiting in a queue
QUOTE Quotes a given string, escaping embedded quotes as necessary
RAND Choose a random number in a range
REALTIME RealTime Read/Write Functions
REALTIME_DESTROY RealTime Destroy Function
REALTIME_STORE RealTime Store Function
217
REGEX Regular Expression
SET SET assigns a value to a channel variable
SHA1 Computes a SHA1 digest
SHARED Gets or sets the shared variable specified
SHELL Executes a command as if you were at a shell.
SIP_HEADER Gets the specified SIP header
SIPCHANINFO Gets the specified SIP parameter from the current channel
SIPPEER Gets SIP peer information
SMDI_MSG Retrieve details about an SMDI message.
SMDI_MSG_RETRIEVE Retrieve an SMDI message.
SORT Sorts a list of key/vals into a list of keys, based upon the vals
SPEECH Gets information about speech recognition results.
SPEECH_ENGINE Change a speech engine specific attribute.
SPEECH_GRAMMAR Gets the matched grammar of a result if available.
SPEECH_RESULTS_TYPE Sets the type of results that will be returned.
SPEECH_SCORE Gets the confidence score of a result.
218
SPEECH_TEXT Gets the recognized text of a result.
SPRINTF Format a variable according to a format string
SQL_ESC Escapes single ticks for use in SQL statements
STAT Does a check on the specified file
STRFTIME Returns the current date/time in a specified format.
STRPTIME Returns the epoch of the arbitrary date/time string structured as described in the format.
SYSINFO Returns system information specified by parameter.
TIMEOUT Gets or sets timeouts on the channel. Timeout values are in seconds.
TOLOWER Convert the string to lower case.
TOUPPER Convert the string to upper case.
TRYLOCK Attempt to obtain a named mutex
TXTCIDNAME TXTCIDNAME looks up a caller name via DNS
UNLOCK Unlocks a named mutex
URIDECODE Decodes a URI-encoded string according to RFC 2396.
URIENCODE Encodes a string to URI-safe encoding according to RFC 2396.
219
VALID_EXTEN Determine whether an extension exists or not
VERSION Return the Version info for this Asterisk
VMCOUNT Counts the voicemail in a specified mailbox
VOLUME Set the TX or RX volume of a channel
220
Apendice C
El plan de llamadas
[general] static=yeswriteprotect=noautofallthrough=yespriorityjumping=yes
[globals] SUP = SIP/1000 FUL = SIP/0057310000000 JUST = SIP/justvoip DYNAMIC_FEATURES=test1#blindxfer#automon#disconnect#atxfer#parkcall#automixmon
[internas]exten => 50,1,Answer exten => 50,n,Wait(1) exten => 50,n,Goto(IVR,s,1)
exten => 97,1,Answer()exten => 97,n,VoiceMailMain(${CALLERID(num)}@default)exten => 97,n,Hangup()
exten => 100,1,Answerexten => 100,n,MusicOnHold(mp3,300)exten => 100,n,Hangup
exten => 101,1,Answer exten => 101,n,Set(DB(${CALLERID(num)}/FOLLOWME)=1) exten => 101,n,Hangup
exten => 102,1,Answer exten => 102,n,Set(DB(${CALLERID(num)}/FOLLOWME)=0) exten => 102,n,Hangup
exten => 123,1,Answer()exten => 123,2,Playback(hello-world)exten => 123,3,Hangup()
exten => 150,1,Answerexten => 150,n,Playback(echo-test)exten => 150,n,Echo(15)exten => 150,n,Hangup
exten => 222,1,Answer
exten => 222,n,Wait(2) exten => 222,n,Festival(Por favor ingrese los 5 digitos del numero del empleado.”) exten => 222,n,Read(EMPNUM,beep,5) exten => 222,n,NoOp(EMPNUM: ${EMPNUM}) exten => 222,n,Set(EMPNAME=${ODBC_TIMECLOCK(${EMPNUM})}) exten => 222,n,GotoIf($[”${EMPNAME}foo” = “foo”]?notfound) exten => 222,n,Festival(El nombre del empleado es ${EMPNAME}. Hasta luego.”) exten => 222,n,NoOp(Employee: ${EMPNAME}) exten => 222,n,Hangup exten => 222,n(notfound),Festival(Ningun empleado corresponde al numero ingresado. Hasta luego.) exten => 222,n,Hangup
exten => 650,1,Answer() exten => 650,n,Festival(Asterisk y Festival trabajan junto. Chevere!!!) exten => 650,n,Hangup()
exten => 660,1,Answer() exten => 660,n,Playback(welcome) exten => 660,n,Swift(En el centro de comunicaciones de VoztoVoice. Espere mientras lo conectamos con una operadora) exten => 660,n,Wait(2)exten => 660,n,Hangup
exten => _100X,1,Macro(followme)exten => _100X,n,Macro(disponible)exten => _100X,n,Dial(SIP/${EXTEN},45,hHkKtTwWxX)exten => _100X,n,GotoIf($[“${DIALSTATUS}” = “BUSY”]?busy:unavail)exten => _100X,n(unavail),Voicemail(${EXTEN}@default,u)exten => _100X,n,Hangupexten => _100X,n(busy),VoiceMail(${EXTEN}@default,b)exten => _100X,n,Hangup
exten => _200[01],1,Agentlogin(${EXTEN})exten => _200[01],n,Hangup
exten => 3000,1,Queue(ventas) exten => 3000,n,Hangup
exten => _4XXX,1,NoOp() exten => _4XXX,n,Dial(SIP/voznet/${EXTEN},30) exten => _4XXX,n,Hangup()
exten => _66XX,1,Answer() exten => _66XX,n,Wait(2)exten => _66XX,n,Record(/tmp/prompt${EXTEN:2}:wav) exten => _66XX,n,Wait(2) exten => _66XX,n,Playback(/tmp/prompt${EXTEN:2})
222
exten => _66XX,n,Wait(2) exten => _66XX,n,Hangup()
exten => 10000,1,Dial(gtalk/gtalk/[email protected])exten => 10000,n,Congestion(3)exten => 10000,n,Hangup
[externas]exten => _3XXXXXXXXX,1,Dial(Mobile/NokiaE71/${EXTEN},45)exten => _3XXXXXXXXX,n,Hangup
exten => _9.,1,Dial(DAHDI/g1/${EXTEN:1},45)exten => _9.,n,Hangup
exten => _00573.,1,Dial(${JUST}/${EXTEN})exten => _00573.,n,Playback(all-outgoing-lines-unavailable)exten => _00573.,n,Hangup()
[conferencias]exten => _350[012],1,Meetme(${EXTEN},scM(default))exten => _350[012],n,Hangup
exten => 3510,1,Meetme(,DM(default))exten => 3510,n,Hangup
exten => _500[01],1,Meetme(${EXTEN}) exten => _500[01],n,Hangup
[dundi-local]exten => _0057.,1,Dial(SIP/justvoip/${EXTEN})exten => _1XXX,1,Dial(SIP/${EXTEN},15)exten => _1XXX,n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)exten => _1XXX,n(busy),Voicemail(${EXTEN}@default,b)exten => _1XXX,n,Hangupexten => _1XXX,n(unavail),Voicemail(${EXTEN}@default,u)exten => _1XXX,n,Hangup
[dundi-remoto]switch => DUNDi/vozorg
[fax]exten => _X.,1,Dial(SIP/justvoip/${EXTEN})exten => _X.,n,Hangup
[from-pstn]exten => s,1,Dial(SIP/1000,45)exten => s,n,Hangup
223
[from-eutelia]exten => s,1,NoOp( Call from Eutelia )exten => s,n,Answerexten => s,n,Wait(2)exten => s,n,Dial(SIP/1000,45)exten => s,n,Hangupexten => fax,1,Dial(IAX2/iaxmodem)exten => fax,n,Hangup
[google-in]exten => s,1,NoOp( Call from Gtalk )exten => s,n,Set(CALLERID(name)=”From Google Talk”)exten => s,n,Dial(SIP/1000,30)exten => s,n,GotoIf($[”${DIALSTATUS}” = “BUSY”]?busy:unavail)exten => s,n(unavail),Voicemail(1000@default,u)exten => s,n,Hangup()exten => s,n(busy),VoiceMail(1000@default,b)exten => s,n,Hangup()
[subscribe]exten => 1000,hint,SIP/1000exten => 1001,hint,SIP/1001exten => 701,hint,park:701@parkedcallsexten => 702,hint,park:702@parkedcallsexten => 703,hint,park:703@parkedcallsexten => 704,hint,park:704@parkedcallsexten => 705,hint,park:705@parkedcallsexten => 706,hint,park:706@parkedcallsexten => 707,hint,park:707@parkedcallsexten => 708,hint,park:708@parkedcallsexten => 709,hint,park:709@parkedcallsexten => 710,hint,park:710@parkedcalls
[solo-internas]include => internasinclude => subscribeinclude => parkedcalls
[phones]include => internasinclude => externasinclude => subscribeinclude => parkedcallsinclude => conferencias
[macro-disponible]
224
exten => s,1,ChanIsAvail(SIP/${MACRO_EXTEN})exten => s,n,Gotoif($[${AVAILSTATUS} = 4]?4:3)exten => s,n,MacroExitexten => s,n,Playback(all-circuits-busy-now)exten => s,n,Hangup
[macro-followme]exten => s,1,Set(FM=${DB(${MACRO_EXTEN}/FOLLOWME)}) exten => s,n,NoOp(${FM}) exten => s,n,GotoIf($[”${FM}” = “1”]?followme:exit) exten => s,n(followme),Followme(${MACRO_EXTEN},san) exten => s,n(exit),Macroexit#include “IVR”
Archivo IVR
[IVR] exten => s,1,Wait(1) exten => s,2,Set(CHANNEL(language)=es) exten => s,3,Set(TIMEOUT(digit)=7)exten => s,4,Set(TIMEOUT(response)=10)exten => s,5,BackGround(custom/espeng)exten => s,6,WaitExten()exten => 1,1,goto(IVR1,s,1)exten => 2,1,goto(IVR2,s,1)exten => i,1,Playback(invalid)exten => i,2,Playback(goodbye)exten => i,3,Hangupexten => t,1,goto(IVR,s,2)exten => h,1,Hangup
[IVR1]exten => s,1,Set(TIMEOUT(digit)=7)exten => s,2,Set(TIMEOUT(response)=10) exten => s,3,Set(CHANNEL(language)=en)exten => s,4,BackGround(custom/engmenu)exten => s,5,WaitExten()exten => 1,1,Playback(demo-echotest)exten => 1,2,Echo() exten => 2,1,MusicOnHoldexten => 3,1,Playback(pls-wait-connect-call)exten => 3,2,Goto(internas,3000,1) exten => i,1,Playback(invalid) exten => i,2,Playback(goodbye) exten => i,3,hangup exten => t,1,goto(IVR1,s,1) exten => h,1,Hangup
225
[IVR2]exten => s,1,Set(TIMEOUT(digit)=7) exten => s,2,Set(TIMEOUT(response)=10) exten => s,3,Set(CHANNEL(language)=es) exten => s,4,BackGround(custom/espmenu) exten => s,5,WaitExten() exten => 1,1,Playback(demo-echotest) exten => 1,2,Echo() exten => 2,1,MusicOnHold exten => 3,1,Playback(pls-wait-connect-call) exten => 3,2,Goto(internas,3000,1) exten => i,1,Playback(invalid) exten => i,2,Playback(goodbye) exten => i,3,hangup exten => t,1,goto(IVR1,s,1) exten => h,1,Hangup
Archivo enviofaxChannel: SIP/justvoip/0039XXXXXXXXXXXCallerid: "FAX"WaitTime: 30Maxretries:3RetryTime: 300Account: 1000Application: SendFaxData: /tmp/prueba.tif
226
Apendice D
GNU Free Documentation LicenseVersion 1.3, 3 November 2008
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. <http://fsf.org/> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or otherfunctional and useful document "free" in the sense of freedom: toassure everyone the effective freedom to copy and redistribute it,with or without modifying it, either commercially or noncommercially.Secondarily, this License preserves for the author and publisher a wayto get credit for their work, while not being considered responsiblefor modifications made by others.
This License is a kind of "copyleft", which means that derivativeworks of the document must themselves be free in the same sense. Itcomplements the GNU General Public License, which is a copyleftlicense designed for free software.
We have designed this License in order to use it for manuals for freesoftware, because free software needs free documentation: a freeprogram should come with manuals providing the same freedoms that thesoftware does. But this License is not limited to software manuals;it can be used for any textual work, regardless of subject matter orwhether it is published as a printed book. We recommend this Licenseprincipally for works whose purpose is instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium, thatcontains a notice placed by the copyright holder saying it can bedistributed under the terms of this License. Such a notice grants aworld-wide, royalty-free license, unlimited in duration, to use thatwork under the conditions stated herein. The "Document", below,refers to any such manual or work. Any member of the public is alicensee, and is addressed as "you". You accept the license if youcopy, modify or distribute the work in a way requiring permissionunder copyright law.
A "Modified Version" of the Document means any work containing theDocument or a portion of it, either copied verbatim, or withmodifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section ofthe Document that deals exclusively with the relationship of thepublishers or authors of the Document to the Document's overallsubject (or to related matters) and contains nothing that could falldirectly within that overall subject. (Thus, if the Document is inpart a textbook of mathematics, a Secondary Section may not explainany mathematics.) The relationship could be a matter of historicalconnection with the subject or with related matters, or of legal,
commercial, philosophical, ethical or political position regardingthem.
The "Invariant Sections" are certain Secondary Sections whose titlesare designated, as being those of Invariant Sections, in the noticethat says that the Document is released under this License. If asection does not fit the above definition of Secondary then it is notallowed to be designated as Invariant. The Document may contain zeroInvariant Sections. If the Document does not identify any InvariantSections then there are none.
The "Cover Texts" are certain short passages of text that are listed,as Front-Cover Texts or Back-Cover Texts, in the notice that says thatthe Document is released under this License. A Front-Cover Text maybe at most 5 words, and a Back-Cover Text may be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy,represented in a format whose specification is available to thegeneral public, that is suitable for revising the documentstraightforwardly with generic text editors or (for images composed ofpixels) generic paint programs or (for drawings) some widely availabledrawing editor, and that is suitable for input to text formatters orfor automatic translation to a variety of formats suitable for inputto text formatters. A copy made in an otherwise Transparent fileformat whose markup, or absence of markup, has been arranged to thwartor discourage subsequent modification by readers is not Transparent.An image format is not Transparent if used for any substantial amountof text. A copy that is not "Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plainASCII without markup, Texinfo input format, LaTeX input format, SGMLor XML using a publicly available DTD, and standard-conforming simpleHTML, PostScript or PDF designed for human modification. Examples oftransparent image formats include PNG, XCF and JPG. Opaque formatsinclude proprietary formats that can be read and edited only byproprietary word processors, SGML or XML for which the DTD and/orprocessing tools are not generally available, and themachine-generated HTML, PostScript or PDF produced by some wordprocessors for output purposes only.
The "Title Page" means, for a printed book, the title page itself,plus such following pages as are needed to hold, legibly, the materialthis License requires to appear in the title page. For works informats which do not have any title page as such, "Title Page" meansthe text near the most prominent appearance of the work's title,preceding the beginning of the body of the text.
The "publisher" means any person or entity that distributes copies ofthe Document to the public.
A section "Entitled XYZ" means a named subunit of the Document whosetitle either is precisely XYZ or contains XYZ in parentheses followingtext that translates XYZ in another language. (Here XYZ stands for aspecific section name mentioned below, such as "Acknowledgements","Dedications", "Endorsements", or "History".) To "Preserve the Title"of such a section when you modify the Document means that it remains asection "Entitled XYZ" according to this definition.
228
The Document may include Warranty Disclaimers next to the notice whichstates that this License applies to the Document. These WarrantyDisclaimers are considered to be included by reference in thisLicense, but only as regards disclaiming warranties: any otherimplication that these Warranty Disclaimers may have is void and hasno effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, eithercommercially or noncommercially, provided that this License, thecopyright notices, and the license notice saying this License appliesto the Document are reproduced in all copies, and that you add noother conditions whatsoever to those of this License. You may not usetechnical measures to obstruct or control the reading or furthercopying of the copies you make or distribute. However, you may acceptcompensation in exchange for copies. If you distribute a large enoughnumber of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, andyou may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly haveprinted covers) of the Document, numbering more than 100, and theDocument's license notice requires Cover Texts, you must enclose thecopies in covers that carry, clearly and legibly, all these CoverTexts: Front-Cover Texts on the front cover, and Back-Cover Texts onthe back cover. Both covers must also clearly and legibly identifyyou as the publisher of these copies. The front cover must presentthe full title with all words of the title equally prominent andvisible. You may add other material on the covers in addition.Copying with changes limited to the covers, as long as they preservethe title of the Document and satisfy these conditions, can be treatedas verbatim copying in other respects.
If the required texts for either cover are too voluminous to fitlegibly, you should put the first ones listed (as many as fitreasonably) on the actual cover, and continue the rest onto adjacentpages.
If you publish or distribute Opaque copies of the Document numberingmore than 100, you must either include a machine-readable Transparentcopy along with each Opaque copy, or state in or with each Opaque copya computer-network location from which the general network-usingpublic has access to download using public-standard network protocolsa complete Transparent copy of the Document, free of added material.If you use the latter option, you must take reasonably prudent steps,when you begin distribution of Opaque copies in quantity, to ensurethat this Transparent copy will remain thus accessible at the statedlocation until at least one year after the last time you distribute anOpaque copy (directly or through your agents or retailers) of thatedition to the public.
229
It is requested, but not required, that you contact the authors of theDocument well before redistributing any large number of copies, togive them a chance to provide you with an updated version of theDocument.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document underthe conditions of sections 2 and 3 above, provided that you releasethe Modified Version under precisely this License, with the ModifiedVersion filling the role of the Document, thus licensing distributionand modification of the Modified Version to whoever possesses a copyof it. In addition, you must do these things in the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.C. State on the Title page the name of the publisher of the Modified Version, as the publisher.D. Preserve all the copyright notices of the Document.E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.H. Include an unaltered copy of this License.I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
230
M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections orappendices that qualify as Secondary Sections and contain no materialcopied from the Document, you may at your option designate some or allof these sections as invariant. To do this, add their titles to thelist of Invariant Sections in the Modified Version's license notice.These titles must be distinct from any other section titles.
You may add a section Entitled "Endorsements", provided it containsnothing but endorsements of your Modified Version by variousparties--for example, statements of peer review or that the text hasbeen approved by an organization as the authoritative definition of astandard.
You may add a passage of up to five words as a Front-Cover Text, and apassage of up to 25 words as a Back-Cover Text, to the end of the listof Cover Texts in the Modified Version. Only one passage ofFront-Cover Text and one of Back-Cover Text may be added by (orthrough arrangements made by) any one entity. If the Document alreadyincludes a cover text for the same cover, previously added by you orby arrangement made by the same entity you are acting on behalf of,you may not add another; but you may replace the old one, on explicitpermission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this Licensegive permission to use their names for publicity for or to assert orimply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under thisLicense, under the terms defined in section 4 above for modifiedversions, provided that you include in the combination all of theInvariant Sections of all of the original documents, unmodified, andlist them all as Invariant Sections of your combined work in itslicense notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, andmultiple identical Invariant Sections may be replaced with a singlecopy. If there are multiple Invariant Sections with the same name butdifferent contents, make the title of each such section unique byadding at the end of it, in parentheses, the name of the originalauthor or publisher of that section if known, or else a unique number.Make the same adjustment to the section titles in the list ofInvariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled "History"in the various original documents, forming one section Entitled"History"; likewise combine any sections Entitled "Acknowledgements",and any sections Entitled "Dedications". You must delete all sectionsEntitled "Endorsements".
231
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and otherdocuments released under this License, and replace the individualcopies of this License in the various documents with a single copythat is included in the collection, provided that you follow the rulesof this License for verbatim copying of each of the documents in allother respects.
You may extract a single document from such a collection, anddistribute it individually under this License, provided you insert acopy of this License into the extracted document, and follow thisLicense in all other respects regarding verbatim copying of thatdocument.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other separateand independent documents or works, in or on a volume of a storage ordistribution medium, is called an "aggregate" if the copyrightresulting from the compilation is not used to limit the legal rightsof the compilation's users beyond what the individual works permit.When the Document is included in an aggregate, this License does notapply to the other works in the aggregate which are not themselvesderivative works of the Document.
If the Cover Text requirement of section 3 is applicable to thesecopies of the Document, then if the Document is less than one half ofthe entire aggregate, the Document's Cover Texts may be placed oncovers that bracket the Document within the aggregate, or theelectronic equivalent of covers if the Document is in electronic form.Otherwise they must appear on printed covers that bracket the wholeaggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you maydistribute translations of the Document under the terms of section 4.Replacing Invariant Sections with translations requires specialpermission from their copyright holders, but you may includetranslations of some or all Invariant Sections in addition to theoriginal versions of these Invariant Sections. You may include atranslation of this License, and all the license notices in theDocument, and any Warranty Disclaimers, provided that you also includethe original English version of this License and the original versionsof those notices and disclaimers. In case of a disagreement betweenthe translation and the original version of this License or a noticeor disclaimer, the original version will prevail.
If a section in the Document is Entitled "Acknowledgements","Dedications", or "History", the requirement (section 4) to Preserveits Title (section 1) will typically require changing the actualtitle.
232
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Documentexcept as expressly provided under this License. Any attemptotherwise to copy, modify, sublicense, or distribute it is void, andwill automatically terminate your rights under this License.
However, if you cease all violation of this License, then your licensefrom a particular copyright holder is reinstated (a) provisionally,unless and until the copyright holder explicitly and finallyterminates your license, and (b) permanently, if the copyright holderfails to notify you of the violation by some reasonable means prior to60 days after the cessation.
Moreover, your license from a particular copyright holder isreinstated permanently if the copyright holder notifies you of theviolation by some reasonable means, this is the first time you havereceived notice of violation of this License (for any work) from thatcopyright holder, and you cure the violation prior to 30 days afteryour receipt of the notice.
Termination of your rights under this section does not terminate thelicenses of parties who have received copies or rights from you underthis License. If your rights have been terminated and not permanentlyreinstated, receipt of a copy of some or all of the same material doesnot give you any rights to use it.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of theGNU Free Documentation License from time to time. Such new versionswill be similar in spirit to the present version, but may differ indetail to address new problems or concerns. Seehttp://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number.If the Document specifies that a particular numbered version of thisLicense "or any later version" applies to it, you have the option offollowing the terms and conditions either of that specified version orof any later version that has been published (not as a draft) by theFree Software Foundation. If the Document does not specify a versionnumber of this License, you may choose any version ever published (notas a draft) by the Free Software Foundation. If the Documentspecifies that a proxy can decide which future versions of thisLicense can be used, that proxy's public statement of acceptance of aversion permanently authorizes you to choose that version for theDocument.
11. RELICENSING
"Massive Multiauthor Collaboration Site" (or "MMC Site") means anyWorld Wide Web server that publishes copyrightable works and alsoprovides prominent facilities for anybody to edit those works. Apublic wiki that anybody can edit is an example of such a server. A
233
"Massive Multiauthor Collaboration" (or "MMC") contained in the sitemeans any set of copyrightable works thus published on the MMC site.
"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.
"Incorporate" means to publish or republish a Document, in whole or in part, as part of another Document.
An MMC is "eligible for relicensing" if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the siteunder CC-BY-SA on the same site at any time before August 1, 2009,provided the MMC is eligible for relicensing.
ADDENDUM: How to use this License for your documents
To use this License in a document you have written, include a copy ofthe License in the document and put the following copyright andlicense notices just after the title page:
Copyright (c) YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
If you have Invariant Sections without Cover Texts, or some othercombination of the three, merge those two alternatives to suit thesituation.
If your document contains nontrivial examples of program code, werecommend releasing these examples in parallel under your choice offree software license, such as the GNU General Public License,to permit their use in free software.
234