Libro Asterisk 1.8.X - Versión 1.0 (1)

March 24, 2018 | Author: Fernando Ruiz | Category: Server (Computing), Software, Computer Networking, Technology, Computing


Comments



Description

Libro Asterisk 1.8.X v. 1.0 Abril 2012 By VozToVoice www.voztovoice.org 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 H de este libro. 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. Copyright (C) 2012-2016 Andrea Sannucci ii INDICE Capitulo I - Instalación de Asterisk ….......................................................................................... 1 1.1 Preparación del VPS Linode 1.2 GRUB, Kernel-XEN y clave RSA 1.3 Utilidades, librerías, dependencias 1.4 Libpri 1.5 DAHDI 1.6 App_fax, GoogleTalk, LibiCAL y SRTP 1.7 Instalación de Asterisk 1 7 16 19 19 21 27 Capitulo II - Configuración inicial de Asterisk ......................................................................... 36 2.1 Instalar y configurar un cortafuego 2.2 Carpetas y archivos 2.3 asterisk.conf 2.4 modules.conf 2.5 Música en espera y MP3 2.6 Preparación del dialplan – extensions.conf 36 39 41 43 45 48 Capitulo III – Protocolo SIP y archivo sip.conf.......................................................................... 54 3.1 sip.conf 3.2 Directmedia 3.3 Contraseñas seguras 3.4 Ngrep 3.5 SoftPhone X-Lite y REGISTER 3.6 Softphone 3CX 3.7 Llamadas entre extensiones 3.8 SIP INVITE y CANCEL 56 69 70 71 72 77 79 80 Capitulo IV – Protocolo IAX2 – iax.conf ................................................................................. 84 4.1 iax.conf 4.2 Softphone Zoiper 84 89 Capitulo V - GoogleTalk – gtalk.conf jabber.conf................................................................... 95 5.1 jabber.conf y gtalk.conf 5.2 Google Voice 95 101 iii 5.3 Aplicación JabberSend 5.4 La función JABBER_RECEIVE 102 104 Capitulo VI - Asterisk y la red PSTN........................................................................................ 107 6.1 Tarjeta Digium TDM410 6.1.1 OSLEC 6.2 Tarjeta Digium TE120P 6.2.1 MFG/R2 – Openr2 6.4 Wanpipe 6.5 Linksys SPA3102 – Gateway FXO/FXS 108 112 116 117 122 124 Capitulo VII - Dialplan – Configuración avanzada.................................................................. 134 7.1 Las Variables 7.2 Pattern Matching 7.3 La aplicación Echo 7.4 El contexto Subscribe 7.5 Las Macro 7.6 Autenticar las Llamadas Salientes con la aplicación Authenticate 7.7 Limitar llamadas salientes: funciones GROUP y GROUP_COUNT 134 137 138 139 143 146 149 Capitulo VIII - IVR …................................................................................................................. 156 8.1 Grabación de las locuciones 8.2 Configuración numero geográfico 8.3 Creación del IVR 156 157 158 Capitulo IX - Funcionalidades avanzadas de Asterisk – features.conf ................................... 164 9.1 features.conf 9.2 Callgroup y Pickupgroup 9.3 Aplicación Dial y features.conf 164 172 174 Capitulo X - Asterisk y los calendarios ….................................................................................. 180 10.1 calendar.conf 10.2 CALENDAR_BUSY 10.3 CALENDAR_EVENT 10.4 CALENDAR_QUERY y CALENDAR_QUERY_RESULT 10.5 CALENDAR_WRITE 10.6 Enviar las notificaciones de los calendarios a números fijos/celulares 181 190 192 194 197 201 iv Capitulo XI - CCSS (Call Completion Supplementary System) – Rellamada …................... 206 11.1 Configuración del CCSS 11.2 CCSS 1ª Prueba 11.3 CCSS 2ª Prueba 11.4 CCSS 3ª Prueba 206 208 209 210 Capitulo XII – Asterisk Realtime............................................................................................... 213 12.1 Realtime estático 12.2 Realtime dinámico 12.2.1 Extensiones SIP en Realtime 12.2.2 Extensiones IAX en Realtime 12.2.3 Dialplan en Realtime dinámico 213 220 220 228 233 Capitulo XIII – IVR avanzados – func_odbc.conf ........... ....................................................... 237 13.1 Empleados 13.2 Encuesta 237 242 Capitulo XIV - Buzón de voz – voicemail.conf........................................................................ 246 14.1 voicemail.conf 14.2 Mensajes de voz en una base de datos 14.3 Buzones de voz en una base de datos Capitulo XV - Las conferencias audio ................................................................................... 15.1 meetme.conf 15.2 Aplicación ConfBridge 15.3 Meetme en Realtime Dinámico 15.4 Aplicación Page 246 258 261 265 265 269 271 274 Capitulo XVI - Distribución automática de llamadas – Colas de espera …........................... 278 16.1 Los agentes 16.2 Las colas de espera – queue.conf 16.3 Agentes dinámicos 16.4 Estadísticas de las colas 16.5 Colas, agentes y estadísticas en Realtime dinámico 278 281 291 294 297 v Capitulo XVII - Asterisk y los FAX …........................................................................................ 309 17.1 IAXmodem 17.2 Hylafax 17.3 Protocolo T38 17.3.1 Aplicación ReceiveFax 17.3.2 Applicación SendFax 309 313 328 332 334 Capitulo XVIII - Conexiones entre servidores Asterisk …....................................................... 339 18.1 Conectar dos servidores Asterisk con el protocolo SIP 18.2 Conectar dos servidores Asterisk con el protocolo IAX2 18.3 El protocolo DUNDi 18.4 Conectar dos servidores Asterisk con OpenVPN 18.5 Conectar dos Servidores Asterisk con TLS y SRTP Capitulo XIX – AMI y AGI …............................................................................................ 19.1 AMI (Asterisk Manager Interface) 19.2 AGI (Asterisk Gateway Interface) 19.3 Las variantes AGI 19.3.1 EAGI 19.3.2 FastAGI 19.3.3 Async AGI 339 343 345 356 374 382 382 391 397 397 398 400 Capitulo XX - Los registros en Asterisk …................................................................................. 405 20.1 CDR (Call Detail Record) 20.1.1 cdr.conf 20.1.2 cdr_manager.conf 20.1.3 CDR adaptive 20.2 CEL (Channel Event Logging) 20.3 Logger.conf 20.3.1 Debug 405 407 409 411 416 423 426 Capitulo XXI - Seguridad en Asterisk …................................................................................... 429 21.1 Reglas de oro 21.2 Fail2ban 429 429 Capitulo XXII - Monitorear Asterisk ….....................................................................................434 vi 22.1 Monit 22.2 SNMP 22.3 Nagios 22.3.1 NDOutils 22.4 Monitoreo calidad llamadas 22.4.1 Monitoreo calidad llamadas desde la consola de Asterisk 22.4.2 Monitoreo calidad llamadas con VoIPMonitor 434 439 442 453 455 455 456 Capitulo XXIII - Conectar un Softphone (Blink) de forma segura: SIP TLS y SRTP …...... 462 23.1 Creación de los certificados 23.2 Configuración Softphone Blink 462 466 Capitulo XXIV - Openfire y Asterisk …..................................................................................... 471 24.1 Instalación de Openfire 24.2 Instalar el Plugin SIPPhone en Openfire 24.3 El Plugin Asterisk-IM 24.4 Asterisk como cliente en Openfire 24.5 Conectar dos servidores Openfire 24.6 Openfire Connection Manager 471 479 483 487 490 494 Capitulo XXV - Asterisk y alta disponibilidad ......................................................................... 499 25.1 Replicación MySQL Master-Slave 25.2 Replicación MySQL Master-Master 25.3 DRBD - Raid1 vía TCP 25.4 Heartbeat 499 505 515 522 Capitulo XXVI - Asterisk GUI …............................................................................................. 529 Capitulo XXVII – FreePBX …................................................................................................... 535 Apéndice A – Instalar CentOS 5.8 en una maquina virtual con VirtualBox Apéndice B – Archivos de configuración Apéndice C – Licencia GNU FDL 542 564 582 vii Introducción Después de unos cuantos meses de trabajo, toma vida la primera versión del libro dedicado a la versión 1.8.X de Asterisk PBX. Como siempre pasa con los manuales, muchos dirán que no se abordaron algunos temas importantes, otros que la parte descriptiva es muy sucinta. La verdad, todos tienen razón. Iba a añadir una cuantos párrafos más pero pensé que podía dejarlo para “mañana”. Lo que si les puedo decir es que en la próxima versión estarán presentes estos termas: • • • Aplicación Chan_spy Aplicación GotoIfTime (para enrutar las llamadas entrantes según la fecha y la hora) El funcionamiento de la negociación de los codec audio a lo largo de una llamada Siempre he sido una persona muy parca con las palabras y la escritura. No me gusta alargarme demasiado cuando escribo y no me gusta que las palabras sobren. Puede ser que en algunas partes del libro me he pasado un poco aplicando esta regla, pero para eso están las primera versiones de un manual. De ellas se aprende para mejorarlas. La que me gusta de este manual es que parte desde la instalación del sistema operativo (Linux CentOS 5.8) y acompaña quien lo lee hacia la instalación y configuración de Asterisk hasta armar una centralita completamente lista para las funciones básicas e intermedias. Todo esto probando cada nueva configuración como si se estuviera trabajando en un laboratorio de prueba. Quiero darles las gracias a los viejos y nuevos participantes a mis cursos a distancia que son los que me animaron y me animan a escribir y mejorar este libro. Es gracias a ellos que he ido aprendiendo cada día más y que me inspiran con sus preguntas a la hora de escribir. viii Capitulo I Instalación de Asterisk Asterisk es el programa Open Source más reconocido para implementar una PBX. Para una lista completa de las funcionalidades brindadas, visiten la página de los desarrolladores. Entre ellas: • • • • • • • • • • Registro (Log) de llamadas Grabación de llamadas Desvío de llamadas Trasferencia de llamadas Conferencias audio Música en espera Gestión de colas (call center) Soporte para tarjetas y Gateway FXO, FXS, digitales y celulares IVR Buzón de voz Este libro abarca la instalación de Asterisk en un VPS (Servidor Virtual Privado) remoto y es valida para cualquier Servidor Linux CentOS. Con el VPS remoto 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. En este caso, considerando la relación calidad/precio, se ha optado por los VPS de la empresa Linode. Para aquellos que quieran trabajar con un servidor local, en la apéndice A es presente una guía para la instalación de CentOS en VirtualBox. 1.1 Preparación del VPS Una vez adquirido el servidor Linode, desde la pagina de administración, se selecciona el enlace que aparece en la imagen que sigue: Se escoge el centro de datos donde se quiere tener el servidor virtual remoto (en este caso Dallas): Terminada la configuración se presiona el botón “Rebuild”.En la nueva ventana que aparecerá se configurarán algunos parámetros (distribución Linux. se crean dos nuevas particiones seleccionando el enlace “Create a new disk image”: 2 . Se deja una parte del espacio del disco duro para crear dos particiones que se utilizarán para la configuración de alta disponibilidad. swap y contraseña del usuario root. En la sección “Disk Images”. Empezará el proceso de instalación y configuración del sistema operativo. Memoria disco. La primera: La segunda: Para añadir las dos particiones al perfil del VPS se selecciona el enlace que aparece en la siguiente imagen: 3 . Por eso en el próximo párrafo se verá como instalar en el servidor la ultima versión disponible del Kernel-XEN. De esta versión no hay las fuentes disponibles y eso imposibilita la instalación de DAHDI.Ya se puede iniciar el servidor presionando el botón “Boot”.18-linode43). el Kernel que se instala es la versión “Latest 3.0 (3. Como se puede ver en la imagen.y en la sección “Block device Assignment”. que aparece en el lado derecho de la pagina de administración de Linode. se puede acceder al servidor con el programa PuTTy (un cliente SSH): 4 . como indicado en la imagen que sigue. Una vez que el servidor esté corriendo. se añaden las dos particiones como mostrado en la imagen: Se va al final de la pagina y se presiona el botón “Save Changes”.0. earth.Para conocer la dirección IP del servidor Linode. Aparecerá la siguiente ventana: 5 .li/~sgtatham/putty/latest/x86/putty. se entra en la siguiente pagina. donde aparecen todos los datos de configuración de la red: Se descarga el programa PuTTy para Windows desde esta pagina: http://the.exe Una vez descargado se ejecuta. Terminada la configuración se presiona el botón “Save” y luego el botón “Open” que aparece más abajo. El resultado será: La primera cosa que hay que hacer es actualizar el sistema: yum -y update y luego reiniciarlo: reboot Se esperan un par de minutos y se vuelve a entrar con el cliente PuTTy. Si se está utilizando Linux se abre una ventana terminal y para conectarse al servidor remoto se ejecuta el siguiente comando: ssh root@IPlinode en lugar de IPlinode se pone la dirección IP publica del servidor remoto.En “Host Name (or IP address) se pone la dirección IP del servidor Linode. en “Port” 22 y en “Saved Sessions” un nombre que identifique la conexión al VPS. Se abrirá una nueva ventana donde en “login as” hay que poner root y en “password” la contraseña que se ha escogido al momento de la instalación del sistema operativo. 6 . el5xen.2 GRUB.18-274.18-274.1./selinux-grub Se puede averiguar que efectivamente se ha instalado el sistema de arranque GRUB con este comando: 7 .img Si las versiones son diferentes se modifican las lineas indicando la versión corriente. se averigua cual es la ultima versión disponible del kernel-xen yum info kernel-xen y se compara con la que aparece en estas lineas del archivo selinux-grub: title CentOS (2.1.org/tmp/selinux-grub Como la versión del Kernel-XEN puede cambiar.6.el5xen root=/dev/xvda initrd /boot/initrd-2.12.6. Kernel-XEN y clave RSA En este párrafo se verá como instalar el sistema de arranque GRUB con la ultima versión disponible del Kernel-XEN y como volver más seguro el acceso al servidor remoto a través de la creación y configuración de SSH utilizando una clave RSA.voztovoice.18-274. Si son iguales.6. se cierra el archivo y se vuelve ejecutable: chmod +x selinux-grub y se inicia: .el5xen) kernel /boot/vmlinuz-2.12.12. antes de ejecutar el script. Primero se descarga y se ejecuta el script que sigue que se ocupará de la configuración de GRUB y de la instalación de Selinux: cd /usr/src wget http://www.1.1. se desabilitan: chkconfig iscsi off chkconfig iscsid off El paso a seguir es modificar la configuración del servidor Linode.ls /boot/grub/ Como el script instala dos servicios relacionados con el protocolo iSCSI que no se necesitan. Desde la pagina de administración se selecciona el enlace que aparece en la imagen: En la nueva pagina se modifican los parámetros como indicado en las dos siguientes imágenes: En Botton Settings – Kernel escogemos “pv-grub-x86_32 8 . li/~sgtatham/putty/latest/x86/puttygen.exe Se ejecuta: 9 .earth. Se abrirá una nueva ventana y después de unos segundos aparecerá esta imagen: Para crear la clave RSA se descarga el programa PuTTygen: http://the.Casi al final de la pagina se modifican los dos parámetros indicados cambiado la opción de Yes a No. en la pagina de Linode se entra en el menú “Remote access” y luego se sigue el enlace “Launch Lish Ajax Console” che permite acceder al servidor desde una consola local. Se regresará a la pagina principal del servidor Linode y de ahí se reinicia: Para averiguar que efectivamente el sistema se reinicia utilizando el Kernel-XEN y el gestor de arranque GRUB. Para terminar se guardan los cambios presionando el botón “Save Changes”. Para la creación de la clave se necesita generar una serie aleatoria de números y se hace moviendo el ratón en el cuadro que aparece bajo la linea “Key”: Hay que seguir moviendolo hasta que la barra que aparece no llegue al final de la linea. Terminada la 10 .En “Number of bits in a generated key” se pone 2048 (se crea una clave de 2048 Byte) y luego se presiona el botón “Generate”. se presiona el botón derecho del ratón y se escoge en el menú “copiar”: 11 .operación se tendrá disponible la clave RSA (publica y privada): Se guarda la clave privada en una carpeta del ordenador local presionando el botón “Save private key”(en este caso se nombra claveprivada): Para continuar se selecciona todo el texto que aparece en la imagen que sigue. ssh se crea el archivo authorized_keys que es donde el sistema operativo buscará las claves RSA publicas del sistema (en este caso para el usuario root): nano authorized_keys se pega el contenido copiado desde PuTTygen que debe quedar todo en la misma linea: 12 . se crea la carpeta ssh: mkdir .ssh se permite el acceso a la carpeta creada solamente al usuario root: chmod 700 .ssh se entra en la carpeta: cd . Se accede nuevamente con PuTTy al servidor remoto y se sigue este procedimiento para utilizar la clave publica.El texto copiado es la clave publica. Se guarda el archivo hundiendo las teclas CTRL-X. Se asigna al archivo recién creado los permisos de lectura y escritura solamente al usuario root: chmod 600 /root/.ssh/authorized_keys Terminada esta operación se modifican algunos parámetros del servidor SSH para permitir el acceso al VPS solamente al usuario root si se autentica con la clave RSA; además, para aumentar la seguridad, se cambia el puerto predefinido para el acceso SSH (22 TCP), escogiendo otro (15000 TCP). Esto se hace modificando el archivo de configuración del servidor SSH: nano /etc/ssh/sshd_config Se buscan estas lineas (para buscar un texto con el editor nano hay que hundir la tecla CTRL junto a la tecla W): #Port 22 #RSAAuthentication yes PasswordAuthentication yes y se modifican para que queden: Port 15000 RSAAuthentication yes PasswordAuthentication no De esta forma se cambia el puerto predefinido para acceder al servidor remoto (de 22 a 15000), se activa el acceso con claves RSA y se desactiva la autentificación con nombre de usuario y contraseña. Se guardan los cambios y se reinicia el servidor SSH: /etc/init.d/sshd restart Se abre otra instancia del cliente SSH: 13 Se pone la IP del servidor Linode, come puerto el 15000 y se asigna un nuevo nombre a esta nueva conexión. En la barra de la izquierda se busca el menú “SSH”, luego “Auth” y se presiona el botón “Browse”. Se busca la clave privada en la carpeta donde se ha guardado anteriormente y se selecciona. Se vuelve al menú Session (en la izquierda) y se guarda esta nueva configuración hundiendo el botón “Save”. Ahora hay dos sesiones disponibles en el cliente SSH: Linode y Linode2. Para acceder al servidor Linux se escoge la sesión Linode2, botón “Load” y luego botón “Open”. Debe aparecer esta ventana: 14 Una vez que se haya escrito el nombre de usuario root en “login as:”, automáticamente el cliente se conectará al servidor autenticándose con la clave RSA creada. Para terminar la configuración del VPS, se modifica la hora predefinida del servidor y, si se quieres, el idioma del sistema operativo: rm /etc/localtime rm: remove regular file `/etc/localtime'? Y En el caso de Colombia, se crea un enlace simbólico a la hora de Bogotá: ln -s /usr/share/zoneinfo/America/Bogota /etc/localtime se averigua que la hora sea exacta con el comando: date Para que la hora se actualice de manera automática se instala el servidor NTP (Network Time Protocol): yum install ntp Se configura para que se inicie automáticamente al arrancar el servidor Linux: chkconfig ntpd on y se inicia: service ntpd start Starting ntpd: Para modificar el idioma predefinido (ingles) y ponerlo en español (de Colombia): nano /etc/sysconfig/i18n se modifica esta linea: LANG="en_US.UTF-8" para que quede: 15 LANG="es_CO.iso88591" Para activar el nuevo idioma basta salir y volver a entrar al servidor con PuTTy. 1.3 Utilidades, librerías, dependencias Antes de la compilación de Asterisk, se instalarán una serie de librerías y dependencias que permitirán obtener la instalación de casi todos los módulos de la PBX. Se empieza con Vorbis que es una librería para la compresión/descompresión audio: yum install libvorbis libvorbis-devel vorbis-tools libogg libogg-devel se sigue con CURL que es un cliente que permite recibir o enviar archivos utilizando los protocolos HTTP, HTTPS, FTP, GOPHER, DICT, TELNET: yum install curl curl-devel libidn-devel se instalan todas las librerías y dependencias que se necesitan para compilar las fuentes: yum install gcc ncurses-devel make gcc-c++ libtermcap-devel zlib-devel libtool bison bison-devel yum install openssl-devel bzip2-devel wget newt-devel subversion flex gtk2-devel a seguir para crear y gestionar las bases de datos, MySQL: yum install mysql mysql-server mysql-devel UNIXODBC que es la implementación Linux de los API ODBC que permiten conectarse a muchos sistemas de gestión de base de datos (ej: MySQL): yum install unixODBC unixODBC-devel mysql-connector-odbc libtool-ltdl-devel Se instala FESTIVAL, que es un sistema de text to speech (disponible en español): yum install festival festival-devel Una vez terminada esta parte se empieza a instalar una serie de programas desde las fuentes; el primero es SPEEX que es un programa para la compresión audio específicamente diseñado para la voz. IMPORTANTE: Para todos los programas que se instalan desde las fuentes, antes de descargarlos, averiguar si hay una versión más reciente disponible. cd /usr/src wget http://downloads.xiph.org/releases/speex/speex-1.2rc1.tar.gz 16 tar -xf speex-1.2rc1.tar.gz cd speex-1.2rc1 ./configure --prefix=/usr make make install Se continua con LAME que es utiliza para codificar archivos audio en formato MP3: cd /usr/src wget http://ufpr.dl.sourceforge.net/sourceforge/lame/lame-3.99.5.tar.gz tar -xf lame-3.99.5.tar.gz cd lame-3.99.5 ./configure --prefix=/usr make make install LIBMAD que es un MPEG audio decodificador de alta calidad: 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=/usr make make install WAVPACK es un compresor audio de alto rendimiento sin perdida de calidad: cd /usr/src wget http://www.wavpack.com/wavpack-4.60.1.tar.bz2 tar -xf wavpack-4.60.1.tar.bz2 cd wavpack-4.60.1 17 ./configure --prefix=/usr make make install Se termina con SOX que es un programa que permite la manipulación de archivos audio y la posibilidad de pasarlos de un formato a otro: cd /usr/src wget http://downloads.sourceforge.net/project/sox/sox/14.4.0/sox-14.4.0.tar.gz tar -xf sox-14.4.0.tar.gz cd sox-14.4.0 ./configure -prefix=/usr Al finalizar el configure aparecerá esta tabla donde se encontrarán todos los formatos audio que se podrán manipular con SOX: Se termina con la compilación e instalación: make make install 18 1.4 LIBPRI En el caso que se quiera instalar tarjetas digitales en el servidor Asterisk (E1, T1, ISDN), antes de instalar DAHDI, hay que instalar la librería libpri cd /usr/src wget http://downloads.asterisk.org/pub/telephony/libpri/libpri-1.4.12.tar.gz se descomprime: tar -xf libpri-1.4.12.tar.gz se entra en la carpeta: cd libpri-1.4.12 se compila y se instala: make make install 1.5 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 las conferencias audio (modulo app_meetme) y el trunking IAX2 (tema tratado en la configuración del archivo iax.conf). Se instala el paquete de desarrollo del Kernel-Xen: yum install kernel-xen-devel IMPORTANTE: La única diferencia con un sistema CentOS local o un servidor dedicado es que se instala el paquete estándar del Kernel: yum install kernel-devel Se continua con la ultima versión disponible de DAHDI-Linux: cd /usr/src wget http://downloads.asterisk.org/pub/telephony/dahdi-linux/dahdi-linux-current.tar.gz tar -xf dahdi-linux-current.tar.gz cd dahdi-linux-2.6.0 19 make make install Se termina con la ultima versión disponible de 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.gz cd dahdi-tools-2.6.0 ./configure make menuselect en la ventana que aparece se seleccionan todos los módulos disponibles como indicado en la imagen que sigue: Se guarda la configuración presionando la tecla tabulador hasta posicionarse sobre “Save & Exit”. Se termina con la compilación e instalación: make make install make config Ya se puede iniciar DAHDI: /etc/init.d/dahdi start Loading DAHDI hardware modules: wct4xxp: wcte12xp: [ OK ] [ OK ] 20 wct1xxp: wcte11xp: wctdm24xxp: wcfxo: wctdm: wcb4xxp: wctc4xxp: xpp_usb: [ OK ] [ OK ] [ OK ] [ OK ] [ OK ] [ OK ] [ OK ] [ OK ] No hardware timing source found in /proc/dahdi, loading dahdi_dummy Running dahdi_cfg: [ OK ] 1.6 App_fax, GoogleTalk, LibiCAL y SRTP En este párrafo se verá como instalar SpanDSP, un procesador de señales digitales que en Asterisk permite la instalación del modulo res_fax para la recepción y envío de FAX, y IKSEMEL que permite implementar el protocolo XMPP en Asterisk y de esta forma conectarse a GoogleTalk y/o a cualquier servidor de tipo XMPP (otro ejemplo es Openfire): Para SpanDSP se necesita instalar primero las librerías libtiff y libxml2: yum install libtiff libtiff-devel libxml2 libxml2-devel se continua con SpanDSP: cd /usr/src wget http://www.soft-switch.org/downloads/spandsp/spandsp-0.0.6pre20.tgz tar -xf spandsp-0.0.6pre20.tgz cd spandsp-0.0.6 ./configure --prefix=/usr make make install El protocolo XMPP permite conexione seguras entre cliente y servidor utilizando el protocolo TLS; para ese efecto se instala, antes de IKSEMEL, las relativas librerías: yum install gnutls gnutls-devel gnutls-utils se continua con IKSEMEL: cd /usr/src 21 wget http://iksemel.googlecode.com/files/iksemel-1.4.tar.gz tar -xf iksemel-1.4.tar.gz cd iksemel-1.4 ./configure --prefix=/usr make antes de la instalación se ejecuta un test para averiguar que la compilación haya tenido éxito: make check PASS: tst-ikstack PASS: tst-iks PASS: tst-sax PASS: tst-dom PASS: tst-sha PASS: tst-md5 PASS: tst-filter PASS: tst-jid ================== All 8 tests passed ================== Ya que todo está bien, se puede instalar: make install Antes de la instalación de Asterisk, se termina la preparación del sistema con unos programas más. Primero un servidor de correo electrónico, SENDMAIL: yum install sendmail sendmail-devel sendmail-cf Se configura para que arranque en automático: chkconfig sendmail on Al alquilar el servidor Linode, cada usuario tiene asignado un sub-dominio que se puede utilizar para la configuración del sistema. Este dato aparece en la pagina de administración de Linode, bajo el menú “Remote Access” 22 En este caso el sub-dominio asignado es li371-235.members.linode.com. Ese nombre se pone en la configuración de red del servidor de la siguiente forma: nano /etc/sysconfig/network al final del archivo se añade la siguiente linea: HOSTNAME=li371-235.members.linode.com Se guardan los cambios y se reinicia el servicio de red: service network restart El sub-dominio se utilizará también para el envío de los correos electrónicos. Por defecto el servidor de correo electrónico escucha solamente en la puerto TCP 25 local. Para que sea alcanzable también desde remoto hay que abrir el archivo de configuración de Sendmail: nano /etc/mail/sendmail.mc buscar esta linea: DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl y modificarla como sigue: DAEMON_OPTIONS(`Port=smtp,, Name=MTA')dnl se guardan los cambios y se vuelve a compilar la configuración de Sendmail: make -C /etc/mail 23 se reinicia el servidor de correo: /etc/init.d/sendmail restart para hacer la prueba de conexión al servidor de correo electrónico desde remoto, se abre una ventana terminal en Windows y se escribe: C:\> telnet -a IPLinode 25 En lugar de IPLinode se pone la IP del servidor Linode. El resultado: 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 del servidor Linux. En Asterisk permite monitorear, entre otras cosas, los canales y las llamadas. Se utilizará junto a NAGIOS para controlar el servidor Asterisk y enviar avisos cuando se verifique algún tipo de problema: yum install net-snmp net-snmp-devel net-snmp-libs net-snmp-utils En Asterisk existe la posibilidad de guardar los registros de las llamadas en un servidor RADIUS a través de un cliente RADIUS que hay que instalar. En este caso se instala desde las fuentes: cd /usr/src wget http://download.berlios.de/radiusclient-ng/radiusclient-ng-0.5.6.tar.gz tar -xf radiusclient-ng-0.5.6.tar.gz cd radiusclient-ng-0.5.6 ./configure --prefix=/usr make make install 24 gz tar -xf lua-5. En este caso se instala desde las fuentes.sourceforge./configure --prefix=/usr 25 . Primero LIBICAL que permite la implementación del protocolo iCalendar (RFC5546) en Asterisk a través del modulo res_calendar: cd /usr/src wget http://downloads.2.gz cd libical-0.lua.org/ftp/lua-5.0.48.48.tar.2.tar.gz cd lua-5.tar.0 Se modifica el archivo Makefile para que el programa se instale por defecto en la carpeta /usr: nano Makefile se modifica esta linea: INSTALL_TOP= /usr/local para que quede: INSTALL_TOP= /usr Se guardan los cambios. Primero unas dependencias: yum install readline-devel luego el programa: cd /usr/src wget http://www.tar. se compila e instala: make linux make install Para terminar se compilan los paquetes que permiten utilizar las nuevas funcionalidades de Asterisk 1.2.gz tar -xf libical-0.X.48/libical-0. Al terminar la instalación de Asterisk se encontrará un archivo de ejemplo en la carpeta /etc/asterisk.Se continua la preparación del servidor con la instalación del lenguaje de programación LUA que permite escribir el dialplan (o plan de marcado) utilizando este lenguaje.net/project/freeassociation/libical/libical-0.8.48 .0. tar.6.29.29. hay que modificar una linea en el archivo que ejecuta el test: nano test/rtpw_test.6.org/neon/neon-0.tar.4.4.4/srtp-1.sh cambiar esta linea: RTPW=rtpw para que quede: RTPW=.6 .gz cd neon-0.4.4. para que tenga éxito.make make install Luego NEON que es una librería que permite la implementación del protocolo WebDAV en Asterisk: cd /usr/src wget http://webdav.tgz cd srtp ./rtpw Se continua con el test: make runtest 26 .gz tar -xf neon-0.net/project/srtp/srtp/1.tgz tar -xf srtp-1./configure --prefix=/usr CFLAGS=-fPIC make Antes de lanzar el make runtest./configure --prefix=/usr make make install Por ultimo la librería LIBSRTP que permite implementar en Asterisk el cifrado del flujo media a través del protocolo SRTP (RFC3711): cd /usr/src wget http://downloads.sourceforge.29.4. 8.11.X está presente un nuevo menú “Channel Event Logging” que como se verá más adelante.8. Se entra en el menú “Add-ons” y se activan los paquetes que siguen: En Asterisk 1.tar.org/pub/telephony/asterisk/asterisk-1. Como se puede notar. Se descarga la ultima versión 1./configure make menuselect Desde la versión 1.8. permite complementar el CDR (call detail record) con nuevas informaciones relacionadas con las llamadas: 27 .11.gz tar -xf asterisk-1.X disponible: cd /usr/src wget http://downloads.0 .8.8. se inicia con la instalación de Asterisk.0.tar.X lo que antes era un paquete a parte (asterisk-addons) ahora es presente en el paquete principal de Asterisk.0.11.asterisk.gz cd asterisk-1.make install 1. los módulos relacionados con MySQL (menos res_mysql) son “deprecated” y en las versiones futuras de Asterisk serán eliminados.7 Instalación de Asterisk Terminada la preparación del servidor.8. En “Resource modules” se controla que los módulos relacionados con las funciones calendario y cifrado del flujo media estén activados: Se seleccionan todos los módulos en el menú “Utilities” y “AGI Samples”: En “Core Sound Packages” se seleccionan todos los paquetes disponibles: 28 . En “Music On Hold File Packages” se hace lo mismo: Como se hace lo mismo en “Extra Sound Packages”: 29 . o] Error 1 make: *** [addons] Error 2 se continua con: contrib/scripts/get_mp3_source.Se guarda la configuración presionando la tecla tabulador hasta posicionarse sobre “Save & Exit”. Se termina con la compilación e instalación: make Si a lo largo de la compilación aparece este error: make[1]: *** [format_mp3.sh y luego otra vez el make: make se instala Asterisk: make install se instalan los archivos de configuración predefinidos: make samples 30 . successfully used password...... Remove anonymous users? [Y/n] y .se configura el script de arranque de Asterisk: make config Terminada la instalación. /etc/init.. se procede a la configuración de MySQL para crear la base de datos y la tabla donde se guardarán los registros de las llamadas.Dropping test database. skipping... moving on...d/mysqld start se configura para que arranque en automático: chkconfig mysqld on y se crea una contraseña para el usuario root de MySQL (sesamo): IMPORTANTE: para un sistema en producción utilizar siempre contraseñas fuertes mysqladmin -u root password sesamo Para asegurar el servidor MySQL se ejecuta el programa: mysql_secure_installation Se contestan las preguntas somo sigue: Enter current password for root (enter for none): sesamo OK.. Reload privilege tables now? [Y/n] y . Success! Cleaning up. Success! Disallow root login remotely? [Y/n] y ... 31 .. Success! Remove test database and access to it? [Y/n] y . Change the root password? [Y/n] n . lastdata varchar(80) NOT NULL default ''. PRIMARY KEY (`id`). calldate datetime NOT NULL default '0000-00-00 00:00:00'. linkedid varchar(80) NOT NULL default ''. lastapp varchar(80) NOT NULL default ''. Se entra en el cliente de MySQL: mysql -u root -psesamo se crea la base de datos asteriskcdr: mysql> create database asteriskcdr. clid varchar(80) NOT NULL default ''. KEY callerid (clid) ). channel varchar(80) NOT NULL default ''. dst varchar(80) NOT NULL default ''. userfield varchar(255) NOT NULL default ''. dcontext varchar(80) NOT NULL default ''. src varchar(80) NOT NULL default ''. 32 . Thanks for using MySQL! Se reinicia el servidor MySQL: service mysqld restart Se crea la base de datos para guardar los registros de las llamadas. uniqueid varchar(32) NOT NULL default ''. billsec int(11) NOT NULL default '0'. dstchannel varchar(80) NOT NULL default ''. peeraccount varchar(20) NOT NULL default ''. duration int(11) NOT NULL default '0'. your MySQL installation should now be secure. amaflags int(11) NOT NULL default '0'. se selecciona: mysql> use asteriskcdr se crea la tabla cdr (copiando y pegando las lineas que siguen): mysql> CREATE TABLE cdr ( id bigint(20) NOT NULL auto_increment.All done! If you've completed all of the above steps. accountcode varchar(20) NOT NULL default ''. disposition varchar(45) NOT NULL default ''. conf. Se renombra el predefinido: mv /etc/asterisk/cdr_mysql.conf se añaden las siguientes lineas: [global] hostname=localhost dbname=asteriskcdr table=cdr password=sesamo user=asterisk port=3306 sock=/var/lib/mysql/mysql.Con la versión 1.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo'.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo'.conf.conf /etc/asterisk/cdr_mysql.sock Los datos: 33 . Se otorgan los permisos de acceso a la base de datos creada al usuario asterisk.8 de Asterisk se han añadido dos nuevos campos a la tabla CDR: • • linkedid peeraccount que permiten tener informaciones más detalladas de cada llamada. se sale del cliente: mysql> quit En Asterisk la conexión a la base de datos y la tabla de los registros de las llamadas. se actualizan los permisos: mysql> flush privileges. desde remoto: mysql> GRANT ALL PRIVILEGES ON asteriskcdr.old se crea uno nuevo: nano /etc/asterisk/cdr_mysql. desde local mysql> GRANT ALL PRIVILEGES ON asteriskcdr. se configura en el archivo cdr_mysql. nombre del usuario que tiene los permisos para acceder a la base de datos port – puerto donde MySQL recibirá las conexiones (predefinido 3306) sock – archivo que se crea cuando se inicia MySQL y que se necesita indicar para una correcta conexión Se guardan los cambios y se inicia Asterisk: /etc/init. Wrote 0 records since last restart.d/asterisk start se averigua que esté corriendo: /etc/init. se entra en la consola: asterisk -rvvvvvvvvvvvvvvvv se controla que la conexión a la base de datos esté activa: CLI> cdr mysql status Connected to asteriskcdr@localhost. 4. 7. 2.. 8.. 6.nombre de la base de datos table . Se sale de la consola: CLI> quit Executing last minute cleanups 34 . 3.contraseña del usuario que tiene los permisos para acceder a la base de datos user .nombre de dominio o IP del servidor MySQL dbname . port 3306 using table cdr for 59 seconds.nombre de la tabla password . 5. [global] – etiqueta inicial del bloque hostname .d/asterisk status asterisk (pid 2403) is running.1. . Cuando no se especifica diversamente. 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 sean 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. Si Asterisk se encuentra instalado en un computador local conectado a Internet a través de un router hay dos opciones: • • Abrir los puertos desde la pagina de administración del router.0.255 menos los paquetes para la interfaz -lo .1 Instalar y configurar un cortafuegos Para proteger el servidor Linux de accesos no autorizados hay que instalar un firewall (cortafuegos) y abrir los puertos que Asterisk necesita para aceptar conexiones externas. En el caso del VPS Linode se instalará y Configurará IPtables. Configurar una DMZ en el router y luego gestionar los puertos directamente con Iptables en el servidor Linux Para instalar iptables: yum install iptables Iptables se encarga de gestionar todos los paquetes que entren y salgan del servidor Linux.Capitulo II Configuración inicial de Asterisk 2. Para eso se utilizan tres tipos de tablas: • la tabla filter donde pasan todos los paquetes en entrada y salida.255.0. 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. 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.0/127.255. iptables -A OUTPUT -j ACCEPT Se deja pasar todo el trafico en entrada para el protocolo SSH (puerto 15000 TCP) iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 15000 -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 al puerto tcp 5060 (protocolo SIP sobre TCP) iptables -A INPUT -p tcp -m state --state NEW -m tcp --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.0. Véase protocolo TCP iptables -A INPUT -m state --state ESTABLISHED. ya que se han definido los puertos base que se necesitan abiertos. se bloquea todo el trafico restante. o relacionados con conexiones establecidas.0.0/8 -j REJECT Se aceptan todos los paquetes en entrada de conexiones ya establecidas.iptables -A INPUT -i ! lo -d 127.RELATED -j ACCEPT Se dejan pasar todos los paquetes salientes. iptables -A INPUT -j REJECT iptables -A FORWARD -j REJECT Se averigua el estado de las reglas definidas con el comando: iptables -L Aparecerá: 37 . anywhere anywhere Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT all -.anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination ACCEPT all -.conf /etc/asterisk/rtp. una vez establecida la conexión entre dos canales.anywhere anywhere Para guardar los cambios: service iptables save Saving firewall rules to /etc/sysconfig/iptables: Se inicia el servicio: service iptables start Para iniciar iptables automáticamente: chkconfig iptables on reject-with icmp-port-unreachable state RELATED. del flujo audio/video) Se renombra el archivo predefinido: mv /etc/asterisk/rtp.anywhere anywhere ACCEPT udp -.anywhere anywhere REJECT all -.Chain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -.conf 38 .ESTABLISHED state NEW tcp dpt:hydap udp dpt:iax udp dpt:sip state NEW tcp dpt:sip udp dpts:ndmp:dnp icmp echo-request reject-with icmp-port-unreachable reject-with icmp-port-unreachable [ OK ] Para terminar hay que configurar Asterisk para que use los puertos UDP desde 10000 hasta 20000 para el protocolo RTP (es el que se encarga.anywhere anywhere REJECT all -.anywhere anywhere ACCEPT udp -.0.anywhere 127.old Se crea uno nuevo: nano /etc/asterisk/rtp.anywhere anywhere ACCEPT udp -.conf.0.anywhere anywhere ACCEPT tcp -.0/8 ACCEPT all -.anywhere anywhere ACCEPT tcp -.anywhere anywhere ACCEPT icmp -. 2 Carpetas y archivos Al terminar la instalación de Asterisk unas cuantas carpetas nuevas serán creadas. /usr/lib/asterisk/modules Contiene todos los módulos compilados y utilizables en Asterisk.Se copian las siguientes lineas: [general] rtpstart=10000 rtpend=20000 rtpchecksums=no dtmftimeout=3000 rtcpinterval=5000 strictrtp=yes Los datos: • • • • • • • [general] – etiqueta inicial del archivo de configuración rtpstart – puerto inicial para el trafico RTP rtpend – puerto final para el trafico RTP rtpchecksums – Activar o no la suma de verificación en los paquetes del trafico RTP dtmftimeout – la cantidad de tiempo (en mili segundos) que un tono DTMF sin marcador de fin tiene los permisos para continuar en el trafico RTP mili segundos entre los reportes del protocolo RTCP (protocolo che se utiliza para controlar el trafico RTP strictrtp – Lo paquetes que no proceden del mismo flujo RTP utilizado en la conexión serán eliminados Se guardan los cambios efectuados y se recarga la configuración de Asterisk: /etc/init.d/asterisk reload 2. /var/lib/asterisk Que a su vez contiene las siguientes carpetas: agi-bin/ 39 . /etc/asterisk Contiene todos los archivos de configuración de Asterisk. outgoing/ Donde hay que mover los archivo de llamadas (call files). keys/ Claves publicas y privadas que Asterisk necesita para autenticarse con otros servidores o servicios (Ej: DUNDi). sounds/ Contiene todas las locuciones que se pueden utilizar en el plan de marcado (dialplan). /var/spool/asterisk Que contiene: dictate/ Donde se guardarán los archivos audio creados con la aplicación Dictate(). monitor/ Si se graba una llamada. esta es la carpeta donde se guardarán los archivos audio. meetme/ Donde se guardarán las grabaciones de las conferencias.txt en la carpeta 40 . images/ Donde las aplicaciones irán a buscar las imágenes cuando se comuniquen con teléfonos que soportan esta función. Véase el archivo callfiles. 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).donde se guardan los script AGI. firmware/ Donde se guardan los firmware de las tarjetas en uso. doc de las fuentes de Asterisk para una explicación del funcionamiento de estos archivos. [directories](!) astetcdir => /etc/asterisk astmoddir => /usr/lib/asterisk/modules astvarlibdir => /var/lib/asterisk astdbdir => /var/lib/asterisk astkeydir => /var/lib/asterisk astdatadir => /var/lib/asterisk astagidir => /var/lib/asterisk/agi-bin astspooldir => /var/spool/asterisk astrundir => /var/run/asterisk 41 . Se divide en cuatro bloques: • • • • un bloque donde se definen las carpetas de trabajo de Asterisk un bloque donde se definen distintas opciones un bloque donde se definen los permisos para el socket de Asterisk un bloque donde se define el tipo de comportamiento que debe tener Asterisk para determinadas aplicaciones (dialplan. que se encuentra en la carpeta /etc/asterisk. 2. buzón de voz). Realtime). llamadas y eventos).conf En el archivo asterisk. tmp/ Carpeta donde se guardan los archivos temporales creados por algunas aplicaciones (Ej. system/ Carpeta para archivos temporales creados por la aplicación System(). /var/run/asterisk Contiene la ID del proceso de Asterisk cuando esté corriendo. AGI. De revisar cuando se tengan problemas con Asterisk. mensajes. se puede modificar la configuración general de Asterisk. voicemail/ Donde se guardarán los archivos audio de los mensajes de voz dejados en el buzón de voz y los mensajes audio personalizados de cada usuario.3 asterisk.conf. /var/log/asterisk Donde se guardarán todos los registros de Asterisk (errores. console = yes .dumpcore = yes .transmit_silence_during_record = yes .cache_record_files = yes .hideconnect = yes El Bloque [options] permite modificar algunas opciones de Asterisk. Por defecto todas las opciones están comentadas (no aplican).documentation_language = en_US .systemname = my_system_name .initcrypto = yes .highpriority = ye .maxload = 0.quiet = yes .languageprefix = yes .internal_timing = yes .record_cache_dir = /tmp .debug = 3 .autosystemname = yes .astlogdir => /var/log/asterisk El Bloque [directories] es donde se pueden cambiar las carpetas de configuración de Asterisk.runuser = asterisk .execincludes = yes .nocolor = yes .transmit_silence = yes .sendfullybooted = yes .transcode_via_sln = yes .nofork = yes .maxcalls = 10 .timestamp = yes .rungroup = asterisk .lightbackground = yes .9 . se quita el punto y coma de la linea nocolors=yes Si el sistema donde está instalado Asterisk no puede cursar más de 30 llamadas. Algunos ejemplos: • • si se quiere quitar los colores en la consola de Asterisk. se pone maxcalls = 30 y se quita el punto y coma delante de la linea 42 .verbose = 3 .alwaysfork = yes .maxfiles = 1000 .minmemfree = 1 .dontwarn = yes . El valor (!) después de la etiqueta [directories] indica que el bloque esta comentado (no será leído por Asterisk). [options] . astctlowner = root . no se curse más llamadas.4 app_set=1.8 y 1.astctlpermissions = 0660 . después de la etiqueta [modules] se encontrará el parámetro: autoload=yes que significa que todos los módulos compilados se cargarán al iniciar Asterisk.6 app_set=1.4 modules. todos los módulos se guardan en la carpeta /usr/lib/asterisk/modules.6 hay que sostituir el pipe con una coma. [compat] pbx_realtime=1.astctlgroup = apache .[files] . no hay forma de saber de cual servidor es un determinado registro. Otra forma de cargar los 43 . .astctl = asterisk.4 res_agi=1. usuarios y nombre del socket de Asterisk. el AGI y el Realtime (temas que serán abordados en lo próximos capítulos).9 si en lugar del usuario y grupo root.• • • si se quiere que al alcanzar un consumo del 0.ctl El Bloque [files] es donde se definen permisos. Para que esto sea posible.6 El Bloque [compat] es donde se puede cambiar el comportamiento de Asterisk para el dialplan. se separaban con un pipe | Desde la versión 1. En las versiones anteriores a la 1.4 2.6 res_agi=1. en cada servidor Asterisk hay que configurar el parámetro systemname con un valor que identifique el servidor Asterisk. De esta forma en los registros de llamadas se podrá saber en cual PBX se originó la llamada. Si se quiere que Asterisk interprete correctamente los pipe hay que modificar las tres lineas de la siguiente forma: [compat] pbx_realtime=1.6 cuando se definían las opciones de una aplicación. Este comportamiento se debe a la configuración predefinida del archivo modules. Si se abre este archivo.conf. se quita el punto y coma delante de maxload = 0. se quiere que el sistema arranque con usuario y grupo asterisk (que hay que crear) se quita el punto y coma delante de runuser = asterisk y rungroup = asterisk si se utiliza un servidor dedicado para la base de datos y todos los registros de llamadas de distintos servidores Asterisk se guardan en ese servidor. todos los módulos serán cargados.9 de la CPU del servidor.conf Cuando se compila Asterisk. Por defecto cuando se inicia Asterisk. Es muy probable que a lo largo de la configuración de Asterisk. Si no se va a utilizar este protocolo. no se necesitará utilizar algunos módulos y es una buena practica desactivarlos de forma que no se carguen al iniciar Asterisk.so app_chanspy.conf y al final se añade la siguiente linea: noload => chan_skinny.conf.so chan_dahdi. Se abre el archivo modules.so Se guardan los cambios y se reinicia Asterisk: service asterisk restart Se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvv y con el comando: CLI> module show like chan se verán todos los canales disponibles: Module chan_local.conf: nano /etc/asterisk/modules. En este modo se reduce la memoria y los recursos utilizados por la PBX.so chan_unistim.so Description Use Count Local Proxy Channel (Note: used internal 0 Inter Asterisk eXchange (Ver 2) 0 Session Initiation Protocol (SIP) 0 DAHDI Telephony Driver w/PRI 0 OSS Console Channel Driver 0 Listen to the audio of an active channel 0 Bridge Interaction Channel 0 Dump Info About The Calling Channel 0 Media Gateway Control Protocol (MGCP) 0 Gtalk Channel Driver 0 UNISTIM Protocol (USTM) 0 44 .módulos podría ser poner ese parámetro en no y luego en el mismo archivo utilizar el parámetro load para cargar los módulos uno a uno. es mejor desactivarlo en el archivo modules. en el caso de los módulos relacionados con ODBC.so chan_bridge.so chan_mgcp.so chan_gtalk.so chan_iax2.so chan_sip. Como se verá más adelante.so chan_oss. Esto se hace utilizando el parámetro noload. hay que utilizar este parámetro para cargarlos antes de todos los demás. Un ejemplo puede ser el canal Skinny que se utiliza en los teléfonos de marca CISCO.so app_dumpchan. En el mismo archivo encontramos el parámetro preload. Este parámetro se utiliza para cargar un modulo antes de todos los demás. En este párrafo se mostrará la configuración de la música en espera con archivos MP3.conf == Parsing '/etc/asterisk/skinny.0. En muchos servicios de asistencia al cliente es típico escucharla mientras se espera que algún operador nos atienda.so => (Skinny Client Control Protocol (Skinny)) El modulo cargado de esta forma quedará activo hasta el siguiente reinicio de Asterisk.so Linux Telephony API Support 0 17 modules loaded El canal chan_skinny no aparece porque se ha configurado para que no se cargue.c:7144 config_load: Configuring skinny from skinny.so Jingle Channel Driver 0 app_channelredirect.mp3 Informaciones sobre el archivo: sox --i fresas. Si en un determinado momento se quiere cargar un modulo que ha sido configurado para no cargarse al iniciar Asterisk.so [Dec 9 11:09:18] NOTICE[3054]: chan_skinny.so Channel information dialplan functions 0 chan_jingle.0:2000 == Registered channel type 'Skinny' (Skinny Client Control Protocol (Skinny)) == Manager registered action SKINNYdevices == Manager registered action SKINNYshowdevice == Manager registered action SKINNYlines == Manager registered action SKINNYshowline Loaded chan_skinny. Primero se crea la carpeta donde guardar los archivos MP3: mkdir /var/lib/asterisk/mohmp3 Ahora se descarga un archivo mp3 en la carpeta creada.so Redirects a given channel to a dialplan 0 app_chanisavail.voztovoice.org/tmp/fresas.conf': == Found == Skinny listening on 0.mp3 45 .0. se utiliza el comando: CLI> module load chan_skinny.so Check channel availability 0 chan_phone.5 Música en espera y MP3 Una de las funcionalidades de Asterisk es la música en espera. cd /var/lib/asterisk/mohmp3 wget http://www.chan_agent. 2.so Agent Proxy Channel 0 func_channel. conf Se añaden las siguientes líneas al final del archivo: [mp3] mode=files directory=/var/lib/asterisk/mohmp3 random=yes • • • • [mp3] – Nombre de la nueva clase de música en espera mode= files – la nueva clase utilizará archivos audio directory=/var/lib/asterisk/mohmp3 – los archivos se encontrarán en la carpeta indicada en el parametro directory random=yes – los archivos audio se utilizarán de forma aleatoria 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. Se modifica de la siguiente manera: nano /etc/asterisk/musiconhold. el paso que sigue es configurar el archivo musiconhold. Aparecerá: Class: default localhosMode: files 46 .conf.Terminada la descarga del fichero MP3. archivo1. Esto porque los archivo MP3 tendrán que ser convertidos en el formato audio requerido por el canal que está accediendo al servicio. sox fresas. Usando la opción -V aparecerá en la pantalla todo el proceso: 47 .el resultado del sampling. 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 el mismo SOX. -r 22050 frecuencia de sampling de 44100 H/z a 22050 Hz.localhosDirectory: /var/lib/asterisk/moh Class: mp3 Mode: files Directory: /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.mp3 -V -r 22050 -c 1 fresas1.mp3 .mp3 • • • -c 1 pasamos el archivo de estéreo a mono (un canal). d/asterisk restart Para luego averiguar que efectivamente el archivo mp3 esté presente en la lista de archivos para la musica en espera [mp3] asterisk -rvvvvvvvvvvvvvvv CLI> moh show files Class: default File: /var/lib/asterisk/moh/macroform-the_simplicity File: /var/lib/asterisk/moh/manolo_camp-morning_coffee File: /var/lib/asterisk/moh/macroform-robot_dity File: /var/lib/asterisk/moh/reno_project-system File: /var/lib/asterisk/moh/macroform-cold_day Class: mp3 File: /var/lib/asterisk/mohmp3/fresas1 2. la extensión es el numero de teléfono interno de una oficina o de un determinado servicio con el que se quiere comunicar. Para que Asterisk sepa come enrutarlas se definen contextos.mp3 rm: remove regular file `fresas.mp3'? Y Para probar la nueva configuración se necesita crear una extensión en el archivo extensions. Todas las llamadas entrantes y salientes se procesan en este archivo. Este archivo se divide en tres bloques: • • • Parte general Parte dedicada a las variables globales el dialplan 48 . En el lenguaje común. En este párrafo se presentará la configuración base del archivo para luego enriquecerlo a lo largo del libro. extensiones y prioridades.conf es donde se define el dialplan de la centralita. Una pequeña paréntesis.Se borra el archivo original: rm fresas.conf El archivo de configuración de Asterisk extensions. En el caso de Asterisk.conf (el dialplan o plan de marcado) que se verá más adelante. IMPORTANTE: cada vez que se modifican o añaden nuevos archivos en la carpeta hay que recargar la configuración de la música en espera o reiniciar Asterisk: /etc/init. Más adelante se verá como se crea un contexto y dentro del contexto las extensiones y las prioridades.6 Preparación del dialplan – extensions. la extensión es una serie de números o letras que definen un bloque del dialplan dentro del cual se ejecutan aplicaciones o funciones de la PBX. yes=el modulo pbx_config no actualiza automáticamente el dialplan si writeprotect=no y static=yes y se guarda la configuración del dialplan con el comando “dialplan save” se perderán todos los comentarios presentes en el archivo. las variables globales mantendrán su valor definido yes=si se recarga el dialplan. Parámetro [general] static Descripción etiqueta que da inicio a la parte general no=cuando se modifica una extensión en el dialplan el modulo pbx_config reescribirá este archivo y se perderán todos los comentarios presentes. De esta forma se podrá controlar quienes tienen acceso y a que. no=si se recarga el dialplan. el valor asociado al parámetro. la llamada será terminada yes=mejora la velocidad de elaboración del dialplan para contextos con un numero elevado de extensiones. Al final del modulo. En este caso SIP/1000 se asocia a la variable JUST el valor SIP/justvoip se asocia a IAX2/marko la variable marko el valor writeprotect autofallthrough extenpatternmatchnew clearglobalvars [globals] 1000 JUST marko Terminada la configuración general y globals se empieza a construir el dialplan. la configuración completa del archivo. se sale del dialplan. se asocia a la variable 1000 un valor. Cada contexto se compone de extensiones y cada extensión de prioridades. si writeprotect=yes no se perderán los comentarios y se desactiva el comando “dialplan save” yes=si una llamada. las variables globales serán reajustadas y asociadas nuevamente desde esta etiqueta empieza la definición de las variables globales.En la columna descripción. Un primero ejemplo: [internas] se define el contexto internas 49 . en negrita. En uno se definirá la parte accesible a todas las extensiones y en el otro la parte dedicada a las llamadas salientes. por cualquier motivo. Para iniciar se crearan dos contexto: internas y externas. exten => 123. 1 es la prioridad y Answer es la aplicación que se utilizará.2. Asterisk contestará la llamada (Answer) ejecutará la aplicación 50 .Answer el comando exten => es para definir una extensión.5: exten => 200.1. Las prioridades indican el orden en que se procesa el dialplan para una determinada extensión.Hangup La n de la segunda y tercera linea está por “next” y añade una prioridad a la que la precede.Playback(hello-world) la extensión es la misma.Answer exten => 123.X de Asterisk hay una forma mucho más sencilla de escribir el dialplan y es la que se utilizará en este libro: exten => 123.n.6. 123 es la extensión.60) same => n. la prioridad es la numero 2 y en este caso la aplicación es Playback cuya función es enviar el audio de una locución al canal que está llamando La tercera linea: exten => 123.Hangup la extensión es siempre la misma.Playback(hello-world) same => n.Answer same => n.1. Desde una extensión conectada a Asterisk se marca 123 y si esa extensión tiene acceso al contexto internas.2.Answer same => n.n.1.1. Desde la versión 1. Otra forma de escribir esta parte del dialplan es: exten => 123.Playback(hello-world) exten => 123.3.MusicOnHold(mp3.Hangup Marcando la extensión 200.Hangup Ahora se configura otra extensión que permite escuchar la música de espera MP3 creada en el párrafo 2. se ejecutará la primera linea. luego la segunda y por ultimo la tercera. la prioridad es la numero 3 y la aplicación es Hangup que lo que hace es terminar la llamada. Con este primer ejemplo ya se puede empezar a entender como funciona el dialplan. En este caso Answer contesta la llamada La segunda linea: exten => 123. 1.old se crea uno nuevo: nano /etc/asterisk/extensions. De esta forma si un determinado contexto incluye a otro.60) same => n. la llamada terminará (Hangup).Hangup [externas] include => internas 51 . La segunda opción (60) define el tiempo. En el dialplan se pueden definir contextos que incluyen otros contextos.Hangup exten => 200.conf /etc/asterisk/extensions. que se escuchará la música.MusicOnHold que permite escuchar la música de espera de una clase configurada en el archivo musiconhold.Playback(hello-world) same => n.1.conf (es este caso la clase mp3).MusicOnHold(mp3. Pasados los 60 segundos. Se renombra el archivo predefinido: mv /etc/asterisk/extensions.Answer same => n.conf. ese contexto tendrá acceso a las extensiones presentes en el contexto incluido.Answer same => n. en segundos. Por ahora se definen dos de esta forma: [externas] include => internas [locales] include => internas Con estos primeros datos se construye el dialplan.conf y se copian las siguientes lineas: [general] static=yes writeprotect=yse autofallthrough=yse extenpatternmatchnew=yse clearglobalvars=no [globals] 1000=SIP/1000 JUST=SIP/justvoip marko=IAX2/marko [internas] exten => 123. dialplan set extenpatternmatch Use the New extension pattern matching algorithm. Hangup() [pbx_config] -= 2 extensions (6 priorities) in 1 context. Answer() [pbx_config] 2. =Para ver el contexto internas: CLI> dialplan show internas [ Context 'internas' created by 'pbx_config' ] '123' => 1. Hangup() [pbx_config] '200' => 1. =Para una lista de comandos disponibles: 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 debug Show fast extension pattern matching data structures dialplan reload Reload extensions and *only* extensions dialplan remove extension Remove a specified extension dialplan remove ignorepat Remove ignore pattern from context dialplan remove include Remove a specified include from context dialplan save Save current dialplan into a file dialplan set chanvar Set a channel variable dialplan set extenpatternmatch Use the Old extension pattern matching algorithm.[locales] include => internas Se guarda la configuración y se recarga el dialplan desde la consola de Asterisk: asterisk -rvvvvvvvvvvvvv CLI> dialplan reload Para ver el dialplan externas: CLI> dialplan show externas [ Context 'externas' created by 'pbx_config' ] Include => 'internas' -= 0 extensions (0 priorities) in 1 context. dialplan set global Set global dialplan variable dialplan show chanvar Show channel variables dialplan show globals Show global dialplan variables 52 [pbx_config] .60) [pbx_config] 3. Playback(helloworld) [pbx_config] 3. MusicOnHold(mp3. Answer() [pbx_config] 2. dialplan show Show dialplan 53 . . • • Hay que pensar en Asterisk como un conmutador que quizás algún día hemos visto en la recepción de . todo lo relacionado con el protocolo SIP.conf El protocolo SIP es un protocolo de señalización que permite: • • • • • localizar un usuario contactar un usuario para determinar su voluntad de establecer una sesión Negociación de los media (audio/video) que se utilizarán a lo largo de la sesión Modificar una sesión establecida Terminar una sesión establecida Este protocolo ha sido definido por la IETF (The Internet Engineering Task Force) que es la entidad que se encarga de definir los estándar para la red Internet. Al momento de configurar una extensión o una troncal. Un usuario (o User Agent como definido en el protocolo SIP) enviará todas sus peticiones a Asterisk que se encargará de procesarlas y de esta forma permitir establecer sesiones media. En este caso el documento que define el protocolo SIP es el RFC (Request for Comments) 3261. H323). que representan las distintas solicitudes que un dispositivo puede enviar a otro. los mensajes que se envían son una mezcla entre el protocolo HTTP (Hypertext Transfer Protocol) y el protocolo SMTP (Simple Mail Transfer Protocol). El archivo sip. Como Asterisk implementa distintos tipos de protocolos (SIP. los proveedores SIP y. En Asterisk.conf está estructurado en tres bloques: • Una parte general donde se define la configuración global del protocolo SIP.conf es donde se definen las extensiones SIP. las troncales y las conexiones a otros servidores Asterisk. estos serán tomados desde la parte general del archivo.Capitulo III Protocolo SIP y el archivo sip. Un ejemplo son los codecs audio. Desde un punto de vista del funcionamiento. él mismo se encargará de establecer llamadas entre usuarios que están utilizando diferentes protocolos. el archivo sip. Los seis métodos principales del protocolo SIP son: • • • • • • REGISTER INVITE BYE ACK CANCEL OPTIONS Asterisk PBX es un B2BUA (back-to-back user agent) y su función es la de hacer de “intermediario” entre los usuarios. si no se definen algunos parámetros. en general. IAX2. Dentro del protocolo SIP existen los métodos. Un bloque central donde se configura el registro a los proveedores VoIP y/o otros servidores Asterisk Una parte final donde se configuran las extensiones internas. En ese documento se explica como deben funcionar programas y/o dispositivos que quieran implementar el protocolo SIP. Se guardan las modificaciones y se reinicia la red del servidor: service network restart Con el comando: ifconfig 56 .255. Para volver la configuración del sip. Asterisk tiene las mismas funcionalidades.conf lo más real posible. Gateway PSTN. buzón de voz. etc.128. llamada a tres.un Hotel o una empresa. y aprovechar los típicos servicios de una PBX como llamada en espera.168. Con las extensiones configuradas se podrán llamar entre ellas. desvío de llamadas.15 NETMASK=255. contestador automático. se activará esta IP local. En los VPS Linode hay la posibilidad de activar una dirección IP local. se podrán enrutar las llamadas a teléfonos fijos y/o celulares.181.0 En IPADDR hay que poner la IP local creada en su VPS Linode. Normalmente se utiliza para la creación de una red local entre distintos VPS que estén en el mismo Datacenter. Para hacerlo se entra en la pagina de administración del VPS y en la pestaña “Remote Access” se escoge el enlace evidenciado en la imagen que sigue: Aparecerá la dirección IP local: Se anota el valor y se configura una nueva tarjeta de red virtual: nano /etc/sysconfig/network-scripts/ifcfg-eth0:1 Se añaden estas lineas: DEVICE=eth0:1 BOOTPROTO=none ONBOOT=yes IPADDR=192. utilizar proveedores SIP. 8.0. Como desde la versión 1. Asterisk soporta el protocolo IPv6 es posible configurar cuatro escenarios distintos: 1. es posible hundir un botón para transferirla a otra extensión. cada línea de la tabla viene acompañada por una breve explicación Si es presente un asterisco antes del nombre del parámetro. a lo largo de una llamada. Posibles opciones: No y Yes si al servidor es asociado un dominio registrado.0 – Asterisk aceptará conexiones solamente si enviadas a la dirección IPv4 indicada 2. Parámetro [general] allowguest Descripción etiqueta que introduce la parte general de la configuración No = no se permiten llamadas entrantes (INVITE) de usuarios no autenticados (aumenta la seguridad de Asterisk) Yes = se permiten llamadas entrantes (INVITE de usuarios no autenticados default = el contexto donde llegarán las llamadas no autenticadas si allowguest=yes En casi todos los teléfonos SIP. Este parámetro define si Asterisk aceptará este tipo de solicitudes.168.0 – Asterisk aceptará conexiones en todas las direcciones IPv4 presentes en el servidor Linux 57 context allowtransfer realm *udpbindaddr . Se deja comentado Es la dirección IP y el puerto donde Asterisk se pondrá a la escucha para las señalización SIP utilizando el protocolo UDP.veremos la nueva tarjeta de red configurada: 3.Asterisk aceptará conexiones solamente si enviadas a la dirección IPv6 indicada 3. 192.conf.8 de Asterisk o que han habido cambios en su configuración. 2600:3c00::f03c:91ff:fedf:a455 .1 sip.conf La configuración que sigue abarca los parámetros más importantes del sip. significa que es una nueva funcionalidad añadida con la versión 1. Al final de la tabla. En negrita la opción que se utilizará para cada parámetro. se puede definir este parámetro para que la autentificación se haga utilizando ese nombre de dominio (digest authentication RFC2617).1. 0. la configuración completa del archivo.0. sera desconectado. Valor: 30 Numero máximo de conexiones no autenticadas permitidas utilizando el protocolo TCP. envía el tiempo de duración de su registro. permitido para REGISTER y SUBSCRIBE entrantes. Valor: 60 Cuando un cliente se registra a Asterisk.Asterisk aceptará conexiones en todas las direcciones IPv4 y IPv6 dando prioridad a la primera IP que encuentra. Este parámetro indica cada cuantos segundos las suscripción tendrá que ser renovada. Valor:100 Permite hacer búsquedas de registros DNS SRV basadas en los nombres de dominio para llamadas SIP salientes del tipo: SIP/usuario@dominio. Como para el protocolo UDP es posible utilizar cuatro escenarios distintos para indicar IP y puerto de escucha.0. En este caso se configurará para que escuche en todas las direcciones Ipv4 puerto 5060. Valor. Valor 3600 Cada vez que un “mensaje” Sip se envía puede atravesar distintos servidores antes de llegar al destinatario. Valor: 0. Con este parámetro se limita el numero de veces que se puede reenviar.6 es posible configurar Asterisk para que permita la señalización SIP sobre el protocolo TCP Valor yes Es la dirección IP y el puerto donde Asterisk se pondrá a la escucha para las señalización SIP utilizando el protocolo TCP.0:5060 tcpenable *tcpbindaddr Desde la versión 1. Valor: Yes Tiempo máximo. Valor: 120 La mayoría de los teléfonos SIP. en segundos. Se utiliza también para evitar que se creen bucles.0. 70 58 tcpauthtimeout tcpauthlimit srvlookup maxexpiry minexpiry defaultexpiry mwiexpiry maxforwards .0:560 Representa el números de segundos que tiene a disposición un cliente para registrarse utilizando el protocolo TCP. En el caso de Linode será IPv6 Como se va a trabajar con Ipv4. :: . Si no lo hace antes del tiempo indicado.0. Esto porque se “suscribe” a este tipo de servicio en el servidor Asterisk. Valor 3600 Tiempo mínimo. para que Asterisk escuche en todas las direcciones IPv4 puerto 5060 (el predefinido) el Valor es: 0.0. En el caso que no lo haga. lo señalan a través de un icono en la pantalla o un indicador luminoso. Asterisk hace esta búsqueda limitándose al primer valor encontrado. en segundos. cuando la extensión registrada recibe un nuevo mensaje en el buzón de voz. permitido para REGISTER y SUBSCRIBE entrantes.Parámetro Descripción 4. Asterisk considerará que el registro durará el tiempo indicado en este parámetro expresado en segundos. Valor: no all – Se desactivan todos los codec audio y video Se indican los codec audio y video utilizables. África y América Latina clase de música de espera predefinida – default Clase de música de espera cuando un canal de tipo peer se pone en espera – default Asterisk. Este parámetro es muy útil para las transferencias atendida de las llamadas entre extensiones Valor: yes En algunos casos. Valor 60 Asterisk contesta a un INVITE entrante con un solo codec audio en lugar de enviar toda la lista de codecs configurados. permite parquear una llamada. Si colgamos. Valor: yes En Asterisk es posible enviar audio aunque la llamada no ha sido contestada. Valor es (Español) Como se verá más adelante cada “mensaje” SIP se compone de diferentes lineas. Esto permite saber si la extensión misma es alcanzable. Valor: default el idioma predefinido para las locuciones . la única forma de actualizar los datos de una sesión es enviando un SIP UPDATE. Cada linea se llama HEADER o cabecera.6. Con este parámetro se activa o desactiva. Este parámetro define se entre los distintos HEADER se envía también el Remote-Party-ID. Un ejemplo es cuando llamamos un numero celular (en Colombia) y si nadie contesta escuchamos la voz que dice "Sistema correo de voz. Como desde la versión 1. no pagamos nada porque la llamada realmente no 59 *preferred_codec_only disallow allow mohinterpret mohsuggest parkinglot language sendrpid rpid_update prematuremedia .X es posible configurar más de un “contexto” de parqueo. Pueden ser indicados uno por linea o en la misma linea separados por una coma: allow=alaw allow=ulaw o allow=alaw. en este parámetro se indica el predefinido. Tendrá cobro a partir de este momento". entre sus funcionalidades. El método OPTIONS del protocolo SIP se utiliza también para conocer los métodos disponible en un determinado cliente.Parámetro qualifyfreq Descripción Cada cuantos segundos enviar un paquete OPTIONS a la extensión registrada en Asterisk. Europa.ulaw ulaw: se utiliza en Estados Unidos. Esto permite que el llamante envíe el flujo audio con el codec que se ha establecido. Canadá y Australia alaw = se utiliza en Asia. Parámetro Descripción ha sido contestada. es utilizado por algunos Gateway para mejorar la compatibilidad con el protocolo SIP 60=si en una llamada establecida no hay flujo audio por 60 segundos la llamada será terminada 300=si en una llamada en espera no hay flujo audio por 300 segundos. Con inband los tonos se envían en el flujo audio (protocolo RTP). Esta serie de códigos. el Asterisk Manager Interface (AMI) genera el correspondiente evento yes=el AMI generará un evento cuando una peer no se pueda autenticar con la PBX yes=cuando un INVITE o un REGISTER es rechazado por Asterisk.0 Personalizar asterisk asterisk protocolo para el envío de los DTMF (Dual-Tone MultiFrequency). la llamada será terminada 0=no envía un paquete UDP utilizando el protocolo RPT para mantener abierto el NAT yes=permite suscribirse al estado de una extensión subscribe=Este parámetro define el contexto que se utilizará 60 sdpsession sdpowner dtmfmode videosupport maxcallbitrate callevents authfailureevents alwaysauthreject use_q850_reason rtptimeout rtpholdtimeout rtpkeepalive allowsubscribe subscribecontext . Este comportamiento se obtiene poniendo como valor no useragent Asterisk se presentará con este nombre al momento de comunicarse con otros servidores o proveedores SIP. Esta funcionalidad se llama "Early Media". 1. Durante el Early Media. Valor: VozToVoice v. Valor: rfc2833 Otro valor bastante común es inband. Inband no funciona con el codec audio G729 no=no se activa el soporte para video llamadas yes=se activa el soporte para video llamadas Banda máxima utilizable para video llamadas (predefinida 384 kb/s) yes=cuando el estado de una extensión cambia. en lugar de enviar el verdadero motivo del rechazo contestará siempre con un 401 Unauthorized no permitiendo dar pistas a los que están intentando acceder al sistema Yes Permite el envío de los códigos Q850 en el Header Reason que normalmente se utiliza para conocer el motivo porque una llamada SIP ha sido terminada. Serían los tonos que se generan cuando se hunden las teclas del teléfono. los tonos DTMF no funcionan y no se pueden utilizar. yes=Notifica si la extensión está timbrando yes= Notifica si la extensión está en espera yes=cuenta el numero de canales utilizados por una extensión. En el caso del VPS Linode se pone la dirección IP local creada (personalizar con la IP local de su VPS) Ejemplo: 192. Desde la versión 1.135 Personalizar Si la dirección IP publica es dinámica o está asociada a un nombre de dominio.126. Los valores permitidos son: • yes = Habilita la detección de FAX T30 y T38 • no = dehabilitado • cng = Habilita la detección de FAX T30 • t38 = Habilita la detección de FAX T38 En el caso que Asterisk esté instalado en una red local que se encuentra detrás de un NAT. En el VPS Linode se deja comentado Cada cuantos segundos actualizar la asociación dirección IP – nombre de dominio.X. hay que indicar el rango de direcciones IP de la red local.128.255. El nuevo modulo se llama res_fax que sustituye el viejo app_fax ahora “deprecated” Valor: yes.128. en lugar de externaddr se utiliza este parámetro. En el VPS Linode se pone la IP del servidor. Si no se posee un nombre de dominio. la aplicación para enviar y recibir fax ha sido reescrita totalmente.8. En el VPS Linode se deja comentado Define el tipo de comportamiento que debe tener Asterisk al conectarse con otras extensiones/dispositivos. Los distintos valores son: no = usa el parámetro rport (RFC3581) solamente si el cliente remoto lo requiere 61 *t38pt_udptl faxdetect localnet externaddr .168. Este parámetro junto a las funciones GROUP y GROUP_COUNT permite limitar el numero de llamadas simultaneas que una extensión puede hacer. Ejemplo 96.maxdatagram=400 Permite diferenciar el tratamiento de las llamadas entrantes según sea un fax o una llamada de voz.externrefresh *nat . Permite el uso del protocolo T38 (fax sobre IP).fec.Parámetro notifyringing notifyhold callcounter Descripción para permitir a las extensiones acceder al estado de otras.121. se puede utilizar el servicio de dyndns. con este parámetro se indica la dirección IP publica de la red.externhost .0/255.0 Si Asterisk está instalado detrás de un NAT. Valor 20 este parámetro representa el numero de intentos que Asterisk hará para registrarse.provider1. en la base de datos se guardará la dirección IP.com. El parámetro se deja comentado y a seguir se presentan algunos ejemplos: • register => fulano:[email protected] Para el registro con el proveedor el username será fulano. 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:sesamo@sip. Valor yes Con esta linea empieza el segundo bloque del archivo sip.media_address rtcachefriends rtupdate register => registertimeout registerattempts . normalmente proveedores SIP o otro servidores Asterisk. Si queremos que las llamadas entre a una extensión definida.provider1.com:5061 En los dos casos las llamadas entrantes llegaran a la extensión s y al contexto que se define en la configuración de la extensión. Se deja comentado Este parámetro aplica cuando las extensiones están configuradas en una base de datos (se verá más adelante).provider1. la contraseña sesamo y el dominio sip.conf y se utiliza para registrarse a servidores externos. Si ponemos 0.com/1234 Si Asterisk pierde el registro. comedia = usa el parámetro rport solamente si requerido por el dispositivo remoto directmedia no=no se permite el flujo media directo (protocolo RPT) entre las extensiones. El flujo directo solo es posible cuando las extensiones no se encuentran detrás de un NAT Si se quiere que el trafico RTP (audio/video) viaje sobre una IP distinta a la de la señalización SIP. Valor 10 62 . 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ña@sip. Cuando una de estas extensiones se registre a Asteirsk. el tiempo de registro y el nombre de usuario. se puede definir en este parámetro. el puerto. los intentos serán infinitos. Valor no este parámetro también aplica cuando las extensiones están configuradas en una base de datos.Parámetro Descripción force_rport = impone siempre el uso del parámetro rport yes = impone siempre el uso del parámetro rport y envía el flujo audio/video por el mismo puerto utilizado por el dispositivo remoto. este parámetro representa el numero de segundos que Asterisk esperará antes de volver a intentar registrarse. éste controlará si hay mensajes de voz pendientes y en caso positivo se lo comunicará usando MWI = Message Waiting Indicator.6. Para subscribirse en la configuración de la extensión se indicará: mailbox=1234@SIP_Remote. Valor: 1234:password@mysipprovider. Personalizar Valor predefinido: pbx909090 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. cuando la extensión se conecte al servidor Asterisk.X se puede subscribir el estado de un buzón de voz de un servidor remoto.Parámetro mwi => Descripción Desde la versión 1. Valor 1000 es=esta extensión utilizará las locuciones en español friend=es un user y peer al mismo tiempo • user: una extensión que se autentica al servidor Asterisk usando el campo From para hacer llamadas. • peer una extensión que se autentica para las llamadas entrantes utilizando la dirección IP y el puerto La contraseña para la extensión. Valor Yes Si este parámetro es configurado. 63 secret qualify mailbox host dtmfmode context . Parámetro [1000] accountcode language type Descripción Numero de la extensión Código que aparecerá en el registro de llamadas para esta extensión. En el caso del VPS Linode todas las extensiones se conectarán detrás de un NAT (router banda ancha y/o otro tipo de conexión Internet). En este ejemplo el buzón 1234 y contexto SIP_remote.com/1234 La ultima parte es dedicada a la configuración de las extensiones. que es una señal audio o vídeo que puede ser recibida por la mayoría de los teléfonos IP o Softphone Valor 1000@default Si la extensión se conecta remotamente con un IP dinámico se pone dynamic. En caso contrario se pone la dirección IP Protocolo para los tonos DTMF Valor rfc2833 El contexto a que tendrá acceso la extensión.2. desde otra extensión. se configuran solamente los parámetros que la diferencian de las demás. Valor 1 para ambos all=se deshabilita todos los codec (audio/video) alaw=se habilita el codec audio alaw g722=se habilita el codec audio g722 g729=se habilita el codec audio g729 h263=se habilita el codec video H263 disallow allow allow allow allow Se configura una segunda extensión: [1001] type=friend accountcode=1001 language=es secret=pbx9091 qualify=yes mailbox=1001@default host=dynamic dtmfmode=rfc2833 context=externas directmedia=no callerid=zutano <1001> callgroup=1 pickupgroup=1 disallow=all allow=alaw allow=g722 allow=g729 allow=h263 Cuando se deben configurar muchas extensiones. como es el caso de una VPS Linode. el valor es no el nombre y el numero que identifica la extensión cuando llama. Para crear un template la primera linea debe tener esta sintaxis: 64 . valor Fulano <1000> Personalizar estos dos parámetros definen una de las funcionalidades avanzadas de Asterisk. se pueden crear templates (plantillas) donde se definen todos los parámetros compartidos por todas las extensiones. es decir la posibilidad de capturar la llamada de una extensión que está timbrando. Luego por cada una de ellas. están detrás de un NAT.Valor externas como se ha creado en el dialplan directmedia callerid callgroup pickupgroup Si las extensiones. com=dominio del proveedor SIP sip. (!) es las sintaxis que indica que se trata de un template.[int-locales](!) [int-locales] es la descripción del template (en este ejemplo se utilizará para configurar todas las extensiones que tienen acceso solo a llamadas locales). Luego se añaden todas las lineas comunes a todas las extensiones: type=friend language=es qualify=yes host=dynamic dtmfmode=rfc2833 context=locales directmedia=no callgroup=1 pickupgroup=1 disallow=all allow=alaw allow=g722 allow=g729 allow=h263 Ahora para configurar una nueva extensión se puede utilizar ese template de la siguiente forma: [1002](int-locales) accountcode=1002 secret=pbx9092 mailbox=1002@default callerid=Mengano <1002> Terminada la configuración de las extensiones.justvoip.com=Este parámetro permite definir el nombre de dominio que aparecerá en la campo From: de la cabecera SIP. Este parámetro permite definir el nombre de usuario que aparecerá en el campo 65 fromuser . Mucho proveedores lo exigen para autenticar las llamadas nombre de usuario.justvoip. se pasa a la troncal SIP utilizando el proveedor JustVoIP: Parámetro [justvoip] type host fromdomain Descripción nombre que se le asigna a la troncal la troncal es de tipo peer sip. conf /etc/asterisk/sip.conf.conf Se pegan las lineas que siguen: [general] allowguest=no context=default allowtransfer=yes .From de la cabecera SIP. Muchos proveedores lo exigen para autenticar las llamadas.old nano /etc/asterisk/sip.0:5060 tcpenable=yes tcpbindaddr=0.realm=mydomain.tld udpbindaddr=0. defaultuser secret qualify dtmfmode context el mismo valor del parametro fromuser la contraseña. yes rfc2833 from-justvoip=el contexto donde llegarán las llamadas si se utiliza el proveedor también para las llamadas entrantes no es no=no hay NAT entre el servidor Asterisk y el proveedor SIP all alaw g729 directmedia language nat disallow allow allow Ahora se puede copiar toda la configuración en el archivo sip.0.0:5060 tcpauthtimeout=30 tcpauthlimit=100 srvlookup=yes maxexpiry=3600 minexpiry=60 defaultexpiry=120 mwiexpiry=3600 maxforwards=70 66 .0.0.conf predefinido y se crea uno nuevo: mv /etc/asterisk/sip. Antes que nada se renombra el archivo sip.0.conf. media_address=0.register => fulano:[email protected] rtcachefriends=no rtupdate=yes . 1.org .0.externhost=prueba.0.register => fulano:[email protected] sdpsession=asterisk sdpowner=asterisk dtmfmode=rfc2833 videosupport=yes maxcallbitrate=384 callevents=yes authfailureevents=yes alwaysauthreject=yes use_q850_reason=yes rtptimeout=60 rtpholdtimeout=300 rtpkeepalive=0 allowsubscribe=yes subscribecontext=subscribe notifyringing=yes notifyhold=yes callcounter=yes t38pt_udptl=yes.com/1234 registertimeout=20 registerattempts=10 67 .com:5061 .fec.provider1.dyndns.register => fulano:contraseñ[email protected]=400 faxdetect=yes localnet= externaddr= .com .externrefresh=180 nat=force_rport directmedia=no .qualifyfreq=60 preferred_codec_only=no disallow=all allow=ulaw allow=alaw mohinterpret=default mohsuggest=default parkinglot=default language=es sendrpid=ye rpid_update=yes prematuremedia=no useragent=VozToVoice v. .mwi => 1234:[email protected]/1234 [1000] accountcode=1000 language=es type=friend secret=pbx9090 qualify=yes mailbox=1000@default host=dynamic dtmfmode=rfc2833 context=externas directmedia=no callerid=callerid=Fulano <1000> callgroup=1 pickupgroup=1 disallow=all allow=alaw allow=g722 allow=g729 allow=h263 [1001] type=friend accountcode=1001 language=es secret=pbx9091 qualify=yes mailbox=1001@default host=dynamic dtmfmode=rfc2833 context=externas directmedia=no callerid=zutano <1001> callgroup=1 pickupgroup=1 disallow=all allow=alaw allow=g722 allow=g729 allow=h263 [int-locales](!) type=friend language=es qualify=yes host=dynamic 68 . hay que personalizar los parámetros localnet y externaddr en el bloque general. Se entra en la consola de Asterisk: asterisk -rvvvvvvvvvv Se escribe el comando: CLI> sip reload Para ver los peer configurados: 69 . Cada vez que se modifica la configuración del sip.com fromuser= defaultuser= secret= qualify=yes dtmfmode=rfc2833 context=from-justvoip directmedia=no language=es nat=no disallow=all allow=alaw allow=g729 Antes de guardar los cambios.com fromdomain=sip.justvoip.conf hay que recargarla. en el bloque del proveedor SIP Justvoip se ponen los datos de usuario y contraseña creados al momento de la creación de la cuenta con el proveedor.justvoip.dtmfmode=rfc2833 context=locales directmedia=no callgroup=1 pickupgroup=1 disallow=all allow=alaw allow=g722 allow=g729 allow=h263 [1002](int-locales) accountcode=1002 secret=pbx9092 mailbox=1002@default callerid=Mengano <1002> [justvoip] type=peer host=sip. 72. 3 offline Unmonitored: 0 online.169.129 5060 OK (160 ms) 4 sip peers [Monitored: 1 online.2 Directmedia Como se ha dicho anteriormente. este parámetro permite definir si el flujo audio es directo entre los 70 .CLI> sip show peers Name/username Host Dyn Nat ACL Port Status 1000 (Unspecified) D N 5060 UNKNOWN 1001 (Unspecified) D N 5060 UNKNOWN 1002 (Unspecified) D N 5060 UNKNOWN justvoip/pbx2020 77. 0 offline] Para ver los users configurados: CLI> sip show users Username Secret 1000 pbx9090 1001 pbx9091 1002 pbx9092 Accountcode Def.Context ACL NAT 1000 phones No Always 1001 phones No Always 1002 phones No Always Para una lista de los comandos disponibles para el protocolo SIP en Asterisk: CLI> help sip sip notify Send a notify packet to a SIP peer sip prune realtime [peer|all] Prune cached Realtime users/peers sip qualify peer Send an OPTIONS packet to a peer sip reload Reload SIP configuration sip set debug {on|off|ip|peer} Enable/Disable SIP debugging sip set history {on|off} Enable/Disable SIP history sip show {channels|subscriptio List active SIP channels or subscriptions sip show channelstats List statistics for active SIP channels 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 mwi Show MWI subscriptions 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 sched Present a report on the status of the sched queue 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 3. 3 Contraseñas seguras En el archivo sip.dispositivos o pasa por Asterisk que se encarga de enrutarlo de una extensión a otra. como los tonos viajan en el flujo audio y Asterisk no recibe ese flujo. La ventaja es que de esta forma se ahorran recursos del servidor Linux. Si en el sip. 3. Para poder entender un poco mejor este comportamiento. Si alguien lograra entrar en el servidor Linux. no se podrán utilizar funcionalidades avanzadas configuradas en Asterisk que utilizan los tonos para ser activadas. podría conocer todas las contraseñas de las 71 . Este escenario funciona solamente si las extensiones no están detrás de un NAT.conf las contraseñas de las extensiones aparecen en texto plano.conf el parámetro dtmfmode=inband. mientras que el flujo media va directo de una extensión a otra. El trafico SIP y RTP pasa completamente por Asterisk. En el caso que directmedia= yes el gráfico cambiaría de la siguiente forma: SIP SIP RPT La señalización SIP sigue pasando por Asterisk. Un típico ejemplo es cuando se instala el servidor Asterisk dentro de una red local y los teléfonos SIP están conectados en la misma red. con solo abrir el archivo. se puede ver el gráfico que sigue: SIP RPT RPT SIP En este escenario directmedia=no. se instala en el servidor Linux el programa NGREP que permite capturar cualquier tipo de paquete que entre o salga del sistema: cd /usr/src primero se instalan unas dependencias: yum install libpcap-devel luego se descarga el paquete: wget http://downloads.45/ngrep-1. pues el comando sería: echo -n "1000:asterisk:pbx9090" | md5sum cuyo resultado será: 5b09185bfc9148923c47cdf60c3a1681 Para utilizar la contraseña cifrada en la configuración de una extensión. 3. es posible cifrarlas con el algoritmo MD5.tar./configure --prefix=/usr make make install 72 .45 se compila y se instala: .tar.conf se ha dejado comentado.extensiones. en el sip.bz2 se descomprime: tar -xf ngrep-1.net/project/ngrep/ngrep/1.45.bz2 se entra en la carpeta creada cd ngrep-1. Para evitar esto y volver más seguro el sistema.45. el valor predefinido es asterisk. Tomamos como ejemplo la primera extensión cuya contraseña es pbx9090.conf en el bloque de la extensión se quita el parámetro secret y se añade el parámetro md5secret asignándole el valor creado.sourceforge.4 Ngrep Como se quiere tener la traza de los mensajes SIP entre Asterisk y las extensiones. Para cifrarla la sintaxis es: echo -n "<extensión>:<realm>:<secret>" | md5sum Como el parámetro real presente en la parte general del sip. puede ser utilizado para las pruebas presentes en este libro.5 SoftPhone X-Lite y REGISTER X-lite es un softphone gratuito desarrollado por la empresa CounterPath que a pesar de sus limitaciones.3. Primero se configura la cuenta 1000 creada en Asterisk: Account name: una descripción de la cuenta UserID: el numero de la extensión Domain: la dirección IP o el nombre de dominio del servidor Asterisk (la IP del VPS Linode) 73 . se instala y se inicia. Se descarga. Este será el numero que hay que marcar para entrar al buzón de voz y que se configurará posteriormente en el dialplan.Password: la contraseña de la extensión 1000 (pbx9090) Display name: el numero de la extensión Authorization name: el numero de la extensión En la pestaña Voicemail: Se selecciona la casilla “check for voicemail” y en “Number to dial for checking voicemail” se pone 97. 74 . se selecciona la casilla “Auto-detect firewall trasversal method using ICE. hay que seleccionar la casilla “None (use local IP address). Interactive Connectivity Establishment es un protocolo (RFC5245) que permite a los dispositivos que lo utilizan. 75 . Si la conexión es contra un servidor local. como la extensión está detrás de un NAT.En Topology. lograr atravesar el NAT. Se regresa a la consola Linux y se hunden las teclas CTRL-C para terminar la captura de paquetes por parte de Ngrep. Se vuelve al X-Lite y se presiona el botón OK. Como el softphone se encuentra detrás de un NAT. se vuelve a la consola de Linux y se escribe el siguiente comando: ngrep 1000 -W byline port 5060 > /tmp/register De esta forma se capturan todos los paquetes enviados y recibidos por la extensión 1000 y se guardan en el archivo register. Si la conexión es a un servidor local se pueden desactivar las dos casillas. y rport.En Advanced se configura cada cuantos segundos X-lite volverá a registrarse a Asterisk (3600). se selecciona “Send SIP keep-alives para mantener la conexión abierta. Después de unos segundos el softphone debería estar registrado a Asterisk. Antes de presionar el botón Ok para guardar la configuración. Ahora se abre el archivo register: nano /tmp/register 76 . Se recomienda la lectura del RFC3261 para entender como funciona la señalización SIP.255. De hecho el método REGISTER del protocolo SIP sirve para esto. Asterisk indica a X-Lite que se requiere una autentificación basada en el protocolo http digest y envía los datos necesarios para que el softphone pueda autenticarse de esta forma.Asterisk X-Lite ------------------Subscribe-------------> Asterisk X-Lite <------------------200 Ok---------------.Asterisk Ahora el X-Llite está registrado y Asterisk puede localizarlo en el caso entre una llamada para la extensión 1000.Asterisk X-Lite ------------------200 Ok-----------------> Asterisk Una vez que Asterisk acepte el SUBSCRIBE enviado por X-Lite. Si se continua a mirar el archivo register se notará que aparece otro bloque que utiliza el método SUBSCRIBE (RFC4235).Encontraremos esta secuencia: X-Lite ------------------Register---------------> Asterisk X-Lite <-------401 Unauthorized-------------.54 D N 10527 OK (135 ms) 77 . Message-Account: sip:[email protected]. La secuencia es: X-Lite ------------------Subscribe-------------> Asterisk X-Lite <-------401 Unauthorized-------------. Voice-Message: 0/0 (0/0).Asterisk En el mensaje 401 Unauthorized. X-Lite responde enviando una nueva petición de REGISTER añadiendo los datos de autentificación X-Lite ------------------Register---------------> Asterisk X-Lite <------------------200 Ok---------------.126. En la consola de Asterisk aparecerá la extensión conectada: asterisk -rvvvvvvvvvvvvvvvvv CLI> sip show peers Name/username Host Dyn Nat ACL Port Status 1000/1000 190.234.121. Claramente todavía no hay ninguno (ultima parte del mensaje NOTIFY enviado por Asterisk): Messages-Waiting: no.Asterisk X-Lite <-----------------NOTIFY---------------. Todo este bloque está relacionado con el buzón de voz de la extensión 1000 y es el que permite a la misma extensión suscribirse a Asterisk para recibir notificaciones cuando sea presente un nuevo mensaje en el buzón de voz. le enviará un NOTIFY para que el softphone sepa si hay mensajes en el buzón de voz. 255.169. se selecciona el icono Conexión: 78 .129:5060 3. En este caso 3CX. Se descarga. en la pantalla que sigue.Otra forma de ver los mensajes SIP es activar el sip debug en Asterisk. Se puede hacer de forma general: CLI> sip set debug on SIP Debugging re-enabled o solamente para una extensión/troncal especifica: CLI> sip set debug peer 1000 SIP Debugging Enabled for IP: 190.6 Softphone 3CX Se instalará un segundo softphone para las pruebas.54:10527 CLI> sip set debug peer justvoip SIP Debugging Enabled for IP: 77.72. se instala y se inicia: Se presiona el botón evidenciado y.234. En la nueva ventana se presiona el botón New y se configura la extensión 1001: Terminada la configuración se presiona el botón OK y nuevamente OK.255.54 D N 10527 OK (134 ms) 79 .234. La extensión se registrará a Asterisk: CLI> sip show peers Name/username Host Dyn Nat ACL Port Status 1000/1000 190. 2 se explicará cosa son y como se utilizan los Pattern-matching.. Si nadie contesta dentro de 30 segundos la llamada terminará (Hangup).conf y al final del contexto internas se añaden las siguientes lineas: exten => _100[0-2]. La variable $ {EXTEN} es una variable de canal (los distintos tipos de variables se presentarán en el párrafo 7. después del contexto internas se crea el contexto internacio y se añaden las siguientes lineas: [internacio] exten => _00.URL]]]) En este caso Technology es SIP.. El proveedor Justvoip requiere que la sintaxis para marcar cualquier numero sea: 00 + código país + numero..Hangup Como se quiere que solamente las extensiones configuradas con el contexto externas tengan acceso a este contexto se añade esta linea al contexto externas: include => internacio para que el bloque quede: [externas] 80 . 1 es la prioridad y Dial es la aplicación que se utiliza para iniciar una llamada. nano /etc/asterisk/extensions. Para poder utilizar el proveedor para las llamadas salientes.7 Llamadas entre extensiones Si desde la extensión 1000 se llama la extensión 1001.1.Dial(SIP/${EXTEN}.options[.234.1) y contendrá el numero marcado.1. resource es ${EXTEN} y timeout es 30 segundos.Hangup En la primera linea. La sintaxis es: Dial(Technology/Resource[&Technology2/Resource2[&.]][.Dial(SIP/justvoip/${EXTEN}.30) same => n.255. De esta formas si marcamos 1000 1001 o 1002 todas las llamadas entrarán en esta parte del dialplan. En el párrafo 7.1001/1001 190.54 D N 10870 OK (220 ms) 3.timeout[. después del comando exten => la “_” indica que se está utilizando un Patternmatching.30) same => n. en la consola de Asterisk aparecerá: NOTICE[29214]: chan_sip. En este ejemplo [0-2] significa que la cuarta cifra puede ser uno 0 un 1 o un 2.c:20785 handle_request_invite: Call from '1000' to extension '1001' rejected because extension not found in context 'externas' Esto porque no se ha configurado todavía el Dialplan para permitir las llamadas entre las extensiones. "SIP/1000. El resultado en la consola de Asterisk será: Executing [1000@externas:1] Dial("SIP/1000-00000001". Se vuelve a la ventana terminal y se termina la captura de los paquetes con CTRLC En el archivo invite estará presente esta secuencia: X-Lite ----------------INVITE---1001-----> <-------401 Unauthorized--------------------------ACK------------------> ----------------INVITE---1001-----> <------------100 Trying-------------------------INVITE 1000--------> <--------180 Ringing-------------<------------180 Ringing------------81 Asterisk 3CX . Para ver como funciona se hará la traza de una llamada con ngrep.8 SIP INVITE y CANCEL El método SIP que se utiliza para iniciar una sesión media. Se contesta la llamada y después de unos segundos se cuelga.30") in new stack y en el teléfono 3CX: 3. En la ventana terminal del servidor se escribe: ngrep 1000 -W byline port 5060 > /tmp/invite Luego desde la extensión 1000 se llama la extensión 1001.include => internas include => internacio Se guardan los cambios y se recarga el dialplan. es INVITE. asterisk -rvvvvvvvvvvvvvvv CLI> dialplan reload Ahora desde la extensión 1000 se marca el numero 1001. Asterisk devuelve el 180 Ringing a X-Lite. En la ventana terminal de linux se escribe: ngrep 1000 -W byline port 5060 > /tmp/cancel Luego desde la extensión 1000 se llama la extensión 1001 y después de unos segundos se cuelga. A partir de este momento termina realmente la llamada. Cuando la extensión 1001 contesta la llamada genera un 200 OK y Asterisk un ACK confirmando que ha recibido el 200 OK. Se vuelve a la ventana terminal y se termina la captura de los paquetes con CTRL-C. X-Lite tiene que autenticarse. Asterisk contesta con un Trying (probando) y envía el INVITE al 3CX que contesta con un 180 Ringing (timbrando).<------------200 OK--------------------------------ACK---------------> <---------------200 OK--------------------------------ACK------------------> Sesion Media <----------------BYE-------------------------------200 OK-------------> <----------------BYE-----------------------------------200 OK-------------------> El X-LIte envía un INVITE para la extensión 1001 a Asterisk. esta es la secuencia: X-Lite ----------------INVITE---1001-----> <-------401 Unauthorized--------------------------ACK------------------> ----------------INVITE---1001-----> <------------100 Trying-------------------------INVITE 1000--------> <--------180 Ringing-------------<------------180 Ringing----------------------------BYE-------------------> <--------------200 OK----------------<-------487 Request Terminated--------------------ACK-----------------> --------------CANCEL-----------> 82 Asterisk 3CX . X-Lite contesta con ACK confirmando que ha recibido la respuesta de Asterisk. Analizando el archivo cancel. Asterisk contesta diciendo que para aceptar el INVITE. Cuando la extensión 1001 cuelga se genera un BYE que es recibido por Asterisk que contesta con un 200 OK. Una segunda prueba es que la extensión 1000 cuelgue antes que la extensión 1001 conteste. luego envía otro INVITE con sus datos de autentificación. Asterisk envía el BYE al X-Lite que contesta con un 200 OK. Asterisk envía el 200 OK a X-Lite y cuando este confirma la recepción del mensaje con un ACK inicia la sesión media (en este caso solo audio) entre las dos extensiones. c:20785 handle_request_invite: Call from '005714013434' rejected because extension not found in context 'locales'.487 Request Terminated------------------ACK----------------> Ahora para probar el proveedor SIP se marca. un numero internacional (por ejemplo la linea de atención al cliente de Avianca): 005714013434 Si se intenta marcar el mismo numero. desde la extensión 1000. desde la extensión 1002 no funcionará ya que esa extensión no tiene acceso al contexto internacio: NOTICE[10455]: chan_sip.<-------------200 OK-------------<----. '1002' to extension De esta forma podemos controlar las extensiones que tienen acceso a las llamadas salientes. como se verá más adelante. 83 . . Una funcionalidad interesante de este protocolo y que quizás puede ser útil implementar en una instalación de Asterisk. DAHDI tiene que ser instalado porque es la fuente de sincronización que IAX2 necesita para funcionar en esta modalidad. de esta forma.0 no=no se realiza la suma de verificación de los paquetes UDP yes=mejora la seguridad contra “brute force password attacks” retrasando el envío de los rechazos de autentificación Automated Message Accounting.0. Parámetro [general] bindport bindaddr Descripción Esta etiqueta define el inicio de la parte general de la configuración del protocolo IAX2 El puerto UDP usado por este protocolo.0. reduciendo de hecho.1 iax. se divide en tres bloques: • • • Una parte general donde se configuran los parámetros del protocolo Un bloque central donde se configuran los registros a proveedores IAX2 o otro servidores Asterisk Un bloque final dedicado a la configuración de las extensiones En la columna descripción aparecerá en negrita el valor del parámetro. los problemas relacionados con el NAT que padece el protocolo SIP. Con este parámetro se configura un nochecksums delayreject amaflags . 4.conf Este archivo.0. como el sip. Este parámetro va configurado antes del bindaddr. A pesar de haber sido aceptado por la IETF y haberse vuelto un estándar de hecho (RFC5456) son muy pocos los proveedores que ofrecen este tipo de conexión y los teléfonos que lo soportan. eliminando. que permite utilizar un único “trunk” para distintos flujos media. La idea detrás de IAX era crear un protocolo que pudiera utilizar el mismo puerto para la señalización y la sesión media. es la del trunking.conf El protocolo IAX (ahora IAX2) ha sido desarrollado por Mark Spencer. el ancho de banda necesario.0.CAPITULO IV Protocolo IAX2 – iax. Para que el trunking sea utilizable en Asterisk.0 Asterisk escuchará en todas la direcciones IP presentes en el servidor Linux. Valor: 0. De hecho IAX2 utiliza el puerto estándar 4569 UDP para la señalización y el transporte de la sesión media. Si se indica 0. toda la configuración del archivo. Valor 4569 Es la dirección IP y el puerto donde Asterisk se pondrá a la escucha para las señalización IAX2 utilizando el protocolo UDP. quien empezó a escribir el código de Asterisk PBX y actual gerente de la empresa Digium. Al final del modulo.conf. medium. Configurando este parámetro con el valor 1240. Pueden ser indicados uno por linea o en la misma linea separados por una coma: allow=alaw allow=ulaw o allow=alaw. Este campo se puede personalizar en cada extensión.Parámetro Descripción campo del CDR (call data records) univoco para todas las llamadas. mejorando la calidad del audio en las conversaciones yes=si no se recibe un ACK después de una NEW enviado dentro de 2000ms. para evitar que el servidor Asterisk se estanque. se anula la solicitud Controla quien tiene la prioridad en la negociación de los codec audio. high all – Se desactivan todos los codec audio y video Se indican los codec audio y video utilizables. Este parámetro acepta como valores: low. es=el idioma predefinido para las locuciones clase de música de espera predefinida – default Clase de música de espera cuando un canal de tipo peer se pone en espera – default Con este parámetro se define el ancho de banda disponible para las llamadas y en base a este se escogerán los codecs audio a utilizar entre los configurados. hay la posibilidad que se verifique una mala calidad del audio.ulaw 60=tiempo mínimo de espiración del registro de las troncales IAX2 60=tiempo máximo de espiración del registro de las troncales IAX2 yes=se habilita el cifrado de la señalización y del flujo media no=no se fuerza el uso del cifrado define el tamaño máximo de los datos (bytes) que pueden pasar por una troncal IAX2 cuando se configura el parámetro trunk=yes. Valor: documentation srvlookup yes=Permite hacer búsquedas de registros DNS SRV basadas en los nombres de dominio para llamadas SIP salientes del tipo: IAX2/usuario@dominio. si los paquetes UDP los fragmenta el sistema operativo Linux. significa que será el mismo Asterisk el que se encargará de fragmentar los paquetes audio más grandes de 1240 byte. Con 128000 bytes pasarán por la troncal 800 llamadas con codec alaw y paquetes audio de 20ms cuando el trafico que pasa por una troncal IAX2 es bastante alto. 86 language mohinterpret mohsuggest bandwidth disallow allow minregexpire maxregexpire encryption forceencryption trunkmaxsize trunkmtu autokill codecpriority . Como la mayoría de los teléfonos IAX no la soportan se indica que es opcional para todas las direcciones IP. Este parámetro con el que sigue hace referencia a esa nueva implementación.0 auto=se requiere el calltoken solo si el teléfono lo soporta El segundo bloque empieza con las lineas de register.0.6.net Registro con nombre usuario.0. Valor yes Asterisk. en la base de datos se guardará la dirección IP.0. Valor: default En septiembre del 2009 hubo una actualización del protocolo IAX2 para mejorar la seguridad. Por ahora se configurará solamente una extensión.0/0.Parámetro Puede ser: • caller • host • disabel rtcachefriends rtupdate Descripción Este parámetro aplica cuando las extensiones están configuradas en una base de datos (se verá más adelante). Valor no este parámetro también aplica cuando las extensiones están configuradas en una base de datos.net Registro con nombre. permite parquear una llamada. Más adelante se verá como configurar una troncal y utilizar IAX2 para el envío de FAX utilizando IAXmodem y Hylafax.linux-support.X es posible configurar más de un “contexto” de parqueo. el tiempo de registro y el nombre de usuario.0.linux-support. Como desde la versión 1. dominio y puerto remoto (sin contraseña) • register => marko:[key]@tormenta. 0. Algunos ejemplos: • register => marko:secretpass@tormenta. Cuando una de estas extensiones se registre a Asteirsk. en este parámetro se indica el predefinido. Parametro [marko] type host Descripción Nombre de la extensión friend Puede ser peer y user Si la extensión se conecta remotamente con un IP dinámico se pone dynamic. entre sus funcionalidades. En caso contrario se pone la dirección IP 87 . contraseña y dominio • register => joe@remotehost:5656 Registo con nombre. clave RSA (key) y dominio parkinglot calltokenoptional requirecalltoken register => En en tercero y ultimo bloque se configuran las troncales/extensiones IAX2. el puerto. 0 nochecksums=no delayreject=yes amaflags=documentation srvlookup=yes language=es mohinterpret=default mohsuggest=defautl bandwidth=high disallow=all allow=alaw allow=alaw minregexpire=60 maxregexpire=60 encryption=yes forceencryption=no 88 . Valor predefinido: pbx9094 El contexto a que tendrá acceso la extensión. Valor auto qualify callerid requirecalltoken Para crear el archivo de configuración de iax.conf /etc/asterisk/iax.0. cuando la extensión se conecte al servidor Asterisk.0.Parametro secret context mailbox Descripción La contraseña para la extensión.conf. se renombra el predefinido y se crea uno nuevo: mv /etc/asterisk/iax.conf Se copian las siguientes lineas: [general] bindport=4569 bindaddr=0.conf. Valor Yes marko Véase parte general. que es una señal audio o vídeo que puede ser recibida por la mayoría de los teléfonos IP o Softphone Valor 1234@default 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. Valor externas Si este parámetro es configurado.old nano /etc/asterisk/iax. éste controlará si hay mensajes de voz pendientes y en caso positivo se lo comunicará usando MWI = Message Waiting Indicator. trunkmaxsize=128000 trunkmtu=1240 autokill=yes codecpriority=host rtcachefriends=no rtupdate=yes parkinglot=default calltokenoptional=0.0.net [marko] type=friend host=dynamic secret=pbx9094 context=externas mailbox=1234@default qualify=yes callerid=marko requirecalltoken=auto Se guardan los cambios y se actualiza la configuración de IAX2: asterisk -rvvvvvvvvvvvvvvv CLI> iax2 reload Para ver la configuración de la extensión recién creada: CLI> IAX2 show peer marko * Name : marko Secret : <Set> Context : externas Parking lot : Mailbox : 1234@default Dynamic : Yes Callnum limit: 0 Calltoken req: Auto Trunk : No Encryption : (aes128.register => marko:[email protected] => joe@remotehost:5656 .net .0.linux-support.keyrotate) Callerid : "marko" <> Expire : -1 ACL : No 89 .0.linux-support.0 requirecalltoken=auto .register => marko:[key]@tormenta.0.0/0. 0. Una vez instalado se escoge el menú Settings -> Preferences en la ventana que aparece se elige "Create New IAX account" 90 . se utilizará el softphone Zoiper. every 10000ms when UNREACHABLE (sample smoothing Off) Para una lista de los comandos disponibles para el protocolo IAX2: CLI> help IAX2 4.Addr->IP : (Unspecified) Port 0 Defaddr->IP : 0.0 Port 4569 Username : Codecs : 0x8 (alaw) Codec Order : (alaw) Status : UNKNOWN Qualify : every 60000ms when OK.2 Softphone Zoiper Para conectarse a la extensión recién creada en el archivo iax.conf.0. Se descarga y se instala. Se entra nuevamente en el Menú "Settings -> Preferences": Se escoge el usuario marko: En alto a la derecha. También en la consola de Asterisk el usuario aparecerá registrado: CLI> IAX2 show peers Name/Username Host Mask Port Status 91 .se pone el nombre de la cuenta (marko) y se hunde el botón OK: Se ponen los datos come definidos en el archivo di configuración iax. aparecerá la voz "Registered".conf y se hunde el botón Register. Luego el botón OK que aparece al fondo de la ventana. 129. 0 offline.129. Se averigua que la extensión esté conectada: asterisk -rvvvvvvvvvvvvvvv CLI> sip show peers Name/username Host Dyn Nat ACL Port Status 1000/1000 190.254.133 D N 5060 OK (137 ms) justvoip/pbx2020 77.129 5060 OK (161 ms) 4 sip peers [Monitored: 4 online.255 26599 1 iax2 peers [1 online. 0 offline Unmonitored: 0 online.169.255.133 (D) 255.72. se configura la extensión 1002: Se presiona el botón o ok y en la nueva ventana se ponen los datos de conexión: Se presiona el botón register y el botón ok que aparece al fondo de la pagina. 0 unmonitored] CLI> quit (E) OK (127 ms) Ya que en Zoiper se pueden configurar también extensiones SIP.254.254.marko 190.129.255.254.133 D N 27256 OK (250 ms) 1002/1002 190. 0 offline] CLI> quit 92 .129.133 D N 27174 OK (125 ms) 1001/1001 190. A partir de este momento, todas las extensiones SIP y IAX2 están conectadas al servidor Asterisk. Los iconos de los tres softphone: Ahora la pregunta: ¿Cómo se configura el dialplan para que se pueda llamar el usuario marko ya que la extensión no es un numero sino un nombre? Se hace de la siguiente manera: nano /etc/asterisk/extensions.conf al final del contexto internas se añade: exten => 1234,1,Dial(IAX2/marko,30) same => n,Hangup Se guardan los datos y se recarga el dialplan asterisk -rvvvvvvvvvvvv CLI> dialplan reload Ahora desde la extensión 1000 se marca 1234. El resultado en la consola de Asterisk: Executing [1234@externas:1] Dial("SIP/1000-00000007", "IAX2/marko,30") in new stack El resultado en Zoiper: De esta forma se ha hecho la prueba de una llamada entre dos teléfonos con distintos protocolos. 93 CAPITULO V GoogleTalk – gtalk.conf jabber.conf Como se ha visto a lo largo de la instalación de Asterisk, la centralita soporta el protocolo XMMP que permite conectarla a servidores que utilizan ese protocolo. En Asterisk el modulo relacionado es el res_jabber.so. Para ver si efectivamente este modulo ha sido compilado y instalado correctamente, se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvvvv Primero se controla que el modulo exista: CLI> module show like res_jabber Module Description Use Count res_jabber.so AJI - Asterisk Jabber Interface 0 1 modules loaded luego se quita y se vuelve a cargar para controlar eventuales errores: CLI> module unload res_jabber.so == Unregistered application 'JabberSend' == Unregistered application 'JabberSendGroup' == Unregistered application 'JabberStatus' == Unregistered application 'JabberJoin' == Unregistered application 'JabberLeave' == Manager unregistered action JabberSend == Unregistered custom function JABBER_STATUS == Unregistered custom function JABBER_RECEIVE > JABBER: Disconnecting CLI> module load res_jabber.so == Parsing '/etc/asterisk/jabber.conf': == Found == Manager registered action JabberSend == Registered application 'JabberSend' == Registered application 'JabberSendGroup' == Registered application 'JabberStatus' == Registered application 'JabberJoin' == Registered application 'JabberLeave' == Registered custom function 'JABBER_STATUS' == Registered custom function 'JABBER_RECEIVE' Loaded res_jabber.so => (AJI - Asterisk Jabber Interface) Al cargar un modulo aparecen las aplicaciones y las funciones que ese modulo activa. Se sale de la consola: CLI> quit Para la configuración de un usuario GoogleTalk en Asterisk además del modulo res_jabber.so, hay que configurar el modulo chan_gtalk que es el que permite llamadas de este tipo: • • • Asterisk → GoogleTalk GoogleTalk → Asterisk Asterisk → GoogleVoice Esto significa que se podrán recibir llamadas de usuarios GoogleTalk en Asterisk y luego, a través de la configuración del dialplan, enrutarlas a cualquier extensión configurada en la PBX. Siempre configurando adecuadamente el dialplan será posible, desde una extensión, llamar usuarios GoogleTalk y efectuar llamadas utilizando el servicio GoogleVoice. Para la configuración se aconseja crear una nueva cuenta en Google. 5.1 jabber.conf y gtalk.conf Se empieza con el archivo de configuración jabber.conf. Como siempre en la columna descripción, en negrita, aparecen los valores que hay que configurar. Al final de las tablas, la configuración de los dos archivos. Parámetro [general] debug autoprune Descripción etiqueta que define el inicio de la parte general no=no se activa el debug en la consola de Asterisk yes=se activa el debug en la consola de Asterisk yes=elimina automáticamente los usuario de la lista de amigos no=no elimina automáticamente los usuarios de la lista de amigos yes=si un usuario añade el usuario configurado en este archivo a su lista de amigos, Asterisk automáticamente lo añadirá a la lista de amigos no=no lo añade automáticamente A partir de la versión 1.8 de Asterisk es posible monitorear el estado de las extensiones remotas utilizando el protocolo XMPP. Este parámetro indica si se habilita el soporte para la especificación XEP-048 del protocolo XMPP. Se deja comentado Este parámetro especifica si los nodos para el monitoreo de las extensiones remotas se crean en automático o no. Se deja comentado. autoregister ;collection_nodes=yes ;pubsub_autocreate=yes 96 ;auth_policy=accept=yes La especificación XEP-048 se basa en un sistema de suscripciones que los usuarios activan para recibir actualizaciones. Con este parámetro en yes las suscripciones de los usuarios se aceptan en automático. Se deja comentado A partir de esta etiqueta, la configuración del usuario GoogleTalk. Suponiendo que el usuario creado es [email protected], en la etiqueta se pone el nombre de usuario. Personalizar con el nombre del usuario google creado. puede ser client o component dominio del servidor GoogleTalk. Valor: talk.google.com [campus.voztovoice] type serverhost ;pubsub_node=pubsub.dominio.com Nombre del nodo para publicar los eventos para la configuración del monitoreo de extensiones remotas. Se deja comentado username secret port usetls usesasl El nombre del usuario creado en Google. En este ejemplo [email protected]. Personalizar la contraseña asociada al usuario creado en Google. Personalizar 5222 Es el puerto que utiliza GoogleTalk para aceptar conexiones yes=se activa el protocolo TLS. De esta forma todos los paquetes intercambiados entre cliente y servidor serán cifrados yes=se activa el protocolo sasl. Sasl es un protocolo de autentificación y autorización que permite la negociación de protocolos de cifrado entre cliente y servidor. si se quiere añadir un amigo a la lista de amigos directamente desde la configuración del archivo se indica en este parámetro. Si los amigos que se quieren añadir son distintos, se pone una linea con este parámetro para cada amigo. Para este ejemplo se pone [email protected] en esta linea. Se especifica si esta conexión se utilizará o no para la generación de eventos en la configuración del monitoreo de las extensiones remotas. Se deja comentado Mensaje de estado que aparecerá junto al nombre de usuario. Valor: Asterisk Server 100=tiempo máximo para la entrega de un mensaje (en segundos) buddy ;distribute_events=yes statusmessage timeout Terminada la configuración del archivo jabber.conf, se continua con el archivo gtalk.conf. En la columna descripción, en negrita, aparecen los valores que hay que configurar. 97 Parámetro [general] context bindaddr Desc inicia la parte general del archivo contexto del dialplan donde entrarán las llamadas de los usuarios GoogleTalk. Valor: google-in dirección ip para la escucha de peticiones GoogleTalk. Se configura para que escuche en todas las direcciones presentes en el servidor. Valor: 0.0.0.0 A partir de la versión 1.8 de Asterisk se ha añadido este parámetro, que permite definir la IP publica del servidor. Se pone la IP de Linode no=no se permiten llamadas de usuarios GoogleTalk que no estén en la lista de amigos yes=se permiten a partir de esta etiqueta empieza la configuración para los usuarios huéspedes (que no están en la lista de amigos). all=se desactivan todos los codec audio alaw=se activa el codec audio alaw google-in=nombre del contexto del dialplan donde llegarán las llamadas de usuarios huéspedes se pone la etiqueta definida en el jabber.conf para el usuario GoogleTalk configurado en Asterisk. en este ejemplo es campus.voztovoice. Personalizar a partir de esta linea, se definen todos los amigos que se quiere tener en la lista. Para un ejemplo real el usuario es voztovoicenet. nombre del usuario: [email protected] all=se desactivan todos los codec audio alaw=se activa el codec audio alaw se pone la etiqueta definida en el jabber.conf para el usuario GoogleTalk configurado en Asterisk. en este ejemplo es campus.voztovoice. Personalizar el contexto del dialplan donde llegarán las llamadas del usuario google-in externip allowguest [guest] disallow allow context connection [voztovoicenet] username disallow allow connection context Una vez definidos todos los parámetros de jabber.conf y gtalk.conf, se crean los respectivos archivos. Primero se renombran los predefinidos: mv /etc/asterisk/jabber.conf /etc/asterisk/jabber.conf.old 98 mv /etc/asterisk/gtalk.conf /etc/asterisk/gtalk.conf.old Luego se crea el archivo jabber.conf: nano /etc/asterisk/jabber.conf se pegan las siguientes lineas: [general] debug=yes autoprune=no autoregister=yes ;collection_nodes=yes ;pubsub_autocreate=yes ;pubsub_autocreate=yes [campus.voztovoice] type=client serverhost=talk.google.com ;pubsub_node=pubsub.dominio.com [email protected] secret=password port=5222 usetls=yes usesasl=yes [email protected] ;distribute_events=yes statusmessage=Asterisk Server timeout=100 IMPORTANTE: antes de guardar la configuración, hay que personalizar los parámetros username, secret y la etiqueta [campus.voztovoice], con los datos de su cuenta Google. Se pasa al archivo gtalk.conf nano /etc/asterisk/gtalk.conf [general] context=google-in bindaddr=0.0.0.0 externip=IPasterisk allowguest=yes 99 [guest] disallow=all allow=alaw context=google-in connection=campus.voztovoice [voztovoicenet] [email protected] disallow=all allow=alaw connection=campus.voztovoice context=google-in IMPORTANTE: antes de guardar la configuración, hay que personalizar el parámetro connection con la etiqueta inicial de la configuración del usuario GoogleTalk en el archivo jabber.conf (en este ejemplo campus.voztovoice) y el parámetro externip. Terminada la configuración de los dos archivos se entra en la consola de Asterisk y se recargan los dos módulos; primero res_jabber.so y luego chan_gtalk.so: asterisk -rvvvvvvvvvvvvv CLI> module unload res_jabber.so CLI> module unload chan_gtalk.so CLI> module load res_jabber.so CLI> module load chan_gtalk.so Después de algunos segundos, el usuario debería estar conectado: CLI> jabber show connections Jabber Users and their status: User: [email protected] ---Number of users: 1 - Connected Para ver la lista de amigos conectados ([email protected]) CLI> jabber show buddies Jabber buddy lists Client: [email protected] Buddy: [email protected] Resource: talk5D9E1034 node: http://www.asterisk.org/xmpp/client/caps version: asterisk-xmpp 100 Jingle capable: yes Status: 1 Priority: 10 Para una lista de comandos disponibles en los dos módulos CLI> help jabber jabber create collection Creates a PubSub node collection. jabber create leaf Creates a PubSub leaf node jabber delete node Deletes a PubSub node jabber list nodes Lists PubSub nodes jabber purge nodes Purges PubSub nodes 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 connections Show state of clients and components jabber test Shows roster, but is generally used for mog's debugging. CLI> help gtalk gtalk show channels Show GoogleTalk channels Por ultimo si se entra en GoogleTalk con otro nombre de usuario y se añade a la lista de amigos el usuario configurado en Asterisk (en este ejemplo [email protected]), el resultado será: El icono del teléfono que aparece, indica que se puede tener una conversación audio con ese usuario. Ahora se pasa al dialplan. Como contexto para las llamadas entrantes de usuarios GoogleTalk, se ha definido google-in. Este contexto va creado en el dialplan: nano /etc/asterisk/extensions.conf Después del bloque internas se añaden estas lineas. [google-in] exten => s,1,NoOp( Call from Gtalk ) same => n,Dial(SIP/1000,30) same => n,Hangup() Todas las llamadas que entren desde GoogleTalk se desvían a la extensión 1000. Si dentro de treinta segundos la extensión 1000 no contesta, la llamadas terminará Para las llamadas salientes se pone al final del contexto internas: 101 exten => _[a-z].,1,Dial(gtalk/campus.voztovoice/${EXTEN},30) same => n,Hangup Una explicación de las dos lineas: Se dice a Asterisk de llamar a través del canal gtalk, usando la conexión campus.voztovoice que es la etiqueta que inicia el bloque de configuración del usuario [email protected]. Con _[a-z]. se puede marcar a cualquier usuario GoogleTalk cuyo nombre empieza con una letra del alfabeto (de a a z). Si después de 30 segundos, nadie contesta, se termina la llamada. Para que esto funcione, hay que añadir un bloque nuevo en el archivo gtalk.conf para cada nuevo usuario siguiendo las mismas pautas utilizadas para configurar el usuario [email protected]. En el caso que se quiera llamar un usuario no configurado en gtalk.conf, hay que añadirlo de esta forma en el dialplan (contexto internas): exten => 10000,1,Dial(gtalk/campus.voztovoice/[email protected],30) same => n,Hangup suponiendo que [email protected] es el usuario que se quiera llamar. Se guardan los cambios. Otra forma de actualizar el dialplan sin entrar en la consola de Asterisk es: asterisk -rx "dialplan reload" Dialplan reloaded. Se puede hacer una primera prueba llamando el usuario [email protected] desde el X-LIte Se marca de esta manera: Se presiona el botón “Call”. El resultado: Para llamar al usuario [email protected] se marcará la extensión 10000 desde X-Lite. Como nota utilizando el cliente GoogleTalk en un celular Android, es posible efectuar llamadas al usuario configurado en Asterisk pero no es posible (hasta el momento) recibirlas. 5.2 Google Voice Google Voice es el servicio de Google que permite efectuar llamadas a cualquier parte del mundo. Esta 102 funcionalidad es disponible en la pagina personal de la cuenta Google: Desde la versión 1.8.X de Asterisk, es posible efectuar llamadas utilizando una cuenta Google Voice. Para llamar, por ejemplo, a Estados Unidos, la sintaxis es +1 más el numero a llamar. En el contexto internacio del dialplan: nano /etc/asterisk/extensions.conf se añade: exten => _1XXXXXXXXXX,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com) same => n,Hangup Como se puede ver el + se pone delante de la variable ${EXTEN} ( +${EXTEN}). De esta forma no hace falta marcarlo. Para las llamadas a cualquier otro país la sintaxis es + código país numero. En el mismo contexto internacio se añade: exten => _NNXX.,1,Dial(gtalk/campus.voztovoice/+${EXTEN}@voice.google.com) same => n,Hangup 5.3 Aplicación JabberSend Una aplicación que se activa con el modulo res_jabber.conf es “JabberSend” que permite enviar mensajes instantáneos a usuarios GoogleTalk. La sintaxis de la aplicación es: 103 JabberSend(Jabber,JID,Message) Un ejemplo. Cada vez que una extensión llame la extensión de la música en espera, queremos enviar un mensaje a un usuario GoogleTalk para que se entere. Se modifica el dialplan: nano /etc/asterisk/extensions.conf se cambia este bloque: exten => 200,1,Answer same => n,MusicOnHold(mp3,60) same => n,Hangup para que quede: exten => 200,1,Answer same => n,Jabbersend(campus.voztovoice,[email protected],Estamos escuchando MP3) same => n,MusicOnHold(mp3,60) same => n,Hangup Cambiar “campus.voztovoice” con la etiqueta que define el usuario configurado en el archivo jabber.conf; cambiar el usuario [email protected] con el usuario Gmail al que se quiere enviar el mensaje. Se guardan los cambios y se recarga el dialplan: asterisk -rx "dialplan reload" Desde la extensión 1000 se marca la extensión 200. El resultado: 5.4 La función JABBER_RECEIVE La función JABBER_RECEIVE ha sido añadida en la versión 1.8 de Asterisk. Esta función permite interactuar con un usuario Google Talk a través del envío y recepción de mensajes de textos. Para el envío de mensajes de texto se utiliza la aplicación SendText que permite, cuando un canal ya está conectado, enviar texto a ese canal. 104 es enviar un mensaje de texto a un usuario Google Talk para pedirle su nombre y luego almacenar su respuesta en una variable.30) same => n. se modifica el dialplan: nano /etc/asterisk/extensions. es la etiqueta definida para el usuario Google Talk configurado en el archivo jabber. para que se vea como funciona.La sintaxis de la función es: asterisk -rvvvvvvvvvvvvvv CLI> core show function JABBER_RECEIVE JABBER_RECEIVE(account. Se guardan los cambios y se recarga el dialplan: asterisk -rx "dialplan reload" 105 .30) same => n.Dial(SIP/1000.SendText(Espera un momento mientras te comunicamos con un operador) same => n.1. es el nombre del usuario Google Talk con el que se quiere interactuar timeout.Set(CALLERID(name)=${nombre}) same => n. bienvenido en VozToVoice) same => n.Hangup() La variable ${CALLERID(name)} contendrá el nombre del usuario Google Talk.Set(nombre=${JABBER_RECEIVE(campus.${CALLERID(name)}.Wait(2) same => n.Dial(SIP/1000. que tendrá el usuario Google Talk para escribir una respuesta Un ejemplo sencillo.NoOp( Call from Gtalk ) same => n.timeout]) • • • account.Hangup() para que quede: [google-in] exten => s. en segundos. Para efectuar la prueba.SendText(Hola ${nombre}.conf este bloque: [google-in] exten => s.voztovoice.NoOp( Call from Gtalk ) same => n.voztovoice) jid. es el tiempo.1.Como te llamas?) same => n.jid[.conf (en este caso campus.SendText(Hola.20)}) same => n. se llama el usuario configurado en Asterisk. lo ponga en comunicación con un determinado departamento de la empresa Solicitar al usuario Google Talk dos números a llamar y luego desde Asterisk comunicarlos entre ellos. Posibles aplicaciones de esta función: • • • Brindar a los usuarios Google Talk. la posibilidad de crear una extensión en Asterisk digitando todos los parámetros relacionados crear un IVR textual que permita al usuario GoogleTalk escoger una opción que. el nombre que el usuario ha digitado en la ventana de chat de Google Talk. 106 . Este es un ejemplo muy sencillo.Ahora desde un usuario GoogleTalk. En la ventana de chat de Google Talk: En el X-Lite: Aparecerá como callerid. por ejemplo. . . Estos dispositivos pueden ser de distintos tipos: • • • • • • Tarjetas o Gateway FXO Tarjetas o Gateway FXS Tarjetas o Gateway mixtos (FXO-FXS) Tarjetas o Gateway BRI (ISDN) Tarjetas o Gateway PRI (primarios E1.CAPITULO VI Asterisk y la red PSTN Asterisk puede ser conectado a la red telefónica tradicional a través de tarjetas telefónica o Gateway. La diversa nomenclatura de estas lineas está relacionada con los países donde se usan. Los dispositivos BRI (Basic rate interface) permiten conectar una linea ISDN (Integrated Services Digital Network) al servidor Asterisk. E1 en Europa y gran parte de latino américa. J1. T1. son lineas digitales que según el tipo brindan de 23 (T1) o 30 (E1) canales de voz. Brasil y Argentina). Los dispositivos Mixtos FXO/FXS combinan los dos tipos de conexiones según las necesidades del adquirente. En la E1 los canales de señalización son los 0 y 16. Un ejemplo de dispositivo FXO/FXS es la tarjeta Digium TDM410 que permite instalar un total de 4 módulos. J1 en Japón. FXS (Foreign Exchange Station) es un dispositivo de computador que permite conectar éste a un teléfono analógico. . Los dispositivos E1. realizar y recibir llamadas de teléfono. y mediante un software especial. J1) Tarjetas o Gateway GSM/UMTS FXO (Foreign Exchange Office) es un dispositivo de computador que permite conectar éste a la RTB. sean FXO o FXS. Las lineas ISDN están compuestas por dos canales audio (de 64Kbit/s cada uno) y un canal (D) para la señalización con la central telefónica (de 16 Kbit/s). T1. que también se pueden denominar primarios. En la T1 los canales 0 y 24 son reservados para la señalización. T1 son la lineas disponibles en Estados Unidos. En este capitulo se verá como instalar las siguientes tarjetas: • • Digium TDM410 con 4 puertos FXO Digium TE120 (E1) y los siguientes programas: • • • OSLEC para la cancelación de eco El driver Wanpipe para tarjetas Sangoma La librería open2r para la señalización de primarios que se utiliza en algunos países de latino américa (entre ellos México. 6. Se comprueba que la tarjeta ha sido reconocida: lspci -n debe aparecer: 0000:01:00. 7. 3. En este caso se instalará con 4 módulos FXO para cuatro lineas telefónicas analógicas. 5. 4.d/dahdi stop El primer archivo que hay que modificar es el /etc/dahdi/system. Antes de iniciar con la configuración se para Asterisk y luego DAHDI: /etc/init. Encender el computador Normalmente CentOS reconoce automáticamente la nueva tarjeta instalada y le asigna un IRQ para que pueda comunicar con el procesador del computador. 2. Los pasos a seguir son: 1. Apagar el computador Desconectar el cable de alimentación Abrir el chasis del Computador Insertar la tarjeta en una ranura PCI disponible Volver a poner el chasis del computador Conectar el cable de alimentación al computador Conectar las lineas telefónicas a los puertos FXO de la tarjeta a través de un normal cable telefónico 8.conf 109 .0 0200:d161:8005 Ahora se puede configurar.1 Tarjeta Digium TDM410 La tarjeta Digium TDM410 puede hospedar 4 módulos de tipo FXO y FXS.d/asterisk stop /etc/init. 6. la zona geográfica donde se va a utilizar la tarjeta.. entre otras cosas. congestión. ocupado. Los países cuya configuración está disponibles son: • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • Estados Unidos (us) Australia (au) Francia (fr) Holanda (nl) Inglaterra (uk) Finlandia (fi) España (es) Japon (jp) Noruega (no) Austria (at) Nueva Zelanda (nz) Italia (it) Grecia (gr) Taiwan (tw) Chile (cl) Suecia (se) Bélgica (be) Singapur (sg) Israel (il) Brasil (br) Hungría (hu) Lituania (lt) Polonia (pl) Sudáfrica (za) Portugal (pt) Estonia (ee) México (mx) India (in) Alemania (de) Suiza (ch) Dinamarca (dk) Republica Checa (cz) China (ch) Argentina (ar) Malasia (my) Tailandia (th) Bulgaria (bg) Venezuela (ve) Filipinas (ph) 110 . Esto sirve para la generación de los tonos de la linea (timbrando. etc.).En ese archivo se define. "425" }.!0/10.ringcadence = { 1500.0 nano zonedata. { DAHDI_TONE_RECORDTONE. .! 425/100.• • • • • • Rusia (ru) Turquía (tr) Panamá (pa) Macao China (mo) Costa Rica (cr) Emiratos Árabes (ae) Para Colombia esta configuración no está presente y para activarla hay que modificar un archivo de la fuentes de dahdi-tools: cd /usr/src/dahdi-tools-2. .0/250" }. "425/250.!0/100.425/350. 111 . .!0/100. }.0/250" }.mfr2_level = -8. "425/1000.0/15000" }.425" }. "!950/330.c al final del archivo.!425/100.!0/100. antes de esta linea: { .0/4500" }.!1400/330. .6. "1400/500. "425" }. . .dtmf_high_level = -9.dtmf_low_level = -11. { DAHDI_TONE_BUSY. { DAHDI_TONE_RINGTONE.int/ITU-T/inr/forms/files/tones-0203. "425/100.!0/100. { DAHDI_TONE_STUTTER. { DAHDI_TONE_CALLWAIT.0/250.!425/100. }.itu.0/6000" }. .zone = -1 } se añaden las siguientes lineas: { . "400+450/300. "!425/100. .0/250.description = "Colombia".mfr1_level = -7. 4000 }.!0/100.!1800/330.0/1000" }.pdf */ { DAHDI_TONE_DIALTONE.country = "co".zone = 46.425/650.!425/100. { DAHDI_TONE_INFO.tones = { /* References: http://www. { DAHDI_TONE_DIALRECALL.!0/100.!425/100. IMPORTANTE: El contenido de la linea DAHDI_TONE_SHUTTER tiene que estar en el mismo renglón. { DAHDI_TONE_CONGESTION. Predefinida es mg2: echocanceller = mg2.2. en este caso se configuran 4 modulos FXO: fxsks=1-4 que se puede escribir también: fxsks=1.3.4 para terminar se define la cancelación de eco.old y se crea uno nuevo: nano /etc/dahdi/system.Se guardan los cambios y se vuelve a compilar dahdi-tools: make distclean .1-4 Se guardan los cambios.conf /etc/dahdi/system. Para mejorar la cancelación de eco se instala OSLEC 112 .conf Se añaden las primeras dos lineas relacionadas con la zona geográfica: loadzone = co defaultzone = co Se define el tipo de señalización (fxsks para FXO y fxoks para FXS)./configure make manuselect make make install make config se renombra el archivo predefinido: mv /etc/dahdi/system.1-4 El archivo final será: loadzone = co defaultzone = co fxsks=1-4 echocanceller = mg2.conf. 6./staging/echo/|" /usr/src/dahdi-linux2.6.6. ¿Por qué OSLEC logra solucionar con mayor eficacia los problemas de eco? Porque a pesar que sea un cancelador de eco de 32ms.0/drivers/staging/echo/Kbuild 113 ..voztovoice.bz2 Se preparan las fuentes de DAHDI para la compilación de OSLEC: mkdir /usr/src/dahdi-linux-2.28. actúa justo en los casos en que se produce este tipo de retraso.tar. Más alto el tiempo de retraso.6.28 wget http://www. las compañías telefónicas no aplican ningún tipo de cancelación de eco y es propio en estos casos que los 32ms de OSLEC son suficientes para cancelar el eco de manera satisfactoria.6./staging/echo/|obj-m += .0/drivers/staging cp -fR /usr/src/linux-2.0/drivers/dahdi/Kbuild echo 'obj-m += echo.6.tar. son las mismas compañías telefónicas que normalmente se encargan (a nivel de centrales) de eliminar el eco que se produce. Cuando las llamadas son internacionales y el eco producido considerable (centenares de ms). Las librerías DAHDI vienen con un cancelador de eco software que a veces no logra solucionar este tipo de problema.1.bz2 se descomprimen: tar -xf linux-2.org/campus/pbx05/linux-2.6.28.o|" /usr/src/dahdilinux-2.6..o|obj-m += dahdi_echocan_oslec. Cuando las llamadas son locales o de larga distancia.1 OSLEC El eco es generado por la reflexión del audio trasmitido que se devuelve a quien lo ha originado con un retraso que puede variar de algunos mili segundos a centenares de mili segundos. OSLEC está disponible en la fuentes del Kernel a partir de la versión 2. OSLEC ha sido desarrollado por David Rowe.6.6.o' > /usr/src/dahdi-linux-2. más fastidioso el eco.0/drivers/staging sed -i "s|#obj-m += dahdi_echocan_oslec.28 Para instalarlo se siguen estos pasos: cd /usr/src se descargan las fuentes del Kernel 2.28/drivers/staging/echo /usr/src/dahdi-linux-2. un ingeniero electrónico australiano. En estos casos la mejor solución es instalar el cancelador de eco OSLEC.0/drivers/dahdi/Kbuild sed -i "s|#obj-m += . 1-4 Para terminar la configuración de la tarjeta hay que modificar el archivo chan_dahdi.conf nano /etc/dahdi/system.0 make distclean .conf se cambia esta linea echocanceller=mg2.6.0 make distclean make make install DAHDI-Tools: cd /usr/src/dahdi-tools-2.conf /etc/asterisk/chan_dahdi./configure make menuselect make make install make config Se modifica el system.Ahora se recompilan DAHDI-linux y DAHDI-tools: cd /usr/src/dahdi-linux-2.old y se crea uno nuevo: nano /etc/asterisk/chan_dahdi.6.conf Se añaden las siguientes lineas: [trunkgroups] [channels] language=es 114 .1-4 para que quede: echocanceller=oslec.conf.conf se renombra el predefinido: mv /etc/asterisk/chan_dahdi. 5.0.1 DAHDI Version: Echo Canceller(s): Configuration 2.1 OSLEC 115 .2. En este caso los cuatro canales FXO pertenecen todos al grupo 1 Reiniciamos primero DAHDI y luego Asterisk /etc/init.context=from-pstn overlapdial=yes signalling=fxs_ks toneduration=100 usecallerid=yes cidsignalling=v23 cidstart=polarity hidecallerid=no callwaiting=yes callwaitingcallerid=yes threewaycalling=yes transfer=yes canpark=yes cancallforward=yes callreturn=yes echocancel=yes relaxdtmf=yes rxgain=2. A partir de la linea channel => se configuran los canales.4.0 txgain=3.d/asterisk start Se controla que efectivamente la cancelación de echo configurada sea OSLEC: dahdi_cfg -vvv DAHDI Tools Version .d/dahdi start /etc/init.0 callerid = asreceived amaflags=documentation accountcode=pstn busydetect=yes busycount=6 mohinterpret=default mohsuggest=default group=1 channel => 1-4 En el bloque channels se configuran los parámetros validos para todos los canales. 45) same => n. nano /etc/asterisk/extensions.conf al final del contexto internas se pone: 116 .====================== El en servidor Linode.45) same => n.Dial(DAHDI/G1/${EXTEN:1}.45) same => n.1Dial(DAHDI/g1/${EXTEN:1}.Hangup G1= Usa las líneas del grupo X de Mayor a menor exten => _9[12456789]XXXXXXX!. se recibirán solamente una serie de errores ya que la tarjeta no está realmente instalada. Este dialplan no se utilizará para llamadas a celulares.1.1.45) same => n.1.Dial(DAHDI/R1/${EXTEN:1}.Hangup R1= Usa las líneas del grupo X de Mayor a menor pero de manera aleatoria Se usará este ultimo bloque. exten => _9[12456789]XXXXXXX!.Hangup g1= Usa las líneas del grupo X de menor a Mayor exten => _9[12456789]XXXXXXX!.Hangup r1= Usa las líneas del grupo X de menor a Mayor pero de manera aleatoria exten => _9[12456789]XXXXXXX!.Dial(DAHDI/r1/${EXTEN:1}. Se antepone el numero 9 para indicar que marcando 9 más el numero de destino se está saliendo por las lineas analógicas. Se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvv se mira la configuración del canal 1: CLI> dahdi show channel 1 Se sale de la consola: CLI> quit Si se decide utilizar las 4 lineas telefónicas para las llamadas locales y nacionales hay cuatro forma de escribir el dialplan (para Colombia). E1 o J1. Apagar el computador 117 .45) same => n.1.Dial(SIP/1000.Dial(DAHDI/R1/${EXTEN:1}.Hangup Para llamadas entrantes después del contexto google-in: [from-pstn] exten => s.45) exten => s.conf Se recarga el dialplan: asterisk -rvvvvvvvvvvvvv CLI> dialplan reload se sale de la consola: CLI> quit 6.Hangup El contexto from-pstn es el que se ha definido en el archivo chan_dahdi.2 Tarjeta Digium TE120P La tarjeta TE120P es una tarjeta con una conexión T1.n. El tipo de conexión se configura a través de un jumper presente en la tarjeta: Los pasos a seguir son: 1.1.exten => _9[12456789]XXXXXXX!. Desconectar el cable de alimentación Abrir el chasis del Computador Insertar la tarjeta en una ranura PCI disponible Volver a poner el chasis del computador Conectar el cable de alimentación al computador Conectar el cable RJ45 de la linea E1 a la tarjeta Encender el computador Se paran los servicios Asterisk y DAHDI: service asterisk stop service dahdi stop 6.2.gz se entra en la carpeta: cd openr2-1.2.googlecode. 6.3.1 y se compila: . 8.1. 3. 4.gz se descomprime: tar -xf openr2-1.1 MFG/R2 ./configure make 118 .Openr2 Como en algunos países de latino américa. 5.0 make distclean . 7.8.tar.3.11.1.tar.com/files/openr2-1.3. se utiliza la señalización MFG/R2 para que DAHDI la pueda implementar hay que instalar la librería Openr2: se descarga: cd /usr/src wget http://openr2./configure --prefix=/usr make make install Luego hay que volver a compilar Asterisk: cd /usr/src/asterisk-1. so.so: ldd channels/chan_dahdi.3 => /usr/lib/libopenr2.so res_config_mysql.so WARNING WARNING WARNING no hay problema ya que esos módulos se han anteriormente compilado con la misma versión de Asterisk.3 (0x004bf000) Para ver las distintas versiones de la señalización MFG/R2 soportadas por la librería: r2test -l Variant Code Country AR Argentina BR Brazil CN China CZ Czech Republic CO Colombia EC Ecuador ID Indonesia ITU International Telecommunication Union MX Mexico PH Philippines VE Venezuela 119 .so format_mp3.so | grep openr2 libopenr2. make config Para averiguar que la librería ha sido englobada en el el modulo chan_dahdi.make install Si aparece este WARNING (advertencia): WARNING WARNING WARNING Your Asterisk modules directory. Please ensure that these modules are compatible with this version before attempting to run Asterisk.so.so cdr_mysql. located at /usr/lib/asterisk/modules contains modules that were not installed by this version of Asterisk.so app_saycountpl. app_mysql. Algunos ejemplos podrían ser: span => 1.17-31 dchan = 16 bchan son los canales audio y dchan el canal para la señalización. En este caso 1 Timing: determina la fuente de sincronización para la tarjeta. Posibles valores: 0 = la fuente la genera la misma tarjeta 1 = la fuente es remota Line Build Out: 0 predefinido Framing: en las lineas E1 puede ser CAS (Channel Associated Signaling) o CSS (Common Channel Signaling ) Coding: puede ser AMI o HBD3.cas.0.0.Terminada la instalación de la librería se averigua si la tarjeta ha sido reconocida por CentOS: lspci -n el resultado debe ser: 0000:01:00. y la cancelación de eco: echocanceller => oslec.Yellow] Number: el puerto donde está conectado el cable de la linea E1.css.0.hdb3 Luego se configuran los canales: bchan = 1-15.conf 120 .17-31 se termina con: loadzone = co defaultzone = co Por ultimo se configura el chan_dahdi. Estos datos normalmente los facilita el proveedor de la linea.0. En algunos casos al final de la linea se pone CRC4 para el control de los paquetes.conf es: span => <Number>.<Timing>.1-15.<Framing>.<Coding>[.crc4 o span => 1.0 0200: ISDN controller: Unknown device d161:0120 Cuando se configura una linea E1 la sintaxis en el archivo system.hdb3.<Line Build Out>. 0 txgain=3.los dos valores más importantes son: switchtype signaling que también facilita el proveedor.conf span=1.17-31 Para la señalización MFC/R2 sería: system.hdb3 cas=1-15:1101 dchan=16 cas=17-31:1101 loadzone = co 121 .0. Lo más común es: switchtype=euroisdn signaling=pri_cpe Un ejemplo de archivo de configuración es: [trunkgroups] [channels] usecallerid=yes hidecallerid=no callwaiting=yes usecallingpres=yes callwaitingcallerid=yes threewaycalling=yes transfer=yes canpark=yes cancallforward=yes callreturn=yes echocancel=yes echocancelwhenbridged=yes relaxdtmf=yes rxgain=2.1.cas.0 immediate=no context=from-pstn group=1 switchtype=euroisdn signaling=pri_cpe channel => 1-15. 0 immediate=no context=from-pstn group=1 signalling = mfcr2 mfcr2_variant = co mfcr2_get_ani_first = no mfcr2_max_ani = 10 mfcr2_max_dnis = 4 mfcr2_category = national_subscriber mfcr2_mfback_timeout = -1 mfcr2_metering_pulse_timeout = -1 mfcr2_logdir = log mfcr2_logging = all channel => 1-15.0 txgain=3.17-31 Terminada la configuración se reinician los servicios: service dahdi start service asterisk start y se averigua en la consola si todos los canales están configurados: CLI> dahdi show channels 122 .defaultzone = co chan_dahdi.conf [trunkgroups] [channels] usecallerid=yes hidecallerid=no callwaiting=yes usecallingpres=yes callwaitingcallerid=yes threewaycalling=yes transfer=yes canpark=yes cancallforward=yes callreturn=yes echocancel=yes echocancelwhenbridged=yes relaxdtmf=yes rxgain=2. com/linux/current_wanpipe/wanpipe-3.5. 5.23. 4.23 y se instala: ./Setup dahdi se escribe y y se continua con envío: 123 .sangoma. 6. 2. Primero se instala la tarjeta: Los pasos a seguir son: 1.3 Wanpipe Se termina esta parte del capitulo con la instalación del driver Wanpipe necesario para tarjetas SANGOMA.6.23.5. 3.tgz se descomprime: tar -xf wanpipe-3. Apagar el computador Desconectar el cable de alimentación Abrir el chasis del Computador Insertar la tarjeta en una ranura PCI disponible Volver a poner el chasis del computador Conectar el cable de alimentación al computador Conectar el cable RJ45 de la linea E1 a la tarjeta Encender el computador se para Asterisk y DAHDI: service asterisk stop service dahdi stop Se descarga el driver: cd /usr/src wget ftp://ftp. 8.tgz se entra en la carpeta: cd wanpipe-3.5. 7. conf.old /etc/dahdi/system.conf mv /etc/asterisk/chan_dahdi. y para volver a la configuración anterior. Al terminar este párrafo. Luego se inicia wanpipe: wanrouter start DAHDI service dahdi start Asterisk: service asterisk start Para terminar se personalizan los parámetros creados por wancfg.old /etc/asterisk/chan_dahdi. Al finalizar aparecerá: Ahora se ejecuta: wancfg_dahdi que creará todos los datos de configuración para la tarjeta instalada. se vuelven a poner los archivos predefinidos: mv /etc/dahdi/system. Empieza la compilación del driver y de las utilidades.se selecciona 1 más envío.conf.conf y se reinician los dos servicios: service dahdi start 124 . una linea FXS y cada linea se puede configurar como si fuera una extensión SIP. Para finalizar. Por defecto el SPA3102 no permite conectarse a la pagina de administración desde remoto. Se abre una pestaña nueva del navegador y se pone la siguiente dirección: http://192.168.0. La configuración que sigue abarca solamente la parte FXO ya que todas las llamadas entrantes se contestarán desde una extensión SIP.service asterisk start 6. así que lo primero que hay que hacer es activarla. En Ethernet se conecta un cable de red que luego se conectará al toma de red del computador.1 Aparecerá la pagina de administración del SPA3102: 125 . en Internet se conecta un cable de red que luego se conecta al Router. En Line se conecta el cable del teléfono que viene de la línea telefónica.4 Linksys SPA3102 – Gateway FXO/FXS El SPA3102 es un Gateway que soporta una linea FXO. Entre los nuevo iconos: Se da click dos veces. En este caso 192.100. Aparecerá: 126 . Ya se puede desconectar el cable del puerto Ethernet del ATA y volver a conectar el computador al router.100 El segundo paso es configurar una clave para el administrador y una para el usuario. Si la versión del firmware no es la 5.10 se actualiza.1. Se activa la conexión desde remoto: Para guardar cada cambio. Se da click en el enlace “advanced” y luego en la pestaña “Wan Setup”. al final de la pagina se presiona el botón “Submit All Changes”. Se descomprime el archivo en el escritorio del computador. Esto se hace en la pestaña Voice y luego System: Se presiona el botón Submit All Changes.Se averigua la versión del Firmware instalada y la dirección IP asignada por el Router. se pueden descargar desde esta pagina. Los firware para el SPA3102.168. Ahora se puede acceder al SPA3102 indicando la dirección IP asignada por el Router. Para aceptar la advertencia se presiona el botón “Continue”: Se pone la dirección IP local del SPA3102 y la del computador donde se ha descargado el Firmware. Se continua con el botón “OK”: 127 . Se presiona el botón “OK”: Se revisan todos los datos y para iniciar la actualización se presiona el botón “Upgrade”. se vuelve a entrar en la pagina de administración del ATA y se configura la cuenta SIP para la línea FXO. Se va a la pestaña Voice y luego en PSTN Line donde se configura solamente la parte que interesa: 128 . Cuando termine. La operación tarda unos minutos.Se pone el usuario admin y la clave que se acaba de crear. Line Enable = yes NAT Keep Alive Enable = yes (si el Asterisk es remoto y el ATA se encuentra detrás de un NAT) NAT Keep Alive Msg = viene por defecto con la opción $NOTIFY que envía un paquete de tipo SIP NOTYFY para tener abierta la conexión. Se puede dejar la linea en blanco. De esta forma se envía a Asterisk solamente un paquete UDP vacío como hacen la mayoría de los teléfonos SIP: Proxy = dirección IP o nombre de dominio del servidor Asterisk remoto Register = yes Display Name = poner el numero de teléfono de la línea telefónica (por ejemplo) UserID = el nombre de la extensión que luego se configurará en Asterisk Use Auth ID =yes Auth ID = lo mismo que User ID 129 . Como codec predefinido se activa alaw y como segundo G729: Se definen dos Dialplan: El primero para las llamadas salientes y el segundo para las llamadas entrantes. Todas las llamadas entrantes se enrutan a la extensión s de Asterisk: En la configuración del Gateway VoIP –> PSTN se pone: VoIP-To-PSTN Gateway Enable =yes VoIP Caller Auth Method = none (ninguna autentificación) One Stage Dialing = yes Line 1 VoIP Caller DP = para las llamadas salientes se utilizará el dialplan 1 En la configuración del Gateway PSTN – > VoIP se pone: PSTN-To-VoIP Gateway Enable =yes PSTN Calles Auth Method = none (de esta forma cuando el ATA conteste no solicitará ningún PIN para acceder al Gateway VoIP) PSTN Ring Thru Line 1 = no (ya que no se va a conectar un teléfono analógico al ATA) PSTN Caller Default DP = 2 (Para este Gateway se utilizará el diaplan 2) 130 . Esto valores.conf y al final del archivo. aparecen en la guía de administrador del SPA3102. Ahora el ATA intentará conectarse a Asterisk sin éxito ya que la extensión no ha sido creada.Cuando entre una llamada desde la red PSTN el Gateway VoIP del ATA contestará después de 2 segundos y pasará la llamada también a las extensión s de Asterisk: Detect Polarity Reversal = no (para Colombia) Detect PSTN Long silence = yes (si no hay flujo audio del lado PSTN por 30 segundos (parámetro que sigue) la llamada terminará PSTN Long Silence Duration = 30 Detect VoIP Long Silence = yes Lo mismo para lado VoIP VoIP Long Silence Duration = 30 Detect Disconnect Tone = Yes Disconnect Tone = el valor de su país. Se abre el archivo sip. se añade el siguiente bloque: nano /etc/asterisk/sip. para muchos países. Se termina presionando el botón “Submit All Changes”.conf [spa3102] type=friend secret=password qualify=yes nat=yes host=dynamic directmedia=no 131 . Dial(SIP/spa3102. debería aparecer): El dialplan: nano /etc/asterisk/extensions.conf para las llamadas salientes al final del contexto internas se pone: exten => _8. después del contexto google-in. Para las llamadas entrantes.Busy(3) same => n.context=from-spa3102 dtmfmode=rfc2833 language=es callerid=LineaTel <NumTel> allowtransfer=yes allowsubscribe=yes subscribecontext=subscribe callcounter=yes disallow=all allow=alaw allow=g729 Se guardan los cambios y se recarga la configuración SIP: asterisk -rx "sip reload" Después de unos segundos en la pagina del SPA3102 (Menú Voice.45.D(${EXTEN:1})) same => n. se le envía los dígitos del numero a marcar quitando el 8 (opción D de la aplicación Dial).. En cuanto el ATA conteste. se configura el contexto from-spa3102 (como definido en la configuración de la extensión en el sip.conf) y se pone: 132 . todas las llamadas pasarán para el SPA3102.1. pestaña Info.Hangup De esta forma marcando 8 + el numero a llamar. 133 . Otra prueba: se marca desde un celular al numero de la línea telefónica y se espera que empiece a timbrar la extensión 1000. La llamada saldrá por el SPA3102. Se guardan los cambios y se recarga el dialplan: asterisk –rvvvvvvvvvvvvvvv CLI> dialplan reload Ahora desde cualquier teléfono SIP conectado a Asterisk se marca un numero anteponiendo el 8.[from-spa3102] exten => s. después de dos segundos empezará a timbrar también la extensión 1000.NoOp same => n.Hangup De esta forma cuando alguien llamará el numero de la línea telefónica. Claramente la llamada entrante se puede enviar a un IVR o configurar para que timbre más de una extensión.1.Dial(SIP/1000) same => n. . Hangup que se ha creado para llamar la extensión IAX2 marko.1. En esta parte se ilustrarán: • • • • • • • • las variables los pattern matching la aplicación ECHO el contexto subscribe las Macro la aplicación Authenticate Limitar llamadas salientes Enrutamiento llamadas entrantes según fecha hora 7. Se utilizan mucho en matemática y su función en Asterisk es reducir la complexidad del dialplan. se ha explicado la división del dialplan en contextos.Dial(${marko}. En el párrafo 2.1 Las variables Una variable es un objeto al que se asocia un valor. extensiones y prioridades.6. ¿Cual es su función en el dialplan? En este caso simplificarlo.30) same => n. En la preparación del dialplan se ha visto el bloque dedicado a las variables globales y se han configurado tres. Si se retoma el bloque de dialplan: exten => 1234. En Asterisk existen tres tipos de variables: • • • variables globales variables de canal variables de ambiente Las variables globales son aquellas cuyo valor no cambia a lo largo del dialplan.CAPITULO VII Dialplan – Configuración avanzada Para poder entender mejor como funciona y como se construye un dialplan en Asterisk.1.Hangup Cuando se utiliza una variable en el dialplan la sintaxis es: carácter dolar $ seguido por el nombre de la . entre ellas: marko=IAX2/marko De esta forma se asocia al nombre de variable marko el valor IAX2/marko.Dial(IAX2/marko. simplificar su construcción y añadirle una lógica más comprensible.30) same => n. hay que aclarar algunos conceptos claves. esta parte puede ser escrita también de la siguiente forma: exten => 1234. Para saber cuales son y que valor tienen en un determinado canal. Para crearlas se utiliza la aplicación Set. cuando se crean variables.Answer same => n. Todas las variables generadas son en mayúsculo. Algunas aplicaciones y funciones de Asterisk al ejecutarse generan variables.Answer same => n. por ejemplo.30) same => n.1.Dumpchan same => n. Este tipo de variables se utilizan mucho en el dialplan para modificar valores del canal y/o para guardar algunos datos de las llamadas para luego utilizarlos.Playback(hello-world) same => n. Es una buena practica. la que ya se ha visto ${EXTEN}.Dial(${MARKO}.variable entre dos llaves {}.1. Cuando la llamada termine.Hangup La variable ${MARKO} estará totalmente vacía. no es lo mismo si en el dialplan se pone: exten => 1234. A lo largo de la construcción del dialplan se presentarán distintos ejemplos. Un ejemplo: Set(numero=1) Para toda la duración de la llamada el valor de la variable ${numero} será 1. el valor asociado a la variable volverá a ser nulo. se utiliza la aplicación Dumpchan.Hangup para que quede: exten => 123. En el caso de la variable ${marko} que está escrita toda en minúsculo. como.Playback(hello-world) same => n. utilizar nombres en minúsculo para diferenciarlas de las variables generadas por Asterisk. Para verla en acción se abre el archivo del dialplan: nano /etc/asterisk/extensions.1.Hangup Se guardan las modificaciones y se recarga el dialplan: asterisk -rvvvvvvvvvvvvvvv CLI> dialplan reload 136 . Las variables de canal tienen validez solamente para la llamada corriente.conf se modifica este bloque: exten => 123. Las variables son case sensitive. es decir que hay diferencia si se escriben en mayúsculas y minúsculas. Hay muchas variables predefinidas que se crean durante una llamada. El resultado en la consola de Asterisk será: Dumping Info For Channel: SIP/1000-00000001: =========================================================== Info: Name= SIP/1000-00000001 Type= SIP UniqueID= 1318352043. Una variable muy peculiar es la variable ${EXTEN}.253.215:15480 CLI> quit Para una lista completa de las variables predefinidas se puede consultar la Wiki de Asterisk. Esta variable tiene la siguiente sintaxis ${EXTEN:x:y) donde x es la posición inicial e y el numero de dígitos que se 137 . SIPDOMAIN=96.121. que contiene el numero marcado.Ahora desde la extensión 1000 se marca el numero 123.173.126.135 SIPURI=sip:[email protected] CallerIDNum= 1000 CallerIDName= callerid=Fulano DNIDDigits= 123 RDNIS= (N/A) Parkinglot= Language= es State= Up (6) Rings= 0 NativeFormat= 0x8 (alaw) WriteFormat= 0x8 (alaw) ReadFormat= 0x8 (alaw) RawWriteFormat= 0x8 (alaw) RawReadFormat= 0x8 (alaw) 1stFileDescriptor= 29 Framesin= 1 Framesout= 0 TimetoHangup= 0 ElapsedTime= 0h0m0s Context= externas Extension= 123 Priority= 2 CallGroup= 1 PickupGroup= 1 Application= DumpChan Data= (Empty) Blocking_in= (Not Blocking) Variables: SIPCALLID=YzBkYjQ1MjYyOWYxMzllYjU5Y2RhNmM3MDM3MjFkYTU. Para crearlas se utiliza la aplicación SET y la función ENV. Un ejemplo: Set(PBX=${ENV(LANG)}) En este ejemplo a la variable PBX estará asociado el idioma configurado en el servidor Linux.UTF-8") in new stack Executing [50@externas:2] NoOp("SIP/1000-0000000b". "Idioma Servidor en_US. asterisk -rvvvvvvvvvvvvvv CLI> dialplan reload Desde la extensión 1000 se marca el numero 50.Hangup Se guardan los cambios y se recarga el dialplan.1.Set(PBX=${ENV(LANG)}) same => n.conf en el contexto internas se ánade este bloque: exten => 50. "PBX=en_US. En la consola de Asterisk: Executing [50@externas:1] Set("SIP/1000-0000000b". 7.2 Pattern Matching 138 .Noop(Idioma Servidor ${PBX}) same => n. "") in new stack No todas las variables de ambiente se pueden leer desde Asterisk. para probarla en el dialplan: nano /etc/asterisk/extensions.UTF-8") in new stack Executing [50@externas:3] Hangup("SIP/1000-0000000b".quieren extraer: Tomando como numero de partida 57300200: ${EXTEN:1} devolverá 7300200 ${EXTEN:1:4} devolverá 7300 ${EXTEN:2:6} devolverá 300200 ${EXTEN:5:3} devolverá 200 Las variables de ambiente se utilizan para leer la variables del sistema (Linux). se utilizan los Pattern Marching o patrones de llamada. Cuando se pone un pattern matching en la creación de una extensión.conf y en el contexto internas se añade el siguiente bloque: exten => 150. siempre hay que anteponer el guion abajo _ Si. Estos caracteres se ponen en lugar de uno o más dígitos. la primera linea sería: exten => _00573XXXXXXXXX. Si se quiere crear una extensión donde entren todas las llamadas a los celulares de Colombia (prefijo 3) con el proveedor Justvoip.1. Para configurarla se modifica el dialplan: nano /etc/asterisk/extensions.3 La aplicación Echo La aplicación Echo se utiliza para medir el tiempo de retorno de la voz. que permiten crear extensiones en el dialplan que “intercepten” los números marcados.Dial(SIP/justvoip/${EXTEN}) El punto después del 00573.1.6-8] . Sería absurdo indicar todos los números de teléfono de Colombia porque un usuario podría marcar uno de ellos. ! puede ser un numero de 0 a 9 puede ser un numero de 1 a 9 puede ser un numero de 2 a 9 puede ser un numero de 1 a 4 o de 6 a 8 (punto) puede ser uno o más caracteres puede ser cero o más caracteres. Para este tipo de situaciones. por ejemplo.1. indica que lo que sigue puede ser compuesto de uno o más dígitos. La lista es la siguiente: • • • • • • X Z N [1-4. Puede ser útil para revisar eventuales retrasos y o problemas en la calidad del audio. Algunos ejemplos.Answer 139 .1.Dial(SIP/${EXTEN}) 7.El dialplan se construye de modo que todos los posibles números marcados puedan ser “interceptados” por Asterisk.Dial(SIP/justvoip/${EXTEN}) Si no se conoce exactamente de cuantos dígitos está compuesto un numero de celular la misma linea cambiaría de la siguiente forma: exten => _00573. el numero de extensiones configuradas en Asterisk van desde 1000 hasta 1099 el dialplan para las llamadas entre extensiones sería: exten => _10XX.. hint. 7.IAX2/marko La prioridad Hint es una prioridad especial que permite monitorear el estado de las extensiones.hint.conf y después del contexto internas se añade el siguiente bloque: [subscribe] exten => 1000. En este caso se utilizará la primera forma.SIP/1002 exten => marko. Se guardan los 140 .4 El contexto Subscribe A lo largo de la configuración del archivo sip.Hangup Se guardan los cambios y se recarga el dialplan: asterisk -rx "dialplan reload" Desde cualquier extensión registrada a Asterisk se marca el numero 150 y se hace la prueba.hint.SIP/1001 exten => 1002.hint.conf se ha hablado de la posibilidad de monitorear el estado de una extensión y en la parte general del archivo se han configurados los siguientes parámetros para activar esta funcionalidad: callcounter=yes allowsubscribe=yes subscribecontext=subscribe notifyringing=yes notifyhold=yes Ahora para que el sistema funcione. Otra forma de escribir el bloque es: [subscribe] exten => _100[0-2].SIP/100[0-2] exten => marko.hint.hint.Playback(demo-echotest) same => n. en el dialplan hay que configurar el contexto subscribe.Echo same => n.SIP/1000 exten => 1001.Playback(demo-echodone) same => n.same => n.1001 y 1002 y la extensión IAX2 marko. En este caso las extensiones SIP 1000. Se abre el archivo: nano /etc/asterisk/extensions.IAX2/marko es decir utilizando los Pattern Marching. cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvvvvvvvv CLI> dialplan reload Con el comando: CLI> core show hints -= Registered Asterisk Dial Plan Hints =1000@subscribe : SIP/1000 1001@subscribe : SIP/1001 1002@subscribe : SIP/1002 marko@subscribe : IAX2/marko State:Idle Watchers 0 State:Unavailable Watchers 0 State:Unavailable Watchers 0 State:Unavailable Watchers 0 Se verán los hints configurados y en la ultima columna cuantas extensiones se han subscrito al estado de las demás (en este caso ninguna). Se vuelve a la ventana terminal y se termina la captura de 141 . en la ventana del terminal se sale de la consola de Asterisk: CLI> quit y se inicia la captura de los paquetes SIP: ngrep 1000 -W byline port 5060 > /tmp/subscribe Se vuelve al Xlite y se presiona el botón OK. Ahora se abre el Xlite configurado como extensión 1000 y se presiona el icono evidenciado: En la nueva ventana: Al lado de la casilla “Softphone” se escribe 1001 y luego se presiona el botón Add. Antes de presionar el botón “OK” para terminar la operación. Xlite La parte final del paquete de Notify enviado por Asterisk a la extensión 1000 será: <?xml version="1. estará anexa esta parte: <?xml version="1.0" encoding="ISO-8859-1"?> <presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:pp="urn:ietf:params:xml:ns:pidf:person" xmlns:es="urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status" xmlns:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" entity="sip:[email protected]</contact> <status><basic>closed</basic></status> </tuple> </presence> Asterisk está comunicando a la extensión 1000 que la extensión 1001 no está en linea (Not online) Se capturan nuevamente los paquetes con el comando: ngrep 1000 -W byline port 5060 > /tmp/notify Se abre el softphone 3CX configurado como extensión 1001 y una vez que esté registrado a Asterisk se termina la captura de los paquetes.Asterisk X-Lite <-----------------NOTIFY---------------. En el archivo notify se encontrará la siguiente secuencia: Asterisk --------NOTIFY--------------> Xlite Asterisk <--------200 OK-------------.121.126.los paquetes SIP.0" encoding="ISO-8859-1"?> <presence xmlns="urn:ietf:params:xml:ns:pidf" xmlns:pp="urn:ietf:params:xml:ns:pidf:person" xmlns:es="urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status" 142 .Asterisk X-Lite -------------------200 OK----------------> Asterisk Y en el NOTIFY final.121. La secuencia de los paquetes será: X-Lite ------------------Subscribe---------------> Asterisk X-Lite <-------401 Unauthorized-------------.135"> <pp:person><status> <ep:activities><ep:away/></ep:activities> </status></pp:person> <note>Not online</note> <tuple id="1001"> <contact priority="1">sip:[email protected] X-Lite ------------------Subscribe---------------> Asterisk X-Lite <-------------------200 Ok---------------. En el Xlite aparecerá: 143 . Si se vuelve a la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvv CLI> core show hints -= Registered Asterisk Dial Plan Hints =1000@subscribe : SIP/1000 1001@subscribe : SIP/1001 1002@subscribe : SIP/1002 marko@subscribe : IAX2/marko State:Idle Watchers 0 State:Idle Watchers 1 State:Unavailable Watchers 0 State:Unavailable Watchers 0 En la columna Watchers de la extensión 1001 hay un 1 que indica que hay una extensión que está monitoreando su estado. Se abre Zoiper (configurado con las cuentas SIP 1002 y IAX2 marko) y en el Xlite se subscribe el estado de ambas.135"> <pp:person><status> </status></pp:person> <note>Ready</note> <tuple id="1001"> <contact priority="1">sip:[email protected]:ep="urn:ietf:params:xml:ns:pidf:rpid:rpid-person" entity="sip:[email protected]</contact> <status><basic>open</basic></status> </tuple> </presence> Asterisk estará comunicando a la extensión 1000 que la extensión 1001 está en linea ya que la extensión 1000 ha subscrito el estado de esa extensión.121. El resultado será: Desde la extensión 1001 se marca el numero 150 (test de echo).126. 5 Las Macro Si en el dialplan algunas acciones se repiten a menudo. La sintaxis de la aplicación Macro: asterisk -rvvvvvvvvvvvv CLI> core show application Macro -= Info about application 'Macro' =[Synopsis] Macro Implementation. Arguments become ${ARG1}. 144 . ${ARG2}. jumping to the 's' extension of that context and executing each step. [Description] Executes a macro using the context macro-<name>. 7. Asterisk brinda la posibilidad de crear una Macro que permite simplificar este tipo de operaciones. and priority are stored in ${MACRO_EXTEN }. ${MACRO_CONTEXT} and ${MACRO_PRIORITY} respectively. If you Goto out of the Macro context. The calling extension. then returning when the steps end. context. etc in the macro context. the Macro will terminate and control will be returned at the location of the Goto.Por ultimo. desde la extensión 1002 se llama la extensión 1001: La misma cosa se puede hacer en los Teléfonos SIP de mesa que soportan los BLF (Busy Lamp Field). La aplicación macro crea las siguientes variables de canal: • • • • ${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}. and N + 1 otherwise.. It may be possible that stack-intensive applications in deeply nested macros could cause asterisk to crash earlier than this limit.argumento2. en base a éste. etc. Macro will attempt to continue at priority MACRO_OFFSET + N + 1 if such a step exists. It is advised that if you need to deeply nest macro calls. argumento1. Please use the 'Read' application in order to read DTMF from a channel currently executing a macro. ${ARGN) son las variables que contienen los argumentos que se han enviado a la Macro.arg2[.conf Al final del archivo se añaden estas líneas: 145 .If ${MACRO_OFFSET} is set at termination..argumentoN) ArgumentoN es un valor o una variable que se pasa a la macro al momento de llamarla desde el plan de llamadas. Primero hay que salir de la consola y modificar el plan de llamadas: CLI> quit nano /etc/asterisk/extensions. WARNING!!!: Because of the way Macro is implemented (it executes the priorities contained within it via sub-engine). WARNING!!!: Use of the application 'WaitExten' within a macro will not function as expected. [Syntax] Macro(name[. macros are limited to 7 levels of nesting (macro calling macro calling macro. that you use the Gosub application (now allows arguments like a Macro) with explict Return() calls instead.arg1[.]]]) [Arguments] name The name of the macro El comando seria: Macro(nombre_de_la_macro. Para empezar a utilizar la aplicación Macro se creará una muy sencilla que antes de marcar una extensión controle su estado y. envíe la llamada a una determinada parte del dialplan.. and a fixed per-thread memory stack allowance.). prioridad + 1 de donde se llamó.El canal está timbrando RINGINGUSE .Set(estado=${DEVICE_STATE(SIP/${MACRO_EXTEN})}) exten => s.45) same => n.Hangup exten => s.No se está usando INUSE .[macro-disponible] exten => s.1.n.1.n.MacroExit Una explicación de las aplicaciones y funciones nuevas que aparecen en las lineas de la Macro: La función DEVICE_STATE: controla si una extensión está disponible y retorna un valor que se asignará a la variable “estado”.Gotoif($["${estado}" = "NOT_INUSE"]?5) exten => s. Los posibles valores son: • • • • • • • • • UNKNOWN – El canal es valido pero su estado no es conocido NOT_INUSE .Hangup Se guardan los cambios y se actualiza el plan de llamadas: 146 . Para insertar la Macro en el dialplan creado. el dialplan continua con la prioridad que sigue.Hangup Para que quede: exten => _100[0-2].El canal no es valido UNAVAILABLE . sino ve a otra prioridad indicada (falso).1. La aplicación Busy: si la extensión no se encuentra libre se envía al llamante una señal de ocupado La aplicación MacroExit: sale de la macro y vuelve al mismo contexto.n.El canal está en espera La aplicación Gotoif: literalmente es: ve a la prioridad indicada si se presenta una determinada condición (verdadero). Si la segunda prioridad no se especifica.Busy exten => s. exten => _100[0-2].Dial(SIP/${EXTEN}.Dial(SIP/${EXTEN}.Macro(disponible) same => n.30) same => n.El canal está en uso BUSY . extensión.n.El canal está timbrando y en uso ONHOLD .El canal no está disponible (no está registrado a Asterisk) RINGING .El canal está ocupado INVALID . se modifica el bloque configurado para las llamadas entre extensiones. "1?5") in new stack Goto (macro-disponible.45") in new stack Se cierra el 3CX Softphone (extensión 1001) y se marca otra vez desde la extensión 1000 la extensión 1001: Executing [1001@externas:1] Macro("SIP/1000-00000013". Este es un caso típico en la configuración de Asterisk. Ese contexto no tiene acceso al contexto internacio. Algunas extensiones tienen acceso a la lineas salientes y otras no.5) Executing [s@macro-disponible:5] MacroExit("SIP/1000-00000011".6 Autenticar las Llamadas Salientes con la aplicación Authenticate Al momento de crear las extensiones en el archivo sip. para tenerlo. 7. el resultado será: [Feb 2 10:29:18] NOTICE[31745]: chan_sip. "SIP/1001. a la extensión 1002 se ha asociado el contexto locales.conf. Para conocer la sintaxis de la aplicación: asterisk -rvvvvvvvvvvvvvv 147 . "disponible") in new stack Executing [s@macro-disponible:1] Set("SIP/1000-00000013".s. si se marca el numero 00573126814740 desde las extensión 1002. Otra forma de configurar Asterisk es que las extensiones que no tienen acceso a las lineas salientes.asterisk -rvvvvvvvvvvvvvvv CLI> dialplan reload Ahora se marca desde la extensión 1000 la extensión 1001 (ambas conectadas a Asteirsk) y se controla lo que aparece en la consola de Asterisk: Executing [1001@externas:1] Macro("SIP/1000-00000011". "") in new stack Executing [1001@externas:2] Dial("SIP/1000-00000011". "estado=NOT_INUSE") in new stack Executing [s@macro-disponible:2] GotoIf("SIP/1000-00000011". "disponible") in new stack Executing [s@macro-disponible:1] Set("SIP/1000-00000011". tengan que autenticarse. "estado= UNAVAILABLE") in new stack Executing [s@macro-disponible:2] GotoIf("SIP/1000-00000013". pues la extensión 1002 no puede efectuar llamadas salientes utilizando el proveedor SIP Justvoip.195. Este tipo de configuración se hará utilizando la aplicación Authenticate. "") in new stack Como el estado de la extensión 1001 es “UNAVAILABLE” (en negrita) se procesa la prioridad 3 (el Busy) y se termina la llamada. Para comprobarlo. De esta forma hay un control sobre la llamadas salientes y se puede tener un registro de los usuarios que han utilizado el servicio.81:10000) to extension '00573126814740' rejected because extension not found in context 'locales'.c:22147 handle_request_invite: Call from '1002' (186. "0?5") in new stack Executing [s@macro-disponible:3] Busy("SIP/1000-00000013".112. CLI> core show application authenticate [Syntax] Authenticate(password[. the channel will have its account code set to the corresponding account code in the file.maxdigits[. When one of the passwords is matched. not a literal file m: Interpret the given path as a file which contains a list of account codes and password hashes delimited with ':'. Defaults to 0 .txt se añade la siguiente linea: Mengano:c4819d06b0ca810d38506453cfaae9d8 Se guardan los cambios.options[. Se llamará este contexto “auten” 148 . Ahora se crea un nuevo contexto al cual tenga acceso la extensión 1002. r: Remove the database key upon successful entry (valid with 'd' only) maxdigits maximum acceptable number of digits. listed one per line in the file. Stops reading after maxdigits have been entered (without requiring the user to press the '#' key). su valor cifrado será: echo -n "4488" | md5sum c4819d06b0ca810d38506453cfaae9d8 Luego se crea el archivo de texto con el nombre del usuario de la extensión y la respectiva contraseña cifrada: nano /tmp/pin. En este caso se cifrarán.prompt]]]) [Arguments] password Password the user should know options a: Set the channels' account code to the password that is entered d: Interpret the given path as database key. Las contraseñas se pueden escribir en claro o cifradas con MD5. prompt Override the agent-pass prompt file. La opción password puede contener un valor o referirse a un archivo de texto que contenga una lista de nombres con las respectivas contraseñas separada por el carácter “:”. Si el PIN para la extensión 1002 (Mengano) es 4488.wait for the user press the '#' key.no limit . NoOP same => n.nano /etc/asterisk/extensions.Authenticate(/tmp/pin. el dialplan pasará a la línea que sigue donde se iniciará la llamada.1..Hangup Los parámetros utilizados en la aplicación Authenticate: • • El primero define la carpeta y el nombre del archivo que contiene las contraseñas. El ultimo parámetro indica que los dígitos del PIN son 4 evitando de tener que utilizar la tecla numero para terminar el envío de los dígitos.Dial(SIP/justvoip/${EXTEN}) same => n. Cuando Asterisk lo pide.conf después del contexto internas se añade el siguiente bloque: [auten] exten => _00.am. Empezará la llamada al numero marcado. se ingresará la contraseña 4488.4) same => n. • • Si la contraseña digitada está en el archivo de texto creado. La Opción a define que en el registro de las llamadas el campo Accountcode contendrá el nombre del usuario independientemente de la extensión que haya utilizado para efectuar la llamada La opción m define que el archivo de texto contendrá las contraseñas cifradas con MD5. En el contexto locales se añade el contexto auten para que la extensión 1002 tenga acceso al bloque recién creado (en negrita los cambios): [locales] include => internas include => auten Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvv CLI> dialplan reload Desde la extensión 1002 se marca el numero 005714013434. Se sale de la consola de Asterisk: CLI> quit Para averiguar que efectivamente la llamada ha sido cargada a la cuenta del usuario Mengano se entra en el cliente MySQL: 149 .txt. 00 sec) Se sale del cliente MySQL: mysql> quit 7.X si se quería limitar el numero de llamadas salientes/entrantes para una extensión.dst. se le avise que no puede y al mismo tiempo si los 2 canales de la troncal se están utilizando.8.6. este parámetro ha sido marcado como “deprecated”.channel. A partir de la versión 1. se le avise al usuario que no hay más canales disponibles para las llamadas salientes.accountcode from cdr where accountcode='Mengano'. se utilizaba el parámetro call-limit que había que añadir en la configuración de la extensión en el sip. Lo que hay que hacer es construir un dialplan donde si una extensión intenta sacar la tercera llamada simultanea. esto quiere decir que no se recomienda su uso en las nuevas versiones.7 Limitar llamadas salientes: funciones GROUP y GROUP_COUNT Hasta la versión 1.billsec. En su lugar se han introducido dos funciones: • • GROUP GROUP_COUNT A través de estas dos funciones. es posible limitar el numero de canales utilizados en las llamadas entrantes y salientes. Si se quiere conocer en cualquier momento los canales utilizados por cada extensión/troncal 150 . Se quiere limitar a 2 el numero de llamadas salientes para cada extensión configurada y al mismo tiempo se quieres limitar a 2 las llamadas salientes por la troncal Justvoip.X. El resultado será: +------+--------------+-------------------+---------+-------------+ | src | dst | channel | billsec | accountcode +------+--------------+-------------------+---------+-------------+ | 1002 | 005714013434 | SIP/1002-00000014 | 15 | Mengano +------+--------------+-------------------+---------+-------------+ 1 row in set (0.conf. Un ejemplo practico.X de Asterisk y por consecuencia en la versión 1.4.mysql -u root -psesamo Se selecciona la base de datos asteriskcdr (donde se ha creado la tabal CDR): mysql> use asteriskcdr y se hace una consulta en la tabal CDR (que contiene todos los registros de las llamadas): mysql> select src. Hangup Una explicación del dialplan creado: • • En la segunda linea se se asigna al grupo voip la troncal justvoip En la tercera linea se asigna al grupo salida la variable ${CALLERID(num)} que contiene el 151 . Retomando el dialplan hasta ahora creado. se va a aplicar la regla definida a las llamadas salientes.Playback(all-outgoing-lines-unavailable) same => n.Set(GROUP(salida)=${CALLERID(num)}) same => n..configurada en Asterisk.NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip) same => n.conf En el contexto internacio se modifican estas lineas: exten => _00.Dial(SIP/justvoip/${EXTEN}) same => n. el comando es: asterisk -rvvvvvvvvvvvvvvvvv CLI> sip show inuse * Peer name In use 1000 0/0/0 1001 0/0/0 1002 0/0/0 justvoip 0/0/0 Limit 2147483647 2147483647 2147483647 2147483647 Bajo la columna In use.1.Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)}) same => n.Dial(SIP/justvoip/${EXTEN}.Hangup Para que queden: exten => _00X.Hangup same => n(busy).30) same => n.Set(GROUP(voip)=justvoip) same => n.Set(trunksal=${GROUP_COUNT(justvoip@voip)}) same => n.NoOp same => n..1. Se abre el archivo del dialplan: nano /etc/asterisk/extensions. los significados de las tres columnas (de la izquierda a la derecha) son: • • • Canales in uso Canales timbrando Canales en espera Bajo la columna Limit se puede notar que prácticamente no existe ningún limite.Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy) same => n. Executing [005714013434@externas:5] Set("SIP/1001-00000020". "") in new stack -.Executing [005714013434@externas:1] NoOp("SIP/1000-00000022". "trunksal=1") in new stack -.Executing [005714013434@externas:1] NoOp("SIP/1001-00000020".Executing [005714013434@externas:2] Set("SIP/1001-00000020". sino seguir con el dialplan. "GROUP(voip)=justvoip") in new stack -. "GROUP(salida)=1000") in new stack -.Executing [005714013434@externas:3] Set("SIP/1001-00000020". "extsal=1") in new stack -. " Hay 1 llamadas desde la extension 1001 y 1 con el proveedor Justvoip") in new stack -. "GROUP(voip)=justvoip") in new stack -. Si las llamadas desde las extensiones son mayores a dos o las llamadas de la troncal son mayores a dos. "extsal=1") in new stack 152 . En la linea que empieza con la etiqueta busy. En la consola de Asterisk aparecerá: Primera llamda == Extension Changed 1001[subscribe] new state InUse for Notify User 1000 -.SIP/justvoip-00000021 is making progress passing it to SIP/1001-00000020 == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -. "trunksal=2") in new stack -.Executing [005714013434@externas:3] Set("SIP/1000-00000022". Ahora para hacer una primera prueba.Executing [005714013434@externas:5] Set("SIP/1000-00000022".Called SIP/justvoip/005714013434 -.• • • • • numero de la extensión que está llamando En la cuarta linea se aumenta de una unidad el valor del grupo voip y se asigna el nuevo valor a la variable trunksal En la quinta linea se aumenta de una unidad el valor del grupo salida y se asigna el nuevo valor a la variable extsal En la sexta linea se envía el valor de las llamadas totales de las extensiones y de la troncal a la consola de Asterisk En la séptima linea se define este comportamiento. "0?busy") in new stack -Executing [005714013434@externas:8] Dial("SIP/1001-00000020".Executing [005714013434@externas:4] Set("SIP/1001-00000020".Executing [005714013434@externas:7] GotoIf("SIP/1001-00000020".Executing [005714013434@externas:2] Set("SIP/1000-00000022".Executing [005714013434@externas:6] NoOp("SIP/1001-00000020". "") in new stack -. El operador lógico | está en lugar de la palabra inglés OR. se comunica a la extensión que no hay lineas disponibles para las llamadas salientes. "SIP/justvoip/005714013434") in new stack Segunda Llamada == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -. desde la extensión 1001 (el softphone 3CX) se marca el numero 005714013434 y al mismo tiempo desde la extensión 1000 se marca dos veces al mismo numero. ir a la etiqueta (busy).Executing [005714013434@externas:4] Set("SIP/1000-00000022". "GROUP(salida)=1001") in new stack -. Executing [005714013434@externas:4] Set("SIP/1000-00000024".<SIP/1000-00000024> Playing 'all-outgoing-lines-unavailable.Executing [005714013434@externas:7] GotoIf("SIP/1000-00000024".Executing [005714013434@externas:7] GotoIf("SIP/1000-00000022". "extsal=2") in new stack -. class 'default'. " all-outgoing-linesunavailable") in new stack -. "trunksal=3") in new stack -.Goto (externas.Executing [005714013434@externas:11] Hangup("SIP/1000-00000024".Executing [005714013434@externas:6] NoOp("SIP/1000-00000022". "SIP/justvoip/005714013434") in new stack Tercera Llamada == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -.10) -.SIP/justvoip-00000023 is making progress passing it to SIP/1000-00000022 -.Executing [005714013434@externas:6] NoOp("SIP/1000-00000024". " Hay 1 llamadas desde la extension 1000 y 2 con el proveedor Justvoip") in new stack -.Called SIP/justvoip/005714013434 -.Executing [005714013434@externas:2] Set("SIP/1000-00000024".-.Executing [005714013434@externas:10] Playback("SIP/1000-00000024".Executing [005714013434@externas:5] Set("SIP/1000-00000024". "") in new stack Con el comando sip show inuse. "1?busy") in new stack -. a lo largo de la segunda llamada. el Gotoif es verdadero y el dialplan sigue desde la prioridad con la etiqueta busy anunciando que no hay más linea salientes disponibles.SIP/justvoip-00000023 answered SIP/1000-00000022 -. "") in new stack -.ulaw' (language 'es') [Feb 6 11:52:16] NOTICE[3578]: channel.Executing [005714013434@externas:3] Set("SIP/1000-00000024".Started music on hold. "GROUP(salida)=1000") in new stack -. "GROUP(voip)=justvoip") in new stack -. " Hay 2 llamadas desde la extension 1000 y 3 con el proveedor Justvoip") in new stack -. "0?busy") in new stack -Executing [005714013434@externas:8] Dial("SIP/1000-00000022". aparecerá: CLI> sip show inuse * Peer name In use 1000 1/0/0 1001 1/0/0 1002 0/0/0 justvoip 2/0/0 Limit 2147483647 2147483647 2147483647 2147483647 Cuando la extensión 1000 intenta sacar la tercera llamada.005714013434.Executing [005714013434@externas:1] NoOp("SIP/1000-00000024".c:4148 __ast_read: Dropping incompatible voice frame on SIP/1000-00000024 of format alaw since our native format has changed to 0x4 (ulaw) -. 153 . on SIP/justvoip-00000023 -.SIP/justvoip-00000021 answered SIP/1001-00000020 == Using UDPTL CoS mark 5 == Using SIP RTP CoS mark 5 -. 154 . . Ejemplo: Si se llama la extensión 6650 el archivo audio tendrá el nombre prompt50.Wait(2) same => n. Para implementarla hay que modificar el dialplan.conf En el contexto internas se pone el siguiente bloque: exten => _66XX.Answer() same => n. Consiste en un central telefónica (en este caso Asterisk) 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 las teclas del teléfono. En el lenguaje técnico habría que diferenciar dos tipos de sistemas: • • El IVR permite hacer consulta a base de datos.Record(/tmp/prompt${EXTEN:2}:wav) same => n. la contestadora automática permite navegar entre menús vocales permitiendo elegir entre distintos menús hasta llegar a la información que se está buscando En este capitulo se presentará la configuración de una contestadora automática.CAPITULO VIII IVR IVR es la sigla de Interactive Voice Response.Wait(2) same => n. 8. nano /etc/asterisk/extensions. devolver los resultados y. interactuar de forma activa con el usuario.Playback(/tmp/prompt${EXTEN:2}) same => n. Algunos ejemplos: el menú que se escucha cuando se llama un centro de atención al cliente.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 se ha marcado desde el Softphone.1.1 Grabación de las locuciones En Asterisk con la aplicación Record se pueden grabar archivos audios para luego utilizarlos en la creación de un IVR.Wait(2) same => n. en general. los bancos que permiten hacer consultas o pagos a través de un menú vocal. que se traduce del inglés como Respuesta de Voz Interactiva.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 • • • • . se vuelve a grabar marcando el mismo numero.wav .wav prompt02. para la oficina de ventas marque 3” prompt03. for sales office.“para efectuar un test de eco marque 1. A veces es útil y aconsejable crear las mismas locuciones en otros formatos audio.“for english press one. Para crear las locuciones en otros formatos audio hay un comando disponible en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvv Asterisk de manera predefinida busca las locuciones en la carpeta /var/lib/asterisk/sounds. el comando será: CLI> file convert custom/prompt01. para español marque dos” prompt02. Como han sido copiadas en la carpeta custom. Una vez terminadas las grabaciones se crea un nueva carpeta: mkdir /var/lib/asterisk/sounds/custom y se mueven los tres archivos (prompt01. para escuchar la música en espera marque 2.“for echo test press 1.wav . IMPORTANTE: para terminar la grabación hay que presionar la tecla numero # Se actualiza el dialplan: asterisk -rvvvvvvvvvvvvvvvv CLI> dialplan reload CLI> quit Esta solución permite grabar hasta 99 archivos audio. Este proceso se llama transcoding y utiliza bastantes recursos del servidor. esto para que Asterisk no tenga que decodificar y codificar las locuciones a otro formato audio según el codec configurado en el teléfono IP o softphone de quien está llamando. Para el ejemplo a seguir hay que grabar tres archivos de audio que contengan las siguientes frases: • • • prompt01.Si la grabación no es satisfactoria.wav . se termina con 6603 y se graba la tercera.ulaw 157 .wav y prompt03. luego 6602 y se graba la segunda. La nueva grabación remplazará la vieja. press 3” Desde la extensión 1000 se marca 6601 y se graba la primera frase.wav) a la carpeta creada cd /tmp mv prompt* /var/lib/asterisk/sounds/custom El formato audio de las locuciones es Wav. for music on hold press 2.wav custom/prompt01. 76>.209. El resultado en la consola de Asterisk será: NOTICE[7577]: chan_sip. Desde la extensión 1000 se marca el numero.alaw para el formato alaw. al momento de configurarlo.conf aprovechando el comando include: nano sip. en “Ingresar Nombre Dominio o Dirección IP “ se pone la dirección IP del servidor y en “Usuario o Extensión” la letra s. Esto normalmente se hace desde el panel de control que cada cliente tiene a disposición. El el caso que se adquiera un numero geográfico. La sintaxis es 00 + código país + numero geográfico. es configurar el “Mapping”. la empresa que lo vende. puede visitar la pagina de la empresa VozToVoice. Para conocer la sinopsis del comando record: CLI> core show application record CLI> quit 8.De esta forma se convierte la locución al formato audio ulaw CLI> file convert custom/prompt01. Otra cosa que el proveedor permite. Esta lista de IP hay que incluirla en el sip.2 Configuración numero geográfico Cuando se adquiere un numero geográfico.conf de Asterisk todas las direcciones IP de donde puede llegar una llamada.conf sino las llamadas no serán autenticadas pues serán rechazadas.voztovoice.c:20701 handle_request_invite: Sending fake auth rejection for device "6620016037" <sip:6620016037@46. Con ese numero ya se puede hacer una primera prueba.tag=as4dbd19b8 Asterisk no puede autenticar el INVITE en entrada Para solucionar el problema hay que añadir en el sip.org/tmp/didvoztovoice Ahora se incluye el archivo didvoztovoice en el sip.19.wav custom/prompt01. Para una idea de como funciona y de como se configuran los números geográficos. es decir definir que dirección SIP o numero de teléfono hay que llamar cuando entre una llamada al numero geográfico. Estas direcciones están configuradas en un archivo que se descargará: cd /etc/asterisk wget http://www. facilita siempre el rango de IP de donde ella envía los INVITE para las llamadas entrantes.conf al final del archivo se añade: 158 . 3.2.Set(TIMEOUT(digit)=7) exten => s. se entra en la consola de Asterisk y se recarga la configuración SIP: asterisk -rvvvvvvvvvvvvvvvvvv CLI> sip reload Segunda prueba: se marca nuevamente el numero se mira que pasa en la consola de Asterisk: NOTICE[7577]: chan_sip.Hangup exten => t. ya se puede configurar el IVR.s.19.WaitExten() exten => 1. Se guardan los cambios.Set(CHANNEL(language)=en) exten => s.Set(TIMEOUT(response)=10) exten => s.3.2) exten => i.s.4.#include didvoztovoice El comando #include toma un archivo de texto y lo engloba en la configuración.3 Creación del IVR Con la locuciones grabadas.Hangup [IVR1] exten => s.2.goto(IVR2.Playback(invalid) exten => i.4.goto(IVR.BackGround(custom/prompt01) exten => s.3.s. nano /etc/asterisk/IVR se copian los tres bloques que siguen: [IVR] exten => s.78' to extension 's' rejected because extension not found in context 'from-voztovoice' Ya la llamada no viene rechazada sino que no se puede enviar a ninguna parte del dialplan porque no Asterisk no encuentra el contexto from-voztooice.1.2) exten => h. Para hacerlo se crea un nuevo archivo que luego se incluirá en el dialplan.1.1.Wait(1) exten => s.1) exten => 2.1.1) exten => i.1.Set(CHANNEL(language)=es) exten => s.Goto(IVR.Set(TIMEOUT(response)=10) exten => s.BackGround(custom/prompt03) 159 .209.s.c:20785 handle_request_invite: Call from '46.1.6. Más adelante se creará ese contexto 8.Set(TIMEOUT(digit)=7) exten => s.2.5.goto(IVR1.1. s.s.2.1.2.Playback(invalid) exten => i.s.1.3.3.4.2.goto(IVR2.Playback(invalid) exten => i.Echo() exten => 2.1) – si el llamante presiona 2.goto(IVR1.1.Set(CHANNEL(language)=es) exten => s.exten => s.Set(TIMEOUT(digit)=7) exten => s.1.1.1) exten => i.Goto(internas.hangup exten => t.goto(IVR2. WaitExten() .5. extensión s.s.1.Set(TIMEOUT(response)=10) exten => s.Goto(IVR2.BackGround(custom/prompt02) exten => s.MusicOnHold exten => 3.1) exten => i. BackGround(custom/prompt01) – presenta la locución prompt01 y al mismo tiempo se pone a la escucha de los dígitos que pueda presionar el llamante. prioridad 1 2.1.Playback(demo-echotest) exten => 1.1) – si el llamante presiona 1 va (goto) al contexto IVR1. va (goto) al contexto IVR2.1.Hangup [IVR2] exten => s.goto(IVR1.2.WaitExten() exten => 1.Goto(internas.1.Hangup Se guardan los cambios.1.2.Espera que el llamante presione una tecla 1.Playback(pls-wait-connect-call) exten => 3.Goto(IVR1.s.3.1.1.2. extensión s.1.WaitExten() exten => 1.1) exten => i.1) exten => i.1. Una explicación de las nueva funciones y aplicaciones que aparecen en el IVR: • • • • • • • • Wait(1) – Espera un segundo Set(CHANNEL(language)=es) – Se pone como idioma predefinido para las locuciones el español Set(TIMEOUT(digit)=7) – numero de segundos máximo (7) entre el primer dígito y los siguientes Set(TIMEOUT(response)=10) – numero de segundos que el sistema esperará para que el llamante presione una tecla del teléfono.5.MusicOnHold exten => 3.hangup exten => t.2.Playback(demo-echotest) exten => 1.Playback(pls-wait-connect-call) exten => 3. prioridad 1 160 .1.1) exten => h.s.Echo() exten => 2.100.100.1) exten => h. la llamada se enviará al contexto internas. antes del contexto internas. hay que crearla: nano /etc/asterisk/extensions.2. La parte interesante es que si se digita el numero tres.Goto(IVR.Hangup from-didvoztovoice es el contexto donde llegarán las llamadas al numero geográficos (configurado para cada troncal IP presente en el archivo didvoztovoice).Hangup – si el llamante cuelga. el llamante no presiona ninguna tecla. 1001 y 1002 simultáneamente hasta que una de las tres conteste la llamada. se ejecuta la extensión h La extensión i se utiliza para capturar dentro del dialplan. prioridad 2 (presenta nuevamente el menú inicial) t.Playback(invalid) – si la tecla presionada no es valida (ni 1 ni 2) comunica el error i.Answer same => n.1.s.1.1) y para incluir el archivo IVR al dialplan.2) – y devuelve el llamante al contexto IVR.s. dígitos errados.Dial(SIP/1000&SIP/1001&SIP/1002.conf en el contexto internas se añade el siguiente bloque: exten => 100.2) – si dentro de 10 segundos (TIMEOUT(response)).Wait(1) same => n.30) same => n.Answer same => n.goto(IVR.s. se añade este bloque: [from-didvoztovoice] exten => s. al final del archivo se añade esta linea 161 .1. Para probar el IVR en local se añaden estas lineas en el contexto internas: exten => 75.s. extensión 100.1. La extensión t se utiliza cuando la función TIMEOUT está presente en el dialplan La extensión h se utiliza para añadir nuevas lineas de dialplan cuando se cuelga la llamada El segundo bloque del IVR es bastante parecido y envía el llamante a la extensión que haya digitado.1.Goto(IVR. Para que todas las llamadas externas sean atendidas por el IVR.• • • • i.2) same => n.Noop same => n. Este tipo de configuración se llama Ring Group. extensión s. vuelve a presentar el menú inicial h.Goto(IVR.1.Hangup Lo que se hará es marcar a las extensiones 1000. prioridad 1 Como esa extensión todavía no existe. en el caso que no se marque ninguna. Ejemplos: • • • un IVR que gestione colas de espera diferenciadas por departamento (ventas.#include IVR Se guardan los cambios y desde la consola de Asterisk: asterisk -rvvvvvvvvvvvvvv CLI> dialplan reload Ahora desde la extensión 1000. asistencia técnica. las posibilidades son prácticamente infinitas.) un IVR que permita marcar directamente una extensión o. compras. un IVR que avise el llamante que las oficinas están cerradas y que envíe la llamada al buzón de voz 162 . se marca la extensión 75 para probar el IVR desde local. Al momento de crear un IVR. envíe la llamada a una operadora. etc. . Valor 45 yes = la llamada parqueada se transfiere a la extensión que la parqueó. En ese caso hay que crear el contexto en el dialplan Locución que se enviará al canal parqueado cuando alguien lo llama o cuando se activa/desactiva la grabación de la llamada Valor beep Define a quien hay que enviar el courtesytone.conf A seguir la tabla con los parámetros del archivo y la descripción. Estas son: • • • • Parqueo de las llamadas Transferencia ciega y asistida Captura de las llamadas (Pickup) Grabación de las llamadas 9. Parámetro [general] parkext => parkpos => parkinghints Descripción Inicia la parte general del archivo 700 = numero de extensión donde transferir una llamada para parquearla 701-709 = numero de extensiones reservadas para parquear las llamadas no = las prioridades Hint para monitorear el estado de las extensiones dedicadas al parqueo hay que configurarlas manualmente en el dialplan. la configuración completa del archivo.CAPITULO IX Funcionalidades avanzadas de Asterisk – features. Puede ser: • parked (canal parqueado) • caller (quien llama un canal parqueado) • both (ambos) Activa o desactiva la secuencia de tonos para transferir la llamada cuando es una llamada parqueada. Pasado ese tiempo la llamada se transfiere a la extensión definida en el próximo parámetro.1 features.conf El archivo features.. En negrita la opción que se utilizará para cada parámetro. Con yes se crean de forma automática Numero de segundos que quedará parqueada una llamadas. extensión s. Con no se envía al contexto parkedcallstimeout.conf es donde se configuran las funcionalidades avanzadas de Asterisk que luego se pueden utilizar a lo largo de una llamada. prioridad 1. Puede ser: • callee (llamado) • caller (llamante) parkingtime => comebacktoorigin courtesytone parkedplay parkedcalltransfers . Al final de tabla. Valor 5 La locución que avisará que la transferencia de llamada asistida ha tenido éxito. Valor default Numero de segundos de espera entre los dígitos cuando se está transfiriendo una llamada. Valor beeperr Tiempo máximo de espera entre los dígitos para activar las funcionalidades definidas después de la etiqueta [featuremap] (en mili segundos) Valor 2000 Tiempo máximo disponible para contestar una transferencia asistida 165 parkedcallhangup parkedcallrecording parkedmusicclass transferdigittimeout => xfersound xferfailsound pickupexten pickupsound pickupfailsound featuredigittimeout atxfernoanswertimeout . Valor beep La locución que avisará que la captura de llamada no ha tenido éxito. Valor beeperr Secuencia de tonos para capturar la llamada de una extensión que está timbrando. Depende de la configuración de los parámetros callgroup y pickupgroup de cada extensión.Parámetro • • parkedcallreparking both (ambos) no (no permitido) Descripción Activa o desactiva la secuencia de tonos para parquear la llamada cuando es una llamada parqueada. Valor *8 La locución que avisará que la captura de llamada ha tenido éxito. Valor beep La locución que avisará que la transferencia de llamada no ha tenido éxito. Puede ser: • callee (llamado) • caller (llamante) • both (ambos) • no (no permitido) Activa o desactiva la secuencia de tonos para terminar una llamada cuando es una llamada parqueada. Puede ser: • callee (llamado) • caller (llamante) • both (ambos) • no (no permitido) Activa o desactiva la secuencia de tonos para grabar una llamada cuando es una llamada parqueada. Puede ser: • callee (llamado) • caller (llamante) • both (ambos) • no (no permitido) La clase de música en espera que escuchará el canal que ha sido parqueado. Valor no Numero de segundos de espera antes de intentar nuevamente devolver la llamada (si atxferdropcall = no).MOH_Class]] [applicationmap] 166 . Se dejan las cuatro lineas comentadas. Valor 10 Numero de veces que se intentará devolver una llamada transferida a quien la transfirió sin éxito.findslot => next [featuremap] blindxfer => disconnect => automon => atxfer => parkcall => automixmon => A partir de esta etiqueta empieza la configuración de las funcionalidades # = tecla para activar la transferencia ciega *0 = secuencia de dígitos para terminar una llamada *1 = secuencia de dígitos para iniciar la grabación de la llamada (en dos archivos audio.parkpos => 801-810 .context => empresa2 . Si está en yes la llamada no se devuelve y se considera terminada. La etiqueta define el nuevo bloque y los tres parámetros que siguen el contexto. el numero de las extensiones reservadas y como se van utilizando las extensiones. Para asignar una extensión a un determinado “slot” de parqueo. parámetro parkinglot. Un ejemplo es si quiere diferenciar las llamadas parqueadas por el departamento de ventas.<ActivateOn>[/<ActivatedBy>]. atxferloopdelay atxfercallbackretries . Valor 2 Se puede crear más de un bloque de extensiones para parquear las llamadas. uno para cada canal) *2 = secuencia de dígitos para activar la transferencia asistida *7 = secuencia de dígitos para parquear una llamada (se puede usar esta secuencia o #700) *3 = secuencia de dígitos para iniciar la grabación de una llamada (en un único archivo audio donde se mezclarán los dos canales audio) A partir de esta etiqueta se pueden configurar funcionalidades personalizadas.conf.<Application> [. en la configuración de la extensión en el sip. Asterisk devuelve la llamada a quien la estaba transfiriendo.[parkinglot_empresa2] .Parámetro (en segundos). La sintaxis es: <FeatureName> => <DTMF_sequence>. Valor 15 atxferdropcall Descripción Si quien transfiere una llamada con el método “asistido” cuelga antes que la llamada sea transferida completamente. se pone el nombre del contexto presente en la linea que sigue.<AppArguments>[. de las llamadas parqueadas por el departamento de compras. old se crea uno nuevo nano /etc/asterisk/features. Hay que presionar la tecla # y luego el numero de la extensión. Se escuchará timbrar la extensión y una vez que el interlocutor conteste. se podrá hablar con él (por ejemplo para anunciar la llamada que se va a transferir).conf. con peer para el otro canal.peer. Los valores son self y peer. La llamada será transferida y el el canal de quien la transfirió será colgado atxfer: A lo largo de una conversación se quiere transferir la llamada a otra extensión. Se presiona la secuencia *2 y luego el numero de la extensión donde se quiere transferir la llamada. both (ambos).Parámetro • • • Descripción FeatureName: El nombre de la funcionalidad. el otro escuchará la locución tt-monkeys mientras el canal que activó la funcionalidad. ActivatedBy: Este parámetro define quien tiene acceso a la funcionalidad.tt-monkeys. Solamente cuando se colgará la llamada será efectivamente transferida.conf y se copian las lineas que siguen: [general] parkext => 700 parkpos => 701-709 167 . escuchará la música en espera Antes de crear el archivo una pequeña explicación de la diferencia entre transferencia ciega y transferencia asistida: • blinxfer: A lo largo de una conversación se quiere transferir la llamada a otra extensión. DTMF_sequence: la secuencia de dígitos para activar la funcionalidad. Con self la funcionalidad se activa para quien la activa. • • • • test1 => *9. • Ahora se crea el archivo de configuración features. Application: La aplicación que se va a ejecutar. MOH_Class: la clase de música en espera que escuchará el canal libre mientras se ejecuta la funcionalidad en el otro canal.default = Digitando la secuencia *9 desde un canal. callee (llamado).conf /etc/asterisk/features. ActivateOn: aquí se define para quien activar la funcionalidad.Playback.conf. Se renombra el predefinido: mv /etc/asterisk/features. Las opciones son: caller (llamante). AppArguments: Las opciones asociadas a la aplicación. context => empresa2 . Se va a recoger la configuración del archivo así como se dejó en el modulo anterior.[parkinglot_empresa2] .parkinghints=no parkingtime => 45 comebacktoorigin=yes courtesytone=beep parkedplay=boht parkedcalltransfers=caller parkedcallreparking=caller parkedcallhangup=caller parkedcallrecording=caller parkedmusicclass=default transferdigittimeout => 5 xfersound=beep xferfailsound=beeperr pickupexten=*8 pickupsound=beep pickupfailsound=beeperr featuredigittimeout=2000 atxfernoanswertimeout=15 atxferdropcall=no atxferloopdelay=10 atxfercallbackretries=2 .findslot => next [featuremap] blindxfer => # disconnect => *0 automon => *1 atxfer => *2 parkcall => *7 automixmon => *3 [applicationmap] test1 => *9.conf [general] static=yes writeprotect=yse 168 .parkpos => 801-810 .Playback.default Se guardan los cambios. Para volver disponibles estas funcionalidades hay que modificar el plan de llamadas.tt-monkeys.peer. En negrita aparecen las modificaciones: nano /etc/asterisk/extensions. com.Hangup [internas] exten => 50.Echo same => n.60) same => n.2) exten => 100.MusicOnHold(mp3.1.voztovoice.45) same => n.1.Set(PBX=${ENV(LANG)}) same => n.1.autofallthrough=yse extenpatternmatchnew=yse clearglobalvars=no [globals] 1000=SIP/1000 JUST=SIP/justvoip marko=IAX2/marko DYNAMIC_FEATURES=test1#blindxfer#automon#disconnect#atxfer#parkcall#automixmon [from-didvoztovoice] exten => s.Hangup exten => 123.Goto(IVR.Noop same => n.1.Answer same => n.1.Dial(SIP/${EXTEN}.Answer same => n.Wait(1) same => n.Noop(Idioma Servidor ${PBX}) same => n.1.Estamos escuchando MP3) same => n.Hangup exten => 75.Answer same => n.Playback(hello-world) same => n.Hangup 169 .Dial(SIP/1000&SIP/1001&SIP/1002.Answer same => n.30) same => n.1.Playback(demo-echotest) same => n.Playback(demo-echodone) same => n.s.Hangup exten => 150.Dumpchan same => n.Answer same => n.Macro(disponible) same => n.Hangup exten => 200.1.2) same => n.Jabbersend(campus.Goto([email protected] exten => _100[0-2].s. Dial(gtalk/campus.exten => 1234.NoOP same => n.park:703@parkedcalls exten => 704.30) same => n.Authenticate(/tmp/pin.hint.IAX2/marko exten => 701.park:708@parkedcalls exten => 709.park:702@parkedcalls exten => 703.Dial(SIP/justvoip/${EXTEN}) same => n.Hangup exten => _66XX.park:704@parkedcalls exten => 705.hint.hint.hint.voztovoice/[email protected] [subscribe] exten => 1000.hint.D(${EXTEN:1})) same => n..30) same => n.hint.SIP/1001 exten => 1002..park:709@parkedcalls [google-in] 170 .Hangup exten => _9[12456789]XXXXXXX!.Playback(/tmp/prompt${EXTEN:2}) same => n.hint.park:707@parkedcalls exten => 708.1.Hangup [auten] exten => _00.Busy(3) same => n.Dial(SIP/spa3102.Dial(gtalk/campus.park:705@parkedcalls exten => 706.Dial(DAHDI/R1/${EXTEN:1}.Hangup exten => 10000.hint.1.Wait(2) same => n.SIP/1002 exten => marko.SIP/1000 exten => 1001.30) same => n.Dial(IAX2/marko.park:701@parkedcalls exten => 702.hint.hint.Wait(2) same => n.Wait(2) same => n.park:706@parkedcalls exten => 707.4) same => n.1.Answer() same => n.txt.com.voztovoice/${EXTEN}.hint.Hangup() exten => _[a-z].1.45) same => n.1.Hangup exten => _8.hint.Record(/tmp/prompt${EXTEN:2}:wav) same => n.45..am.1.hint.1. Dial(gtalk/campus.Dial(SIP/1000.Hangup [externas] include => internas include => internacio include => parkedcalls [locales] include => internas include => auten 171 .1.Hangup exten => _1XXXXXXXXXX..Hangup [internacio] exten => _00X.1.SendText(Espera un momento mientras te comunicamos con un operador) same => n.Set(GROUP(salida)=${CALLERID(num)}) same => n.Dial(SIP/1000.Set(GROUP(voip)=justvoip) same => n. bienvenido en VozToVoice) same => n.30) same => n.1.NoOp same => n.45) exten => s.Hangup exten => _NNXX.1.Como te llamas?) same => n.voztovoice/+${EXTEN}@voice..Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy) same => n.exten => s.Playback(all-outgoing-lines-unavailable) same => n.1.20)}) same => n.NoOp( Call from Gtalk ) same => n.1.voztovoice.Hangup same => n(busy).Set(trunksal=${GROUP_COUNT(justvoip@voip)}) same => n.Hangup() [from-spa3102] exten => s.Set(nombre=${JABBER_RECEIVE(campus.SendText(Hola.Dial(gtalk/campus.SendText(Hola ${nombre}.${CALLERID(name)}.NoOp same => n.Dial(SIP/1000) same => n.Dial(SIP/justvoip/${EXTEN}) same => n.com) same => n.voztovoice/+${EXTEN}@voice.Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)}) same => n.google.com) same => n.Set(CALLERID(name)=${nombre}) same => n.Hangup [from-pstn] exten => s.NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip) same => n.google.n.Wait(2) same => n. include => parkedcalls [macro-disponible] exten => s.MacroExit #include IVR Para que las funcionalidades configuradas en features.------Pickup *8 *8 Blind Transfer # # Attended Transfer *2 One Touch Monitor *1 Disconnect Call * *0 Park Call *7 172 . De esta forma siempre se podrá saber cuantas llamadas están parqueadas (en los teléfonos IP software y hardware que soportan esta funcionalidad).n.Gotoif($["${estado}" = "NOT_INUSE"]?5) exten => s.Set(estado=${DEVICE_STATE(SIP/${MACRO_EXTEN})}) exten => s. Después de la etiqueta [subscribe] se han añadido nueve líneas para poder monitorear el estado de las extensiones utilizadas para parquear las llamadas. Hay tres aplicaciones relacionadas con el parqueo de llamadas que se pueden utilizar en el dialplan: • • • Park ParkAndAnnounce ParkedCall Se guardan los cambios y se reinicia Asterisk: /etc/init.n. asterisk -rvvvvvvvvvvvv CLI> features show Builtin Feature Default Current --------------------. tendrán acceso al contexto parkedcalls es decir podrán llamar una extensión parqueada.1.Hangup exten => s. además de tener acceso al contexto internas y internacio. Todas las extensiones que tengan acceso al contexto externas.n. Lo mismo para las extensiones que tienen acceso al contexto [locales].Busy exten => s.n. Para terminar en las etiquetas [externas] y [locales] se ha añadido el contexto parkedcalls.conf sean activas hay que definir la variable DYNAMIC_FEAUTURES y añadirle todas las funcionalidades que se han configurado.d/asterisk restart Desde la consola de Asterisk podemos ver las funcionalidades activadas. One Touch MixMonitor *3 Dynamic Feature Default Current --------------------.1002 Extensiones soporte: 2000 . Una configuración un poco más compleja podría ser: Extensiones ventas: 1000 .2002 Extensiones compras: 3000 .1001 .3002 Extensión oficina dirección: 4000 173 .------test1 no def *9 Feature Groups: --------------(none) Call parking (Parking lot: default) -----------Parking extension : 700 Parking context : parkedcalls Parked call extensions: 701-709 9.3001 .conf y es *8. La secuencia de dígitos para capturar una llamada se acaba de configurar el el archivo features.2 Callgroup y Pickupgroup En todas las extensiones SIP configuradas se han definido los siguientes parámetros: callgroup=1 pickupgroup=1 ¿Qué significa? Significa que todas las extensiones pertenecen al grupo de llamadas 1 y pueden capturar las llamadas del grupo de llamadas 1.2001 . 3 La extensión 4000.3 podrá capturar las llamadas de 174 . Para que esto sea posible. con el parámetro pickupgroup configurado con 1.2.2. en la configuración de cada extensión se pone: [1000] callgroup=1 pickupgroup=1 [1001] callgroup=1 pickupgroup=1 [1002] callgroup=1 pickupgroup=1 [2000] callgroup=2 pickupgroup=2 [2001] callgroup=2 pickupgroup=2 [2002] callgroup=2 pickupgroup=2 [3000] callgroup=3 pickupgroup=3 [3001] callgroup=3 pickupgroup=3 [3000] callgroup=3 pickupgroup=3 [4000] callgroup=4 pickupgroup=1.El escenario es que cada trabajador de cada departamento pueda capturar las llamadas de los teléfonos del departamento en que trabaja y que desde la oficina de dirección se pueda capturar las llamadas de cualquier extensión de cualquier departamento. Como tecnología se ha indicado SIP porque justvoip usa solo este tipo de protocolo. exten => 00573001000000.3 Aplicación Dial y features.3001.1. es decir terminará la llamada.45) same => n.conf En este párrafo se ilustrará como integrar en el dialplan las funcionalidades configuradas en el archivo features.conf se tendrá que utilizar unas 175 ..timeout][.URL]): • • • • • • Dial: el nombre de la aplicación que nos permite efectuar una llamada Technology: el protocolo o la tecnología usada para efectuar la llamada (ej: SIP. La sintaxis de la aplicación Dial: Dial(Technology/resource[&Tech2/resource2.1001. es decir: • • • grupo 1 – 1000. Asterisk procesará la línea siguiente del dialplan.. IAX2) resource: el recurso utilizado 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 el teléfono soporta la funcionalida) Algunos ejemplos: exten => 1000.las extensiones que perteneces a uno de los grupos configurados.Dial(SIP/1000.Dial(IAX2/justvoip/00573001000000.1. Esperará una respuesta por 45 segundos y si nadie contesta terminará la llamada.1002 grupo 2 – 2000. esperará 30 segundos.options][.Hangup En este caso si desde un SoftPhone o IP Phone conectados a la centralita se marca el numero 0057300100000.2001.Hangup Para configurar las funcionalidades definidas en el archivo features.1.45) same => n.3002 9. Si la extensión 1000 no contesta dentro de los treinta segundos.][.conf utilizando la aplicación Dial. En el caso de proveedores que utilicen el protocolo IAX2 sería: exten => 00573001000000.Hangup Si se marca la extensión 1000 Asterisk llamará dicha extensión usando el protocolo SIP.Dial(SIP/justvoip/00573001000000.. Asterisk llamará dicho numero usando un proveedor VoIP (en este caso especifico Justvoip).2002 grupo 3 – 3000..45) same => n.. creará dos archivos audio.xX) • x: permite al llamado empezar la grabación de la llamada presionando la secuencia de dígitos definida en features.conf.45. 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: permite al llamante empezar la grabación de la llamada presionando la secuencia de dígitos definida en features.conf.conf.1. uno por cada canal W: permite al llamante empezar la grabación de la llamada presionando la secuencia de dígitos definida en features. exten => 100X.Dial(SIP/${EXTEN}.Dial(SIP/ ${EXTEN}.45.Dial(SIP/${EXTEN}. 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 • Si se quiere. exten => 100X.Dial(SIP/${EXTEN}.1. en este caso.conf exten => 100X.conf T: permite al llamante transferir la llamada presionando la secuencia de dígitos definida en features. Asterisk.hHkKtTwWxX) 176 .wW) • • w: permite al llamado empezar la grabación de la llamada presionando la secuencia de dígitos definida en features.conf K: permite al llamante parquear la llamada presionando la secuencia de dígitos definida en features. activar todas estas opciones a la vez.opciones de la aplicación Dial.45.conf H: permite al llamante colgar la llamada presionando la secuencia de dígitos definida en features. la aplicación Dial aparecerá de esta forma: exten => _100X.kK) • • k: permite al llamado parquear la llamada presionando la secuencia de dígitos definida en features. uno por cada canal.Dial(SIP/${EXTEN}.conf exten => 100X. Asterisk. creará dos archivos audio.45.45.1.45.1.hH) Las opciones presentes: • • h: permite al llamado colgar la llamada presionando la secuencia de dígitos definida en features.Dial(SIP/${EXTEN}.1.1. por ejemplo.conf exten => 100X. en este caso.tT) • • t: permite al llamado transferir la llamada presionando la secuencia de dígitos definida en features.conf. hHkKtTwWxX) same => n.Macro(disponible) same => n. (en negrita los cambios): nano /etc/asterisk/extensions.1.conf exten => _100[0-2].Hangup Se actualiza el dialplan: asterisk -rvvvvvvvvvvvvv CLI> dialplan reload En el X-Lite se añaden todas las extensiones reservadas para el parqueo de las llamadas.A seguir se presentarán algunos registros como aparecen en la consola de Asterisk al activar o desactivar las funcionalidades descritas.Dial(SIP/${EXTEN}. Para terminar se modifica el dialplan para incluir estas funcionalidades en las llamadas entre extensiones.45. El resultado tienes que ser: Ahora desde la extensión 1001 se marca la extensión 1002 y cuando esta conteste se parquea la llamada (con la secuencia de dígitos *7 o #700). El resultado será: 177 . ulaw' (language 'es') Digitando nuevamente la secuencia *3 terminará la grabación de la llamada: -.wav 178 . filename: auto-1318460210-1001-1002 == Begin MixMonitor Recording SIP/1002-0000000a -.<SIP/1001-00000009> Playing 'beep. presionando el botón derecho del ratón sobre la linea de la extensión 701 se podrá llamar la extensión parqueada es decir la extensión 1002. Desde el X-Lite.User hit '*3' to record call.<SIP/1001-00000009> Playing 'beep.User hit '*3' to stop recording call.1 root root 233964 Oct 12 17:57 auto-1318460210-1001-1002. En la consola de Asterisk aparecerá: -. == MixMonitor close filestream == End MixMonitor Recording SIP/1002-0000000a Se sale de la consola de Asterisk: CLI> quit Se averigua que se haya creado el archivo: ls -l /var/spool/asterisk/monitor/ -rw-r--r-. Otra prueba que se puede hacer es grabar la llamada utilizando la secuencia de dígitos *3 para tener un solo archivo audio de toda la conversación. Desde la extensión 1001 se marca nuevamente a las 1002 y cuando esta conteste.La extensión 1002 esta parqueada en la extensión 701.ulaw' (language 'es') -. se activa la grabación de la llamada digitando *3. la llamada será capturada por la extensión 1000 que podrá hablar con la extensión 1001.Para probar la captura de llamada. 179 . Si todo funciona bien. se llama desde la extensión 1001 a la extensión 1002 y cuando ésta timbre. desde la extensión 1000 (X-Lite) se digita *8. . puede interactuar con estos formatos de Calendario.Capitulo X Asterisk y los calendarios Asterisk puede ser integrado con distintos formatos de calendarios. se averigua que los módulos estén habilitados: . MS Exchange: utilizado por Microsoft Exchange 2003 Ms Exchange Web Services: utilizado por Exchange 2007 y superiores.so Asterisk MS Exchange Web Service Calenda 0 res_calendar_icalendar.so Asterisk Calendar integration 1 res_calendar_caldav.so Asterisk MS Exchange Calendar Integratio 0 Para que estén activados en Asterisk. oportunamente configurado. Para el formato de los datos se apoya a iCalendar. Los formatos soportados son: • • iCalendar: es un estándar Internet (RFC5546) que ha sido utilizado por primera vez por Apple con su aplicación iCal CalDAV: es un estándar Internet (RFC4791) que permite a un cliente acceder a la información de eventos programados presentes en un servidor. Los módulos que se encargan de esta integración son: asterisk -rvvvvvvvvvvvvv CLI> module show like res_calendar Module Description Use Count res_calendar. Yahoo! Calendar y Thunderbird de Mozilla Fundation. Es una extensión del estándar Internet WebDAV (RCF 4918).ics file integration 0 res_calendar_exchange. • • Esto significa que Asterisk. Esta nueva funcionalidad ha sido incluida desde la versión 1. entre ellas. Actualmente es utilizado por muchas aplicaciones. el comando make menuselect.so Asterisk iCalendar .so Asterisk CalDAV Calendar Integration 0 res_calendar_ews.8. desde la carpeta de las fuentes de Asterisk.X. hay que compilar las siguientes dos librerías: • • Neon libical Al momento de ejecutar. Google Calendar. Zimbra. Este valor tiene que ser mayor del parámetro refresh. Personalizar Puede ser: • iCal • caldav • exchange (Microsoft Exhange 2003) • ews ( Microsoft Exchange 2007 y superiores) Para Google Calendar el tipo es caldav La URL para conectarse al calendario. la opción que se utilizará para cada parámetro. extensión definida • ejecutar una aplicación y definir sus parámetros. En el caso de GoogleCalendar la sintaxis es: https://www.1 calendar. Valor: 10 Por cada consulta extraer los eventos que tendrán lugar en los próximos N minutos. se simulará la conexión al calendario de Google. la configuración completa del archivo. En negrita.com Personalizar la contraseña del usuario Google Cada cuantos minutos consultar el Calendario de Google para actualizar los datos en Asterisk.com/events/ Personalizar username@gmail con su cuenta de Google Nombre usuario gmail. Valor: 180 (3 horas) Este parámetro anula cualquiera notificación configurada para un evento y la cambia por el valor indicado en minutos. Valor 10 Cuando falten los N minutos definidos en el parámetro autoreminder. Parámetro [campusvoztovoice] type Descripción Etiqueta que permite identificar el calendario que se está configurando. A partir de los próximos parámetros podemos definir dos comportamientos distintos cuando la extensión 1000 conteste la llamada: • enviar la llamada a un contexto. En este archivo se puede configurar más de un calendario y cada uno será identificado por una etiqueta inicial. En campus.conf El archivo para la configuración de los calendarios es calendar. es posible enviar una llamada a la extensión indicada en este parámetro. Suponiendo que este calendario es asociado a la extensión 1000. nombre del contexto: calendario 182 este ejemplo: url user secret refresh timeframe autoreminder channel context . Para crear un entorno real. que se puede activar utilizando una cuenta Gmail registrada.google.conf y se encuentra en la carpeta /etc/[email protected]/calendar/dav/[email protected]. La sintaxis es: Tecnología/numero. A seguir la tabla con los parámetros de configuración. se pone SIP/1000. Al final de la tabla. Primero se crea una copia del archivo predefinido: mv /etc/asterisk/calendar.app= Playback .google. el parámetro user y el parámetro secret con los datos de su cuenta Google.conf [campusvoztovoice] type=caldav url=https://www.conf.com secret=password refresh=10 timeframe=180 autoreminder=10 channel=SIP/1000 context=calendario extension=cal waittime=45 . cuando la extensión 1000 conteste.Parámetro extension app appdata waittime numero de extensión: cal Descripción aplicación a ejecutar cuando la extensión conteste: Playback opciones para la aplicación: demo-congrats este ultimo parámetro define el tiempo (en segundos) que tendrá la extensión 1000 para contestar la llamada.conf /etc/asterisk/calendar. Se guardan los cambios Ahora se entra en la pagina del calendario de Google y se van añadiendo una serie de eventos para el día en que se está configurando este modulo.com/events/ user=campus.old y se crea uno nuevo: nano /etc/asterisk/calendar.com/calendar/dav/username@gmail. En este ejemplo se han creado tres: 183 . se utilizarán los dos parámetros context/extension. Como configuración predefinida.voztovoice@gmail. Valor 45 Con estos parámetros se configura el primer calendario. el parámetro url.appdata=demo-conrats IMPORTANTE: Personalizar los datos de la etiqueta inicial. [email protected]/events/ Aparecerá: 184 .so Si aparece esta advertencia: [Feb 7 16:20:09] WARNING[27477]: res_calendar_caldav. En este caso: https://www.com/calendar/dav/campus.Se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvvvvv Se recarga el modulo calendario: CLI> module reload res_calendar. Se abre una ventana del navegador y se pega la url que aparece en el archivo calendar.conf.c:157 caldav_request: Unknown response to CalDAV calendar campusvoztovoice.google. request REPORT to /calendar/dav/campus. ¿Por qué? Primero se descarta que sea un problema de la configuración de los datos en el archivo calendar.com/events/: Could not read status line: connection was closed by server significa que la configuración no está funcionando.voztovoice@gmail. Se termina presionando el botón “Iniciar sesión”. Si se mira el parametro url del archivo. esto quiere decir que se basa en una conexión segura y que la librería que permite la conexión CalDAV (neon) debe implementar el protocolo SSL. Esto significa que los datos de configuración del archivo calendar.conf son correctos. ¿Será que Neon no se ha compilado con el soporte SSL? Se entra en la carpeta de las fuentes de neon: cd /usr/src/neon-0.29.6 y se lanza nuevamente un configure: .Se pone el nombre de usuario de Google y la contraseña. se notará que empieza con https./configure Cuando el comando termine: Por defecto neon no se compila con el soporte SSL. Si la conexión tiene éxito aparecerá una ventana de descarga que pedirá de guardar un archivo de texto: El archivo descargado contendrá todos los datos del calendario. pues para solucionar el problema hay que volver a compilar neon y luego Asterisk: 185 . 8.make distclean ./configure --prefix=/usr --with-ssl=openssl Ahora si se compiló con el soporte SSL.11./configure Se necesita volver a entrar en la interfaz gráfica para seleccionar los módulos Add-ons ya que por defecto no están seleccionados: make menuselect 186 . Se termina la compilación e instalación: make make install Ahora hay que volver a compilar Asterisk. Primero se para el servicio: service asterisk stop Se entra en la carpeta de las fuentes: cd /usr/src/asterisk-1.0 se borra la compilación anterior: make distclean se vuelve a compilar: . CLI> calendar show calendars Con este comando aparecerá la lista de calendarios configurados y el estados de cada uno: Calendar Type Status ---------------campusvoztovoice caldav free Con este comando: CLI> calendar show calendar campusvoztovoice se pueden ver los eventos programados en los próximos 180 minutos (parámetro timeframe=180). 187 . se inicia nuevamente Asterisk: service asterisk start Se entra en la consola y se recarga nuevamente el modulo Calendario: asterisk -rvvvvvvvvvvvvv CLI> module reload res_calendar. Si no aparecen es porque todavía Asterisk no ha actualizado la información ya que lo hace cada 10 minutos (parametro refresh=10). Modificar campusvoztovoice con el nombre de su calendario.Se guardan los cambios y se vuelve a compilar: make make install Terminada esta operación.so Si no aparecen errores y/o advertencias significa que esta vez la conexión al calendario de Google ha tenido éxito y se debería poder ver algunos eventos programados. ¿Cómo se construye el dialplan para que la extensión 1000 pueda saber que cita está para iniciar?. los requisitos son: • • • Paquete Perl Paquete perl-libwww sox 188 . Lefteris Zafiris.Aparece el evento de las 7:30 y el evento de las 9:30. Aunque la parte de los AGI se verá de manera más detallada en el ultimo modulo del curso. Ahora para que la llamada llegue a la extensión 1000 hay que crear el contexto calendario y la extensión cal (como configurado en el archivo calendar. Hay que instalar un sistema de texto a voz que lea un texto y lo transforme en audio. ha desarrolado un AGI que se conecta al sistema de texto a voz de Google y transforma un texto en audio.conf). en este caso se implementará esta solución. Para que el AGI funcione. El evento programado a las 11 no aparece porque el modulo está configurado para que lea los eventos de los próximos 180 minutos. ".5.13. compila e instala mpg123: cd /usr/src wget http://downloads.tar. Por eso se copia el AGI en esa carpeta y se vuelve ejecutable: cp googletts."${CALENDAR_EVENT(summary)}.13.gz Se entra en la carpeta creada: cd asterisk-googletts-0.agi. se instalan los paquetes de perl: yum install perl perl-libwww-perl se descarga.tar./configure --prefix=/usr make make install Ya se puede descargar el archivo que contiene el AGI: cd /usr/src wget http://www.4/mpg123-1.agi Por ultimo se modifica el dialplan: nano /etc/asterisk/extensions.bz2 tar -xf mpg123-1.• • mpg123 el servidor donde está instalado Asterisk debe tener acceso a Internet Como sox ya está instalado.5.4 .agi /var/lib/asterisk/agi-bin/ chmod +x /var/lib/asterisk/agi-bin/googletts.voztovoice.gz Se descomprime: tar -xf asterisk-googletts-0.bz2 cd mpg123-1.sourceforge.org/campus/pbx18/asterisk-googletts-0.13.13.tar.5 Por defecto Asterisk busca los AGI en la carpeta /var/lib/asterisk/agi-bin.1.net/project/mpg123/mpg123/1.NoOp(Llamada desde el calendario) same => n.4.4.conf y antes del contexto internas se crea el nuevo contexto: [calendario] exten => cal.tar.es) 189 .Agi(googletts. "a las ${STRFTIME(${CALENDAR_EVENT(start)}.Wait(1) same => n. Asterisk llamará la extensión 1000 y cuando esta conteste.Hangup En la segunda y tercera linea se inicia el AGI y se leen las variables $ {CALENDAR_EVENT(summary)} y ${CALENDAR_EVENT(start)} que contienen el titulo del evento y la hora de inicio respectivamente.Agi(googletts.agi..Playback(goodbye) same => n.es) same => n.%H:%M)}. La llamada llegará siempre con este CALLERID: Cuando el evento iniciará en el calendario aparecerá el estado ocupado: asterisk -rvvvvvvvvvvvvvv CLI> calendar show calendars Calendar Type Status ---------------campusvoztovoice caldav busy Esto es así siempre y cuando en la configuración del evento en el Calendario se haya configurado la opción: Para saber que tipo de informaciones se pueden conocer acerca de un evento programado el comando 190 .same => n. hay que transformarla en el formato de hora y minutos a través de la función STRFTIME Se recarga el dialplan: asterisk -rx "dialplan reload" 10 minutos antes del inicio del evento. le anunciará el tipo de evento y la hora en que va a iniciar.". Como la hora se lee en el formato EPOCH. The location of the eventt categories . [Syntax] CALENDAR_EVENT(field) [Arguments] field summary .The VEVENT SUMMARY property or Exchange event 'subject' description .The priority of the event calendar .The name of the calendar associated with the event uid . 2=BUSY Todos los parámetros bajo la etiqueta [Arguments] se pueden extraer del calendario y utilizar en el dialplan.The categories of the event priority .2 CALENDAR_BUSY Es una función que permite consultar un calendario para ver si su estado es libre o ocupado.The end time of the event busystate .The text description of the event organizer .The organizer of the event location .The unique identifier for this event start .es: asterisk -rvvvvvvvvvvvvvv CLI> core show function CALENDAR_EVENT -= Info about function 'CALENDAR_EVENT' =[Synopsis] Get calendar event notification data from a notification call. Un ejemplo: el calendario 191 CALENDAR_QUERY . 1=TENTATIVE. Para conocer todas las funciones disponibles en Asterisk para trabajar con los calendarios: CLI> core show function calendar + tecla tabulador CALENDAR_BUSY CALENDAR_EVENT CALENDAR_QUERY_RESULT CALENDAR_WRITE 10.The busy state of the event 0=FREE. [Description] Whenever a calendar event notification call is made. Este tipo de respuesta se puede utilizar en el dialplan asociando el calendario a una determinada extensión y en base al estado del calendario procesar la llamada de diferentes formas. the event data may be accessed with this function.The start time of the event end . En el caso que el resultado sea 1. se anuncia al llamante de llamar más tarde.Hangup y al final del archivo.45.Agi(googletts.Macro(calendario) same => n.Macro(disponible) same => n.Noop(Estado = ${estado}) same => n.conf se modifica este bloque: exten => _100[0-2].1. Si el estado del calendario es ocupado.1. Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvvvvvvvvvvv 192 .Macro(disponible) same => n. sino se pasa la llamada a la extensión 1000.es) same => n.Hangup Esta nueva macro controla primero si la extensión que se está llamando es la 1000.Set(estado=${CALENDAR_BUSY(campusvoztovoice)}) same => n.45. se le anuncia al llamante (con el AGI de google) que la extensión se encuentra ocupada y que llame más tarde).agi.Dial(SIP/${EXTEN}. Si el resultado es 0 se sale de la Macro y se vuelve al contexto."la extensión se encuentra ocupada.1.Hangup para que quede: exten => _100[0-2].hHkKtTwWxX) same => n.Gotoif($[${estado} = 1]?ocupado) same => n.configurado en Asterisk está asociado a la extensión 1000.MacroExit same => n(ocupado). Si resulta ocupado.Noop(${MACRO_EXTEN}) same => n. Se abre el dialplan nano /etc/asterisk/extensions. si resulta libre Asterisk devuelve el valor 0). extensión.GotoIf($[${MACRO_EXTEN} = 1000]?calendario) same => n.hHkKtTwWxX) same => n. llame mas tarde. Asterisk devuelve el valor 1. Gracias". Si es así continua desde la etiqueta calendario donde revisa si el calendario asociado a la extensión 1000 (en este caso campusvoztovoice) resulta libre o ocupado.Dial(SIP/${EXTEN}. prioridad +1 de donde la Macro se ha llamado. antes de esta linea: #include IVR se añade la nueva macro: [macro-calendario] exten => s.MacroExit same => n(calendario). "disponible") in new stack -.Executing [s@macro-calendario:1] NoOp("SIP/1001-0000000f".agi.CLI> dialplan reload se averigua el estado del calendario: CLI> calendar show calendars Calendar Type Status ---------------campusvoztovoice caldav busy Como en este caso resulta el ocupado. "1?calendario") in new stack -.Executing [s@macro-calendario:9] Hangup("SIP/1001-0000000f".<SIP/1001-0000000f>AGI Script googletts.agi -. "estado=NOT_INUSE") in new stack -.Executing [s@macro-disponible:2] GotoIf("SIP/1001-0000000f".Executing [s@macro-disponible:5] MacroExit("SIP/1001-0000000f". "googletts.Executing [s@macro-calendario:4] Set("SIP/1001-0000000f".Executing [1000@externas:1] Macro("SIP/1001-0000000f". returning 0 -. "Estado = 1") in new stack -.agi completed. "") in new stack -.es") in new stack -. se debería escuchar el anuncio que la extensión se encuentra ocupada. Gracias". description – La descripción del evento organizer – El organizador del evento location – Sitio donde tiene lugar el evento 193 . El resultado de la llamada en la consola: Extension Changed 1001[subscribe] new state InUse for Notify User 1000 -. "1?5") in new stack -.Executing [1000@externas:2] Macro("SIP/1001-0000000f". si desde la extensión 1001 se marca a la extensión 1000. "1000") in new stack -.s.s. "calendario") in new stack -. "1?ocupado") in new stack -.Executing [s@macro-disponible:1] Set("SIP/1001-0000000f".Playing '/tmp/80eb1469553d3ab98b95661fbf6a2f1c' (escape_digits=) (sample_offset 0) -.3 CALENDAR_EVENT Como ya se ha visto más arriba.Launched AGI Script /var/lib/asterisk/agi-bin/googletts. Más en detalle: • • • • summary – El titulo del evento.4) -.s.Executing [s@macro-calendario:5] NoOp("SIP/1001-0000000f".8) -.Executing [s@macro-calendario:8] AGI("SIP/1001-0000000f". esta función permite extraer todas las informaciones relacionadas con un evento.5) -. "") in new stack 10.Goto (macro-calendario.Goto (macro-disponible. "estado=1") in new stack -."la extension se encuentra ocupada. llame mas tarde.Executing [s@macro-calendario:6] GotoIf("SIP/1001-0000000f".Executing [s@macro-calendario:2] GotoIf("SIP/1001-0000000f".Goto (macro-calendario. Lo importante es que cada persona que tiene o quiere participar a la conferencia ponga en su calendario personal la misma información en los campos Titulo y lugar. En Google calendar sería: ¿Parece complicado? La verdad no. se pueden construir diferentes bloques de dialplan.• • • • • • • categories – Categoría del evento priority – Prioridad asignada al evento calendar – Nombre del calendario asociado con el evento uid – numero único que identifica el evento start – Fecha y hora de inicio de un evento end – Fecha y hora en que termina el evento busystate – El estado configurado para el evento Con estos datos. En en dialplan: 194 . Un ejemplo es configurar un evento de Conferencia y en la casilla lugar indicar un numero de cuarto de conferencia. cM(default)) same => n.Playback(goodbye) same => n.%H:%M)}.Agi(googletts.es) same => n. 10..Agi(googletts.NoOp(Llamada desde el calendario) same => n.4 CALENDAR_QUERY y CALENDAR_QUERY_RESULT Esta dos funciones sirven para hacer consultas en los calendarios configurados en Asterisk y sacar los datos de interés.Agi(googletts.Playback(goodbye) same => n. desde la consola de Asterisk: 195 .es) same => n.conf Se modifica este bloque: [calendario] exten => cal."${CALENDAR_EVENT(summary)} a las ${STRFTIME($ {CALENDAR_EVENT(start)}.Hangup same => n(conf). Si la variable está vacía devuelve 1 sino 0."a las ${STRFTIME(${CALENDAR_EVENT(start)}.Hangup En la linea dos se utiliza la función ISNULL que permite averiguar si una variable está vacía.agi.. En la linea con la etiqueta conf se utiliza el AGI de texto a voz de Google y se le anuncia a la extensión la descripción del evento.1. Para saber que datos se pueden extraer.".Gotoif($[${ISNULL(${CALENDAR_EVENT(location)})} = 0 & "$ {CALENDAR_EVENT(summary)}" = "Conferencia"]?conf) same => n. Se profundizará el tema de las conferencias en el Capitulo XV.Wait(1) same => n.".1.nano /etc/asterisk/extensions."${CALENDAR_EVENT(summary)}.agi.%H:%M)}.".Confbridge(${CALENDAR_EVENT(location)}.es) same => n. En la linea siguiente se utiliza la aplicación ConfBridge para crear una conferencia dinámica cuyo numero es el que aparece en el campo lugar (location) del calendario y se envía la extensión a esa conferencia.es) same => n.agi.Wait(1) same => n.agi.NoOp(Llamada desde el calendario) same => n.Agi(googletts.Hangup Para que quede: [calendario] exten => cal. La lógica de la linea funciona de la siguiente manera: Si la variable ${CALENDAR_EVENT(location)} no está vacía “y” (el carácter &) la variable $ {CALENDAR_EVENT(summary) contiene el valor Conferencia ir a la etiqueta conf sino continuar con la linea que sigue."${CALENDAR_EVENT(description)}". asterisk -rvvvvvvvvvvvvvv CLI> core show function CALENDAR_QUERY_RESULT • • • • • • • • • • • • getnum – numero de eventos que tendrán lugar en el rango de tiempo indicado en la consulta (en este caso 180 minutos) summary – Titulo del evento description – Descripción del evento organizer – Organizador del evento location – Lugar del evento categories – Categoría del evento priority – Prioridad del evento calendar – Nombre del calendario uid – Numero que identifica univocamente el evento start – Hora de inicio del evento end – Hora en que termina el evento busystate – El estado del calendario La sintaxis de la función es: CALENDAR_QUERY_RESULT(id. se crean dos nuevos eventos: Se averigua que los eventos aparecen en Asterisk: 196 . con esta opción se define a que evento hace referencia el campo que se quiere extraer Para ver como funcionan.field[.entry]) • • • id – el valor obtenido con la función CALENDAR_QUERY field – El campos que se quiere extraer de un determinado evento entry – en el caso que la función CALENDAR_QUERY haya almacenado en su id más de un evento. agi.Hangup • Linea 2 – Como en la configuración de los calendarios se ha puesto como limite de consulta los 180 minutos.conf Linea 3 – se asigna a la variable id el resultado de la consulta en el calendario campusvoztovoice indicando la ora de inicio y la hora final de la consulta.Set(numeve=${CALENDAR_QUERY_RESULT(${id}.es) same => n.Set(id=${CALENDAR_QUERY(campusvoztovoice.While($[${numeve} > 0]) same => n.es) same => n.Set(num=1) same => n.getnum)}) same => n.start.${EPOCH}.Noop(Consulta en el calendario) same => n.%H:%M)}".Endwhile same => n. No se puede hacer consultas más allá de este tiempo sin cambiar la configuración del parámetro timeframe en calendar.."${CALENDAR_QUERY_RESULT(${id}.Agi(googletts.agi.${num})}".1.summary.Set(num=$[${num}+1]) same => n.Perfecto! Ahora se crea el dialplan para hacer una consulta al calendario: nano /etc/asterisk/extensions.conf En el contexto internas se añade este bloque: exten => 51.${fin})}) same => n.$ {num})}.Set(numeve=$[${numeve}-1]) same => n. es decir los eventos 197 • . se añade a la variable ${EPOCH} el valor 10800 segundos que corresponden a 180 minutos.Set(fin=$[${EPOCH}+10800]) same => n.Agi(googletts."a las ${STRFTIME(${CALENDAR_QUERY_RESULT(${id}. • • • • • • • • que tendrán lugar en lo próximos 180 minutos Linea 4 – se asigna a la variable numeve el numero de eventos que tendrán lugar en los próximos 180 minutos Linea 5 – se asigna a la variable num el valor 1 Linea 6 – la aplicación While se usa para crear un ciclo y este ciclo se ejecutará hasta que la variable ${numeve} sea mayor a 0 Linea 7 – con el AGI del TTS de Google se anuncia el titulo del evento (summary) de la entrada cuyo numero es el contenido en la variable ${num} Linea 8 - con el AGI del TTS de Google se anuncia la hora (start) de la entrada cuyo numero es el contenido en la variable ${num} Linea 9 – se asigna a la variable ${numeve} el valor de la misma variable menos 1. Ejemplo: si el calendario contiene dos eventos en los próximos 180 minutos, la variable ${numeve} contiene el valor 2. Después de esta linea contendrá el valor 1 Linea 10 – Se asigna a la variable ${num} el valor de la variable ${num} + 1. Como inicialmente la variable contenía el valor 1, después de esta linea contendrá el valor 2 Llinea 11 – Con la aplicación EndWhile se cierra el ciclo y el dialplan vuelve a la linea con la aplicación While. Ahora, como la variable ${numeve} es todavía mayor que 0, el ciclo se repite y se leerá el titulo y la hora del segundo evento. La siguiente vez que se vuelve a la aplicación While, la variable ${numeve} contendrá el valor cero pues se saldrá del ciclo “While - Endwhile” y se ejecutará la linea que sigue la aplicación EndWhile, es decir same => n,Hangup De esta forma si llegando a la oficina, se quiere conocer los eventos programados en las próximas 3 horas, basta marcar la extensión 51. Claramente cada persona de la empresa puede tener su calendario personal. 10.5 CALENDAR_WRITE Con la función CALENDAR_WRITE, es posible crear nuevos eventos en el calendario desde Asterisk. En este ejemplo se mostrará como grabar las llamadas salientes con el proveedor Justvoip en un calendario. Para este ejemplo se utilizará un nuevo calendario. Desde la pagina de administración del calendario principal, se entra en la pagina de configuración y se crea un nuevo calendario: 198 Se presiona el botón “Crear un calendario nuevo” y en la nueva pagina se rellenas los campos: Se concluye la creación presionando el botón “Crear calendario”. Se entra en la configuración del nuevo calendario y se anota el siguiente dato: Con el valor del ID del nuevo calendario se configura Asterisk: nano /etc/asterisk/calendar.conf al final del archivo se añade: [llamadas] type=caldav url=https://www.google.com/calendar/dav/[email protected]/events/ [email protected] secret=password refresh=10 timeframe=180 autoreminder=10 channel=SIP/1000 context=calendario extension=cal waittime=45 199 IMPORTANTE: Personalizar los datos de la etiqueta inicial, el parámetro url, el parámetro user y el parámetro secret con los datos de su cuenta Google. Se guardan los cambios y se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvvvv Se recarga el modulo: CLI> module reload res_calendar.so Si no aparecen errores y/o advertencias, todo debería estar bien configurado. Con el comando: CLI> calendar show calendars Calendar Type Status ---------------campusvoztovoice caldav free llamadas caldav free Se puede comprobar que efectivamente los dos calendarios están conectados. Los datos de las llamadas que se guardarán en el calendario son: • • • • extensión que ha iniciado la llamada IP de la extensión numero marcado Fecha de la llamada Para implementar está solución se abre el dialplan: nano /etc/asterisk/extensions.conf se modifica este bloque: [internacio] exten => _00X.,1,NoOp same => n,Set(GROUP(voip)=justvoip) same => n,Set(GROUP(salida)=${CALLERID(num)}) same => n,Set(trunksal=${GROUP_COUNT(justvoip@voip)}) same => n,Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)}) same => n,NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip) same => n,Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy) same => n,Dial(SIP/justvoip/${EXTEN}) same => n,Hangup 200 same => n(busy),Playback(all-outgoing-lines-unavailable) same => n,Hangup Para que quede: [internacio] exten => _00X.,1,NoOp same => n,Set(CALENDAR_WRITE(llamadas,summary,description,location,start)=Llamada de $ {CALLERID(num)} a ${EXTEN},Llamada desde la extension ${CALLERID(num)} al numero $ {EXTEN},IP = ${CHANNEL(peerip)},${EPOCH}) same => n,Set(GROUP(voip)=justvoip) same => n,Set(GROUP(salida)=${CALLERID(num)}) same => n,Set(trunksal=${GROUP_COUNT(justvoip@voip)}) same => n,Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)}) same => n,NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip) same => n,Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy) same => n,Dial(SIP/justvoip/${EXTEN}) same => n,Hangup same => n(busy),Playback(all-outgoing-lines-unavailable) same => n,Hangup Se ha añadido la linea 2 (en amarillo). El contenido de esa linea tiene que quedar en la mismo renglón. Con esa linea se le dice a Asterisk que guarde en el calendario “llamadas” los campos: • • • • summary description location start En la segunda parte de la linea se le asigna a cada campo un valor y más en detalle: • • • • Summary = Llamada de ${CALLERID(num)} a ${EXTEN} Description = Llamada desde la extension ${CALLERID(num)} al numero ${EXTEN} Location = IP = ${CHANNEL(peerip)} Start = ${EPOCH} Las variables presentes: • • • • ${CALLERID(num)} – Contiene el numero de la extensión que ha llamado ${EXTEN} – Contiene el numero marcado ${CHANNEL(peerip)} = Contiene la IP de donde la extensión ha iniciado la llamada ${EPOCH} = Contiene la fecha de inicio de la llamada en formato EPOCH que es el requerido por Google Calendar El resultado en Google Calendar será: 201 Si tenemos sincronizado el calendario en un sistema Android: Claramente este es ejemplo muy sencillo. Se puede elaborar más para sacar más datos de la llamada. Otro ejemplo para utilizar esta función podría ser programar una conferencia a través de un IVR indicando las extensiones que deben participar y guardar los datos en el Calendario. 10.6 Enviar las notificaciones de los calendarios a números fijos/celulares En la configuración que se ha visto hasta el momento, es posible asociar el calendario a una extensión y llamar la extensión configurada para notificarle el comienzo de un evento. Una forma más elaborada de configurar el calendario y de consecuencia el dialplan, es modificar el CALLERID antes de marcar a la extensión y en el caso que no conteste, desviar la llamada a un numero fijo/celular. Para este tipo de configuración se utilizará el chan_local. 202 Primero se modifica la configuración del calendario: nano /etc/asterisk/calendar.conf Se modifica esta linea: channel=SIP/1000 para que quede: Local/6500@internas Se guardan los cambios. De esta forma cuando se acerca un evento y Asterisk envía la notificación, llamará el canal Local, extensión 6000, contexto internas; esa extensión hay que crearla en el dialplan: nano /etc/asterisk/extensions.conf En el contesto internas se añaden las siguientes lineas: exten => 6500,1,Set(CALLERID(name)=Calendario) same => n,Set(CALLERID(num)=CampusVozToVoice) same => n,Dial(SIP/1000,15) same => n,Gotoif($[${DIALSTATUS} = ANSWER)]?contestada) same => n,Dial(SIP/justvoip/0057XXXXXXXXXX) same => n,hangup same => n(contestada),Hangup • • • • • En la primera linea se asigna al la variable CALLERID(name) la palabra Calendario En la segunda linea se asigna a la variable CALLERID(num) el nombre del calendario (en este caso CampusVozToVoice) En la tercera linea se marca a la extensión 1000 por 15 segundos Si la extensión contesta (GotoIF verdadero), se va a la etiqueta (contestada) y se termina la llamada Si la extensión no contesta dentro de 15 segundos, se marca al un numero fijo o celular. Se guardan los cambios y se crea un nuevo evento en el calendario para probar la configuración. Se reinicia Asterisk: service asterisk restart Se espera la llamada del calendario. Primero timbrará la extensión 1000: 203 Si no se contesta dentro de 15 segundos, la llamada se enviará al numero fijo/celular configurado: En este caso el CALLERID no es el que se ha configurado en el dialplan ya que su envío/recepción depende del Proveedor VoIP utilizado. 204 Capitulo XI CCSS (Call Completion Supplementary System) – Rellamada El CCSS es una nueva funcionalidad de Asterisk 1.8.X que permite solicitar el servicio de rellamada cuando el llamado no ha contestado y/o su extensión se encuentra ocupada. El sistema se basa en el Internet Draft “draft-ietf-bliss-call-completion-04”. Un Internet Draft es una propuesta de estandarización presentada a la IETF (Internet Engineering Task Force) para que sea analizada y, si el caso, aprobada y transformada en un RFC (Request for Comment), es decir, un estándar de hecho. En este caso los desarrolladores de Asterisk han optado por implementar un sistema que todavía no es un estándar de hecho. Esto explica porque muchas veces no hay interoperabilidad entre dispositivos SIP de distintos productores aunque, supuestamente, todos utilizan el protocolo SIP. Actualmente la única PBX que utiliza este Draft es Asterisk y no hay sofphone ni teléfonos SIP que lo implementen. Es por este motivo que al momento de configurar esta funcionalidad, se podrá utilizar su configuración nativa solamente entre servidores Asterisk (desde la versión 1.8.X). Para su utilizo entre Asterisk y los teléfonos SIP o softphone hay que optar por su configuración genérica que realmente no se basa en el Draft mencionado, sino en un sub-sistema que se apoya a la función DEVICE_STATE. ¿Cómo funciona el sistema? El sistema aplica a llamadas no contestadas CCNR (Call Completion on No Response) o cuando la extensión llamada se encuentra ocupada CCBR (Call Completion on Busy Subscriber) y solamente para canales SIP. Si se utiliza el agente genérico para solicitar la rellamada, habrá que utilizar la aplicación CallCompletion. Si se utiliza el agente nativo, el mismo productor del dispositivo que implementa el Draft, indicará como activarla. Normalmente es a través de una tecla del teléfono o presionando un botón ya programado para esta función. Un ejemplo. La extensión 1000 llama la extensión 1001. Si la extensión 1001 no contesta, la extensión 1000 tendrá un tiempo predefinido para solicitar una rellamada. La solicitud se hace utilizando la aplicación CallCompletion en el dialplan. Una vez solicitada la rellamada, se activará un temporizador que definirá por cuanto tiempo la solicitud quedará activa. Si dentro de este tiempo la extensión 1001 efectúa una llamada, Asterisk la considerará nuevamente activa y en cuanto termine la llamada, marcará primero la extensión 1000 y luego la extensión 1001. Si la rellamada tiene éxito, la solicitud sera eliminada. Si la rellamada no tiene éxito (la extensión 1001 no contesta nuevamente o está hablando), habrá que solicitar una nueva rellamada. En cualquier momento se puede anular una solicitud de rellamada utilizando la aplicación CallCompletionCancel en el dialplan. 11.1 Configuración del CCSS ¿Cómo se configura el sistema de rellamada en Asterisk? Primero hay que configurar el archivo ccss.conf. En este archivo se define un único parámetro que es el numero máximo de solicitudes que pueden estar activas en la PBX. Los demás datos que se encuentran el el archivo son para la configuración de las extensiones. Se renombra el archivo predefinido: mv /etc/asterisk/ccss.conf /etc/asterisk/ccss.conf.old Se crea uno nuevo: nano /etc/asterisk/ccss.conf y se pone, después de la etiqueta general, el parámetro cc_max_requests: [general[ cc_max_request=20 De esta forma se limita a veinte el numero máximo de solicitudes activas en el sistema. Se guardan los cambios. Ahora la parte de las extensiones, donde se pueden configurar una serie de parámetros. Los parámetros que no se configuran, tomarán como valor el predefinido: Parámetro cc_offer_timer Descripción Tiempo máximo, en segundos, para solicitar una rellamada cuando una llamada no ha tenido éxito. Valor 20 Tiempo de vida, en segundos, de una solicitud de rellamada cuando le extensión llamada estaba ocupada. Valor 4800 Tiempo de vida, en segundos, de una solicitud de rellamada cuando la extensión llamada no ha contestado. Valor 7200 Cuando la extensión que ha solicitado la rellamada, recibe la llamada del sistema tendrá el numero de segundos indicados en este parámetro para contestar. Si no lo hace la rellamada será anulada. Valor: 20 Este parámetro describe el tipo de comportamiento de Asterisk cuando se comunicará con el llamante para una rellamada. Puede ser: • never: deshabilita la posibilidad de solicitar una rellamada para el llamante • generic: cuando no se utiliza el Draft sino el sub-sistema basado en el 207 ccbs_available_timer ccnr_available_timer cc_recall_timer cc_agent_policy • DEVICE_STATE native: cuando se utiliza el Draft para el sistema de rellamada (el teléfono del llamante lo soporta) cc_monitor_policy Este parámetro describe el tipo de comportamiento de Asterisk cuando se comunicará con el llamado para una rellamada. Puede ser: • never: deshabilita la posibilidad de recibir una rellamada • generic: activará el monitorep del llamado utilizando el sub-sistema basado en el DEVICE_STATE • native: cuando se utiliza el Draft para el sistema de rellamada (el teléfono del llamado lo soporta) • always: cuando no se sabe si el teléfono soporta el Draft. De esta forma Asterisk intentará utilizar el sistema nativo y si no funciona, el genérico Limita el numero de rellamadas activas para el llamante. Si cc_agent_policy=generic, este valor no será tomado en consideración. Valor: 5 Limita el numero de rellamadas que un dispositivo puede aceptar. Valor: 5 cc_max_agents cc_max_monitors = 5 Para poder hacer una prueba se configurará en las extensiones 1000,1001 y 1002 solamente dos parámetros: • • cc_agent_policy=generic cc_monitor_policy=generic Se abre el archivo sip.conf nano /etc/asterisk/sip.conf y al final del bloque de configuración de cada extensión se pone: cc_agent_policy=generic cc_monitor_policy=generic Se guardan los cambios. Como se va a utilizar el sistema genérico, en el dialplan hay que configurar una extensión para la aplicación CallCompletion y otra para la aplicación CallCompletionCancel 208 nano /etc/asterisk/extensions.conf en el contexto internas se añaden las siguientes lineas: exten => *30,1,CallCompletionRequest same => n,Agi(googletts.agi,"Rellamada activada",es) same => n,Hangup exten => *31,1,CallCompletionCancel same => n,Agi(googletts.agi,"Rellamada anulada",es) same => n,Hangup Se guardan los cambios y se recarga toda la configuración de Asterisk: service asterisk reload 11.2 CCSS 1ª Prueba Desde la extensión 1000 se llama la extensión 1001. Cuando esta esté timbrando, se rechaza la llamada: A partir de ese momento, la extensión 1000 tendrá 20 segundos para solicitar la rellamada. Se puede ver, desde la consola de Asterisk, que la rellamada ha sido ofrecida por la extensión 1000 CLI> cc report status Ahora para solicitarla desde la extensión 1000 se marca *30. CLI> cc report status 209 Siendo el tipo de solicitud CCNR, tendrá un tiempo de vigencia de 7200 segundo (dos horas), como indicado en ccnr_available_timer como valor predefinido. Para que la rellamada se efectúe, el sistema esperará que la extensión 1001 haga una llamada y de esta forma saber que ya está activa nuevamente. Para averiguarlo, desde la extensión 1001 se marca 150 (test de echo) y después de unos segundos de cuelga. Casi en seguida entrará una llamada a la extensión 1000: Como se puede ver el CallerID es la misma extensión 1000 y esto indica que se trata de una rellamada. Cuando la extensión 1000 contesta se pueden presentar dos escenarios: • • la extensión 1001 no contesta nuevamente. La rellamada corriente se anula y la extensión 1001 ofrece nuevamente a la extensión 1000 la posibilidad de solicitar una rellamada. la extensión 1001 contesta. La rellamada solicitada se anula. La extensión 1000 tiene 20 segundos para contestar la llamada entrante (valor predefinido del parámetro cc_recall_timer). Si no lo hace, la rellamada se considerará terminada. 11.3 CCSS 2ª Prueba Desde la extensión 1000 se llama la extensión 1001. La extensión 1001 rechaza la llamada. La extensión 1000 solicita la rellamada marcando *30. Después de unos minutos, decide que ya no la necesita. Marcando *31 la anula. Las distintas secuencias desde la consola de Asterisk: 210 Si la solicitud de CC es anulada, no se puede solicitar nuevamente. 11.4 CCSS 3ª Prueba Desde la extensión 1000 se llama la extensión 1001. La extensión 1001 contesta la llamada. Cuando la conversación termine, la extensión 1000, a pesar que la extensión 1001 ha contestado, podrá solicitar una rellamada. Este tipo de comportamiento tiene su lógica ya que el hecho que la llamada ha sido contestada, no significa que el llamante ha podido hablar con el llamado (como en este caso). Esto porque si en el dialplan se configura que si la extensión 1001 no contesta dentro de un tiempo, la llamada se pasa a un buzón de voz o a un IVR, realmente la extensión 1000 no ha podido hablar con la extensión 1001. Si se mira la consola, efectivamente la rellamada se está ofreciendo: 211 Consejos: 1. El sistema de rellamada consuma bastante recursos del sistema. Para limitar este consumo es buena practica: • configurar el parámetro cc_max_requests con un valor bajo • configurar el parámetro cc_offer_time con un valor bajo • En el sip.conf, por cada extensión, configurar el parámetro cc_agent_policy con never y activar el agente desde el dialplan utilizando la función CALLCOMPLETETION. Para el bloque de las llamadas entre extensiones seria algo como: exten => _100[0-2],1,Macro(disponible) same => n,Macro(calendario) same => n,Set(CALLCOMPLETION(cc_agent_policy)=generic) same => n,Dial(SIP/${EXTEN},45,hHkKtTwWxX) same => n,Hangup 2. la rellamada nativa funciona solamente si el paquete libxml2-devel ha sido instalado en el servidor Linux antes de compilar Asterisk. Esto porque el Draft se basa en un sistema de SUBSCRIBE, NOTIFY y PUBLISH donde el cuerpo del paquete SIP contiene la información en ese formato (XML). 212 Capitulo XII Asterisk Realtime ARA (The Asterisk Realtime Architecture) es un método para almacenar los archivos de configuración de Asterisk y/o objetos en una base de datos. Existen dos tipos de Realtime: • • Estático Dinámico 12.1 Realtime estático Con el Realtime estático es posible guardar los archivos de configuración de Asterisk en una base de datos. Se dice estático porque cuando se hagan cambios en la base de datos, hay que recargar la configuración de Asterisk. Si las configuraciones se guardan en la base de datos, ya no se podrán utilizar los archivos de texto, es decir que si por ejemplo, se guarda la configuración del dialplan en Realtime estático, la PBX no leerá el archivo extensions.conf. El archivo donde se configura el Realtime estático es extconfig.conf y la sintaxis es: file.conf => driver,database[,table] • • • • file.conf: archivo de configuración que se quiere guardar en la base de datos driver: que motor de base de datos se va a utilizar (MySQL, ODBC, Postgres, SQLite3) database: el nombre de la base de datos table: el nombre de la tabla en la base de datos Los únicos archivos de configuración que no se pueden guardar con el Realtime estático son: • • • asterisk.conf logger.conf extconfig.conf Otros tres archivos se pueden guardar en la base de datos solamente si el modulo del motor que se va a utilizar se carga en el modules.conf antes de los demás módulos. Esto se hace con la declaración preload. Como se va a utilizar ODBC, la modifica que hay que hacer es: nano /etc/asterisk/modules.conf se buscan estas dos lineas: ;preload => res_odbc.so ;preload => res_config_odbc.so y se modifican para que queden: preload => res_odbc.so preload => res_config_odbc.so Los dos módulos (que se utilizan para el Realtime con ODBC), se cargarán antes de los demás módulos y de esta formas se podrán guardar en Realtime también estos archivos: • • • manager.conf cdr.conf rtp.conf ¿Cual es el procedimiento para configurar el Realtime estático en Asterisk con ODBC? 1. 2. 3. 4. 5. Se crea una nueva base de datos Se crea la tabla para el Realtime estático Se configurar el conector ODBC Se configura el archivo de configuración de Asterisk res_odbc.conf Se configura el archivo extconfig.conf Visto gráficamente sería: Se inicia creado una nueva base de datos: mysql -u root -psesamo mysql> create database asterisk; Se otorgan los permisos de acceso a la base de datos creada al usuario asterisk, desde local: 215 mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo'; desde remoto: mysql> GRANT ALL PRIVILEGES ON asterisk.* TO 'asterisk'@'%' IDENTIFIED BY 'sesamo'; se crea la tabla para el Realtime estático: mysql> use asterisk mysql> CREATE TABLE `ast_config` ( `id` int(11) NOT NULL auto_increment, `cat_metric` int(11) NOT NULL default '0', `var_metric` int(11) NOT NULL default '0', `filename` varchar(128) NOT NULL default '', `category` varchar(128) NOT NULL default 'default', `var_name` varchar(128) NOT NULL default '', `var_val` varchar(128) NOT NULL default '', `commented` int(11) NOT NULL default '0', PRIMARY KEY (`id`), KEY `filename_comment` (`filename`,`commented`) ); El nombre de la tabla es totalmente arbitrario y se puede personalizar para volverlo más amigable. Una explicación de los parámetros que aparecen en la tabla: • • • • • • • • ID – es un numero progresivo que se crea automáticamente cat_metric – el peso de la categoría o bloque dentro del archivo. Un valor bajo significa que la categoría aparecerá más arriba en el archivo de configuración var_metric – el peso de un objeto o parámetro dentro de la categoría. Un valor bajo significa que el objeto aparecerá más arriba en la categoría filename – el nombre del archivo de configuración de Asterisk que se quiere guardar en la base de datos category – la categoría o bloque del archivo de configuración var_name – el nombre del objeto o del parámetro que se está configurando var_val – el valor del objeto o parámetro commented – si es cualquier valor diferente a cero, la entrada en la base de datos aparecerá como comentada. Para entender mejor como funciona, se guardará el archivo musiconhold.conf en Realtime estático. mysql> INSERT INTO ast_config (cat_metric,var_metric,filename,category,var_name,var_val) VALUES ('0','0','musiconhold.conf','default','mode','files'); 216 var_metric.'mp3'. Como se puede notar en esta primera linea el cat_metric es 1 e indica que estamos creando un segundo bloque en el archivo de configuración.var_name.var_metric.'musiconhold. Esto se hace en dos archivos de configuración: • • odbcinst. En la ultima linea se define que los archivos audio de la música de espera de la clase mp3 se reproducirán aleatoriamente.'mode'.filename.category.var_val) VALUES ('1'.var_val) VALUES ('1'.5): mysql> INSERT INTO ast_config (cat_metric.filename.'directory'. mysql> INSERT INTO ast_config (cat_metric. se configura el conector ODBC.var_val) VALUES ('1'.conf'.'default'.'yes').'musiconhold.'mp3'.var_metric.var_metric.ini odbc.'musiconhold.var_name.category.'random'.'musiconhold.conf'.category.filename.'2'. En la ultima linea se define que los archivos audio de la música de espera de la clase default se reproducirán aleatoriamente.'directory'. Se repiten las tres lineas para la música de espera MP3 (como se había configurado en el párrafo 2.filename.'random'.'1'.category.'/var/lib/asterisk/mohmp3').'1'.'default'.Con esta primera linea se crea la clase default y se define que el modo es files. Para iniciar se borra el archivo predefinido odbcinst.conf'. Con esta segunda linea se define que la carpeta que contiene los archivos audio para la clase default es /var/lib/asterisk/moh mysql> INSERT INTO ast_config (cat_metric.'musiconhold. Con esta segunda linea se define que la carpeta que contiene los archivos audio para la clase mp3 es /var/lib/asterisk/mohmp3 mysql> INSERT INTO ast_config (cat_metric. mysql> INSERT INTO ast_config (cat_metric.filename.'mp3'.var_name. Se sale del cliente MySQL: mysql> quit Creada la base de datos y la tabla.conf'.var_name.ini En el primero se configuran las conexiones ODBC → librerías base de datos.'2'. En el segundo se configuran las base de datos.ini 217 .var_metric.'0'.'yes').var_name.conf'.'files').'/var/lib/asterisk/moh').category.var_val) VALUES ('0'.var_val) VALUES ('0'. rm /etc/odbcinst.ini asterisk – nombre del usuario que tiene acceso a la base de datos creada 218 .ini se crea uno nuevo: nano /etc/odbcinst.ini y para ODBC → MySQL se ponen las siguientes lineas: [MySQL] Description = ODBC para MySQL Driver = /usr/lib/libmyodbc3.so FileUsage = 1 Para una versión 64 bit de CentOS sería: [MySQL] Description = ODBC para MySQL Driver = /usr/lib64/libmyodbc3.ini se copian las siguientes lineas que crean una conexión a la base de datos MySQL asterisk: [asterisk] Description = MySQL Asterisk Driver = MySQL Database = asterisk Server = localhost User = asterisk Password = sesamo Port = 3306 Option = 3 Se guardan los cambios.so Setup = /usr/lib64/libodbcmyS. Para probar la conexión entre ODBC y la base de datos asterisk se usa el comando: isql asterisk asterisk sesamo • • asterisk – etiqueta que da inicio al bloque configurado en odbc.ini nano /etc/odbc.so Setup = /usr/lib/libodbcmyS.so FileUsage = 1 Se continua con odbc. Se renombra el archivo predefinido y se crea uno nuevo: mv /etc/asterisk/res_odbc. Para salir: SQL> quit El siguiente paso es configurar res_odbc. El valor asterisk es el que se ha configurado en el bloque que se acaba de crear en el archivo odbc.conf después de esta linea: .• sesamo – la contraseña del usuario asterisk creado en MySQL El resultado: +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ La conexión entre ODBC y la base de datos MySQL asterisk funciona perfectamente.ast_config 219 .conf /etc/asterisk/res_odbc.extensions.conf => sqlite.ini Se guardan los cambios y se modifica el ultimo archivo: nano /etc/asterisk/extconfig.conf Se copian las siguientes lineas: [ENV] [asterisk] enabled => yes dsn => asterisk username => asterisk password => sesamo pre-connect => yes sanitysql => select 1 idlecheck => 3600 connect_timeout => 10 La linea más importante es dsn => asterisk.conf.asterisk.conf.old nano /etc/asterisk/res_odbc. ini res_odbc.old Se reinicia Asterisk: service asterisk restart Se entra en la consola: asterisk -rvvvvvvvvvvvvvv se averigua que la conexión en Realtime esté activa (desde el lado Asterisk): CLI> odbc show all ODBC DSN Settings ----------------Name: asterisk DSN: asterisk Last connection attempt: 1969-12-31 19:00:00 Pooled: No 220 .conf.conf.conf /etc/asterisk/musiconhold.ast_config Se guardan los cambios.asterisk.conf Ahora que se ha configurado la música de espera en Realtime se renombra el archivo de texto: mv /etc/asterisk/musiconhold. El nombre asterisk que aparece en la linea se refiere al nombre de la etiqueta con que inicia la configuración de la conexión en res_odbc.conf => odbc.conf extconfig. Gráficamente: odbc.se pone: musiconhold. Algunos campos de la tabla son opcionales mientras otros son obligatorios.Connected: Yes se mira la configuración de la música de espera: CLI> moh show classes Class: default Mode: files Directory: /var/lib/asterisk/moh Class: mp3 Mode: files Directory: /var/lib/asterisk/mohmp3 Parece que todo está bien. Ejemplo: se pueden configurar las extensiones en el sip. Asterisk actualizará la configuración en tiempo real. 12. etc. Cuando se hace un cambio en la base de datos. buzones de voz. agentes. colas de espera. 12.1 Extensiones SIP en Realtime La parte más complicada de la configuración de SIP en Realtime. Desde la extensión 1000 se marca el numero 200 para probar la música de espera MP3 en Realtime. Una tabla base debe contener por lo menos estos parámetro: • • • • • • • • • • • • • type name secret context host ipaddr port regseconds defaultuser fulcontact regserver useragent lastms 221 . es la creación de la tabla donde almacenar los parámetros de las extensiones SIP. Estos objetos pueden ser: extensiones. funcionarán ambas. Al recargar la configuración SIP. los objetos creados en la base de datos “conviven” con los presentes en los archivos de configuración.conf y al mismo tiempo en la base de datos. A diferencia del Realtime estático.2.2 Realtime Dinamico El Realtime dinámico permite guardar objetos en una base de datos. : subscribe Language : es Accountcode : 1000 AMA flags : Unknown Transfer mode: open CallingPres : Presentation Allowed.Cont. Not Screened Callgroup : 1 Pickupgroup : 1 Mailbox : 1000@default VM Extension : asterisk LastMsgsSent : 32767/65535 Call limit : 2147483647 Dynamic : Yes Callerid : "callerid=Fulano" <1000> MaxCallBR : 384 kbps Expire : 2917 Insecure : no Nat : Always ACL : No T.175.156 Port 22840 222 . se puede tomar como referencia el resultado de este comando: CLI> sip show peer 1000 * Name : 1000 Secret : <Set> MD5Secret : <Not set> Remote Secret: <Not set> Context : externas Subscr.38 EC mode : FEC T.38 MaxDtgrm: 400 DirectMedia : No PromiscRedir : No User=Phone : No Video Support: Yes Text Support : No Ign SDP ver : No Trust RPID : No Send RPID : Yes Subscriptions: Yes Overlap dial : Yes Forward Loop : Yes DTMFmode : rfc2833 Timer T1 : 500 Timer B : 32000 ToHost : Addr->IP : 190.38 support : Yes T.253.Para crear una tabla más completa. 253. `callingpres` varchar(20) default NULL.Defaddr->IP : 0. `usereqphone` varchar(10) default NULL.Trsp : UDP Def. : UDP Allowed. 223 .g729:20) Auto-Framing : No 100 on REG : Yes Status : OK (129 ms) Useragent : Reg. `secret` varchar(40) default NULL.rinstance=3201f90c0a78b7d0 Qualify Freq : 60000 ms Sess-Timers : Accept Sess-Refresh : uas Sess-Expires : 1800 secs Min-Sess : 90 secs Parkinglot : Todos los parámetros que aparecen en la lista. `subscribemwi` varchar(10) default NULL. `auth` varchar(10) default NULL.0. CLI> quit Para empezar se crea la tabla en la base de datos asterisk: mysql -u root -psesamo mysql> use asterisk mysql> CREATE TABLE `sipexten` ( `name` varchar(40) NOT NULL default ' '. `language` varchar(10) default NULL. se pueden configurar en la tabla. Contact : sip:1000@190. `fromuser` varchar(40) default NULL. `mailbox` varchar(20) default NULL.0. `type` varchar(10) NOT NULL default ' '. `fromdomain` varchar(40) default NULL. `callerid` varchar(40) default NULL. `md5secret` varchar(40) default NULL.0 Port 5060 Prim. `remotesecret` varchar(40) default NULL.156:22840.175.ulaw:20. `defaultuser` varchar(40) default NULL.Transp. Username: 1000 SIP Options : replaces replace Codecs : 0x8010c (ulaw|alaw|g729|h263) Codec Order : (alaw:20. `cid_number` varchar(40) default NULL. `vmexten` varchar(20) default NULL. `nat` varchar(3) NOT NULL.0. `regexten` varchar(20) default NULL. Query OK. `callgroup` varchar(20) default NULL. `Directmedia` varchar(3) default 'no'. `Deny` varchar(31) default ''. `defaultip` varchar(20) NOT NULL default '0. `disallow` varchar(20) default 'all'. `setvar` varchar(200) default NULL. `port` int(6) NOT NULL default '0'. `rtptimeout` varchar(15) default NULL.ini. ni el res_odbc. `ipaddr` varchar(45) NOT NULL default ' '. `subscribecontext` varchar(40) default NULL. `qualify` varchar(15) default NULL.01 sec) Se sale del cliente MySQL mysql> quit Bye En este caso como la base de datos es la misma del Realtime estático. `maxcallbitrate` varchar(15) default NULL. KEY `ipaddr` (`ipaddr`.`port`).`port`) ). `allowtransfer` varchar(20) default NULL. El único archivo que hay que modificar es el extconfig.`context` varchar(40) NOT NULL default ' '. KEY `host` (`host`. `rtpholdtimeout` varchar(15) default NULL. `pickupgroup` varchar(20) default NULL. `autoframing` varchar(10) default NULL. `lastms` int(11) NOT NULL default '-1'.conf nano /etc/asterisk/extconfig. `allow` varchar(20) default NULL. `host` varchar(40) default 'dynamic'. `amaflags` varchar(20) default NULL. `regserver` varchar(20) default NULL. `Permit` varchar(31) default NULL. PRIMARY KEY (`name`). `regseconds` int(11) NOT NULL default '0'.conf 224 . `useragent` varchar(40) default NULL. `outboundproxy` varchar(40) default NULL.0. no hay que modificar ni el odbc.0'. `insecure` varchar(20) default NULL. `rtpkeepalive` varchar(15) default NULL. 0 rows affected (0. `fullcontact` varchar(60) default NULL.ini. `accountcode` varchar(20) default NULL. 580-1..net/project/webadmin/webmin/1.580-1.570-1. ########################################### [100%] Operating system is CentOS Linux 1:webmin ########################################### [100%] Webmin install complete. En este caso se ha optado por Webmin. key ID 11f63c51 Preparing. se pueden utilizar distintos programas.noarch. Se instalan unas dependencias (para conexiones seguras): yum install perl-Net-SSLeay Se descarga el paquete: cd /usr/src wget http://downloads.sipexten Se guardan los cambios y se actualiza la configuración de Asterisk: /etc/init.rpm: Header V3 DSA signature: NOKEY.asterisk para que queden: sippeers => odbc.sourceforge. entre otros: webmin e phpadmin.rpm warning: webmin-1.noarch.rpm y se instala rpm -ivh webmin-1.asterisk.Se modifican esta linea: .noarch.sippeers => odbc..580/webmin-1. Antes de entrar en la pagina de administración de Webmin hay que abrir el puerto 10000 en el firewall: nano /etc/sysconfig/iptables Después de esta linea: -A INPUT -p udp -m udp --dport 10000:20000 -j ACCEPT se pone: # Webmin -A INPUT -p tcp -m state --state NEW -m tcp --dport 10000 -j ACCEPT 225 .d/asterisk reload Ahora se puede configurar la primera extensión SIP en Realtime. Para volver más sencillo el trabajo con las bases de datos. En la pagina que aparece.Se guardan los cambios y se reinicia iptables: service iptables restart Ahora desde un navegador Web se pone la dirección para entrar en Webmin. Al fondo de la nueva pagina se presiona el botón “View Data” y luego “Add Row”. en la derecha se escoge el menú “Servers” y luego “MySQL Database Server”: En Login se pone root (el usuario MySQL) y como contraseña sesamo: Se selecciona la base de datos Asterisk y luego la tabla Sipexten. Se puede empezar a crear la primera extensión en Realtime: 226 . Si es un servidor Linode se pone el nombre de dominio del Linode sino la IP: https://IPservidor:10000 En Username se pone root y en Password la contraseña del usuario root de Linux. 227 . 228 . 2 Extensiones IAX en Realtime La configuración de las extensiones IAX en realtime es bastante similar a la que se ha mostrado para las extensiones SIP.conf Se recarga la configuració sip: CLI> sip reload y se mira si aparece: CLI> sip show peers like 1004 En la columna Realtime aparece “Cached RT” que significa que la extensión está configurada en Realtime y que se activó el parámetro rtcachefriends. Para ver la configuración de la nueva extensión hay que utilizar el siguiente comando: CLI> sip show peer 1004 load Para la parte user: CLI> sip show user 1004 load Se configura el X-lite para conectarse a la extensión 1004.conf y conocer su estado hay que modificar dos parámetros: • • qualify=yes en la configuración de la extensión rtcachefriends=yes en la parte general del archivo sip. En la consola de Asterisk aparecerá: Si se quiere ver el estado de la extensión en la consola de Asterisk como si fuera configurada en el archivo sip.Al terminar se presiona el botón "Save". Si desde la consola de Asterisk se escribe el comando: asterisk -rvvvvvvvvvvvv CLI> sip show peers la nueva extensión configurada no aparecerá. 12. Desde la extensión 1004 se marca 123 para probarla.2. Primero hay que crear la tabla 229 . `transfer` varchar(10) NULL. `host` varchar(40) NULL default 'dynamic'. `callerid` varchar(100) NULL. `mailbox` varchar(40) NULL. `port` int(5) NULL. `qualifysmoothing` varchar(10) NULL. `defaultip` varchar(20) NULL. `disallow` varchar(40) NULL. `outkey` varchar(40) NULL. `maxauthreq` varchar(5) NULL. `qualifyfreqok` varchar(10) NULL. 230 . `regexten` varchar(40) NULL. `auth` varchar(20) NULL. `cid_number` varchar(40) NULL. `mohsuggest` varchar(20) NULL. `qualify` varchar(10) NULL. `codecpriority` varchar(40) NULL. `accountcode` varchar(20) NULL. `language` varchar(10) NULL. `qualifyfreqnotok` varchar(10) NULL. `context` varchar(40) NULL. `jitterbuffer` varchar(3) NULL. `regcontext` varchar(40) NULL. `trunk` varchar(3) NULL. `type` varchar(10) NOT NULL default 'friend'. `sourceaddress` varchar(20) NULL.mysql -u root -psesamo mysql> use asterisk mysql> CREATE TABLE `iaxexten` ( `name` varchar(40) NOT NULL default ''. `secret` varchar(40) NULL. `encryption` varchar(20) NULL. `mohinterpret` varchar(20) NULL. `sendani` varchar(10) NULL. `inkeys` varchar(40) NULL. `dbsecret` varchar(40) NULL. `ipaddr` varchar(20) NULL. `allow` varchar(40) NULL. `regseconds` int(11) NULL. `fullname` varchar(40) NULL. `username` varchar(40) NULL. `forcejitterbuffer` varchar(3) NULL. `mask` varchar(20) NULL. `requirecalltoken` varchar(4) NULL. port) ).asterisk .conf se cambian estas dos lineas: . mysql> quit Luego se modifica el archivo extconfig.iaxpeers => odbc. `setvar` varchar(200) NULL.asterisk. port). `amaflags` varchar(20) NULL. INDEX host (host.asterisk para que queden: iaxusers => odbc.conf: nano /etc/asterisk/extconfig. `adsi` varchar(10) NULL.asterisk. INDEX name (name.iaxexten se guarda la configuración y se crea una extensión IAX en Realtime desde Webmin entrando en la tabla iaxexten: 231 . INDEX ipaddr (ipaddr. INDEX name2 (name. host). port). PRIMARY KEY (`name`). ipaddr.iaxusers => odbc.iaxexten iaxpeers => odbc.`timezone` varchar(20) NULL. 232 . Como para el protocolo SIP se cambia el parámetro rtcachefriends en el iax.Al terminar se presiona el botón “Save”.conf: nano /etc/asterisk/iax.conf rtcachefriends=no para que quede: rtcachefriends=yes Se guarda la configuración y se actualiza Asterisk: service asterisk reload En el cliente Zoiper se configura el usuario marko2 y se mira en la consola de Asterisk si está registrado: asterisk -rvvvvvvvvvvvvvv CLI> iax2 show peers Para terminar hay que modificar el dialplan para que se pueda marcar a la extensiones creadas en Realtime: 233 . 30) same => n.45.hHkKtTwWxX) same => n.Hangup para que quede: exten => _100[0-2. está el dialplan.hint.Macro(calendario) same => n.conf Se modifica este bloque: exten => _100[0-2].CLI> quit nano /etc/asterisk/extensions.3 Dialplan en Realtime dinamico Entre los objetos que se pueden guardar en Realtime dinámico.2.Hangup siempre en el contexto internas se pone: exten => 1235. Esta puede ser una optima solución cuando se quieren compartir partes de dialplan entre distintos servidores Asterisk o cuando se quiere tener el motor de la base de datos en otro servidor.1.Macro(disponible) same => n. De esta forma se pueden crear distintos dialplan para distintos servidores Asterisk conectados en Realtime a la base de datos.SIP/1004 exten => marko2.Hangup para terminar en el contexto subscribe se añade: exten => 1004. Para iniciar se crea la tabla para guardar el dialplan en la base de datos: mysql -u root -psesamo mysql> use asterisk mysql> CREATE TABLE `dialplan` ( 234 .Dial(SIP/${EXTEN}.Macro(calendario) same => n.45.hHkKtTwWxX) same => n.Macro(disponible) same => n.Dial(SIP/${EXTEN}.Dial(IAX2/marko2.4].IAX2/marko2 Se guarda los cambios y se recarga el dialplan: asterisk -rx "dialplan reload" 10.1.1.hint. KEY `id` (`id`) ).app.extensions => odbc.'70'.priority. mysql> INSERT INTO dialplan (context. el resultado será: mysql> select * from dialplan. `app` varchar(20) NOT NULL default ''.exten.appdata) VALUES ('test'. mysql> INSERT INTO dialplan (context.app.exten.asterisk. `exten` varchar(20) NOT NULL default ''.priority. `context` varchar(20) NOT NULL default ''.'Playback'.conf Se busca esta linea: . Se sale del cliente MySQL y se modifica el archivo extconfig.'0').'0'). `priority` tinyint(4) NOT NULL default '0'.asterisk y se modifica para que quede: extensions => odbc.conf: mysql> quit nano /etc/asterisk/extconfig.'70'.app.`id` int(11) NOT NULL auto_increment.`exten`.exten.'2'.'70'.'3'.'Hangup'.appdata) VALUES ('test'.'Answer'.appdata) VALUES ('test'.dialplan 235 .`priority`). PRIMARY KEY (`context`.priority. `appdata` varchar(128) NOT NULL default ''.'1'.'demo-congrats'). ahora se crea una extensión muy sencilla en la tabla: mysql> INSERT INTO dialplan (context. Se guardan los cambios y se pasa al dialplan nano /etc/asterisk/extensions.conf Antes del contexto internas se añade este bloque que configura Asterisk para que busque el contexto test en la base de datos: [test] switch => Realtime y se añade las lineas en negrita en los dos bloques que siguen: [externas] include => internas include => internacio include => parkedcalls include => test [locales] include => internas include => auten include => parkedcalls include => test De esta forma las extensiones que tengan acceso al contexto externas o locales. tendrán acceso también al contexto test. 236 . Se guardan los cambios y se reinicia Asterisk: service asterisk restart Desde la extensión 1000 se marca el numero 70 y se prueba el nuevo contexto creado en Realtime. . numero de matricula 2. En este modulo. PRIMARY KEY (`nombre`). `matricula` int(4) NOT NULL. KEY `id` (`id`) ).'1237').'1235'). El archivo que se utiliza para este tipo de configuración es el func_odbc. .Capitulo XIII IVR avanzados – func_odbc.conf La función func_odbc permite hacer consultas en base de datos directamente desde el dialplan. Se añaden a la tablas cuatro empleados: mysql> INSERT INTO empleados (nombre.'1234').('perengano'. el resultado: mysql> select * from empleados. nombre Se crea la tabla en la base de datos Asterisk: mysql -u root -psesamo mysql> use asterisk mysql> CREATE TABLE `empleados` ( `id` int(11) NOT NULL auto_increment. se ilustrarán dos diferentes escenarios: • • Buscar el nombre de un empleado en base a su numero de matricula Guardar los resultados de una encuesta telefónica en una base de datos 13. `nombre` varchar(20) NOT NULL.('mengano'.conf. ('zutano'. Al mismo tiempo es posible actualizar o modificar entradas de la base de datos.'1236').matricula) VALUES ('fulano'.1 Empleados La tabla de los empleados contendrá solamente dos campos: 1. conf /etc/asterisk/func_odbc. Para configurarlo para el español se siguen estos 239 . En Asterisk hay un modulo dedicado a la conexión con un servidor Festival.Ahora se crea el archivo func_odbc.so == Parsing '/etc/asterisk/festival. se utilizará otro sistema de TTS (text to Speech).so CLI> module load app_festival.ini para la base de datos asterisk readsql=SELECT nombre FROM empleados WHERE matricula='${SQL_ESC(${ARG1})}' – la sentencia SQL para hacer consultas en la base de datos asterisk (en este caso la tabla empleados) Para interactuar con el usuario que llame para consultar la base de datos. Primero se renombra el predefinido: mv /etc/asterisk/func_odbc.so => (Simple Festival Interface) CLI> quit Festival viene con el inglés como idioma predefinido.conf': == Found == Registered application 'Festival' Loaded app_festival. Primero se averigua si le modulo está compilado y funcionando: asterisk -rvvvvvvvvvvvvvvv CLI> module unload app_festival.conf.old se crea el nuevo nano /etc/asterisk/func_odbc. en este caso Festival.conf.conf y se copian las siguientes lineas: [Empleados] dsn=asterisk readsql=SELECT nombre FROM empleados WHERE matricula='${SQL_ESC(${ARG1})}' • • • [Empleados] – El nombre de la función que se está creando dsn – el nombre de la etiqueta definida al inicio del bloque configurado en el archivo odbc. Lo único que hace falta es configurarlo. synth (eval (list 'Utterance 'Text string))))) (utt.local 240 .d/asterisk reload Para arrancar el servidor Festival en automático: nano /etc/rc.conf estas son la líneas que hay que añadir: [general] host=localhost port=1314 festivalcommand=(tts_textasterisk "%s" 'file)(quit)\n Se guardan las modificaciones.wave.conf.org/tmp/festival-spanish.rescale wholeutt 5) (utt.wave.wave. Se actualiza la configuración de Asterisk: /etc/init.(language__spanish) (set! voice_default 'voice_el_diphone) (define (tts_textasterisk string mode) "(tts_textasterisk STRING MODE) Apply tts to STRING. This function name may be added to the server safe functions.resample wholeutt 8000) (utt.voztovoice.send." (let ((wholeutt (utt.conf /etc/asterisk/festival.zip unzip festival-spanish.scm se añaden estas líneas antes de la ultima linea del archivo .zip Ahora se modifica el archivo de configuración de festival nano /usr/share/festival/festival. This function is specifically designed for use in server mode so a single function call may synthesize the string.old nano /etc/asterisk/festival.client wholeutt))) Se guardan los cambios y se modifica el archivo de configuración de festival en Asterisk: mv /etc/asterisk/festival.pasos: cd /usr/share/festival/voices wget http://www. beep.1.Festival(Por favor ingrese los 4 digitos de la matricula del empleado.4 3.0 0.2 4600 1096 pts/1 S 13:36 0:00 /bin/sh /usr/bin/festival_server root 24077 0.conf en el contexto internas se pone: exten => 660./festival_server.6 23464 19324 pts/1 S 13:36 0:00 festival --server . CLI> quit Terminada la configuración y la prueba de Festival se construye el dialplan para hacer consultas a la tabla empleados: nano /etc/asterisk/extensions. /usr/bin/festival_server > /dev/null & Se controla que esté corriendo: ps aux | grep festival root 24071 0.4) 241 .Read(EMPNUM.1 4028 688 pts/1 S+ 13:36 0:00 grep festival Se modifica el Dialplan para crear una extensión que permita hacer una prueba del servidor Festival: nano /etc/asterisk/extensions.Answer same => n.scm root 24081 0.0 0.Hangup() Se actualiza el dialplan desde la consola asterisk -rvvvvvvvvvvvvvvvvv CLI> dialplan reload Desde la extensión 1000 se marca la extensión 650 para escuchar la frase que se acaba de configurar en el dialplan.conf en el contexto internas se pone: exten => 650. Chevere!!!) same => n.al final del archivo se añade esta linea: /usr/bin/festival_server > /dev/null & Se inicia el servidor festival.Answer() same => n.) same => n.1.Wait(2) same => n.Festival(Asterisk y Festival trabajan junto. Linea6 – Si la consulta devuelve un valor se va a la etiqueta (nombre). Hasta luego.conf': == Found -. "2") in new stack -. "1?nombre") in new stack -. Desde la lógica de MySQL sería: select nombre from empleados where matricula='$ {EMPNUM}'.Executing [660@externas:4] Read("SIP/1000-00000010".9) 242 . si la consulta no devuelve ningún valor se continua en el dialplan (la función EXIST permite averiguar si una determinada variable contiene un valor o está vacía) Linea7 – En el caso la consulta no haya tenido éxito. Hasta luego.Accepting a maximum of 4 digits.same => n.Executing [660@externas:3] Festival("SIP/1000-00000010".beep.Executing [660@externas:5] Set("SIP/1000-00000010". "") in new stack -. "Por favor ingrese los 4 digitos de la matricula del empleado.Hangup same => n(nombre). En la consola: Executing [660@externas:1] Answer("SIP/1000-00000010".) same => n.Set(EMPNAME=${ODBC_Empleados(${EMPNUM})}) same => n.) same => n.Festival(Ningun empleado encontrado.Festival(El nombre del empleado es ${EMPNAME}. se anuncia al llamante que no se ha encontrado ningún empleado que tenga ese numero de matricula Linea8 – se termina la llamada Linea9 – Si la consulta ha tenido éxito.<SIP/1000-00000010> Playing 'beep. "EMPNUM.alaw' (language 'es') -.Hangup Una explicación de las lineas: • • • • • Linea1 – se contesta la llamada Linea2 – se esperan dos segundos Linea3 – Se usa Festival para leer el texto y enviarlo como audio Linea 4 – Con la aplicación Read se espera que el llamante digite 4 números y se guardan en la variable EMPNUM Linea 5 – Se hace la consulta en la tabla Empleados como configurado en el archivo func_odbc.Executing [660@externas:2] Wait("SIP/1000-00000010".") in new stack == Parsing '/etc/asterisk/festival. "EMPNAME=fulano") in new stack -.Goto (externas.Executing [660@externas:6] GotoIf("SIP/1000-00000010". -.User entered '1234' -.4") in new stack -. se anuncia al llamante el nombre del empleado Linea10 – se termina la llamada • • • • • Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvvvvvvvvvvvvvv CLI> dialplan reload Desde la extensión 1000 se marca 660 y se hacen diferentes pruebas.660.GotoIf($[${EXISTS(${EMPNAME})}]?nombre) same => n. `resp4` int(1) default NULL.Executing [660@externas:10] Hangup("SIP/1000-00000010". Los pasos a seguir son: • • • crear la tabla para la encuesta crear un nuevo bloque en el archivo func_odbc. se utilizará Festival.resp2.resp4) values ("${SQL_ESC(${VAL1})}".conf al final del archivo se añade el siguiente bloque: [Encuesta] dsn=asterisk writesql=insert into encuesta (Fecha. 10) exited non-zero on 'SIP/1000-00000010' 13. La encuesta está compuesta por 4 preguntas. Las preguntas se pueden pregrabar o.conf nano /etc/asterisk/func_odbc. Hasta luego.Executing [660@externas:9] Festival("SIP/1000-00000010". PRIMARY KEY (`id`) ).2 Encuesta Se quiere suministrar una encuesta a los clientes de la empresa para medir el grado de satisfacción de los mismos. se sale del cliente mysql: mysql> quit se abre el archivo func_odbc. como en este caso. "El nombre del empleado es fulano."$ 243 . `resp2` int(1) default NULL. `fecha` datetime default NULL.conf crear un nuevo bloque de dialplan Se inicia creando la tabla: mysql -u root -psesamo mysql> use asterisk mysql> CREATE TABLE `encuesta` ( `id` bigint(20) NOT NULL auto_increment. `resp1` int(1) default NULL.") in new stack == Parsing '/etc/asterisk/festival.conf': == Found -. "") in new stack == Spawn extension (externas.-. `resp3` int(1) default NULL. 660.resp3.resp1. 1..10) same => n.conf en el contexto internas se pone: exten => 670...10) same => n.Read(var4.Read(var2.Read(var1..{SQL_ESC(${VAL2})}".${var2}.10) same => n.1.1..Festival(Pregunta tres) same => n.."${SQL_ESC(${VAL3})}".s.%y%m%d%H%M%S)}.Read(var3."${SQL_ESC($ {VAL5})}") IMPORTANTE: El contenido de la sentencia writesql tiene que estar en la misma linea. Para terminar se modifica el dialplan: nano /etc/asterisk/extensions.Goto(encuesta.1.Hangup El bloque de dialplan es bastante comprensible.1.Playback(thank-you-cooperation) same => n. Se presentan las cuatros preguntas. Se guardan los dígitos en 4 variables distintas y al terminar la encuesta se guardan los resultados en la tabla encuesta a través de la función ODBC_Encuesta que se acaba de crear en el archivo func_odbc.${var3}. Se repite la operación 3-4 veces. Para ver los resultados: mysql -u root -psesamo mysql> use asterisk 244 ."${SQL_ESC(${VAL4})}".${var1}.Festival(Pregunta cuatro) same => n.Set(ODBC_Encuesta()=${STRFTIME(${EPOCH}.${var4}) same => n. Se guardan las modificaciones y se actualiza Asterisk: service asterisk reload Desde unas de las extensiones conectadas a Asterisk se marca el 670 y se contestan las preguntas.Wait(2) same => n.1) same => n..Festival(Pregunta uno) same => n.Festival(Pregunta dos) same => n...conf.Answer same => n.1.10) same => n.Hangup y después del contexto internas se pone el siguiente bloque: [encuesta] exten => s. 245 .mysql> select * from encuesta. Los resultados aparecen ordenados por ID y fecha. . Anexo al correo electrónico es posible enviar el mensaje de voz en distintos formatos audio.1 voicemail. En negrita los valores de cada parámetro. entrará en función el buzón de voz.Capitulo XIV Buzón de voz – voicemail. Parámetro [general] format serveremail Inicia la parte general Los formatos audio en que se grabará cada mensaje de voz.conf es donde se configura todo lo relacionado con el buzón de voz.com. en segundos. Un ejemplo para Linode: buzondevoz@li370-135. la configuración completa del archivo. A través de la configuración de este archivo es posible. Valor 100 Numero máximo de segundos que puede durar un mensaje de voz. Numero máximo de mensajes de voz guardados para cada buzón de voz. además. Valor 5 Duración máxima.conf En el archivo voicemail. Valor buzondevoz@dominio. en la tabla a seguir se indicarán los parámetros que se van a configurar con una breve descripción. Valor 3000 Descripción attach maxmsg maxsecs minsecs maxgreet skipms . 14. se puede usar el teclado numérico del teléfono para adelantar o devolver el mensaje. Valor 180 Cuando se escuchan los mensaje de voz. siempre y cuando se configure el dialplan oportunamente.conf Como por lo demás archivos de configuración. Valor 500 Numero mínimo de segundos para que un mensaje de voz sea reconocido como tal y enviado al buzón de voz del destinatario. del mensaje de bienvenida que cada propietario de un buzón de voz puede grabar para presentarse. Si se recibe una llamada y no se contesta o la línea está ocupada.members. Se expresa en mili segundos.linode.com Personalizar yes = se anexa al correo electrónico el archivo audio que contiene el mensaje de voz. Valor wav49|gsm|wav Correo electrónico del remitente en la notificaciones de la presencia de un nuevo mensaje de voz. Al final de la tabla. crear distintos grupos de buzones de voz (distintas empresa) y configurar distintas zonas horarias. grabará el mensaje de voz dejado por quien llama y enviará una notificación por correo electrónico al llamado. Más bajo el número. se mueven a la carpeta OLD (viejos) en automático. hay que hacerlo desde el menú del buzón de voz yes = cada mensaje de voz reenviado se considerará urgente. este no será tomado en cuenta. si el parámetro anterior se ha configurado. mailbox y nueva contraseña se pasarán al script. es posible ejecutar un script externo. se termina la grabación. Se deja comentado cada vez que se cambie la contraseña de un buzón de voz.externnotify=/usr/bin/myapp .externpassnotify=/usr/bin/myapp directoryintro charset pbxskip fromstring usedirectory .Parámetro maxsilence Descripción Si mientras se deja un mensaje en el buzón de voz hay un silencio mayor al numero de segundos indicados en este parámetro.odbcstorage . hay que definirla en este parámetro. Valor 128 Numero máximo de intentos para marcar la clave asociada al buzón de voz personal. Valor 3 yes = una vez escuchados los nuevos mensajes de voz. Se explicará más adelante. Este parámetro permite buscar en el directorio la persona a la que se quiere dejar o reenviar el mensaje de voz Se pueden guardar los mensajes de voz en un base de datos 248 silencethreshold maxlogins moveheard forward_urgent_auto . Valor ISO-8859-1 yes = quita la sigla [PBX] en el asunto de los correos electrónicos Nombre del remitente del los correos electrónicos. Valor dir-intro El estándar ISO para los correo electrónicos que se enviarán para notificar la llegada de un nuevo mensaje de voz.externpass=/usr/bin/myapp . Valor Buzón de Voz yes = los mensajes de voz que se reciben se pueden reenviar a otros usuarios/extensiones del servidor Asterisk. Valor no si se quiere ejecutar una aplicación cada vez que llega un nuevo mensaje de voz. También se pueden dejar directamente mensajes de voz a otros buzones. Valor 4 Tienes que ser un valor menor del parámetro minsecs El numero indicado en este parámetro indica el nivel de ruido y sirve para definir que se considera silencio. las variables contexto. La locución de introducción de la aplicación directory. más sensible al ruido. si se configura en no. Se deja comentado Cada vez que se cambie la contraseña de un buzón de voz y se configure el nombre de un script en este parámetro. Nuevo mensaje de voz ${VM_MSGNUM} en el buzon de voz $ {VM_MAILBOX} Contenido del correo electrónico. Valor wav yes = antes de escuchar el mensaje de voz se anuncia el CallerID del llamante nombre del contexto del dialplan donde buscar el contexto de los buzones de voz para anunciar en lugar del numero de extensión el nombre de la persona que dejó el mensaje. Desde la versión 1. el ${VM_DATE}. En este caso se utiliza Sendmail.iso88591 yes = se envían los nuevos mensajes de voz anexos al correo electrónico de notificación. Valor internas yes = anuncia la duración del mensaje de voz define la duración mínima del mensaje de voz para que sea 249 emailbody emaildateformat mailcmd tz locale attach attachfmt saycid cidinternalcontexts sayduration saydurationm . %d %B %Y at %H:%M:%S comando Linux para enviar el correo electrónico. Valor: Estimando ${VM_NAME}:\n\n\t le estamos enviando este correo para avisarle que ha recibido un nuevo mensaje de voz de ${VM_DUR} segundos (numero $ {VM_MSGNUM})\n\n buzon de voz ${VM_MAILBOX} del numero ${VM_CALLERID}. En este parámetro se define el nombre de la base de datos. Gracias!\n\n\t\t\t\t. Valor: mensajes (se deja comentado) Asunto del correo electrónico de notificación. de los tres formatos audio en que se grabarán los mensaje de voz (definidos en el parámetro format). Se pone el mismo valor configurado para el idioma del sistema operativo: es_CO. Valor asterisk (se deja comentado) .\n\n Llame su buzon de voz para escucharlo. se escoge él que se utilizará para anexar el audio al correo electrónico. Valor. Valor central A partir de este parámetro inicia la configuración avanzada del archivo.8 de Asterisk es posible configurar el idioma para el formato de la fecha que aparece en el mensaje de notificación. Valor /usr/sbin/sendmail -t zona horaria predefinida para indicar fecha y hora de llegada del mensaje de voz.Parámetro Descripción usando el conector ODBC. Tiene que estar todo en la misma linea.odbctable emailsubject El nombre de la tabla de la base de datos donde guardar los mensaje de voz.Tu Buzon de Voz\n Nombre empresa Formato de la hora y fecha del correo electrónico. Valor %A. se anuncian todos los datos del mensaje mismo (fecha.callback=fromvm :exitcontext=fromvm review . Valor externas Permitir o no enviar el mensaje de voz a otra extensión (opción 5 del menú avanzado). Se deja comentado Nombre del contexto donde enviar el llamante si presiona una tecla antes de dejar un mensaje. Para que funcione se necesita que SOX sea instalado en el servidor. CLI.conf . A partir de la versión 1.operador=yes envelope delete volgain nextaftercmd forcename forcegreeting hidefromdir tempgreetwarn passwordlocation . grabar su nombre la primera vez que acceda. permite pasar al mensaje siguiente sin presionar las teclas 7 o 9 (borrar/guardar el mensaje respectivamente) yes = obliga cada usuario con un buzón de voz configurado.Parámetro dialout Descripción anunciado (en minutos). Se deja comentado yes = Permite al llamante escuchar el mensaje de voz que ha grabado antes de enviarlo permite al llamante presionar la tecla 0 para hablar con un operador mientras se encuentra en el buzón de voz. yes = el usuario no aparecerá en el directorio yes = recuerda al usuario que el mensaje de bienvenida que está usando es temporal hasta que no grabe uno personalizado. Posibles valores: – voicemail. Valor 2 nombre del contexto del dialplan para efectuar llamadas salientes desde el menú del buzón de voz (opción 4 del menú avanzado). permite subir el volumen de grabación de los mensajes de voz. Un usuario se considera nuevo si la contraseña del buzón de voz coincide con el numero de extensión no = obliga un nuevo usuario a grabar un mensaje de bienvenida para su buzón de voz no = el usuario aparecerá en el directorio.Se guardarán en este archivo 250 sendvoicemail .X de Asterisk es posible definir donde se guardarán las contraseñas para cada buzón de voz.) no = no se borra el mensaje de voz una vez que se ha enviado anexo al correo electrónico de notificación. hora. Valor 0.8.0 yes = en el caso de más de un mensaje de voz presente en el buzón de voz. Se deja comentado yes = antes de reproducir un mensaje de voz. etc. Valor yes Nombre del contexto del dialplan para poder llamar el remitente del mensaje de voz. vm-newpassword=custom_sound dejan comentadas .vm-pls-try-again=custom_sound listen-control-forward-key listen-control-reverse listen-control-pause-key listen-control-restart-key listen-control-stop-key backupdeleted [zonemessages] # = tecla para el avance rápido del mensaje * = tecla para rebobinar el mensaje 0 = tecla numérica para poner en pausa/reanudar el mensaje 2 = tecla numérica para volver a escuchar el mensaje desde el inicio 13456789 = teclas numéricas para terminar la escucha de un mensaje de voz (todas.vm-invalid-password=custom_sound . presionando 4 del primero mensaje ir al ultimo. menos las ya configuradas) 50 = numero máximo de mensajes de voz permitidos en la carpeta de borrados a partir de esta etiqueta se configuran las distintas zona horarias que se podrán configurar para cada buzón de voz. Lo mismo pasará con el correo electrónico de notificación. escuchará la fecha y la hora en que se dejó el mensaje de voz según el país en que se encuentre.vm-mismatch=custom_sound . define una longitud mínima para la contraseña del buzón de voz (en numero de cifras).Parámetro – Descripción spooldir – la contraseñas se guardarán en un archivo de texto (secret.conf) que hay que crear en la carpeta /var/spool/asterisk/voicemail/contexto/usuario donde contexto es el nombre del contexto al que pertenece el buzón de voz y usuario es el numero del buzón de voz de la extensión messagewrap yes = Mientras se están escuchando los mensajes de voz. Se .vm-password=custom_sound estos parámetros permiten personalizar las locuciones. presionando 6 desde el ultimo mensaje escuchado volver al primero. De esta forma el propietario de cada buzón de voz. Valor 4 minpassword . permite. Siguen algunos ejemplos America/New_York|'vm-received' Q 'digits/at' IMp America/Chicago|'vm-received' Q 'digits/at' IMp Europe/Copenhagen|'vm-received' a d b 'digits/at' HM America/Bogota|'vm-received' aebY 'digits/at' HM 251 eastern central european colombia .vm-reenterpassword=custom_sound .vm-passchanged=custom_sound . .com attach=yes maxmsg=100 maxsecs=500 minsecs=5 maxgreet=180 skipms=3000 maxsilence=4 252 . Como la contraseña es igual al numero de extensión.tz=mexico 1235.linode.com.fulano@gmail. uno por linea.conf y la etiqueta lo define.com. De esta forma se han definidos los buzones de voz para todas las extensiones configuradas en Asterisk meno la 1004..opciones 1000.conf se copian las siguientes lineas: [general] format=wav49|gsm|wav [email protected]=colombia 1002.tz=european 1234. Se renombra el predefinido: mv /etc/asterisk/voicemail. Después del [email protected]=colombia 1001.com.marko2.fulano@gmail. se le pedirá de cambiar la contraseña y configurar su buzón de voz.members. correo electrónico.fulano@gmail. En el configuración de las extensiones en el sip.fulano de tal.Parámetro mexico [default] Descripción America/Mexico_City|'vm-received' aebY 'digits/at' HM a partir de esta etiqueta se configuran los contextos para los buzones de voz. se configuran todos los buzones de voz. Ese el el contexto que hay que configurar en el voicemail. la primera vez que el usuario entre en su buzón de voz. nombre apellido.conf...fulano de pascual. van [email protected] se crea uno nuevo: nano /etc/asterisk/voicemail. Ahora se puede crear el archivo. correo pager. correo electrónico y zona horaria presentes en el archivo.zutano pelado. siguiendo la sintaxis: Numero extensión => contraseña.tz=central 1000 => 1001 => 1002 => 1234 => 1235 => IMPORTANTE: Todos los datos (nombre.conf /etc/asterisk/voicemail.conf para el parámetro mailbox se ha puesto como valor “default”. el ${VM_DATE}.iso88591 attach=yes attachfmt=wav saycid=yes cidinternalcontexts=internas sayduration=yes saydurationm=2 dialout=externas sendvoicemail=yes . %d %B %Y at %H:%M:%S mailcmd=/usr/sbin/sendmail -t tz=central locale=es_CO.0 nextaftercmd=yes forcename=yes forcegreeting=no hidefromdir=no 253 .odbctable=mensajes emailsubject=Nuevo mensaje de voz ${VM_MSGNUM} en el buzon de voz ${VM_MAILBOX} emailbody=Estimando ${VM_NAME}:\n\n\t le estamos enviando este correo para avisarle que ha recibido un nuevo mensaje de voz de ${VM_DUR} segundos (numero ${VM_MSGNUM})\n\n buzon de voz $ {VM_MAILBOX} del numero ${VM_CALLERID}.Tu Buzon de Voz\n Nombre empresa .externpassnotify=/usr/bin/myapp directoryintro=dir-intro charset=ISO-8859-1 pbxskip=yes fromstring=Buzon de Voz usedirectory=yes .externnotify=/usr/bin/myapp .externpass=/usr/bin/myapp .operador=yes envelope=yes delete=no volgain=0.silencethreshold=128 maxlogins=3 moveheard=yes forward_urgent_auto=no . Gracias!\n\n\t\t\t\t.callback=fromvm :exitcontext=fromvm review=yes . todo el texto del parametro "emailbody" tiene que estar en la misma linea emaildateformat=%A.odbcstorage=asterisk .\n\n Llame su buzon de voz para escucharlo. required) . 24 hour clock (single digit hours NOT preceded by "oh") .. Supported values: . (*note: not standard strftime value) .vm-invalid-password=custom_sound . or ABdY .vm-newpassword=custom_sound .) . correos electrónicos y zona horaria 1000 => 1000. I or l Hour.N Minute.Q "today".Y Year . d or e numeric day of month (first. thirty-first) . February. Sunday. with 00 pronounced as "o'clock" . 'filename' filename of a soundfile (single ticks around the filename . "yesterday" or ABdY . B or b or h Month name (January.tz=colombia 254 ..) . 12 hour clock . .vm-pls-try-again=custom_sound listen-control-forward-key=# listen-control-reverse=* listen-control-pause-key=0 listen-control-restart-key=2 listen-control-stop-key=13456789 backupdeleted=50 [zonemessages] .vm-mismatch=custom_sound .H Hour. .vm-passchanged=custom_sound . [email protected] "" (for today). personalizar nombres.tempgreetwarn=yes passwordlocation=voicemail.. "yesterday". with 00 pronounced as "hundred" (US military time) . (*note: not standard strftime value) .fulano de tal. apellidos.. 24 hour clock (single digit hours preceded by "oh") . ${VAR} variable substitution ..conf messagewrap=yes minpassword=4 .k Hour.com.. .M Minute.. A or a Day of week (Saturday.vm-password=custom_sound .R 24 hour time. including minute eastern=America/New_York|'vm-received' Q 'digits/at' IMp central=America/Chicago|'vm-received' Q 'digits/at' IMp european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM colombia=America/Bogota|'vm-received' aebY 'digits/at' HM mexico=America/Bogota|'vm-received' aebY 'digits/at' HM [default] . weekday.vm-reenterpassword=custom_sound .. P or p AM or PM . 1001 => 1001.com..fulano@gmail. se creará una Macro.fulano@gmail. Se guardan los cambios y se recarga la configuración del voicemail..fulano de pascual.com.tz=central IMPORTANTE: personalizar el parámetro serveremail con su nombre de dominio y los parámetros [email protected]=mexico 1235 => 1235.conf: asterisk -rvvvvvvvvvvvvvvvv CLI> voicemail reload Para ver los usuarios configurados y los mensajes de voz presentes: CLI> voicemail show users Context Mbox User Zone NewMsg default general New User 0 default 1000 fulano de tal colombia 0 default 1001 fulano de pascual colombia 0 default 1002 zutano de tal european 0 default 1234 marko mexico 0 default 1235 marko2 central 0 Para ver la zonas horarias configuradas: CLI> voicemail show zones Zone Timezone Message Format mexico America/Bogota 'vm-received' aebY 'digits/at' HM colombia America/Bogota 'vm-received' aebY 'digits/at' HM european Europe/Copenhagen 'vm-received' a d b 'digits/at' HM central America/Chicago 'vm-received' Q 'digits/at' IMp eastern America/New_York 'vm-received' Q 'digits/at' IMp Se sale la consola: CLI> quit Para que una llamada si no es contestada o si la extensión está ocupada se envíe al buzón de voz.com.marko2. Como esta parte es igual para todas las extensiones.conf 255 . correo electrónico y zona horaria de cada buzón de voz.zutano pelado.. hay que modificar el dialplan. Se abre el archivo del dialplan: nano /etc/asterisk/[email protected]=colombia 1002 => 1002.marko.tz=european 1234 => 1234.. Macro(disponible) same => n.Answer same => n.VoicemailMain same => n.Hangup exten => 1235.1.Hangup para que queden: exten => _100[0-2.Hangup exten => 1234.30) same => n.Dial(IAX2/marko2.conf) Linea2 – cuelga la llamada Para entrar al buzón de voz general y luego digitar numero de buzón y contraseña: exten => 98.Hangup exten => 1235.Primero se añade la parte para llamar el buzón de voz en el contexto internas: exten => 97.Dial(SIP/${EXTEN}.1.1.30) same => n.1.30) same => n.4].hHkKtTwWxX) same => n.Macro(voicemail) same => n.hHkKtTwWxX) same => n.Directory(default.Dial(IAX2/marko.45.45.Hangup se modifica estos tres bloques para que queden: exten => _100[0-2.Hangup Para buscar un usuario en el directorio: exten => 99.1.Macro(calendario) same => n.1.Hangup • • • Linea1 – contesta la llamada Linea2 – envía la llamada al buzón de voz del llamante (CALLERID(num) y al contexto default (configurado en voicemail.e) same => n.Hangup exten => 1234.internas.VoiceMailMain(${CALLERID(num)}@default) same => n.1.1.1.Macro(voicemail) same => n.Dial(SIP/${EXTEN}.Dial(IAX2/marko2.Dial(IAX2/marko.4].30) same => n.Macro(voicemail) 256 . b) same => n.Hangup La aplicación dial genera la variable DIALSTATUS que contiene uno de los siguientes valores: • • • • • • • • CHANUNAVAIL CONGESTION NOANSWER BUSY ANSWER CANCEL DONTCALL TORTURE En base al valor se enviará la llamada a un determinado punto de la macro. La extensión 1001 será transferida al buzón de voz de la extensión 1000 donde se dejará un mensaje. Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvvvvv CLI> dialplan reload La primera operación es la de configurar el buzón de voz de la extensión 1000.Hangup exten => s-CANCEL. Si el apellido existe.1.Goto(s-${DIALSTATUS}. En la interfaz de X-Lite (extension 1000). Como ultima prueba. desde la extensión 1001 se marca la extensión 1000 y no se contesta la llamada..Hangup exten => _s-. por ejemplo.1. si el valor es BUSY.conf) de la extensión 1002.1.same => n.u) same => n. se podrá llamar directamente desde esta aplicación. Terminada esta operación se marca desde la extensión 1000 el numero 99 para probar el directorio.1) exten => s-BUSY. En el directorio se busca una persona digitando en el teclado del teléfono las primeras tres letras del apellido. Hacer la prueba marcando el apellido (como configurado en el voicemail.Congestion same => n.1.1. Desde esa extensión se marca el numero 97 y se siguen los pasos indicados por las locuciones. aparecerá: 257 .Hangup exten => s-CONGESTION. la llamada se transferirá al buzón de voz anunciando al llamante que la extensión está hablando.Voicemail(${MACRO_EXTEN}@default.Voicemail(${MACRO_EXTEN}@default.Hangup Luego al final del archivo se crea la macro: [macro-voicemail] exten => s. Se puede comprobar también desde la consola: CLI> voicemail show users Context Mbox User Zone NewMsg default general New User central 0 default 1000 fulano de tal colombia 1 default 1001 fulano de pascual colombia 0 default 1002 zutano pelado european 0 default 1234 marko mexico 0 default 1235 marko2 central 0 7 voicemail users configured. Los tres archivos audio (en los tres formatos definidos en voicemail.conf) se encontrarán en la carpeta: 258 . y con el correo electrónico recibido: El anexo es el archivo audio con el mensaje de voz. Se puede escuchar el mensaje llamando también el numero 97.La parte evidenciada indica que hay un mensaje en el buzón de voz de la extensión 1000. ademas de guardarse en la carpeta indicada en el párrafo anterior. [message] origmailbox=1000 context=macro-voicemail macrocontext=locales exten=s-BUSY priority=1 callerchan=SIP/1002-00000032 callerid="Mengano" <1002> origdate=Thu Oct 20 01:37:07 AM UTC 2011 origtime=1319074627 category= flag= duration=10 14. hay que volver a seleccionar los 259 .1 root root 16895 Oct 19 20:37 msg0000. Se entra en la carpeta de las fuentes de Asterisk y se siguen estos pasos: cd /usr/src/asterisk-1.1 root root 17127 Oct 19 20:37 msg0000.ls . Esto permite implementar aplicaciones que desde la Web permitan escuchar los mensajes de voz y revisar todos los datos de los mismos.2 Mensajes de voz en una base de datos Los mensaje de voz./var/spool/asterisk/voicemail/default/1000/INBOX/ -rw-r--r-.11. hay que volver a compilar Asterisk con el soporte ODBC para el buzón de voz. como ya se ha visto anteriormente.8.gsm -rw-rw-rw.txt -rw-r--r-.WAV El archivo msg0000.1 root root 166124 Oct 19 20:37 msg0000.txt contiene toda la información relacionada con el mensaje de voz: . . pueden guardarse en una base de datos.wav -rw-r--r-. Message Information file .1 root root 271 Oct 19 20:37 msg0000. Esta configuración se basa en el conector ODBC y una base de datos (en este caso MySQL)./configure make menuselect Cuando se recompila Asterisk.0 make distclean . Para que funcione. modulos Add-ons: Luego en el menú “Voicemail Build Options” seleccionar “ODBC_STORAGE”: Se guardan los cambios y se compila Asterisk: make Antes de instalar nuevamente los modulo de Asterisk.conf: nano /etc/asterisk/voicemail.sql Creada la tabla hay que modificar dos parámetros en el archivo voicemail.conf modificar estas dos lineas: . mysql -u root -psesamo asterisk < contrib/realtime/mysql/voicemail_messages. para guardar los mensaje de voz en la base de datos. hay que crear la tabla. se para el servicio: service asterisk stop Luego se instala: make install Ahora.odbctable=mensajes 260 .odbcstorage=asterisk . En algunos casos los datos de las tablas se encuentran en la carpeta contrib/realtime/mysql de las fuentes de Asterisk como es para los mensajes de voz. so == Parsing '/etc/asterisk/voicemail.callerid from voicemail_messages.00 sec) Perfecto!! 261 .so CLI> module load app_voicemail.conf': == Found == Registered application 'VoiceMail' == Registered application 'VoiceMailMain' == Registered application 'MailboxExists' == Registered application 'VMAuthenticate' == Registered application 'VMSayName' == Registered custom function 'MAILBOX_EXISTS' == Manager registered action VoicemailUsersList Loaded app_voicemail.para que queden: odbcstorage=asterisk odbctable=voicemail_messages Se guardan los cambios y se inicia Asterisk: service asterisk start Se entra en la consola de Asterisk y se averigua que el modulo esté funcionando con ODBC Storage: asterisk -rvvvvvvvvvvvvvvvvvv CLI> module unload app_voicemail.conf': == Found == Parsing '/etc/asterisk/users. Para averiguar que el mensaje ha sido guardado en la tabla: mysql -u root -psesamo mysql> use asterisk mysql> select dir.context. desde la extensión 1001 o 1002 se llama la extensión 1000 y se deja un mensaje en el buzón de voz.so Loaded app_voicemail. +--------------------------------------------------+--------+-----------------+-----------------+ | dir | msgnum | context | callerid | +--------------------------------------------------+--------+-----------------+-----------------+ | /var/spool/asterisk/voicemail/default/1000/INBOX | 0 | macro-voicemail | "zutano" <1001> | +--------------------------------------------------+--------+-----------------+-----------------+ 1 row in set (0.msgnum. Para probarlo.so => (Comedian Mail (Voicemail System) with ODBC Storage) Por lo que aparece en negrita parece que si. conf Se modifica esta linea: .14. también los buzones de voz se pueden guardar en una base de datos.asterisk para que quede: voicemail => odbc.sql Creada la tabla se configura el realtime dinámico: nano /etc/asterisk/extconfig. como ya se ha dicho anteriormente.11.3 Buzones de voz en una base de datos Además de los mensajes de voz. Los pasos a seguir son: • • • crear la tabla en la base de datos configurar el realtime dinámico reiniciar asterisk Como para la tabla de los mensajes de voz..8. se utilizará la tabla presente en las fuentes de Asterisk: cd /usr/src/asterisk-1.voicemail Se guardan los cambios y se reinicia Asterisk: service asterisk restart Ahora se configura el buzón de voz de la extensión 1004 (la configurada en SIP realtime) en la tabla a través de webmin: 262 .asterisk.voicemail => odbc.0/contrib/realtime/mysql/ mysql -u root -psesamo asterisk < voicemail. En este caso se utilizará el Realtime dinámico. es que esto permite modificar los valores directamente desde la base de datos o desde una aplicación Web que trabaje con la base de datos. La ventaja. En la tabla aparecen todas las opciones que se pueden configurar para un buzón de voz. Se termina 263 . 264 .presionando el botón “Save” y desde la extensión 1004 se marca el 97 para probar la configuración. Si todo funciona. ya se ha terminado con la configuración de los buzones de voz. . Confbridge ha sido añadida a Asteirks a partir de la versión 1. Valor yes Hay una conferencia programada a las 8 de la mañana.X y no necesita DAHDI para funcionar. 15. La configuración de meetme se hace a partir de un archivo dedicado mientras las conferencias creadas con Confbridge no necesitan configuración previa. se presentan los parámetros con una breve descripción.Las conferencias audio – meetme.1. existen dos aplicaciones: • • meetme confbridge La primera es la más conocida y ha sido implementada en Asterisk desde las primeras versiones. En caso contrario hay que dejarlo en no Si las conferencias están configuradas en Realtime este parámetro actualiza la tabla cada vez que un usuario entre o salga de la conferencia.conf Como para los demás archivos de configuración de Asterisk. Valor 32 Este parámetro va configurado en yes solamente si se usan las conferencias en realtime (ARA). meetme no funciona. Esto permite sincronizar el audio de los distintos participantes y evitar retrasos. En negrita los valores que se asignarán. Para utilizar esta funcionalidad. Parámetro [general] audiobuffers Descripción Inicia la parte general de configuración Numero de paquetes audio de 20ms que serán guardados en un buffer de memoria cuando pertenecen a canales que no son DADHI. 300 es el número de schedule logmembercount fuzzystart . Este parámetro se utiliza para definir si un usuario puede o no entrar en la conferencia si e ésta no ha empezado. Sin DAHDI instalado.Capitulo XV Las conferencias audio Cuarta parte . Al final de la tabla el archivo completo. pero implementa menos funciones y no es posible configurarla en Realtime dinámico.conf En Asterisk una funcionalidad bastante interesante es la de las conferencias audio. Meetme se apoya a DAHDI para generar la sincronización de los canales audios presentes en la conferencia creando una canal pseudo-DAHDI para cada conferencia.1 meetme.6. Puede ser un valor entre 2 y 32. Parámetro Descripción segundos. Con el valor en 3600.conf.1234. Cuando falten los segundos indicados en este parámetro para que termine una conferencia programada.conf [general] audiobuffers=32 schedule=no logmembercount=yes fuzzystart=300 earlyalert=3600 endalert=120 267 . Ejemplo. si entra cuando falta menos de una hora recibirá este aviso. Valor 120 a partir de esta etiqueta inicia la configuración de las conferencias.old y se crea uno nuevo con los parámetros indicados en la tabla: nano /etc/asterisk/meetme. La sintaxis es: conf => confno[. Funciona solamente en Realtime earlyalert 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.conf /etc/asterisk/meetme. Si entra más de una hora antes se le anunciará que la conferencia no existe.pin][. a los usuario se les presentará un aviso.adminpin] Se configura la primera sala de conferencia sin PIN de usuario y PIN de administrador Se configura la segunda sala de conferencia con PIN de usuario 1234 y sin PIN de administrador Se configura una tercera sala de conferencia con PIN de usuario 1234 y PIN de administrador 5678 endalert [rooms] conf => 3500 conf => 3501. 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.5678 Se renombra el archivo predefinido: mv /etc/asterisk/meetme.1234 conf => 3502. 5678 Se guardan los cambios y se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvvvvv se recarga el modulo app_meetme CLI> module reload app_meetme. la segunda para administrarla.conf) Las tres opciones: • s .scM(default)) same => n. La primera es para entrar en una conferencia.so se revisa la sintaxis de la aplicación meetme: CLI> core show application meetme Como se puede ver hay muchos parámetros y opciones que se pueden configurar.[rooms] conf => 3500 conf => 3501. la tercera es para controlar un canal de la conferencia y la tercera para conocer el numero de usuarios presentes en una conferencia.1. Hay otras aplicaciones relacionadas con las conferencias: CLI> core show application meetme (más la tecla tabulador) MeetMe MeetMeAdmin MeetMeChannelAdmin MeetMeCount Las aplicaciones disponibles son cuatro.1234 conf => 3502. CLI> quit Ahora se modifica el dialplan para utilizar las conferencias.Hangup Llamando la extensión 3500.Meetme(${EXTEN}.Con esta opción se activa el menú del cuarto de conferencias para usuarios y 268 .conf después del contexto internas se añade un nuevo contexto: [conferencias] exten => _350[012].3501 o 3502 se entrará en el cuarto de conferencia (como configurado en meetme.1234. nano /etc/asterisk/extensions. • • administradores.1. 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 se controla con la aplicación MeetmeCount cuantos usuarios están en la conferencia 3520 y se asocia ese valor a la variable count.Al entrar en un cuarto de conferencia se le anunciará al usuario el número de personas presentes M(default) .Cuando en el cuarto de conferencia está solamente una persona. 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. Otro ejemplo que se puede añadir al dialplan es crear una conferencia y definir como numero máximo de participantes 10. para que las extensiones tengan acceso al contexto conferencias hay que añadir la linea en negrita al contexto externas y locales: 269 .conf). Esto se hace con una Macro.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. En el contexto conferencias se pone: exten => 3520.Macro(meetme) same => n.count) same => n.MeetMeCount(${MACRO_EXTEN}.Hangup same => n(llena). si es menor el usuario podrá entrar al cuarto de conferencias.1.Playback(conf-invalid) same => n.DM(default)) same => n. A seguir un ejemplo que se va a añadir al dialplan en el contexto conferencias: exten => 3510. El PIN de la conferencia será el que será digitado por la primera persona que entre en la conferencia. Marcando la tecla asterisco se escuchará el menú c . Para terminar la configuración del dialplan.Set(confmax=10) same => n.Hangup y al final del archivo se añade la Macro: [macro-meetme] exten => s. Si el numero contenido en la variable count es mayor al numero contenido en la variable confmax (10) se va a la línea con la etiqueta (llena) donde se comunicará que la conferencia no es valida y se colgará la llamada. ésta escuchara la música de 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.Gotoif($[${count} > ${confmax}]?llena) same => n.D) same => n.Meetme(.1.Hangup Una explicación.MeetMe(${MACRO_EXTEN}. Para ver las extensiones presentes en la conferencia: CLI> meetme list 3500 User #: 01 1000 callerid=Fulano Channel: SIP/1000-00000003 (unmonitored) 00:02:45 User #: 02 1001 zutano Channel: SIP/1001-00000007 (unmonitored) 00:00:53 2 users in that conference.[externas] include => internas include => internacio include => parkedcalls include => test include => conferencias [locales] include => internas include => auten include => parkedcalls include => test include => conferencias Se guardan los cambios y se actualiza el dialplan: asterisk -rvvvvvvvvvvvv CLI> dialplan reload Ahora desde las extensiones 1000 y 1001 se marca el numero 3500 para entrar en la primera conferencia configurada en el archivo meetme.Executing [3500@externas:2] Hangup("SIP/1000-00000003". "") in new stack Quedará: CLI> meetme list 3500 User #: 02 1002 Mengano 1 user in that conference. Channel: SIP/1002-00000005 (unmonitored) 00:04:09 Para probar la Macro desde la extensión 1000 se marca 3520. 15.alaw' (language 'es') -.2 Aplicación ConfBridge 270 . Para sacar un usuario de la conferencia: CLI> meetme kick 3500 1 == Setting global variable 'MEETMEADMINSTATUS' to 'OK' -.conf.<SIP/1000-00000003> Playing 'conf-kicked. q: Quiet mode (don't play enter/leave sounds). [Description] Enters the user into a specified conference bridge. 271 . M[(class)]: Enable music on hold when the conference has a single caller. If one is not provided. A: Set marked mode. or 'default'. The join sound can be set using the 'CONFBRIDGE_JOIN_SOUND' variable and the leave sound can be set using the 'CONFBRIDGE_LEAVE_SOUND' variable.Para conocer la sintaxis de la aplicación ConfBridge: CLI> core show application ConfBridge -= Info about application 'ConfBridge' =[Synopsis] Conference bridge application. it will use the channel's currently set music class. w: Wait until the marked user enters the conference. NOTE: This application will not automatically answer the channel.options]) [Arguments] confno The conference number options a: Set admin mode. Optionally. [Syntax] ConfBridge([confno][. The user can exit the conference by hangup only. These can be unique to the caller. 1: Do not play message when first person enters s: Present menu (user or admin) when '*' is received (send to menu). c: Announce user(s) count on joining a conference. specify a musiconhold class to use. m: Set initially muted. 272 . `pin` char(20) default NULL. Lo primero es crear la tabla en la base de datos Asterisk: mysql -u root -psesamo mysql> use asterisk mysql> CREATE TABLE `meetme` ( `confno` char(80) NOT NULL default '0'.3 Meetme en Realtime Dinámico Como se ha comentado anteriormente. con ConfBridge no se puede. desde la consola de Asterisk. 15. `starttime` datetime NOT NULL default '0000-00-00 00:00:00'. es posible configurar las conferencias en Realtime dinámico.Hangup Se guardan los cambios y se actualiza el dialplan: asterisk -rvvvvvvvvvvvvvvv CLI> dialplan reload Ahora desde la extensión 1000 se marca el numero 3530. A diferencia de meetme. `adminpin` char(20) default NULL.1.Mcs) same => n. `endtime` datetime default NULL. ni hacer otros tipos de operaciones. `members` int(11) NOT NULL default '0'. `adminopts` char(100) default NULL. `opts` char(100) default NULL.[See Also] Not available Como esta aplicación no contesta automáticamente el canal.Answer same => n. controlar los participantes presentes.ConfBridge(3530. para configurarla en el dialplan hay que iniciar el bloque con un Answer: CLI> quit nano /etc/asterisk/extensions.conf En el contexto conferencias se añade: exten => 3530. voztovoice.wav /var/lib/asterisk/sounds/en 273 .asterisk.meetme Se guardan los cambios y se modifica el parámetro schedule del archivo meetme.tar y moverlas en la carpeta de la locuciones en ingles: mv *.conf se busca esta linea: .conf nano /etc/asterisk/extconfig. se modifica el archivo extconfig. hay que descargarlas: cd /tmp wget http://www.`maxusers` int(11) NOT NULL default '0'.tar descomprimir el paquete: tar -xf confprompts.`starttime`) ).org/tmp/confprompts.conf para permitir la creación de conferencias programadas en Realtime: nano /etc/asterisk/meetme.general y se modifica para que quede: meetme => odbc.meetme => mysql. PRIMARY KEY (`confno`. mysql> quit Creada la tabla.conf schedule= no se cambia a: schedule=yes Se guardan los cambios y se recarga toda la configuración de Asterisk: service asterisk reload Como algunas locuciones para las conferencias programadas no existen en la instalación estándar de Asterisk. La idea es crear una que inicie dentro de 50 minutos y otra que inicie dentro de 5 minutos y que las dos duren una hora. Se guardan los datos presionando el botón Save. La segunda: Las opciones que aparecen en las dos conferencias para los usuarios: • • c – anuncia los usuarios presentes en la conferencia I – obliga al usuario que entra a la conferencia a grabar su nombre 274 .Ahora para la prueba se configuran dos conferencias a través de Webmin. timeout]]) y las opciones disponibles: • • • • d – audio en ambas direcciones i – no se tomarán en cuenta intentos de transferir la llamada q – modo silencioso. volumen del micrófono. el llamante no escuchará un beep r – se grabará la conferencia en un archivo audio 275 . Dependiendo del tipo de opciones configuradas.conf en el contexto conferencias se añade el siguiente bloque: exten => _500[01].1. etcétera). se podrán crear distintos tipos de escenarios: • • • solamente quien ha iniciado la llamada podrá hablar todas las extensiones podrán hablar como sistema de intercomunicación para comunicar breves mensajes a la persona llamada (el teléfono del destinatario abrirá la linea en automático) La sintaxis de la aplicación es: Page(Technology/Resource[&Technology2/Resource2[&.options[. En el primer caso un anuncio avisará que la conferencia no ha empezado.]][. deja entrar el usuario (como configurado en el parámetro fuzzystart..• s – se activa la tecla “*” para entrar en un menú que permite modificar algunos parámetros personales (volumen de la conferencia. La única diferencia con las opciones del administrador es la opción a que activa el modo administrador..Meetme(${EXTEN}) same => n.4 Aplicación Page La aplicación Page se utiliza para crear conferencias instantáneas llamando un grupo de extensiones simultáneamente. 300 segundos). en el segundo. Para terminar hay que añadir las dos conferencias en el dialplan nano /etc/asterisk/extensions. como faltan menos de 5 minutos para que empiece. 15.Hangup Se guardan los cambios y se actualiza la configuración asterisk -rvvvvvvvvvvvvvvvvvv CLI> dialplan reload Ahora se hace una prueba llamando primero la conferencia 5000 y luego la 5001. solamente la 1000 tendrá activado el audio.Page(SIP/1001&SIP/1002) same => n.d) same => n.• • • s – solo se intentará incluir en las conferencias las extensiones cuyo estado sea “NOT_INUSE” A(x) – envía un anuncio a todos los participantes de la conferencia.Page(SIP/1001&SIP/1002.answer-after=0) Yealink . Implica que A(x) sea presente Una prima forma de probar la aplicación es: exten => 501.answer-after=0) Cisco SPA .SIPAddHeader(Call-Info:\. en una empresa donde se quiera comunicar a todos los empleados un anuncio.SIPAddHeader(Alert-Info: Ring Answer) Snom . el dialplan sería: exten => 503. este contestará la llamada en automático y el anuncio será difundido por el sistema de parlantes conectados al ATA.Hangup Una vez que las dos extensiones contesten.Hangup En este caso todas las extensiones tendrán el micrófono activado.SIPAddHeader (P-Auto-answer: normal) same => n.1. Llamando la extensión asociada al PA1. x es el nombre del archivo audio que contiene la locución n – no envía un anuncio a todos los participantes de la conferencia. que a su vez se puede conectar a un sistema de amplificación audio.1.Page(SIP/1001. por ejemplo.1. Utilizar Page como sistema de intercomunicación puede ser muy útil.SIPAddHeader(Alert-Info: info=alert-autoanswer) Polycom . En este caso se conecta a Asterisk una ATA tipo el PA1 de SNOM. Algunos ejemplos: • • • • • Aastra .SIPAddHeader(Call-Info: sip:domain.com\.SIPAddHeader (P-Auto-answer: normal) Ahora in una hipotética oficina donde el gerente quiera hacer una anuncio a la secretaria y ambos están utilizando teléfonos Yealink cuya extensiones son 1000 para el gerente y 1001 para la secretaria.i) same => hangup 276 . Dependiendo de la marca hay que enviar una cabecera especifica en el INVITE para que el teléfono mismo la reconozca y conteste la llamada en automático activando el parlante (alta voz) del teléfono. Las cabeceras se añaden a través de la aplicación Sipaddheader de Asterisk Estas cabeceras cambian según la marca de los telefonos. Una variación de este bloque es: exten => 502. El mismo sistema se utiliza con los teléfonos SIP. d) same => n.Hangup exten => 502.1.El gerente marca 503 y hace el anuncio a la secretaria cuyo teléfono habrá contestado en automático activando el parlante.1. Para terminar este párrafo se modifica el dialplan: nano /etc/asterisk/extensions.conf y en el contexto conferencias se añaden los dos bloques que siguen: exten => 501.Page(SIP/1001&SIP/1002) same => n. 277 .Hangup Se guardan los cambios y se actualiza el dialplan: asterisk -rvvvvvvvvvvvv CLI> dialplan reload Desde la extensión 1000 se marca primero el numero 501 y luego el 502.Page(SIP/1001&SIP/1002. . conf se configuran las colas (pueden ser una o más). Si no contesta dentro de ese tiempo.conf • queues. Al final del la tabla el archivo completo de configuración. los agentes miembros de cada cola y que tipo de estrategia se utilizará para enrutar las llamadas en la cola. definiendo algunas variables y parámetros. En base a su calidad y el tiempo promedio de espera. se está adentro de un sistema de distribución automática de las llamadas. Cuando uno de los operadores que atienden las llamadas está libre. sin saberlo. el tiempo estimado de espera y un largo etcétera). Quizás este es el servicio más importante y estratégico para una empresa. Valor no A partir de esta etiqueta inicia la configuración de los agentes Numero de intentos permitidos a un agente para autenticarse. ¿Cómo funciona? Cada llamada que llega se pone en una cola de espera respetando la prioridad con que ha llegado. según la configuración. A lo largo de la espera. Parámetro [general] multiplelogin [agents] maxlogintries autologoff Descripción etiqueta que da inicio a la parte general del archivo Define si está permitido a una extensión conectarse como agente múltiple. ¿Cómo se configura en Asterisk la gestión de las colas? A través de dos archivos: • agents. Valor 15 yes = si la extensión desde la cual el agente se autologoffunavail . 16.1 Los Agentes Para configurar los agentes que atenderán las llamadas entrantes a las distintas colas hay que modificar el archivo agents.conf. la llamada sera transferida a ese operador. En el queues. será desconectado de la cola. Valor 3 Numero de segundos que un agente tiene para contestar una llamada entrante. el llamante escuchará distintos anuncios (que posición tiene en la cola. En negrita el valor asociado a cada parámetro.conf En el primero se configuran. los clientes estarán evaluando la misma empresa.Capitulo XVI Distribución automática de llamadas – Colas de espera Cuando se llama un centro de atención al cliente. los agentes que atenderán las colas. En la tabla que sigue los distintos parámetros con una breve descripción. savecallsin custom_beep agent 280 . Se deja comentado De manera predefinida las llamadas grabadas se guardan en la carpeta: /var/spool/asterisk/monitor Si se quiere personalizar la carpeta se indica en este parámetro.goodbye=vm-goodbye updatecdr . Valor 5000 Música de espera predefinida para el agente. Las sintaxis es: agent => agentid. Valor no (no tiene que presionarla) # yes = permite al agente terminar una llamada presionando la tecla configurada en el próximo parámetro * Numero de mili segundos que Asterisk esperará antes de volver a llamar un agente que acaba de atender una llamada. Valor no obsoleto.agentpassword.org/calls. Valor beep Ahora se configuran los agentes.voztovoice. de la llegada de una llamada.Fulano acceptdtmf endcall enddtmf wrapuptime musiconhold .group recordagentcalls recordformat . Ejemplo http://www. Se deja comentado Avisa al agente que está conectado permanentemente a la cola.urlprefix . Valor no Formato audio de las llamadas grabadas. automáticamente el agente será desconectado de la cola ackcall Para atender una llamada un agente tiene que presionar la tecla configurada en el próximo parámetro. No usar grabar o no las llamadas de los agentes. Puede ser una URL.Parámetro Descripción conecta se vuelve no disponible. Valor default locución que el agente escuchará al terminar una llamada. Valor wav el prefijo del nombre del los archivos grabados.1234.name Valor: 2000. Si se deja comentado será la predefinida (vm-goodbye) Actualizar o no el CDR con el nombre del agente. 1235.1236.1236 Mengano Se guardan los cambios.1235.urlprefix=http://dominio.conf y se añaden los parámetros de la tabla: [general] multiplelogin=no [agents] maxlogintries=3 autologoff=15 autologoffunavail=yes ackcall=no acceptdtmf=# endcall=yes enddtmf=* wrapuptime=5000 musiconhold=default .Fulano agent => 2001.conf /etc/asterisk/agents.Zutano Descripción 2002.org/calls .Zutano agent => 2002.1234.conf.savecallsin=/home/calls custom_beep=beep agent => 2000.goodbye=vm-goodbye updatecdr=yes .group recordagentcalls=no recordformat=wav .Parámetro agent agent Se renombra el archivo predefinido: mv /etc/asterisk/agents. Se entra en la consola de Asterisk y se recarga el modulo chan_agent.old se crea uno nuevo: nano /etc/asterisk/agents.Mengano 2001.so: asterisk -rvvvvvvvvvvvvvv CLI> module reload chan_agent.so 281 . se ingresa la clave del agente 2000 (1234) seguida por la tecla numero #.Agentlogin(${EXTEN}) same => n. Es poco productivo tener una agente conectado permanentemente a una cola además utilizando parte de la banda disponible.1. se utiliza en el dialplan la aplicación Agentlogin: nano /etc/asterisk/extensions. esperando de atender los clientes. Esta parte se verá en el ultimo párrafo de este capitulo. Es mucho más lógico conectar los agentes de forma dinámica y que mientras esperen las llamadas de los clientes. CLI> agent show 2000 (Fulano) logged in on SIP/1000-00000001 is idle (musiconhold is 'default') 2001 (Zutano) not logged in (musiconhold is 'default') 2002 (Mengano) not logged in (musiconhold is 'default') 3 agents configured [1 online . Una vez autenticado. puedan utilizar el teléfono para otro tipo de actividad. se añade el siguiente bloque: exten => _200[012].conf 282 . el agente empezará a escuchar la música de espera predefinida. asterisk -rvvvvvvvvvvvvvvvvvvvv CLI> dialplan reload Ahora desde la extensión 1000 se marca el numero 2000.2 Las colas de espera – queue. 2 offline] Este sistema de conectar los agentes a las colas se ha vuelto un poco obsoleto para perqueños CallCenter y se está optando más para aplicaciones que permiten añadir a las colas de espera agentes dinámicos. y cuando el sistema lo pide. 3 offline] CLI> quit Para que los agentes puedan autenticarse y atender las colas de que son miembros. 16.Hangup Se guardan los cambios y se actualiza el dialplan.Para ver la lista de los agentes configurados: CLI> agent show 2000 (Fulano) not logged in (musiconhold is 'default') 2001 (Zutano) not logged in (musiconhold is 'default') 2002 (Mengano) not logged in (musiconhold is 'default') 3 agents configured [0 online . Es hora de configurar las colas.conf en el contexto internas. Los clientes serán atendidos de manera paralela hasta que haya agentes disponibles. Al final de la tabla el archivo completo.conf se configuran las distintas colas de espera. De esta forma se reducen considerablemente los tiempos de espera. 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. antes de atender una llamada.announce=queue-ventas 283 . Con este parámetro se define otro tipo de comportamiento. Este comportamiento no tiene en cuenta que pueden haber muchos agentes disponibles que podrían atender los clientes sin esperar que llegarán a ser los primeros de la cola de espera. Parámetro [general] persistentmembers Descripción Etiqueta que define la parte general del archivo yes = se guardan los datos de los miembros de la cola activos en la base de datos interna de Asterisk. Si se reinicia la PBX los miembros serán reasignados a las colas correspondientes.En el archivo queues. Puede ser Mixmonitor o monitor Actualiza o no el valor del campo dstchannel del CDR (el registro de las llamadas) con el nombre del agente. Valor default Este parámetro permite crear un anuncio para que los agentes que pertenecen a más de una cola sepan. Valido solamente para agentes dinámicos Normalmente una cola funciona de la siguiente manera. En la tabla que sigue los distintos parámetros con una breve descripción. de que cola proviene el cliente. Valor no Si un agente hace parte de más de una cola y se ha definido su tiempo de descanso entre una llamada y otra (el parámetro wraptime). En negrita el valor asociado a cada parámetro. Hay unos cuantos usuarios esperando por ser atendidos por los agentes. Valor yes el tipo de aplicación utilizada para grabar las conversaciones de una cola. Valor yes con esta etiqueta se define la primera cola de espera La música de espera para los clientes en la cola. Se deja comentado autofill monitor-type updatecdr shared_lastcall [ventas] musiclass . con este parámetro se define si ese tiempo va respetado entre las distintas colas de que el agente es miembro. Pasado ese tiempo sin ser atendido. Si son agentes dinámicos según el orden con que se han registrado a la cola • Wrandom: asigna la llamada aleatoriamente usando una métrica basada en penalidades. • RRMemory: Distribuye las llamadas “por turnos” entre los agentes disponibles y “recuerda” el último agente al que intentó llamar. • Ringall: Llama todos los agentes disponibles a la vez hasta que uno conteste. Valor ventas-exit En la cola se pueden configurar dos distintos tipos de tiempos de espera. • Fewestcalls: Asigna la siguiente llamada al agente que menos llamadas ha atendido. En base al numero de segundos configurados en este parámetro.Parámetro strategy Descripción En este parámetro se define la lógica con que se enrutarán las llamadas de una cola a los agentes: • Leastrecent: Asigna la siguiente llamada al agente que más tiempo lleva sin atender una llamada. Valor 120 Si el cliente en la cola antes de ser atendido presiona una tecla del teléfono será enviado al contexto definido en este parámetro y a la prioridad correspondiente al dígito que ha marcado. Este primer parámetro define por cuantos segundos timbrará la extensión del agente. • Random: Asigna la siguiente llamada aleatoriamente a cualquier agente disponible. el cliente saldrá de la cola y se ejecutara la siguiente prioridad presente en el dialplan. Valor: 15 numero de segundos de espera antes de llamar otro 284 servicelevel context timeout retry . El segundo es el tiempo máximo que timbrará la extensión de un agente antes de considerarlo no disponible y pasar al siguiente. Este parámetro y los siguientes dos se utilizan para definir que tipo de tiempo de espera tendrá prioridad. • Linear: Llama los agentes siguiendo el orden definido en este archivo de configuración. Parámetro utilizado para la estadísticas de la cola. Uno a nivel de aplicación (dialplan) define el tiempo máximo que un cliente podrá quedar en la cola. en los reportes aparecerá el numero de llamadas contestadas dentro del tiempo definido. Más alto el valor. Valor yes yes = lo agentes que no atenderán una llamada serán puestos en pausa Numero máximo de personas que pueden estar esperando en la cola. Valor 0 Tiempo de descanso de un agente entre una llamada y otra (en segundos) Valor 15 El mismo parámetro de la parte general del archivo se puede configurar por cada cola separadamente. Valor: 4 timeoutpriority En este parámetro se define si se toma en consideración el tiempo de espera definido a nivel de aplicación o a nivel de archivo de configuración.membermacro=macro announce-frequency min-announce-frequency .conf) yes = otra serie de variables serán creadas justo antes de conectar un miembro de la cola con un cliente (véase archivo predefinido queues. Valor 90 Para evitar que cada vez que la posición y/o el tiempo estimado de espera de un cliente cambie se le presente un anuncio.Parámetro Descripción agente si el primero no ha contestado dentro de los 15 segundos definidos en el parámetro anterior.conf) yes = otra serie de variables relacionadas con la cola serán creadas justo antes de conectar un miembro de la cola con un cliente (véase archivo predefinido queues. Se deja comentado Cada cuanto segundos anunciar al cliente en la cola su posición y tiempo estimado de espera. Si hay agentes que atienden más de una cola.conf) Antes de conectar el agente con el cliente se puede ejecutar la macro indicada en este parámetro. Valor app (aplicación) El peso de la cola. más prioridad tendrá la cola. Valor 50 Si se pone 0 no se fijará ningún limite yes = una serie de variables serán creadas justo antes de conectar un miembro de la cola con un cliente (véase archivo predefinido queues. las colas con peso más alto serán atendidas con prioridad respecto a las colas con peso más bajo. este parámetro define un tiempo (en segundos) que se esperará antes de comunicarle su 285 weight wrapuptime autofill autopause maxlen setinterfacevar setqueueentryvar setqueuevar . queue-seconds=queue-seconds .periodic-announce=queue-periodicannounce . Valor 20 A partir de esta linea se pueden personalizar las locuciones predefinidas de la cola de espera.queue-reporthold=queue-reporthold . no.queue-holdtime=queue-holdtime .si la posición del cliente en la cola de espera es más alta del numero especificado en el próximo parámetro.queue-thereare=queue-thereare . u once (una sola vez) Anuncia al cliente su posición en la cola.queue-callswaiting=queue-callswaiting .queue-youarenext=queue-youarenext .queue-thankyou=queue-thankyou . Se deja 286 .queue-minutes=queue-minutes .periodic-announce=anuncio1. Puede ser yes. Se deja comentado Los anuncios pueden ser presentados según un orden aleatorio? Se deja comentado anunciar junto a la posición en la cola el tiempo estimado de espera.anuncio2 en este parámetro se definen los anuncios periódicos personalizados separados por una coma.periodic-announce-frequency=60 Descripción nueva posición/tiempo estimado. . se le anunciará que hay más de “valor del próximo parámetro” clientes esperando en la cola • limit – solo los clientes con una posición en la cola de espera menor o igual al valor del parámetro que sigue. Valores: • yes – si • no – no se le anuncia • more .queue-minute=queue-minute .random-periodic-announce=no announce-holdtime announce-position announce-position-limit announce-round-seconds . Valor 15 Cada cuantos segundos presentar un anuncio personalizado al cliente en la cola de espera. escucharán el anuncio de su posición en la cola de espera 5 Con este parámetro se redondea los minutos y los segundos de espera anunciados al cliente.Parámetro . un agente es considerado no disponible si el estado de su extensión es UNAVAILABLE • invalid .un agente es considerado no disponible si el estado de su extensión es INVALID • unknown – un agente es considerado no disponible si el estado de su extensión es UNKNOWN • wrapup . Puede ser monitor y mixmonitor Este parámetro con el que sigue.invalid. Aquí se define si un cliente puede o no entrar a una cola de espera si no hay agentes disponibles. son: • paused – un agente es considerado no disponible si está en pausa • penalty – un agente es considerado no disponible si el valor de su penalidad es menor al valor asociado a la variable QUEUE_MAX_PENALTY • inuse – un agente es considerado no disponible si el estado de su extensión es INUSE • ringing – un agente es considerado no disponible si su extensión está timbrando • unavailable . son los más importantes en la configuración de la cola. separados por una coma. Valor paused. si todos los agentes se vuelven no disponibles. el cliente será sacado de la cola.unknown 287 . no se grabaran) Se define la aplicación para grabar la conversaciones. Los distintos valores que se pueden utilizar.invalid.Parámetro comentado .un agente es considerado no disponible si está en su tiempo de descanso (wraptime) después de haber atendido una llamada Valor: paused.unavailable.unavailable.unknown monitor-type joinempty leavewhenempty este parámetro aplica a los clientes que ya están en la cola de espera y en base a los valores indicados.monitor-format=gsm|wav|wav49 Descripción formatos audio en que se grabarán las conversaciones de la cola de espera (si se deja comentado. eventwhencalled = yes .conf se añaden las siguientes lineas: [general] persistentmembers=yes autofill=yes monitor-type=mixmonitor updatecdr=no 288 . cuanto tiempo el cliente ha esperado en la cola no = no se envían las llamadas a agentes cuyo estado de la extensión es INUSE tiempo en segundos que el sistema esperará antes de conectar el agente con el cliente.old Se crea uno nuevo: nano /etc/asterisk/queues. el cliente esperará ese tiempo antes de ser conectado con un agente.conf se configuran distintos escenarios para manejar las colas con el sistema de penalidades. Se deja comentado a partir de esta linea se definen los miembros de la cola. En el caso que se haya configurado un escenario para esta cola. Valor 5 yes = el tiempo de espera para que un agente conteste una llamada se resetea si el estado de la extensión es BUSY o CONGESTION en el archivo queuerules.eventmemberstatus = yes reportholdtime ringinuse memberdelay Descripción Estos dos parámetros configurados en yes.Parámetro . La sintaxis es: member => tecnología/extensión. Se renombra el predefinido: mv /etc/asterisk/queues. en este parámetro se define el nombre.penalidad.nombre.conf.conf timeoutrestart .defaultrule=myrule member => Agent/2000 member => Agent/2001 member => Agent/2002 Ahora se guardan los valores de la tabla en el archivo de configuración de las colas. generan una serie de eventos relacionados con la cola en el AMI de Asterisk yes = Se anuncia al agente. De esta forma aunque hayan agentes disponibles. antes de contestar la llamada.conf /etc/asterisk/queues.extensión Se ponen los tres agentes configurados en el archivo agent. eventwhencalled = yes .unknown .unknown leavewhenempty=paused.queue-youarenext=queue-youarenext .periodic-announce-frequency=60 .queue-reporthold=queue-reporthold .invalid.monitor-format=gsm|wav|wav49 monitor-type=mixmonitor joinempty=paused.shared_lastcall=yes [ventas] musicclass=default .queue-thankyou=queue-thankyou .membermacro=macro announce-frequency=90 min-announce-frequency=15 .queue-seconds=queue-seconds .queue-thereare=queue-thereare .random-periodic-announce=no announce-holdtime=once announce-position=more announce-position-limit=5 announce-round-seconds=30 .anuncio2 .unavailable.periodic-announce=anuncio1.queue-minutes=queue-minutes .invalid.announce=queue-ventas strategy=ringall servicelevel=120 context=ventas-exit timeout=15 retry=4 timeoutpriority=app weight=0 wrapuptime=15 autofill=yes autopause=yes maxlen=50 setinterfacevar=yes setqueueentryvar=yes setqueuevar=yes .queue-callswaiting=queue-callswaiting .queue-minute=queue-minute .unavailable.queue-holdtime=queue-holdtime .eventmemberstatus = yes reportholdtime=yes ringinuse=no memberdelay=5 289 . introducida con la versión 1. A:0. 0s talktime).8. cuando la llamada es enviada a un 290 .R) same => n.conf en el contexto internas se ponen las siguientes lineas exten => 3000. or parameters queue remove member Removes a channel from a specified queue queue reset stats Reset statistics for a queue queue set penalty Set penalty for a channel of a specified queue queue show Show status of a specified queue queue {pause|unpause} member Pause or unpause a queue member queue show rules Show the rules defined in queuerules.defaultrule=myrule member => Agent/2000 member => Agent/2001 member => Agent/2002 Se guardan los cambios y se recarga el modulo de la aplicación de las colas en espera: asterisk -rvvvvvvvvvvvvvvvvvvvvv CLI> module reload app_queue.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Unavailable) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet No Callers Con queue show ventas se muestran los datos de las colas.Hangup Con la opción R. queue rules. C:0. W:0.conf CLI> quit Se sale de la consola y se pasa al dialplan: nano /etc/asterisk/extensions. Los comandos asociados a la aplicación queue: CLI> help queue queue add member Add a channel to a specified queue queue reload {parameters|membe Reload queues.1. SL:0.Answer same => n.X de Asterisk.so CLI> queue show ventas ventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime. members.timeoutrestart=yes .Queue(ventas. W:0. C:1. Como no hay agentes disponibles la llamada terminará. Se guardan los cambios y se recarga el dialplan: asterisk -rx "dialplan reload" Desde la extensión 1000 conectada a Asterisk. A:0. W:0. dejará de enviar la musca de espera al cliente y en su lugar el cliente escuchará el tono de timbrado. A:0. 28s talktime). SL:100. C:0.agente. el estado de la cola de espera será: CLI> queue show ventas ventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime. W:0. Cuando el agente (la extensión 1000) reciba la llamada del cliente (la extensión 1001). Una vez conectado se entra a la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvv CLI> queue show ventas ventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime. Ahora desde la extensión 1000 se marca el numero 2000 (para conectarse como agente a las colas de espera). 0s talktime). C:0.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Not in use) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet No Callers El agente 2000 está disponible. SL:0. 0s talktime). Desde la extensión 1001 se marca el numero 3000. se marca la extensión 3000. SL:0.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Not in use) has taken 1 calls (last was 27 secs ago) Agent/2001 (Unavailable) has taken no calls yet No Callers 291 .0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Busy) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet No Callers y al terminar la llamada: CLI> queue show ventas ventas has 0 calls (max 50) in 'ringall' strategy (0s holdtime. A:0. 16.conf en el contexto internas se pone exten => 3001.3 Agentes dinámicos En Asterisk hay dos aplicaciones para añadir y quitar un miembro de una cola. contexto internas. la llamada será enviada al buzón de voz. "ventas") in new stack [Oct 21 16:58:49] WARNING[15270]: app_queue. Se puede crear otro escenario de este tipo: nano /etc/asterisk/extensions.Como se ha visto.Answer same => n. "") in new stack Executing [3001@externas:2] Queue("SIP/1000-00000017". la aplicación addQueueMember es mucho más funcional. "1000@default") in new stack Como no hay agentes disponibles.Hangup De esta forma el llamante tendrá la oportunidad de dejar un mensaje en el buzón de voz. En el plan de llamadas.c:5160 queue_exec: Unable to join queue 'ventas' Executing [3001@externas:3] VoiceMail("SIP/1000-00000017". En el caso de una pequeña empresa que quiera tener un pequeño call center y no quiera que los empleados estén todo el tiempo conectados como agentes sino que puedan desarrollar su normal actividad y al mismo tiempo atender las llamadas de la cola. si no hay agentes disponibles no se deja entrar el cliente a la cola.1.Voicemail(1000@default) same => n. Estas dos aplicaciones son: • AddQueueMember • RemoveQueueMember ¿Cual es la diferencia con la aplicación Agentlogin? La aplicación Agentlogin es pensada para call center de grandes dimensiones. asterisk -rvvvvvvvvvvvv CLI> dialplan reload Desde la extensión 1000 se marca el 3001 (sin agentes conectados). se añaden estos dos bloques: 292 . Como se ha dicho el llamante se envía a la prioridad que sigue. Se guardan los cambios y se recarga el dialplan.Queue(ventas) same => n. Executing [3001@externas:1] Answer("SIP/1000-00000017". SIP/${CALLERID(num)}) same => n.SIP/${CALLERID(num)}) same => n.PauseQueueMember(ventas.1.Playback(beep) same => n. Estas dos aplicaciones se pueden añadir al plan de llamadas de la siguiente forma: exten => *72.1.0. Hay dos aplicaciones más que permiten a los agentes dinámicos ponerse en pausa y no atender las llamadas para luego. los datos del agente deben permanecer en la base de datos.conf exten => *70.Playback(agent-loginok) same => n.Hangup Todos los datos de las conexiones de los agentes dinámicos se guardan en la base de datos interna de Asterisk.nano /etc/asterisk/extensions.Removequeuemember(ventas.1.Playback(agent-loggedoff) same => n.Hangup exten => *71. con el segundo se quitan.SIP/1000. el agente será considerado como no disponible.UnpauseQueueMember(ventas.Playback(beep) same => n. Se guardan los cambios y se recarga el plan de llamadas: asterisk -rvvvvvvvvvvvvv CLI> dialplan reload Ahora desde la extensión 1000 se llama el numero *70 y se mira lo que aparece en la base de datos de Asterisk: CLI> database show /Queue/PersistentMembers/ventas CLI> quit Como en el archivos de las colas de espera se ha configurado el parámetro persistentmembers=yes. después del “descanso” volver a atender la cola. por como se ha configurado la cola. service asterisk restart 293 : SIP/1000.Hangup Con el primer bloque las extensiones se añaden a la cola ventas.Hangup exten => *73. si se reinicia Asterisk.1.SIP/${CALLERID(num)}) same => n. Hay que acordarse que cuando un agente se pone en pausa.0.Addqueuemember(ventas.SIP/1000 .SIP/${CALLERID(num)}) same => n. Para volver activo desde la extensión 1000 se marca el numero *73. A:0.0.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Unavailable) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet SIP/1000 (dynamic) (Not in use) has taken no calls yet No Callers Terminada la prueba se quita la extensión 1000 de la cola de espera llamando desde esa extensión el numero: *71 Se averigua en la base de datos de Asterisk que efectivamente el agente ya no está registrado: CLI> database show Ya no aparece la linea: /Queue/PersistentMembers/ventas : SIP/1000.SIP/1000. SL:100. C:1.SIP/1000 294 .asterisk -rvvvvvvvvvvvvvvvvvvvvvvv CLI> database show /Queue/PersistentMembers/ventas : SIP/1000. W:0. Como el agente dinámico quiere almorzar. Para probarlo desde la extensión 1001 se marca el numero 3001. se pone en pausa marcando el numero *72 Si se mira el estado de la cola: CLI> queue show ventas ventas has 0 calls (max 50) in 'ringall' strategy (2s holdtime.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet Agent/2000 (Unavailable) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet SIP/1000 (dynamic) (paused) (Not in use) has taken no calls yet No Callers Se podrá comprobar que efectivamente el agente dinámico está en pausa.0. 2s talktime).0.0. W:0. El resultado: CLI> queue show ventas ventas has 0 calls (max 50) in 'ringall' strategy (2s holdtime.SIP/1000.SIP/1000 El agente no se ha borrado de la cola de espera. SL:100. A:0. C:1. 2s talktime). 3|NONE|Agent/2000|AGENTLOGIN|SIP/1000-00000003 • AGENTLOGOFF: cuando un agente se desconecta. ADDMEMBER: cuando se añade un agente dinámico a la cola. • Ejemplo: 1323691008|1323691008. Junto al evento aparecerá el nombre de la cola. Junto al evento aparecerá la variable 295 .7|ventas|SIP/1000|ADDMEMBER| • AGENTDUMP: el agente ha rechazado la llamada mientra el cliente estaba escuchando el anuncio de la cola AGENTLOGIN: cuando un agente se conecta utilizando la aplicación Agentlogin. Junto al evento aparecerá la variable UNIQUEID de la llamada. el nombre de la cola a la que se registró el agente y la extensión con la que se registró.4 Estadísticas de las colas Por defecto todas las estadísticas de las colas se guardan en el archivo predefinido queue_log presente en la carpeta /var/log/asterisk. Los eventos que se pueden presentar son: • ABANDON: cuando un cliente abandona la cola sin ser atendido. En el caso que el evento no incluya todos los campos. Entre ellos. Junto al evento aparecerá la variable UNIQUEID de la llamada. El numero del agente y el canal utilizado para el registro. la posición que tenía el cliente cuando abandonó la cola. La mayoría de los programas que permiten obtener gráficos de estas estadísticas. la posición que tenía al momento de entrar en la cola y el tiempo que esperó antes de colgar. • Ejemplo: 1323689794|1323689785. se pueden citar los dos más reconocidos (el primero con una versión Lite gratuita disponible y el segundo comercial) • • Asternic Call Center Stats QueueMetrics ¿Cómo se interpretan los datos presentes en este archivo? Cada linea del archivo puede contener hasta 10 campos distintos separados por un pipe | Estos son: • • • • • • fecha y hora en formado EPOCH identificador único de la llamada nombre de la cola nombre del agente evento que se ha presentado campos de datos (hasta 5) que contienen los valores devueltos por los eventos de la cola.16. en lugar de los datos aparecerá el valor NONE. leen ese archivo. 4|ventas|NONE|ENTERQUEUE||1001 • EXITEMPTY: cuando un cliente viene desconectado de la cola porque no hay agentes disponibles. posición inicial y final del cliente en la cola. el nombre de la cola. la extensión del agente. el tiempo que esperó el cliente antes de ser atendido.2|ventas|SIP/1000|COMPLETECALLER|16|27|1 • CONFIGRELOAD: cuando se recarga la configuración de Asterisk. Junto al evento aparecerá la variable UNIQUEID.4|ventas|Agent/2000|CONNECT|9|1323690653. el nombre de la cola. el nombre de la cola. el tiempo que ha esperado el cliente antes de ser atendido. la extensión del agente que ha atendido el cliente. Ejemplo: 1323689825|1323689785.17|ventas|NONE|EXITEMPTY|1|1|38 • EXITWITHKEY: el cliente mientras esperaba en la cola ha presionado una tecla. 296 . la extensión del agente. el canal utilizado cuando se registró y el tiempo en segundos que ha quedado conectado. Ejemplo: 1323690662|1323690653. Junto al evento aparecerá .5|0 • ENTERQUEUE: cuando un cliente entra en la cola.3|NONE|Agent/2000|AGENTLOGOFF|SIP/1000-00000003|31 • COMPLETEAGENT: cuando un agente que ha atendido una llamada cuelga. la URLsi aplica y el CALLERID del cliente. Junto al evento aparecerá. el nombre de la cola. Ejemplo: 1323690653|1323690653. Junto al evento aparecerá el UNIQUEID de la llamada. la variable UNIQUEID. el UNIQUEID de la llamada entre cliente y agente. el nombre de cola. el UNIQUEID de la llamada. el nombre de la cola. y la posición del cliente en la cola antes de presionar la tecla.UNIQUEID de la llamada. y el tiempo que timbró la extensión del agente. Junto al evento aparecerá el UNIQUEID de la llamada. el UNIQUEID de la llamada del cliente. el numero del agente. Ejemplo: 1323695800|1323694274.4|ventas|Agent/2000|COMPLETEAGENT|9|50|1 • COMPLETECALLER: cuando un cliente atendido por un agente cuelga la llamada. Ejemplo: 1323690712|1323690653. Junto al evento aparecerá. la duración de la llamada y la posición que tenía el cliente al entrar en la cola. Ejemplo: 1323710320|1323710281. y el tiempo que ha esperado en la cola antes de ser desconectado. Ejemplo: 1323531449|NONE|NONE|NONE|CONFIGRELOAD| • CONNECT: cuando un cliente es atendido por un agente. la duración de la llamada y la posición inicial que tenía el cliente al entrar en la cola. el tiempo que esperó el cliente antes de ser atendido. el numero de la tecla presionada (en este caso 8). Junto al evento aparecerá el nombre de la cola y la extensión del agente. Junto al evento aparecerá el UNIQUEID de la llamada. el tiempo de duración de la llamada entes de la transferencia y la posición del cliente al entrar en la cola. el nombre de la cola y la extensión del agente. el nombre de la cola. Junto al evento aparecerá el UNIQUEID de la llamada. y el tiempo que éste ha esperado antes de ser desconectado PAUSE: cuando un agente se pone en pausa utilizando la aplicación PauseQueueMember de Asterisk. • Ejemplo: 1323712663|1323712627.Ejemplo: 1323710850|1323710844.23|ventas|NONE|EXITWITHKEY|8|1 • EXITWITHTIMEOUT: el cliente ha sido desconectado de la cola porque después del tiempo máximo permitido de espera. atendido por un agente. Junto al evento aparecerá el UNIQUEID de la llamada. RINGNOANSWER: cuando la extensión de un agente timbra y al agente no contesta dentro del tiempo configurado.31|ventas|SIP/1000|RINGNOANSWER|45000 • SYSCOMPAT: la llamada ha sido contestada por un agente pero ha terminado porque los dos canales (cliente y agente) no eran compatibles. Junto al evento aparecerá el UNIQUEID de la llamada. la posición final y inicial del cliente en la cola. el nombre de la cola. Junto al evento aparecerá el nombre de la cola y la extensión del agente. aparecerá también el valor Auto-Pause • Ejemplo1: 1323712960|NONE|ventas|SIP/1000|PAUSE| Ejemplo2: 1323710541|NONE|ventas|SIP/1000|PAUSE|Auto-Pause • QUEUESTART: cuando Asterisk ha sido reiniciado Ejemplo: 1323447241|NONE|NONE|NONE|QUEUESTART| • REMOVEMEMBER: cuando una agente se desconecta de la cola con la aplicación Removequeuemember. la extensión del agente que no ha contestado la llamada y el tiempo (en milisegundos) que ha timbrado la extensión del agente: • Ejemplo: 1323711528|1323711480. ningún agente lo ha atendido. 297 . Si el agente ha sido desconectado de la cola porque no ha atendido una llamada antes del tiempo configurado. el contexto utilizado para la transferencia. el numero de la extensión donde ha sido transferida la llamada. el nombre de la cola. la extensión del agente que ha atendido la llamada. el tiempo que ha esperado el cliente en la cola.34|ventas|SIP/1000|TRANSFER|1002|externas|12|24|1 • UNPAUSE: cuando un agente vuelve a conectarse a la cola utilizando la aplicación UnpauseQueueMember. TRANSFER: cuando el cliente. ha sido transferido a otra extensión. `setinterfacevar` varchar(3) default NULL. En esta tabla se pueden configurar todos los valores presentes para la definición de la cola. `penaltymemberslimit` int(11) default NULL. `timeoutpriority` varchar(128) default NULL. `announce` varchar(128) default NULL. `announce-frequency` int(11) default NULL. las conferencias. `timeout` int(11) default NULL. Se inicia con la configuración de las colas. 298 . también para las colas es posible trabajar en Realtime. agentes y estadísticas en Realtime dinámico Como para las extensiones. `setqueueentryvar` varchar(3) default NULL. `retry` int(11) default NULL. `setqueuevar` varchar(3) default NULL. `membermacro` varchar(128) default NULL. `wrapuptime` int(11) default NULL. `autofill` varchar(128) default NULL. `autopause` varchar(128) default NULL. una para cada tipo de objectos que se guardarán. `maxlen` int(11) default NULL. hay que crear tres tablas distintas. `musiconhold` varchar(128) default NULL. `strategy` varchar(128) default NULL. `servicelevel` int(11) default NULL. aunque el único obligatorio es el nombre de la cola misma. se entra en MySQL mysql -u root -psesamo se escoge la base de datos asterisk: mysql> use asterisk se crea la tabla para las colas: mysql> CREATE TABLE `queue_table` ( `name` varchar(128) NOT NULL. En este caso se puede guardar en Realtime: • • • la configuración de las colas los agentes las estadísticas de la cola Como queda claro por lo arriba mencionado. `context` varchar(128) default NULL. los buzones de voz. `weight` int(11) default NULL.5 Colas.16. interface varchar(128). `announce-position` varchar(3) default NULL. `timeoutrestart` varchar(128) default NULL. `random-periodic-announce` varchar(3) default NULL. queue_name varchar(128). interface) ). `monitor-type` varchar(128) default NULL. `periodic-announce` varchar(512) default NULL. `queue-holdtime` varchar(128) default NULL. membername varchar(40).`min-announce-frequency` int(11) default NULL. `queue-minutes` varchar(128) default NULL. `defaultrule` varchar(128) default NULL. `relative-periodic-announce` varchar(3) default NULL. `reportholdtime` varchar(128) default NULL. `eventwhencalled` varchar(128) default NULL. `ringinuse` varchar(3) default NULL. `announce-holdtime` varchar(4) default NULL. `joinempty` varchar(128) default NULL. Se crea la tabla para los agentes de las colas: mysql> CREATE TABLE queue_member_table ( uniqueid INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT. `queue-callswaiting` varchar(128) default NULL. `queue-thereare` varchar(128) default NULL. `leavewhenempty` varchar(128) default NULL. `queue-seconds` varchar(128) default NULL. paused INT(11). `queue-youarenext` varchar(128) default NULL. `periodic-announce-frequency` int(11) default NULL. PRIMARY KEY (`name`) ). `queue-reporthold` varchar(128) default NULL. `queue-thankyou` varchar(128) default NULL. `monitor-format` varchar(128) default NULL. `eventmemberstatus` varchar(128) default NULL. `memberdelay` int(11) default NULL. penalty INT(11). `announce-round-seconds` int(11) default NULL. `queue-minute` varchar(128) default NULL. `announce-position-limit` int(11) default NULL. UNIQUE KEY queue_interface (queue_name. y por ultimo se crea la tabla para guardar las estadísticas de las colas: mysql> CREATE TABLE queue_log ( 299 . index bydate (time).data1. queuename char(50). data3 char(50).asterisk. event char(20). El resultado en la base de datos: mysql -u root -psesamo mysql> use asterisk mysql> select time. data1 char(50). desde la extensión 1000 se marca *70 para conectarse a la cola ventas como agente dinámico y luego desde las demás extensiones se marca el 3001.queue_member_table queue_log => odbc.asterisk.queue_members => odbc.queuename. index qname (queuename.asterisk .time) ).agent.queues => odbc. data5 char(50).queue_table queue_members => odbc.asterisk . data4 char(50). callid char(50). agent char(50).time datetime.asterisk. El resultado: 300 .event.queue_log Se guardan los cambios y se reinicia Asterisk: service asterisk restart Ahora para probar el log de las colas en realtime. data2 char(50).data3 from queue_log.queue_log => mysql.data2. Se sale de MySQL y se modifica el archivo del realtime: mysql> quit nano /etc/asterisk/extconfig.conf se modifican estas tres lineas: .genera para que queden: queues => odbc. Desde Webmin se entra a la tabla queue_table y se rellenan los campos: 301 .Se sale del cliente MySQL: mysql> quit Como segunda prueba se crea otra cola en realtime. 302 . 303 . W:1. C:0. A:0. SL:0.Se guarda la configuración presionando el botón “Save”. 0s talktime). Desde el Webmin se pasa a la tabla queue_member_table y se añaden dos agentes a la cola creada: 304 .0% within 120s No Members No Callers que todavía no tienes agentes configurados. Se vuelve a la consola de Asterisk donde aparecerá la nueva cola: CLI> queue show compras compras has 0 calls (max 50) in 'ringall' strategy (0s holdtime. SL:0. 10s talktime). Una vez conectado en la consola de Asterisk: CLI> queue show compras has 0 calls (max 50) in 'ringall' strategy (0s holdtime. SL:100. W:1. A:0. A:1. 0s talktime). A:0.0% within 120s Members: Fulamo (Agent/2000) (realtime) (Unavailable) has taken no calls yet Sutano (Agent/2001) (realtime) (Unavailable) has taken no calls yet No Callers Para terminar si desde la extensión 1000 se marca 2000 para conectarse como agente 2000. C:4. C:0.0% within 120s Members: Agent/2002 (Unavailable) has taken no calls yet 305 .0% within 120s Members: Fulamo (Agent/2000) (realtime) (Not in use) has taken no calls yet Sutano (Agent/2001) (realtime) (Unavailable) has taken no calls yet No Callers ventas has 0 calls (max 50) in 'ringall' strategy (14s holdtime. W:0.Se vuelve nuevamente a la consola de Asterisk: CLI> queue show compras compras has 0 calls (max 50) in 'ringall' strategy (0s holdtime. SL:0. 0s talktime). W:1. C:0. Agent/2000 (Not in use) has taken no calls yet Agent/2001 (Unavailable) has taken no calls yet SIP/1000 (dynamic) (In use) has taken 4 calls (last was 9443 secs ago) No Callers El agente estará conectado a las dos colas creadas (en negrita). 306 . . Capitulo XVII Asterisk y los FAX Hasta la versión 1.0 Se compila: .2.tar.tar. En este capitulo se presentará primero una solución basada en la combinación del programa IAXmodem con el servidor de FAX Hylafax. Estos dos módulos se apoyan en las librerías SpanDSP y permiten la recepción y envío de FAX a través de dos protocolos: T30 (audio) y T38 (FoIP – Fax over IP).dl.8.X.2.6.2.gz Se descomprime el archivo tar -xf iaxmodem-1.sourceforge./configure make Se copia el programa compilado en la siguiente carpeta: cp iaxmodem /usr/local/sbin Como se van a crear dos módem IAX2.0.X hay dos nuevos módulos: • • res_fax res_fax_spandsp La idea detrás de este cambio es mejorar el soporte del protocolo T38 en Asterisk.gz Se entra en la carpeta: cd iaxmodem-1. Asterisk soportaba la recepción y trasmisión de FAX a través del modulo app_fax. se crean algunas carpetas y archivos para el correcto funcionamiento de IAXmodem: . escrito en lenguaje C que utiliza un canal IAX2 en lugar de una línea telefónica y un DSP software (SpanDSP) en lugar de un chip DSP (Digital Signal Processing). para luego abordar el tema del protocolo T38.1 IAXmodem IAXmodem es un módem software.0. A partir de la versión 1.net/sourceforge/iaxmodem/iaxmodem-1. 17.2. Se descargan las fuentes de IAXmodem: cd /usr/src wget http://switch. IMPORTANTE: en la linea codec hay que indicar un codec audio que no utilice algoritmos de compresión. en port el puerto y en peername el nombre de la troncal.0. En el caso de dos servidores distintos hay que indicar en la línea server la dirección IP del servidor Asterisk. Para el segundo IAXmodem la configuración será: nano ttyIAX2 309 . Se pone la contraseña en secret y en cidname y cidnumber nombre y numero telefónico que usará IAXmodem para presentarse a Asterisk. Esto porque el protocolo T30 funciona solamente con canales audio no comprimidos.mkdir /etc/iaxmodem mkdir /var/log/iaxmodem touch /var/log/iaxmodem/ttyIAX1 touch /var/log/iaxmodem/ttyIAX2 touch /var/log/iaxmodem/iaxmodem En la carpeta de las fuentes de IAXmodem hay un archivo de configuración predefinido para la creación de un módem IAX. Se configura el primero cd /etc/iaxmodem nano ttyIAX1 La lineas son: device /dev/ttyIAX1 owner uucp:uucp mode 660 port 4570 refresh 60 server 127.0. Esta configuración es valida si IAXmodem está instalado en el mismo servidor donde se instaló Asterisk.1 peername iaxmodem1 secret pbx5050 cidname VozToVoice cidnumber XXXXXXXXXX codec alaw Se guardan los cambios. Para configurar distintos IAXmodem hay que modificar en la primera línea el nombre del device. Se puede tomar como referencia para la creación de los dos módem IAX que se utilizarán para la recepción y envío de FAX con Asterisk. 0.0. Ahora hay que modificar la configuración de Asterisk para añadir las dos extensiones IAX (iaxmodem1 y iaxmodem2) en el archivo iax.conf nano /etc/asterisk/iax.1 peername iaxmodem2 secret pbx5051 cidname VozToVoice cidnumber XXXXXXXXXX codec alaw Se guardan los cambios.conf Al final del archivo se añaden los dos bloques que siguen: [iaxmodem1] type=friend context=fax disallow=all allow=alaw username=iaxmodem1 secret=pbx5050 qualify=yes notransfer=yes host=dynamic requirecalltoken=auto [iaxmodem2] type=friend context=fax disallow=all allow=alaw username=iaxmodem2 secret=pbx5051 qualify=yes notransfer=yes host=dynamic requirecalltoken=auto Se guardan los cambios y se actualiza la configuración de IAX2 en Asterisk 310 .device /dev/ttyIAX2 owner uucp:uucp mode 660 port 4571 refresh 60 server 127. asterisk -rvvvvvvvvvvvvvvvvvvv CLI> iax2 reload Se abre otra ventana terminal o se crea otra sesión de PuTTy y se hace una prueba para ver si la conexión entre IAXmodem y Asterisk funciona: cd /usr/local/sbin .0 mv iaxmodem.d/iaxmodem 311 .fedora /etc/init.1' [2011-10-24 09:44:37] Setting peername = 'iaxmodem1' [2011-10-24 09:44:37] Setting secret = 'pbx5050' [2011-10-24 09:44:37] Setting cidname = 'VozToVoice' [2011-10-24 09:44:37] Setting cidnumber = 'XXXXXXXX' [2011-10-24 09:44:37] Setting codec = ulaw [2011-10-24 09:44:37] Opened pty.0./iaxmodem ttyIAX1 debe aparecer: [2011-10-24 09:44:37] Modem started [2011-10-24 09:44:37] Setting device = '/dev/ttyIAX1' [2011-10-24 09:44:37] Setting owner = 'uucp:uucp' [2011-10-24 09:44:37] Setting mode = '660' [2011-10-24 09:44:37] Setting port = 4570 [2011-10-24 09:44:37] Setting refresh = 60 [2011-10-24 09:44:37] Setting server = '127. Se controla que en la consola de Asterisk aparezca la conexión de IAXmodem (volviendo a la otra ventana Terminal abierta): Para iniciar IAXmodem en automático se instala el script presente en la carpeta de las fuentes de IAXmodem: cd /usr/src/iaxmodem-1.d/iaxmodem se vuelve ejecutable: chmod +x /etc/init.0. slave device: /dev/pts/4 [2011-10-24 09:44:37] Created /dev/ttyIAX1 symbolic link Ignoring unknown information element 'Unknown IE' (54) of length 0 [2011-10-24 09:44:37] Registration completed successfully.2.init. 0.0.255.org/binary/linux/redhat/6.1 (D) 255.255.255.255.5-1rhel5.hylafax.hylafax.0.rpm 312 .0.rpm wget ftp://ftp.255 4570 (E) OK (1 ms) iaxmodem2/iaxmo 127.255 4571 (E) OK (3 ms) 4 iax2 peers [3 online. las dos extensiones deben estar registradas: CLI> iax2 show peers Name/Username Host Mask Port Status marko (Unspecified) (D) 255.162.255.206 (D) 255.255 13269 (E) OK (102 ms) iaxmodem1/iaxmo 127.255.255 0 (E) UNKNOWN marko2/marko2 190.0.5/hylafax-server-6. 1 offline.rpm Se instalan: rpm -ivh hylafax*.i386.0.255. 0 unmonitored] Ahora que IAXmodem ha sido instalado y configurado.253.0. 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.5-1rhel5. 17.0.255.d/iaxmodem start Volviendo a la consola de Asterisk.5/hylafax-client-6.2 Hylafax Hylafax es un servidor FAX diseñado para sistemas Linux que se basa en un sistema cliente-servidor. se puede continuar con la instalación y configuración de Hylafax.1 (D) 255.e se configura para el inicio automático: chkconfig --add iaxmodem chkconfig iaxmodem on Se inicia el programa: /etc/init.i386.org/binary/linux/redhat/6. El paso a seguir es la configuración de de Hylafax. Hay que indicar los parámetros como aparecen personalizando el numero de teléfono y el prefijo del país. En negrita los datos que se van insertando desde el teclado. HylaFAX configuration parameters are: [1] Init script starts faxq: [2] Init script starts hfaxd [3] Start paging protocol: Are these ok [yes]? yes yes yes no Se contesta yes.modem. creating one from scratch. Esto se hace a través de la utilidad faxsetup: faxsetup Should an entry be added for the FaxMaster to /etc/aliases [yes]? no Update /var/spool/hylafax/status/any.cache. Modem support functions written to /var/spool/hylafax/etc/setup.info. No scheduler config file exists. Configuration parameters written to /var/spool/hylafax/etc/setup. Luego inicia la configuración de Hylafax. Country code [1]? 57 Area code []? 5 Long distance dialing prefix [1]? 0 International dialing prefix [011]? 00 Dial 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"]? 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: CountryCode: 57 AreaCode: 5 LongDistancePrefix: 0 InternationalPrefix: 00 313 . d/hylafax start Starting HylaFAX queue manager (faxq): [ OK ] Starting HylaFAX server (hfaxd): [ OK ] Restarting HylaFAX modem manager (faxgetty): [ OK ] You do not appear to have any modems configured for use.Are these ok [yes]? yes Creating new configuration file /var/spool/hylafax/etc/config. let's do this from scratch. Country code [57]? Area code [5]? Phone number of fax modem [+1. Also be aware that at any time you can safely interrupt this procedure. Modems are configured for use with HylaFAX with the faxaddmodem(8C) command. time to setup a configuration file for the modem..d/init. The manual page config(5F) may be useful during this process. No existing configuration. Should I restart the HylaFAX server processes [yes]? yes /etc/rc.. Reading scheduler config file /var/spool/hylafax/etc/config.555. Desde la linea que sigue se configura el primer FAX (ttyIAX1) Do you want to run faxaddmodem to configure a modem [yes]? yes Serial port that modem is connected to []? ttyIAX1 Ok. Restarting HylaFAX server processes.999.1212]? +5753850962 Local identification string (for TSI/CIG) ["NothingSetup"]? CursoAsterisk Long distance dialing prefix [1]? 0 International dialing prefix [011]? 00 Dial 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 ttyIAX1 [0600]? Rings to wait before answering [1]? 2 Modem 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) [""]? 314 . Note that if you do not have the modem cabled to the port.pcf TagLineFormat: "From %%l|%c|Page %%P of %%T" MaxRecvPages: 25 Are these ok [yes]? yes Now we are going to probe the tty port to figure out the type of modem that is attached. 315 . however. One class isn't inherently better than another. This takes a few seconds. or whatever). or the modem is turned off.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]? 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 [""]? The non-default server configuration parameters are: CountryCode: 57 AreaCode: 5 FAXNumber: +5753850962 LongDistancePrefix: 0 InternationalPrefix: 00 DialStringRules: etc/dialrules SessionTracing: 11 RingsBeforeAnswer: 2 SpeakerVolume: off GettyArgs: "-h %l dx_%s" LocalIdentifier: CursoAsterisk TagLineFont: etc/lutRS18. this may hang (just go and cable up the modem or turn it on. one probably will suit a user's needs better than others. so be patient. Probing for best speed to talk to modem: 38400 OK. About fax classes: The difference between fax classes has to do with how HylaFAX interacts with the modem and the fax protocol features that are used when sending or receiving faxes. 0 implementations. There is no prototype configuration file for your modem.. Class 1.0 is similar to Class 1 but may add V.. How should it be configured [1. You can use this facility to supply null parameters as "".ttyIAX1" after completing this procedure.0 and 1. In case you are uncertain of the meaning of a configuration parameter you should consult the config(5F) manual page for an explanation.0]? 316 . HylaFAX generally will have more features when using Class 1/1.0 but adds V.34-fax capability. Note also that quote marks (") will not be displayed and will automatically be deleted.1 will require the modem manufacturer to resolve it.0 modem. Class 2.0 than when using most modems' Class 2 or Class 2.0 is similar to Class 2 but may include more features.0]? Hmm. Using prototype configuration file class1.0 can be resolved by modifications to HylaFAX. If you prefer to use your favorite editor instead of this script you should fill things in here as best you can and then edit the configuration file "/var/spool/hylafax/etc/config. Note that modem commands must be specified exactly as they are to be sent to the modem. Other information (ATI3) is "www. Class 2 relies on the modem to perform the bulk of the fax protocol.soft-switch.Class 1 relies on HylaFAX to perform the bulk of the fax protocol.34-fax capability. DTE-DCE flow control scheme [default]? Modem manufacturer is "Unknown". so we will have to fill in the appropriate parameters by hand.0. Finally. Use Class 1 unless you have a good reason not to.0/2. beware that the set of parameters is long. Generally any problems encountered in Class 1/1. Command to enter Class 1 [AT+FCLASS=1. You will need the manual for how to program your modem to do this task. Class 2.1 is similar to Class 2. but usually any problems encountered in Class 2/2. Modem model is "Unknown". This modem looks to have support for Class 1.org". this looks like a Class 1. Product code (ATI0) is "spandsp". Country code [57]? Area code [5]? Phone number of fax modem [+1. let's do this from scratch. The manual page config(5F) may be useful during this process.. Se contesta con yes y se configura el segundo módem (ttyIAX2) Do you want to run faxaddmodem to configure another modem [yes]? yes Serial port that modem is connected to []? ttyIAX2 Ok.1212]? +5753850962 317 . No existing configuration. Reading scheduler config file /var/spool/hylafax/etc/config.Command to stop and wait prior to sending PPM [AT+FTS=7]? Command to stop and wait prior to sending TCF [AT+FTS=7]? Command to stop and wait prior to sending EOP [AT+FTS=9]? Extra bytes in a received HDLC frame [4]? Maximum time to wait for OK after aborting a receive (ms) [200]? Maximum wait for initial identification frame (ms) [40000]? Command to ensure silence after receiving HDLC and before sending [AT+FRS=7]? The modem configuration parameters are: Class1Cmd: AT+FCLASS=1.. el servidor Hyalafax preguntará si se quiere instalar otro.999... time to setup a configuration file for the modem.555.saving current file as /var/spool/hylafax/etc/config.0 Class1PPMWaitCmd: AT+FTS=7 Class1TCFWaitCmd: AT+FTS=7 Class1EOPWaitCmd: AT+FTS=9 Class1FrameOverhead: 4 Class1RecvAbortOK: 200 Class1RecvIdentTimer: 40000 Class1SwitchingCmd: AT+FRS=7 Class1TCFMaxNonZero: 10 Class1TCFMinRun: 1000 Are these ok [yes]? yes Creating new configuration file /var/spool/hylafax/etc/config. Terminada la configuración del primer módem. Don't forget to run faxmodem(8C) (if you have a send-only environment) or configure init to run faxgetty on ttyIAX1. .sav. Also be aware that at any time you can safely interrupt this procedure. Local identification string (for TSI/CIG) ["NothingSetup"]? CursoAsterisk Long distance dialing prefix [1]? 0 International dialing prefix [011]? 00 Dial 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 ttyIAX2 [0600]? Rings to wait before answering [1]? 2 Modem 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]? 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 [""]? The non-default server configuration parameters are: CountryCode: 57 AreaCode: 5 FAXNumber: +5753850962 LongDistancePrefix: 0 InternationalPrefix: 00 DialStringRules: etc/dialrules SessionTracing: 11 RingsBeforeAnswer: 2 SpeakerVolume: off GettyArgs: "-h %l dx_%s" LocalIdentifier: CursoAsterisk TagLineFont: etc/lutRS18.pcf TagLineFormat: "From %%l|%c|Page %%P of %%T" MaxRecvPages: 25 Are these ok [yes]? yes Now we are going to probe the tty port to figure out the type 318 . 1 will require the modem manufacturer to resolve it. There is no prototype configuration file for your modem. Product code (ATI0) is "spandsp". this may hang (just go and cable up the modem or turn it on.0 modem.34-fax capability.org". Probing for best speed to talk to modem: 38400 OK. One class isn't inherently better than another. Use Class 1 unless you have a good reason not to.0 than when using most modems' Class 2 or Class 2. How should it be configured [1.of modem that is attached.soft-switch.1 is similar to Class 2. This modem looks to have support for Class 1..0/2. Using prototype configuration file class1. In case you are uncertain of the meaning of a configuration parameter you should consult the config(5F) manual page for an explanation. 319 . however. Class 2.34-fax capability. Other information (ATI3) is "www.0 is similar to Class 2 but may include more features. HylaFAX generally will have more features when using Class 1/1. one probably will suit a user's needs better than others. DTE-DCE flow control scheme [default]? Modem manufacturer is "Unknown". but usually any problems encountered in Class 2/2. Generally any problems encountered in Class 1/1. Note that if you do not have the modem cabled to the port.0 and 1. or whatever). this looks like a Class 1. This takes a few seconds. or the modem is turned off.0 implementations. Class 2 relies on the modem to perform the bulk of the fax protocol.0. so be patient. Class 2. Modem model is "Unknown". Class 1 relies on HylaFAX to perform the bulk of the fax protocol.0 is similar to Class 1 but may add V.0]? Hmm. You will need the manual for how to program your modem to do this task. About fax classes: The difference between fax classes has to do with how HylaFAX interacts with the modem and the fax protocol features that are used when sending or receiving faxes. so we will have to fill in the appropriate parameters by hand..0 can be resolved by modifications to HylaFAX. Class 1.0 but adds V. ttyIAX2 for faxgetty. You can use this facility to supply null parameters as "". Don't forget to run faxmodem(8C) (if you have a send-only environment) or configure init to run faxgetty on ttyIAX2.. 320 . Finally. If you prefer to use your favorite editor instead of this script you should fill things in here as best you can and then edit the configuration file "/var/spool/hylafax/etc/config. Command to enter Class 1 [AT+FCLASS=1.. .. Note also that quote marks (") will not be displayed and will automatically be deleted.ttyIAX2" after completing this procedure...0]? Command to stop and wait prior to sending PPM [AT+FTS=7]? Command to stop and wait prior to sending TCF [AT+FTS=7]? Command to stop and wait prior to sending EOP [AT+FTS=9]? Extra bytes in a received HDLC frame [4]? Maximum time to wait for OK after aborting a receive (ms) [200]? Maximum wait for initial identification frame (ms) [40000]? Command to ensure silence after receiving HDLC and before sending [AT+FRS=7]? The modem configuration parameters are: Class1Cmd: AT+FCLASS=1. Checking /var/spool/hylafax/etc/config for consistency.0 Class1PPMWaitCmd: AT+FTS=7 Class1TCFWaitCmd: AT+FTS=7 Class1EOPWaitCmd: AT+FTS=9 Class1FrameOverhead: 4 Class1RecvAbortOK: 200 Class1RecvIdentTimer: 40000 Class1SwitchingCmd: AT+FRS=7 Class1TCFMaxNonZero: 10 Class1TCFMinRun: 1000 Are these ok [yes]? yes Creating new configuration file /var/spool/hylafax/etc/config.Note that modem commands must be specified exactly as they are to be sent to the modem. Creating fifo /var/spool/hylafax/FIFO....ttyIAX2. beware that the set of parameters is long. Done setting up the modem configuration. leaving existing file unchanged. done.everything looks ok. Ahora se configura faxgetty en el archivo inittab de forma que la utilidad se inicie al arrancar el servidor Linux: nano /etc/inittab después de esta linea: #6:2345:respawn:/sbin/mingetty tty6 se pone: fax1:2345:respawn:/usr/sbin/faxgetty ttyIAX1 fax2:2345:respawn:/usr/sbin/faxgetty ttyIAX2 Se guardan los cambios y se recarga la configuración de inittab: init q Se averigua que faxgetty este corriendo para los dos FAX: ps aux | grep ttyIAX 321 . El servidor de FAX avisará que para que las llamadas sean contestadas en automático hay que configurar faxgetty (la utilidad que se encarga de esta tarea) y si se quiere iniciar faxmodem para los dos FAX configurados (se contesta yes): You do not appear to be using faxgetty to notify the HylaFAX scheduler about new modems and/or their status. This means that you must use the faxmodem program to inform the new faxq process about the modems you want to have scheduled by HylaFAX. Should I run faxmodem for each configured modem [yes]? yes /usr/sbin/faxmodem ttyIAX1 /usr/sbin/faxmodem ttyIAX2 Done verifying system setup. Beware that if you have modems that require non-default capabilities specified to faxmodem then you should read faxmodem(8C) manual page and do this work yourself (since this script is not intelligent enough to automatically figure out the modem capabilities and supply the appropriate arguments).Hylafax preguntará si se quiere configurar otro módem: Do you want to run faxaddmodem to configure another modem [yes]? no Se contesta no. La configuración de los dos módem ha terminado. conf 322 . se intentará reajustarla: nano /var/spool/hylafax/etc/config.members.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 ] Shutting down HylaFAX queue manager (faxq): [ OK ] Todos los archivos de configuración que se crearán a lo largo del proceso de configuración de Hylafax se guardaran en las carpeta /var/spool/hylafax/etc y /etc/hylafax Para controlar el estado de Hylafax y de los FAX configurados se usa este comando: faxstat El resultado es: HylaFAX scheduler on li370-135.Se reinicia Hylafax /etc/init.ttyIAX1 al final del archivo se añade esta linea: Class1SwitchingCmd: "<delay:7>" Lo mismo se hace con el módem ttyIAX2: nano /var/spool/hylafax/etc/config.linode. se añade un pequeño retraso en la configuración de los módem de forma que si se pierde la conexión.ttyIAX2 al final del archivo se añade esta linea: Class1SwitchingCmd: "<delay:7>" Para recibir una notificación si el fax ha sido enviado hay que modificar el archivo de configuración de Hylafax (la recibirá el usuario root): nano /etc/hylafax/hyla.com: Running Modem ttyIAX2 (+5753850962): Running and idle Modem ttyIAX1 (+5753850962): Running and idle Para mejorar la recepción y envío de los FAX. conf) antes del contexto internas.conf un contesto [fax] (El mismo que se ha configurado para las dos extensiones iaxmodem en iax.com Se reinicia Hylafax: /etc/init.d/hylafax restart Por ultimo se indica que todos los mensajes de correo electrónico para el usuario Faxmaster se envíen al usuario root: nano /etc/aliases después de esta linea: support: postmaster se pone: FaxMaster: root Se guardan los cambios y se recarga la configuración: newaliases Prueba envío. Para el envío de los FAX se crea en extension.si cambia esta linea: #Notify: Done para que quede Notify: Done Para recibir los FAX entrantes a una dirección de correo electrónico externa al servidor: nano /var/spool/hylafax/etc/FaxDispatch se cambia esta linea: SENDTO=FaxMaster para que quede (personalizar la dirección de correo electrónico): SENDTO=fulano@gmail. con las siguientes líneas: 323 . esto significa que si el sistema detecta que la llamada está llegando desde un FAX.Answer same => n. Por eso se hace esta prueba. Hay que tener en cuenta que cuanto se trabaja con pura lineas VoIP el envío y la recepción de los FAX no siempre funciona bien. En este caso con el módem ttyIAX1 se enviará el FAX y con el módem ttyIAX2 se recibirá.Dial(IAX2/iaxmodem2) same => n. sino se llamará la extensión 1000. a la extensión fax. Para probarlo.1.nano /etc/asterisk/extensions. si existe.hangup El primer bloque es para enviar FAX a números externos.1.45) exten => fax. automáticamente “saltará”. sendfax -h ttyIAX1@localhost -n -d numerolocal /tmp/pruebafax.d/asterisk reload Para enviar un fax con el cliente Hylafax la sintaxis es: sendfax -h modem -n -d <faxnumber> <file.1..txt y se pone: Libro Asterisk 1.conf. Si procede de un fax se va a la extensión fax.Dial(SIP/1000.Dial(SIP/justvoip/${EXTEN}) same => n.Wait(6) same => n. en el mismo contexto fax se añade otro bloque: exten => 1235.txt 324 .Hangup exten => 1234. En la parte general del archivo sip. se ha configurado el parámetro faxdetect en yes.X Nombre Apellido Se guardan los cambios.Dial(IAX2/iaxmodem2) same => n. prioridad 1 donde se contestará con el modem FAX iaxmodem2. se esperan 4 segundos para permitir a Asterisk reconocer si la llamada procede de un fax.8.conf [fax] exten => _X. Se guardan los cambios y actualiza el dialplan: /etc/init.1. el segundo es para probar el fax en local.txt> Se crea el archivo de texto que se enviará: nano /tmp/pruebafax.hangup El flujo del dialplan es: se contesta la llamada entrante. com: Running Modem ttyIAX2 (+5753850962): Running and idle Modem ttyIAX1 (+5753850962): Initializing server JID Pri S Owner Number Pages Dials TTS Status 1 127 R root 1234 0:1 0:12 Se entra en la consola de Asterisk y se mira que aparece: asterisk -rvvvvvvvvvvvvv cuando termine la llamada se sale de la consola: 325 .b=#] [-V #] files.members. Si sale este error: Usage: /usr/sbin/textfmt [-1] [-2] [-B] [-c] [-D] [-f fontname] [-F fontdir(s)] [-m N] [-o #] [-p #] [-r] [-U] [-Ml=#. el comando fue "/usr/sbin/textfmt -B -f CourierBold -Ml=0.txt request id is 1 (group id 1) for host localhost (1 file) Se puede controlar el estado del envío con el siguiente comando: faxstat -s HylaFAX scheduler on li374-112.t=#.70/Resource/Init/Fontmap. >out. /NimbusMonL-Bold . Se guardan los cambios y se vuelve a enviar el fax: sendfax -h ttyIAX1@localhost -n -d 1234 /tmp/pruebafax..linode.txt'" es porque hay un problema con los fonts de Ghostscrpt..pfa) . Para solucionarlo se abre el siguiente archivo: nano /usr/share/ghostscript/8.Utilizando el numero local sería: sendfax -h ttyIAX1@localhost -n -d 1234 /tmp/pruebafax.txt En lugar de “numerolocal” se pone el numero definido en el contexto [fax] para la prueba en local.GS y se modifica la linea 92: /Courier-Bold Para que quede: /Courier-Bold (n022004l.r=#.ps Default options: -f Courier -1 -p 11bp -o 0 Se ha producido un error al convertir el documento.4in -p 11 -s default >'/tmp//sndfaxlBau98' <'/tmp/pruebafax. members.CLI> quit y se controla que ha pasado: faxstat -s HylaFAX scheduler on li374-112.com: Running Modem ttyIAX2 (+5753850962): Running and idle Modem ttyIAX1 (+5753850962): Running and idle En este caso el fax se ha enviado con éxito ya que los dos FAX configurados están disponibles.linode. ¿Cómo puedo comprobarlo? Abriendo el correo del usuario root (desde terminal o webmin): y comprobando que el fax enviado ha llegado al correo electrónico definido a lo largo de la configuración de Hylafax: 326 . 3 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.Abriendo el PDF: Si se quiere usar un cliente con interfaz gráfica para el envío de fax. Otra solución más elaborada es AvantFAX. En 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. 17. Todo lo 327 . una buena solución es YajHFC (Yet another Java HylaFAX Client) que siendo escrito completamente en JAVA funciona con cualquier sistema operativo. Esta sencilla operación es la que se hace cuando se quiere enviar un FAX. 38 clásico funciona como se muestra en la imagen que sigue: 328 . Un Gateway T.38.38? Quizás la imagen que sigue ayuda para entender: El FAX está conectado a la línea telefónica y también a un Gateway con soporte T. Ese protocolo ha sido definido por la “International Telecommunication Union” y tomó como sigla T.que pasa en el “mientras” es totalmente transparente. Este Gateway se encarga de transformar el FAX en el formato requerido para ser enviado a través de la red Internet. Las dos maquinas FAX negocian todos los pasajes y para hacerlo utilizan un protocolo.30 En 1998 la misma organización define un nuevo protocolo que permite recibir y enviar fax usando una red a paquetes (Internet).38. La sigla de este protocolo es T.38 se encarga de “decodificar” los paquetes que lleguen para luego pasar el resultado al fax de destinación. En el lado opuesto otro Gateway T. ¿Cómo funciona el protocolo T. 38 solamente como pasarela.8.38 negociar el protocolo de trasporte.Los datos del FAX T. es decir que no está “en el medio” a 329 . En el caso de Asterisk el único protocolo de trasporte permitido es UDPTL que funciona de la siguiente forma: 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]).30 vienen analizados y manipulados para luego ser transformados en paquetes (IFP). Los paquetes se pueden enviar usando tres protocolos de transporte: UDPTL. Asterisk 1. TCP o RTP.X soporta el protocolo T. Será tarea de los Gateway T. Para repetir los paquetes perdidos y controlar que lleguen en el justo orden hay disponibles 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). which is a FAX technology agnostic module that utilizes FAX technology resource modules to complete a FAX transmission. A un lado y al otro de la trasmisión deberán estar dos Gateway T. En Asterisk el envío y recepción de faxes es posible a través de la librería SpanDSP y el modulo res_fax. [Syntax] ReceiveFAX(filename[. [Description] This application is provided by res_fax. Session arguments can be set by the FAXOPT function and to check results of the SendFax() application. which is a FAX technology agnostic module that utilizes FAX technology resource modules to complete a FAX transmission.lo largo del envío del fax. 330 . [Description] This application is provided by res_fax.38 que se hagan cargo de la tarea de enviar/recibir el fax.conf). CLI> core show application SendFax -= Info about application 'SendFAX' =[Synopsis] Sends a specified TIFF/F file as a FAX.options]) [Arguments] options d: Enable FAX debugging. 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 and save as a TIFF/F file. f: Allow audio fallback FAX transfer on T.38 capable channels. Session arguments can be set by the FAXOPT function and to check results of the ReceiveFax() application. s: Send progress Manager events (overrides statusevents setting in res_fax. conf Se pone: [general] udptlstart=4000 udptlend=4099 udptlchecksums=yes udptlfecentries = 3 udptlfecspan = 3 use_even_ports = no Se guardan los cambios y se vuelve a arrancar Asterisk: /etc/init.d/asterisk restart 17.3.old nano /etc/asterisk/udptl..con. z: Initiate a T.conf 331 .38 en Asterisk hay que modificar este archivo: mv /etc/asterisk/udptl. s: Send progress Manager events (overrides statusevents setting in res_fax.[Syntax] SendFAX([filename2[&.38. f: Allow audio fallback FAX transfer on T. options d: Enable FAX debugging..conf /etc/asterisk/udptl. En Voip-info aparece una lista (aunque no muy actualizada). Algunos ATA comercializados soportan el protocolo T.38 reinvite on the channel if the remote end does not.options]) [Arguments] filename2 TIFF file to send as a FAX.conf). Para el soporte T.1 Aplicación ReceiveFax Para el test que se va a ejecutar hay que modificar el dialplan: nano /etc/asterisk/extensions.38 capable channels.]][. Receivefax(/tmp/${UNIQUEID}. Las ultimas lineas: [Mar 23 07:18:03] FAX[11707]: res_fax.fax Se guardan los cambios y se actualiza la configuración de Asterisk: service asterisk reload Se envía el mismo archivo txt utilizado anteriormente: sendfax -h ttyIAX1@localhost -n -d 1234 /tmp/pruebafax. para ver los datos en la consola de Asterisk hay que modificar el archivo logger.Dial(IAX2/iaxmodem2) same => n.1.error para que quede: console => notice. Se abordará la configuración del archivo de forma más detallada en el capitulo 20.Answer same => n.1.c:655 ast_fax_log: FLOW T.error.30 Changing from state 2 to 32 [Mar 23 07:18:03] FAX[11707]: res_fax.se modifica este bloque: exten => 1234.30 Send complete in phase T30_PHASE_E.warning. FAXERROR ${FAXERROR}) same => n.Hangup exten => h. Como se ha activado la opción de debug (d).hangup Para que quede: exten => 1234.warning. state 2 [Mar 23 07:18:03] FAX[11707]: res_fax.Hangup Se guardan los cambios. nano /etc/asterisk/logger.conf que es donde se configuran los distintos registros de Asterisk.tif.c:655 ast_fax_log: FLOW T.30 Changing from phase T30_PHASE_E to T30_PHASE_CALL_FINISHED 332 .1.conf se modifica esta linea: console => notice.txt entran en la consola de Asterisk y miran los resultados del envío: asterisk -rvvvvvvvvvvvvvvvvv Encontraremos todo el debug de la recepción del fax con el protocolo T30.df) same => n.c:655 ast_fax_log: FLOW T.Noop(FAXSTATUS ${FAXSTATUS}. ]][. cuando la extensión conteste.options]) El problema es que con esta aplicación no se puede llamar directamente un FAX en cuanto no hay posibilidad de indicar el numero a marcar. contexto fax que es donde se ha configurado la aplicación para recibir los FAX. El canal Local es un pseudo canal que permite llamar una extensión y un determinado contexto y.0.[Mar 23 07:18:03] FAX[11707]: res_fax.3. Asterisk controla periódicamente esta carpeta a través del modulo pbx_spool.el canal que se va a usar para efectuar la llamada y el numero a llamar. "") in new stack == Spawn extension (fax. Se entra en la carpeta /tmp y se mira si efectivamente está presente un archivo tiff: ls /tmp 1332505066. se ha recibido con éxito. En el escenario que se va a presentar se llamará el numero de destino usando el chan_local. 1234. Un callfile es un archivo de texto donde se definen unas cuantas acciones que Asterisk ejecuta.c:655 ast_fax_log: FLOW FAX Set tx type 9 [Mar 23 07:18:03] FAX[11707]: res_fax.Executing [1234@fax:3] Hangup("IAX2/iaxmodem1-3347".tif 17. la aplicación para enviar FAX en Asterisk es SendFax. pasar el procesamiento del dialplan a esa extensión. El callfile que se va a utilizar: Channel: Local/1234@fax .c:655 ast_fax_log: FLOW FAX FAX exchange complete [Mar 23 07:18:03] FAX[11707]: res_fax. como indica la parte en negrita.c:655 ast_fax_log: FLOW FAX FAX exchange complete -. "FAXSTATUS SUCCESS. 3) exited non-zero on 'IAX2/iaxmodem1-3347' -.so y si hay un archivo de este tipo lo procesa. Para solucionar este problema hay que hacer uso de un callfile.. FAXERROR ") in new stack -.2 Applicación SendFax Como se ha visto en el párrafo 17. una vez preparado se mueve (no se copia) en la carpeta /var/spool/asterisk/outgoing.Executing [h@fax:1] NoOp("IAX2/iaxmodem1-3347".c:655 ast_fax_log: FLOW FAX Set rx type 9 [Mar 23 07:18:03] FAX[11707]: res_fax.3. "") in new stack El fax. Una vez que el destinatario conteste se enviará el archivo Ttiff (la aplicación SendFax solo acepta archivos tiff). el identificativo del llamante 333 . Callerid: "FAX" .. En este caso se llamará la extensión 1234. La sintaxis es muy sencilla: SendFAX([filename2[&.Executing [h@fax:2] Hangup("IAX2/iaxmodem1-3347". el nombre del archivo que se enviará (cambiar el nombre con el que hay en la carpeta /tmp) El resultado del archivo sin los comentarios será: cd /tmp nano enviofax Channel: Local/1234@fax Callerid: "FAX" WaitTime: 30 Maxretries:3 RetryTime: 300 Account: 1000 Application: SendFax Data: /tmp/1332505066.c:655 ast_fax_log: FLOW T.10. una vez que el destinatario conteste se ejecuta la aplicación sendfax Data: /tmp/1329843102.30 Changing from phase T30_PHASE_E to T30_PHASE_CALL_FINISHED [Mar 23 07:26:51] FAX[11883]: res_fax.tif .Se espera un respuesta por 30 segundos Maxretries:3 :se intentará llamar el numero tres veces RetryTime: 300 .dz Ahora se mueve el archivo en la carpeta /var/spool/asteisk/outgoning mv enviofax /var/spool/asterisk/outgoing Se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvv Mar 23 07:26:51] FAX[11883]: res_fax.0.30 Send complete in phase T30_PHASE_E.c:655 ast_fax_log: FLOW T.30 Changing from state 2 to 32 [Mar 23 07:26:51] FAX[11883]: res_fax. en el registro de las llamadas (CDR) se contabilizará la llamada a la extensión 1000 Application: SendFax . entre un intento y otro se esperarán 300 segundos Account: 1000 .WaitTime: 30 . state 2 [Mar 23 07:26:51] FAX[11883]: res_fax.c:655 ast_fax_log: FLOW FAX Set rx type 9 334 .tif.c:655 ast_fax_log: FLOW T. hay unos parámetro relacionados con los FAX: .Attempting call on SIP/justvoip/003907331875163 for application SendFax(/tmp/1332505066.Channel 'SIP/justvoip-00000001' sending FAX: -. Si se quiere probar el envío con el protocolo T38.[Mar 23 07:26:51] FAX[11883]: res_fax.0.conf. "") in new stack == Spawn extension (fax.c:1996 sendfax_t38_init: Audio FAX not allowed on channel 'SIP/justvoip-00000001' and T.dz mv enviofax /var/spool/asterisk/outgoing El resultado en la consola de Asterisk (la parte en negrita): -. > Launching SendFax(/tmp/1332505066.0.38 mode [Mar 23 07:33:58] NOTICE[11945]: pbx_spool. FAXERROR ") in new stack -. aborting.d) (Retry 1) == Using SIP RTP CoS mark 5 > Channel SIP/justvoip-00000001 was answered.tif. For fax detection. "") in new stack Esto significa que el fax se ha enviado con éxito utilizando el protocolo T30.tif. La calidad es mucho mejor.tif [Mar 23 07:33:58] WARNING[11945]: res_fax. The default is *OFF* .Executing [1234@fax:3] Hangup("Local/[email protected] [h@fax:1] NoOp("Local/1234@fax-ee6a. 1234.2".c:366 attempt_thread: Call completed to SIP/justvoip/003907331875163 El discurso cambia si para recibir FAX se utilizan las normales lineas telefónicas.c:2225 sendfax_exec: error initializing channel 'SIP/justvoip-00000001' in T.2". cosa que no hace Justvoip como se puede ver con esta prueba: nano enviofax Channel: SIP/justvoip/003907331870494 Callerid: "FAX" WaitTime: 30 Maxretries:3 RetryTime: 300 Account: 1000 Application: SendFax Data: /tmp/1332505066.38 negotiation failed./tmp/1332505066.0.2' -. [Mar 23 07:33:58] ERROR[11945]: res_fax.c:655 ast_fax_log: FLOW FAX FAX exchange complete -.c:655 ast_fax_log: FLOW FAX Set tx type 9 [Mar 23 07:26:51] FAX[11883]: res_fax. 335 .2". uncomment one of the following lines.d) on SIP/justvoip-00000001 -.Executing [h@fax:2] Hangup("Local/1234@fax-ee6a. hay que utilizar un proveedor VoIP que lo soporte. 3) exited non-zero on 'Local/1234@fax-ee6a. En la configuración del chan_dahdi. "FAXSTATUS SUCCESS.c:655 ast_fax_log: FLOW FAX FAX exchange complete [Mar 23 07:26:51] FAX[11883]: res_fax.tif. The sample below will result in 6 buffers and a full . call is torn down. The faxbuffer policy is reverted after the . When 'faxdetect' is used.faxdetect=both . salientes o desactivar la opción. The default is *OFF*.. para cada canal se puede definir si tiene que reconocer los FAX en las llamadas entrantes.faxdetect=incoming . When this configuration . transmit buffer policy. 336 . the faxbuffer policy will be used for the life of the call . after a fax tone is detected. one could use 'faxbuffers' to configure the DAHDI . buffer policy.faxdetect=outgoing .full De esta forma.faxdetect=no . . . option is used.faxbuffers=>6. . Se presentarán cinco tipos de conexiones: • • • • • Conexiones SIP con nombre de usuario y contraseña Conexiones IAX2 con autentificación sobre IP Conexiones distribuidas con el protocolo DUNDi Conexiones sobre OpenVPN Conexiones SIP con protocolo SIP TLS y audio cifrado (SRTP) 18.conf En el bloque register se añade: register => serverA:pass1@IPserverB/serverB En lugar del IPserverB se pone la dirección IP del servidor B. desde la otra sede se podrán sacar las llamadas utilizando esos Gateway/Tarjetas. A y B. Un escenario típico de este tipo de configuración es cuando una empresa tiene sedes en distintos lugares y quiere que las extensiones de una sede puedan comunicarse con las extensiones de la otra.Capitulo XVIII Conexiones entre servidores Asterisk Este capitulo es dedicado a la conexiones entre servidores Asterisk. Servidor A nano /etc/asterisk/sip. y se quiere conectarlos entre ellos utilizando el protocolo SIP para llamar desde A las extensiones de B y desde B las extensiones de A. Las extensiones del servidor A son de 4 cifras y empiezan por 1.1 Conectar dos servidores Asterisk con el protocolo SIP Hay dos servidores Asterisk. Además. en el servidor B son de 4 cifras y empiezan por el mismo numero 1. si en una de las sedes están instalados Gateway/Tarjetas FXO. Al final del archivo: [serverB] type=friend remotesecret=pass2 context=internas qualify=yes host=dynamic language=es disallow=all allow=gsm allow=ulaw allow=alaw . Con contexto=internas. el servidor B tendrá acceso a todo el dialplan definido en ese contexto. si no existe. IMPORTANTE: cuando se conectan dos servidores Asterisk entre ellos.Con la línea de register. se modifica la linea context poniendo un nombre de contexto y.1.conf En el bloque register se añade:: register => serverB:pass2@IPserverA/serverA al final del archivo: [serverA] type=friend remotesecret=pass1 context=internas 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. se crea ese contexto en el dialplan.6. Servidor B nano /etc/asterisk/sip. Si se quiere que el servidor B tenga acceso solamente a un determinado contexto.X de Asterisk) Se guardan los cambios y se pasa al servidor B. en la configuración de la extensión ya no se utiliza el parámetro secret sino el parámetro remotesecret (esto desde la versión 1. Con las líneas que están después de la etiqueta [serverB] se define una extensión SIP que será aquella usada por el servidor B para conectarse al servidor A.73:5060 N serverA 105 Registered Wed.d/asterisk restart Desde la consola se averigua que haya conexión entre los dos servidores: asterisk -rvvvvvvvvvvvvvv para el servidor A: CLI> sip show registry 69. En los dos se escribe el comando: /etc/init. 26 Oct 2011 10:17:54 339 .196.164. se conecta el servidor serverA al servidor serverB. conf En el contexto internas (para las llamadas a extensiones del servidor B) se añade: exten => _*1XXX.126.Dial(SIP/serverB/${EXTEN:1}.1. 26 Oct 2011 10:18:42 CLI> sip show peers serverA/serverB 96. hay que digitar el siguiente numero: *1000 Servidor B nano /etc/asterisk/extensions.135 D Ahora lo único que hace falta es modificar el archivo extensions.196.121.NoOp() same => n.Hangup() Con estas líneas se configura Asterisk para que todas las llamadas con destino las extensiones cuyo numero empiece por 1 y sean de 4 cifras sean redirigidas hacia el servidor B. Se actualiza la configuración en los dos servidores: asterisk -rvvvvvvvvvvvvvvv 340 .121.135:5060 N D N 5060 OK (1 ms) serverB 105 Registered 5060 OK (2 ms) Wed.1.NoOp() same => n. Para diferenciarlas de las llamadas entre las extensiones locales del servidor A se añade un * delante de las cuatro cifras a marcar.30) same => n.73 para el servidor B: CLI> sip show registry 96. Para diferenciarlas de las llamadas entre las extensiones locales del servidor A se añade un * delante de las cuatro cifras a marcar. Ejemplo: para marcar a la extensión 1000 del servidor B. Servidor A nano /etc/asterisk/extensions.CLI> sip show peers serverB/serverA 69.30) same => n.conf En el contexto internas (para las llamadas a extensiones del servidor A) se añade: exten => _*1XXX.126.Dial(SIP/serverA/${EXTEN:1}.Hangup() Con estas líneas se configura Asterisk para que todas las llamadas con destino las extensiones cuyo numero empiece por 1 y sean de 4 cifras sean redirigidas hacia el servidor B.164.conf de ambos servidores. 1. hay que modificar el plan de llamadas en ambos servidores. Set(CALLERID(num)=serverA) same => n.1.c:12849 check_auth: username mismatch.Hangup() para que quede: exten => _*1XXX.247>. Servidor A nano /etc/asterisk/extensions.CLI> dialplan reload Prueba Desde la extensión 1000 del servidor A se marca *1000 para llamar la extensión 1000 del servidor B y se mira lo que pasa en la consola de Asterisk del servidor B: [2011-01-25 22:42:24] WARNING[14692]: chan_sip.79. ¿Porqué pasa eso? Porque el servidor B piensa que la llamada esté llegando desde la extensión 1000 local y no logra distinguir entre extensión 1000 local y extensión 1000 remota. Para solucionar el problema.30) same => n.conf modificar estas lineas: exten => _*1XXX.c:20212 handle_request_invite: Failed to authenticate device "Fulano" <sip:[email protected]() Servidor B nano /etc/asterisk/extensions.NoOp() same => n. have <1000>.1.NoOp() same => n.Hangup() 341 .30) same => n.144.conf modificar este bloque exten => _*1XXX.Dial(SIP/serverB/${EXTEN:1}.Dial(SIP/serverB/${EXTEN:1}. digest has <serverA> [2011-01-25 22:42:24] NOTICE[14692]: chan_sip.Dial(SIP/serverA/${EXTEN:1}.30) same => n.tag=as2e5f74a9 La llamada no funciona. En el caso de servidores Asterisk con números de extensiones distintos.228.216 nome trunk: serverb Extensiones: 1000-1001-1002 Servidor A Si abre el archivo iax. llamada trunking. En la consola de Asterisk del servidor A aparecerá: Executing [*1000@externas:1] Set("SIP/1000-00000004". que utiliza el mismo trunk para el envío del audio de todas las llamadas.Called serverB/1000 -.SIP/serverB-00000005 is ringing La llamada funciona.conf nano /etc/asterisk/iax. "SIP/serverB/1000. La ventaja de IAX2 está en su característica.49. Set(CALLERID(num)=serverB) same => n. no hace falta modificar el CALLERID antes de marcar.Executing [*1000@externas:2] Dial("SIP/1000-00000004". hay un notable ahorro de banda.30) same => n. Suponiendo que la direcciones IP publicas sean: Servidor A: IP: 96. "CALLERID(num)=serverA") in new stack -.conf 342 .2 Conectar dos servidores Asterisk con el protocolo IAX2 En este párrafo se ilustrará como conectar dos servidor Asterisk a través del protocolo IAX2 y la autentificación con dirección IP. Esta conexión se implementará utilizando las direcciones IP publicas de los Servidores.125.para que queden: exten => _*1XXX.30") in new stack == Using SIP RTP CoS mark 5 == Using SIP VRTP CoS mark 6 == Using UDPTL CoS mark 5 -.1. Este tipo de configuración se necesita solamente si las extensiones de los dos servidores Asterisk tienen los mismos números asignados. De esta forma cuando hay un numero considerable de llamadas que estén pasando por la troncal IAX2.126.Dial(SIP/serverA/${EXTEN:1}.Hangup() Se actualiza el dialplan en ambos servidores y se intenta llamar nuevamente desde el servidor A el numero *1000.112 nome trunk: servera Extensiones: 1000-1001-1002 Servidor B: IP: 66. 18. 255.228.126.112 trunk=yes context=internas qualify=yes Se actualiza la configuración en ambos servidores: asterisk -rvvvvvvvvv CLI> iax2 reload Se averigua que haya conexión entre los servidores (servidor A): CLI> iax2 show peers serverb 66.125.255 4569 (T) (E) OK (1 ms) Servidor B: CLI> iax2 show peers servera 96.216 (S) 255.conf se añaden las lineas: [servera] type=friend host=96.126.255.125.al final del archivo se añaden las siguientes lineas: [serverb] type=friend host=66.228.49. Servidorr B nano /etc/asterisk/iax.112 (S) 255.255.255. además se utilizará en la configuración la funcionalidad del trunkink IAX2 El mismo procedimiento se ejecuta en el servidor B.255 4569 (T) (E) OK (1 ms) CLI> quit En el dialplan se crea un nuevo bloque que permita llamar de un servidor a otro: 343 .49.216 trunk=yes context=internas qualify=yes Es importante destacar que la IP que se define es la del servidor B. Dial(IAX2/serverb/${EXTEN:2}) same => n.112 (format alaw) -.3 El protocolo DUNDi Cuando hay que conectar un numero considerable de servidores Asterisk y compartir las rutas y las extensiones configuradas en cada uno de ellos.Executing [*11000@externas:1] Dial("SIP/1000-00000000".Dial(IAX2/servera/${EXTEN:2}) same => n.Format for call is alaw -.1.conf se añaden las siguientes lineas en el contexto internas: exten => _*1100X. se marca el numero *11000 y se averigua en la consola de Asterisk que la llamada sea cursada correctamente al servidor B.Servidor A nano /etc/asterisk/extensions. 344 .Hangup se actualiza el dialplan: asterisk -rx "dialplan reload" Ahora se pueden efectuar las pruebas. Esto por medio de una red Peer-to-peer (punto-a-punto) en la cual no existen roles fijos de clientes y servidores.Call accepted by 96.conf se añaden las siguientes lineas en el contexto internas: exten => _*1100X.IAX2/servera-17542 answered SIP/1000-00000000 18. Desde la extensión 1000 del servidor A.1. En la consola Asterisk del servidor A aparecerá: -. la solución más funcional es el protocolo DUNDi.Hangup se actualiza el dialplan: asterisk -rx "dialplan reload" Servidor B nano /etc/asterisk/extensions.. sino que los servidores pueden asumir uno u otro rol según el contexto. DUNDi (Distributed Universal Number Discovery) es un protocolo que permite buscar y compartir dialplan entre servidores Asterisk.126. "IAX2/servera/1000") in new stack -.125.Called IAX2/servera/1000 -. 168.142 usuario: server1 Extensiones: 1000-1001-1002 MAC Tarjeta de red: F2:3C:91:DF:5B:3E Servidor B: IP: 192.. Es en este archivo que 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(puede ser IAX2. El protocolo DUNDi se configura en el archivo dundi.182. El puerto predefino para el protocolo DUNDi es el 4520 UDP.236 usuario: server2 Extensiones: 1000-1001-1002 MAC Tarjeta de red: FE:FD:45:A4:C4:49 Los dos servidores están en la misma LAN pero pueden estar ubicados en cualquier punto de la red Internet.168.conf. SIP o H323). Aunque la configuración y puesta en marcha pueda parecer algo complicado. Hay que abrirlo en el cortafuego de los servidores donde se va a utilizar DUNDi: nano /etc/sysconfig/iptables antes de esta linea: -A INPUT -p udp -m udp --dport 4569 -j ACCEPT se pone: # DUNDi -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: IP: 192. con un poco de practica se irán aclarando las ideas y los conceptos claves.A lo largo de la configuración se puede decidir si compartir contextos ya configurados en el Dialplan o crear contextos nuevos definiendo las extensiones que se volverán disponibles a los demás servidores.129. 345 . En la columna descripción.0 todas las direcciones IP disponibles en el servidor Linux Puerto para las conexiones DUNDi (4520 predefinido) El MAC address de la tarjeta de red utilizada para las conexiones DUNDi. Esto permite evitar que las solicitudes queden abiertas por un tiempo indeterminado El modulo pbx_dundi crea una clave.Terminada la configuración de dundi. que rotará de manera automática y que se guardará en la base de datos interna de Asterisk. Valor 32 yes = si no se recibe una respuesta dentro de 2000 ms. Las sintaxis de un contexto es: 346 cachetime ttl autokill secretpath storehistory [mappings] . Valor dundi yes = mantiene un registro de las ultimas solicitudes efectuadas con los tiempos de respuesta de cada una. se anulará la solicitud.0.conf. Más alto el numero más nodos se alcanzará a consultar. se modifica el dialplan para definir cuales son las rutas o contextos que se quiere compartir.conf con una breve descripción para cada uno de ellos.0. organization=EmpresaA locality=Santa Marta stateprov=Magdalena country=Colombia email=admin@servidorA. Con 0. el resultado se guardará por el tiempo definido en este parámetro (en segundos) en la base de datos interna de Asterisk del servidor que envió la solicitud. en negrita el valor de cada parámetro. Valor 3600 Time to Live es un numero que representa el tiempo de vida de la solicitud. De esta forma es posible averiguar cuales son los nodos lentos dentro de la red DUNDi a partir de esta etiqueta se definen los contextos que se va a compartir con los demás servidores Asterisk.com phone=+57XXXXXXXXXX bindaddr port entityid Dirección IP que se quiere utilizar con el protocolo DUNDi. Personalizar con el valor real. Un ejemplo: F2:3C:91:DF:5B:3E Cuando se envía un solicitud para conocer la disponibilidad de una ruta y se encuentra una disponible. Servidor A En la tabla que sigue se indican los parámetros que se configuran en el archivo dundi. con el nombre definido en este parámetro. Parámetro [general] Descripción inicia la configuración general del archivo department=EmpresaA En estos parámetros se indican los datos de la empresa. el contexto DUNDi que se quiere compartir con los demás nodos de la red DUNDi local_context – el contexto local definido en el dialplan donde se configuran las rutas o extensiones que se quieren compartir weight – el peso que se asigna a las rutas que se comparten. Simplificando: se crea un user en el iax.142 .el contexto DUNDi que se va a compartir servera-local . nounsolicited – llamadas de cualquier tipo que no sean solicitadas no son permitidas en esta ruta 2.Parámetro Descripción dundi_context => local_context.168.el contexto definido en el dialplan que contendrá todas las rutas que se van a compartir IAX2 . residential – el numero es de una residencia 4.168. el Servidor A utilizará esa destinación para recibir la llamada.dest[.129.dirección IP del Servidor A (personalizar) 347 • .129.IAX2. si son rutas por las cuales no hay una conexión directa o de alta calidad se pone un numero más alto.conf ${SECRET} .options]] • • • dundi_context . 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. Si son extensiones locales se pone 0.142/${NUMBER} El que aparece arriba es el contexto que se va a definir: • • • • • servera => .usuario que se configurará en el el archivo iax.conf del servidor Asterisk A y dest representa los paramentos para conectarse a ese user options – son las distintas opciones que se pueden añadir a cada contexto DUNDi: 1.es la variable que contiene la clave que el modulo DUNDi crea en automático y que se usará para autenticar el usuario server1 192. Al momento de hacer una solicitud si para el mismo numero requerido existen distintas rutas.la tecnología usada (protocolo) para las llamadas server1 .0. mobile – el numero es un celular 6. nopartial – no se harán búsquedas por números incompletos • • • servera => servera-local.server1:${SECRET}@192.tech.weight. nocomunsolicit – llamadas comerciales no solicitadas no son permitidas en esta ruta 3. commercial – el numero es de una empresa 5. conf /etc/asterisk/dundi. outbound: solo efectúa solicitudes pero no las recibe 3. symmetric: recibe y efectúa solicitudes • host: direccion IP o nombre de dominio del servidor Asterisk B • 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 el 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 crea el archivo dundi. inbound: recibe solamente solicitudes 2.182.conf y se copian los datos de configuración: [general] department=EmpresaA organization=EmpresaA locality=Santa Marta stateprov=Magdalena 348 .236 inkey = server2 outkey = server1 include = all permit = servera qualify = yes • • FE:FD:45:A4:C4:49: MAC address de la tarjeta de red del Servidor Asterisk B con el que se crea la conexión (personalizar) model: puede ser: 1.conf.old se crea uno nuevo: nano /etc/asterisk/dundi.168.conf se definen los servidores Asterisk con los que se va a tener una conexión directa: [FE:FD:45:A4:C4:49] model = symmetric host = 192.Parámetro • Descripción ${NUMBER}: la variable que contendrá el numero que ha sido solicitado Para terminar con la configuración del archivo dundi.conf. Primero se renombra el predefinido: mv /etc/asterisk/dundi. or with the 'init keys' command once Asterisk is running. Primero se entra en la carpeta donde se guardarán las claves: cd /var/lib/asterisk/keys Se crea la clave: astgenkey -n server1 This script generates an RSA private and public key pair in PEM format for use by Asterisk.182. la dirección IP local presente bajo la etiqueta [mappings].IAX2.server1:${SECRET}@192. The resulting files will need to be moved to /var/lib/asterisk/keys if you want to use them.168.0.0. You will be asked to enter a passcode for your key multiple times.country=Colombia [email protected]. and any private keys (. Please enter the same code each time.0 port=4520 entityid=F2:3C:91:DF:5B:3E cachetime=3600 ttl=32 autokill=yes secretpath=dundi storehistory=yes [mappings] servera => servera-local. 349 .key files) will need to be initialized at runtime either by running Asterisk with the '-i' option. el mac address de la tarjeta del servidor B contenido entre corchetes y la dirección ip local del servidor B en host Se guardan los cambios y se crea la clave RSA para autenticar el Servidor Asterisk B.236 inkey = server2 outkey = server1 include = all permit = servera qualify = yes IMPORTANTE: Personalizar los siguientes parámetros: entityid.142/${NUMBER} [F2:3C:91:96:EC:A3] model = symmetric host = 192.129.com phone=+57XXXXXXXXXX bindaddr=0.0. Para crear la clave se usará una utilidad que viene con la instalación de Asterisk. .conf Se añaden las siguientes lineas al final del archivo: [server1] type=user dbsecret=dundi/secret context=servera-local qualify=yes disallow=all allow=ulaw allow=alaw Importante definir el parámetro context con el valor del contexto que se ha definido en nuestra ruta (servera-local) El ultimo archivo que hay que modificar es el dialplan: nano /etc/asterisk/extensions.236:/var/lib/asterisk/keys Personalizar la dirección IP local del servidor B. Generating SSL key 'server1': Generating RSA private key.++++++ e is 65537 (0x10001) writing RSA key Key creation successful.Playback(hello-world) 350 ...pub root@192. Public key: server1..182.pub Private key: server1... La publica se copia en el Servidor Asterisk B: scp server1.conf Antes del contexto internas se define el contexto servera-local y se incluyen las rutas/extensiones que se quiere compartir con el servidor B [servera-local] exten => 20.. uno contiene la clave publica y uno la clave privada..1..n.++++++ ..key Se crearán dos archivos.168..Answer() exten => 20.conf nano /etc/asterisk/iax.. Ahora se puede añadir el usuario server1 al archivo iax...Press ENTER to continue or ^C to cancel. 1024 bit long modulus .... conf Con los oportunos cambios.com 351 .Hangup() Para las solicitudes remotas se crea otro contexto: [dundi-remoto] switch => DUNDi/serverb De esta forma cuando se marca un numero y ese numero no está presente en ningún contexto del dialplan.n. El nombre serverb es el contexto DUNDi que luego se creará en el archivo dundi. la configuración del servidor B será: [general] department=EmpresaB organization=EmpresaB locality=Santa Marta stateprov=Magdalena country=Colombia [email protected] del Servidor Asterisk B Añadimos el contexto dundi-remoto a la lista de contextos disponibles para la extensiones configuradas en el Servidor Asterisk A (en negrita los cambios): [externas] include => internas include => internacio include => parkedcalls include => test include => conferencias include => dundi-remoto [locales] include => internas include => auten include => parkedcalls include => test include => conferencias include => dundi-remoto Se guardan los cambios y se continúa con la configuración del Servidor Asterisk B Servidor B mv /etc/asterisk/dundi.conf /etc/asterisk/dundi.exten => 20. Asterisk consultará el servidor remoto con que tiene una conexión DUNDi.old nano /etc/asterisk/dundi. .168. Generating SSL key 'server2': Generating RSA private key... 1024 bit long modulus .server2:${SECRET}@192. Press ENTER to continue or ^C to cancel.++++++ 352 .0.key files) will need to be initialized at runtime either by running Asterisk with the '-i' option.0..182.142 inkey = server1 outkey = server2 include = all permit = serverb qualify = yes IMPORTANTE: Personalizar los siguientes parámetros: entityid.. la dirección IP local presente bajo la etiqueta [mappings]. Please enter the same code each time..0.168. and any private keys (.phone=+57XXXXXXXX bindaddr=0....236/${NUMBER} [F2:3C:91:DF:5B:3E] model = symmetric host = 192.129.el mac address de la tarjeta del servidor B contenido entre corchetes y la dirección ip local del servidor B en host Se crea la clave RSA para el servidor B: cd /var/lib/asterisk/keys astgenkey -n server2 This script generates an RSA private and public key pair in PEM format for use by Asterisk...0 port=4520 entityid=F2:3C:91:96:EC:A3 cachetime=3600 ttl=32 autokill=yes secretpath=dundi storehistory=yes [mappings] serverb => serverb-local. or with the 'init keys' command once Asterisk is running.IAX2. The resulting files will need to be moved to /var/lib/asterisk/keys if you want to use them. You will be asked to enter a passcode for your key multiple times. ++++++ e is 65537 (0x10001) writing RSA key Key creation successful.pub Private key: server2....n...Hangup() [dundi-remoto] switch => DUNDi/servera Se incluye el contexto dundi-remoto de forma que sea accesible a las extensiones: [externas] include => internas include => internacio include => parkedcalls include => test include => conferencias include => dundi-remoto [locales] 353 .Playback(hello-world) exten => 40.conf [serverb-local] exten => 40.129.pub root@192.... Public key: server2....142:/var/lib/asterisk/keys Personalizar la dirección IP local del servidor A...1...168. Se crea el usuario IAX2 nano /etc/asterisk/iax.......Answer() exten => 40...n...key Se copia la clave publica en el Servidor Asterisk A scp server2.conf [server2] type=user qualify=yes dbsecret=dundi/secret context=serverb-local disallow=all allow=ulaw allow=alaw Para terminar se modifica el plan de llamadas: nano /etc/asterisk/extensions.. 182.236 (S) 4520 Symmetric Unavail OK (1 ms) 1 dundi peers [1 online.3obGb1QtvkUeciZs7rH5CA== /dundi/secretexpiry : 1259212403 aparecerá la clave creada por el modulo pbx_dundi y el tiempo que falta para que caduque.168.d/asterisk restart Se entra en la consola del servidor Asterisk A: asterisk -rvvvvvvvvvvvv se mira 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 mappings dundi 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 Se controla que haya conexión entre los dos servidores: CLI> dundi show peers EID Host Port Model AvgTime Status f2:3c:91:96:ec:a3 192.include => internas include => auten include => parkedcalls include => test include => conferencias include => dundi-remoto Una vez terminada la configuración del Servidor Asterisk B en ambos se reinicia la PBX: /etc/init. 354 . 0 offline. 0 unmonitored] Con el comando: CLI> database show /dundi/secret : qotQe+Vp1B2G7S9yoizlPA==. una librería de compresión datos requerida por OpenVPN: 355 . 0 IAX2/server1:[email protected] es posible cifrar la señalización SIP y el flujo media.8.236/40 (EXISTS|CANMATCH) from f2:3c:91:96:ec:a3.Ahora se puede hacer la primera consulta para controlar que efectivamente las rutas se están compartiendo: CLI> dundi lookup 40@serverb 1.142. expires in 3600 s DUNDi lookup completed in 7 ms Para terminar las pruebas se conecta un softphone al servidor Asterisk B y se intenta llamar la extensión 20 (que es presente en el servidor Asterisk A). Servidor A Primero se instala LZO. en algunos casos. Si se envía una solicitud para una ruta que no existe la respuesta será: CLI> dundi lookup 20@serverb DUNDi lookup returned no results. luego desde una extensión del servidor A se marca el numero 40. Por este motivo. 0 IAX2/server2:kGYzcabppQ577UVIWc6eGQ==@192. la respuesta es que la extensión existe. A pesar de la nueva implementación. expires in 3600 s DUNDi lookup completed in 45 ms En el servidor Asterisk B las extensión compartidas es la 40 y efectivamente enviando la solicitud. Como se ha podido ver. las potencialidades del protocolo DUNDi son realmente grandes.4 Conectar dos servidores Asterisk con OpenVPN Desde la versión 1.conf del servidor Asterisk B. En este párrafo se verá como instalar y configurar OpenVPN en dos servidores Asterisk y como crear una conexión VPN entre los dos.248/20 (EXISTS|CANMATCH) from f2:3c:91:df:5b:3e. DUNDi lookup completed in 3 ms Se hace otra solicitud de prueba desde el Servidor Asterisk B CLI> dundi lookup 20@servera 1. Este párrafo es una pequeña guía para que se pueda empezar a implementarlas. puede ser más funcional crear una red VPN entre servidores Linux y luego utilizarla para configurar troncales en Asterisk.168. todavía hay muchos problemas de compatibilidad entre Asterisk y las distintas marcas/modelos de teléfonos actualmente en el mercado. 18.182. En el comando ademas de la extensión va indicado el contexto como se ha definido en el bloque mappings del dundi. 06.gz Se descomprime y se instala: tar -xf lzo-2.openvpn.2. cliente): cd easy-rsa/2.2.0 Se crea la carpeta donde se guardarán las distintas claves: mkdir /usr/local/sbin/keys nano vars 356 .tar.tar.2./configure make make install Se prepara el servidor Linux para crear las distintas claves (CA.06 .tar.2 se compila: .org/community/releases/openvpn-2./configure --prefix=/usr make make install Ahora se puede instalar la ultima versión disponible de OpenVPN: cd /usr/src se descarga: wget http://swupdate.tar.com/opensource/lzo/download/lzo-2.gz cd lzo-2.2.gz se entra en la carpeta creada: cd openvpn-2.oberhumer.06.2.gz se descomprime: tar -xf openvpn-2.cd /usr/src Se descarga: wget http://www. servidor. ----Country Name (2 letter code) [CO]: State or Province Name (full name) [Magdalena]: Locality Name (eg.org]: En “Common Name” se pone el nombre de dominio de Linode o del servidor Linux que se está 357 .com Name [changeme]:voztovoice Email Address [[email protected] Se guardan los cambios y se prepara el programa para la generación de las claves: .++++++ writing new private key to 'ca.linode.key' ----You are about to be asked to enter information that will be incorporated into your certificate request. If you enter '.++++++ .org" export KEY_EMAIL=admin@voztovoice.'. your name or your server's hostname) [changeme]:li44-242. Esto datos serán los predefinidos que se usaran al momento de la generación de las claves./vars IMPORTANTE: entre el primer punto y el segundo hay un espacio .. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value./clean-all Ahora se puede empezar a generar las claves empezando con la CA (Certificate Authority): . Personalizar los datos de los parametros que siguen: export KEY_DIR=/usr/local/sbin/keys export KEY_COUNTRY="CO" export KEY_PROVINCE="MAG" export KEY_CITY="SantaMarta" export KEY_ORG="VozToVoice" export KEY_EMAIL="admin@voztovoice. company) [VozToVoice]: Organizational Unit Name (eg./build-ca Generating a 1024 bit RSA private key . .. city) [SantaMarta]: Organization Name (eg. section) [changeme]:PBXA Common Name (eg. the field will be left blank.Se modifican las líneas que siguen... ... If you enter '.. your name or your server's hostname) [server]:li44-242..members. Se continua con la clave del servidor: . section) [changeme]:PBXA Common Name (eg.8. the field will be left blank...linode.. company) [VozToVoice]: Organizational Unit Name (eg..++++++ .com Name [changeme]:voztovoice Email Address [[email protected]/openssl-0. There are quite a few fields but you can leave some blank For some fields there will be a default value. What you are about to enter is what is called a Distinguished Name or a DN.2.....key' ----You are about to be asked to enter information that will be incorporated into your certificate request.... commit? [y/n]y Write out database with 1 new entries 358 ....'..org' Certificate is to be certified until Dec 10 14:16:09 2021 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified.linode.members.1/easy-rsa/2.. ----Country Name (2 letter code) [CO]: State or Province Name (full name) [Magdalena]: Locality Name (eg. city) [SantaMarta]: Organization Name (eg.9../build-key-server server Generating a 1024 bit RSA private key ..com' name :PRINTABLE:'voztovoice' emailAddress :IA5STRING:'[email protected] Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CO' stateOrProvinceName :PRINTABLE:'Magdalena' localityName :PRINTABLE:'SantaMarta' organizationName :PRINTABLE:'VozToVoice' organizationalUnitName:PRINTABLE:'PBXA' commonName :PRINTABLE:'li44-242.utilizando...org]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /root/openvpn-2.++++++ writing new private key to 'server. .. your name or your server's hostname) [clienteb]:li44-242.......'...++++++ writing new private key to 'clienteb......com Name [changeme]:voztovoice Email Address [[email protected]]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /root/openvpn-2....1/easy-rsa/2.9......com' name :PRINTABLE:'voztovoice' emailAddress :IA5STRING:'[email protected]' Certificate is to be certified until Dec 10 14:19:20 2021 GMT (3650 days) Sign the certificate? [y/n]:y 359 .cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CO' stateOrProvinceName :PRINTABLE:'Magdalena' localityName :PRINTABLE:'SantaMarta' organizationName :PRINTABLE:'VozToVoice' organizationalUnitName:PRINTABLE:'PBXA' commonName :PRINTABLE:'li44-242. ----Country Name (2 letter code) [CO]: State or Province Name (full name) [Magdalena]: Locality Name (eg. company) [VozToVoice]: Organizational Unit Name (eg...0/openssl-0.. If you enter '..members. section) [changeme]:PBXA Common Name (eg..8.....linode. city) [SantaMarta]: Organization Name (eg........ There are quite a few fields but you can leave some blank For some fields there will be a default value... What you are about to enter is what is called a Distinguished Name or a DN..key' ----You are about to be asked to enter information that will be incorporated into your certificate request./build-key clienteb Generating a 1024 bit RSA private key ..Data Base Updated Para terminar se crea una clave para el cliente (el servidor Asterisk B): ..++++++ .members..... the field will be left blank...linode. Se termina con la generación del parámetro Diffie Hellman .2.2/sample-scripts/ cp openvpn.1 out of 1 certificate requests certified.228. se crean otras claves cliente. generator 2 This is going to take a long time OpenVPN utiliza como puerto predefinido el 1194 (puede ser UDP o TCP según la configuración).d/init.216 --dport 1194 -j ACCEPT -A INPUT -p udp -m udp -s 66. se añaden las siguientes lineas en la configuración: nano /etc/sysconfig/iptables después de esta linea: -A INPUT -p tcp -m state --state NEW -m tcp --dport 15000 -j ACCEPT se pone: # OpenVPN -A INPUT -p tcp -m state --state NEW -m tcp -s 66.d/openvpn chkconfig --add openvpn chkconfig openvpn on Se crea la carpeta donde se guardarán los archivos de configuración de OpenVPN: mkdir /etc/openvpn Se crea el archivo de configuración para el servidor: 360 .49. Hay que abrirlo en Iptables solamente para la IP del servidor B.init /etc/rc. Suponiendo que la IP del servidor B es 66.228.49.216. commit? [y/n]y Write out database with 1 new entries Data Base Updated Si se tiene planeado utilizar la conexión para conectar telefonos IP y/o Softphone.228. 1024 bit long safe prime.49./build-dh Generating DH parameters.216 --dport 1194 -j ACCEPT Se guardan los cambios y se reinicia iptables: service iptables restart Lo siguiente es instalar el script de arranque presente en las fuentes de OpenVPN: cd /usr/src/openvpn-2. crt cert /usr/local/sbin/keys/server.log verb 3 management localhost 7505 Para más informaciones sobre estos parámetros: http://openvpn.log log-append openvpn.key dh /usr/local/sbin/keys/dh1024.cd /etc/openvpn nano server.net/index.crt key /usr/local/sbin/keys/server.0.255.0 ifconfig-pool-persist ipp.txt keepalive 10 120 comp-lzo max-clients 30 persist-key persist-tun log openvpn.php/open-source/documentation/howto.conf Se copian las siguientes lineas: port 1194 proto udp dev tun ca /usr/local/sbin/keys/ca.d/openvpn start En la configuración de red del servidor aparecerá un nuevo dispositivo: ifconfig Servidor B 361 .html#examples Se guardan los cambios y se inicia OpenVPN /etc/init.8.pem server 10.255.0 255. 06.openvpn.tar./configure –prefix=/usr make make install Ahora se puede instalar la ultima versión disponible de OpenVPN: cd /usr/src se descarga: wget http://swupdate.tar.oberhumer.2.gz se descomprime: tar -xf openvpn-2. cliente): cd easy-rsa/2.0 Se crea la carpeta donde se guardarán las distintas claves: mkdir /usr/local/sbin/keys nano vars 362 .com/opensource/lzo/download/lzo-2. servidor.06.2.gz cd lzo-2.tar./configure make make install Se prepara el servidor Linux para crear las distintas claves (CA.2.Se sigue el mismo procedimiento para el servidor B: cd /usr/src Se descarga: wget http://www.org/community/releases/openvpn-2.06 .2.2 se compila: .gz Se descomprime y se instala: tar -xf lzo-2.tar.2.gz se entra en la carpeta creada: cd openvpn-2. org]: 363 . If you enter '. There are quite a few fields but you can leave some blank For some fields there will be a default value. Esto datos serán los que se usaran como predefinidos al momento de la generación de las claves.. . section) [changeme]:PBXB Common Name (eg.'.Se modifican las líneas que siguen. Personalizar los datos desde la segunda linea en adelante: export KEY_DIR=/usr/local/sbin/keys export KEY_COUNTRY="CO" export KEY_PROVINCE="MAG" export KEY_CITY="SantaMarta" export KEY_ORG="VozToVoice" export KEY_EMAIL="[email protected] Se guardan los cambios y se prepara el programa para la generación de las claves: . ----Country Name (2 letter code) [CO]: State or Province Name (full name) [Magdalena]: Locality Name (eg./clean-all Ahora se puede empezar a generar las claves empezando con la CA (Certificate Authority): . city) [SantaMarta]: Organization Name (eg.members. the field will be left blank..com Name [changeme]:voztovoice Email Address [[email protected]. company) [VozToVoice]: Organizational Unit Name (eg./vars IMPORTANTE: entre el primer punto y el segundo hay un espacio ./build-ca Generating a 1024 bit RSA private key . your name or your server's hostname) [changeme]:li212-33.. What you are about to enter is what is called a Distinguished Name or a DN.key' ----You are about to be asked to enter information that will be incorporated into your certificate request.++++++ writing new private key to 'ca.++++++ .com" export KEY_EMAIL=admin@voztovoice. your name or your server's hostname) [server]:li212-33./build-key-server server Generating a 1024 bit RSA private key .En “Common Name” se pone el nombre de dominio de Linode o del servidor Linux que se está utilizando. What you are about to enter is what is called a Distinguished Name or a DN.key' ----You are about to be asked to enter information that will be incorporated into your certificate request. section) [changeme]:PBXB Common Name (eg.members.++++++ writing new private key to 'server.cnf Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CO' stateOrProvinceName :PRINTABLE:'Magdalena' localityName :PRINTABLE:'SantaMarta' organizationName :PRINTABLE:'VozToVoice' organizationalUnitName:PRINTABLE:'PBXB' commonName :PRINTABLE:'li212-33.0/openssl-0.9.linode.com Name [changeme]:voztovoice Email Address [[email protected].. If you enter '.com ' name :PRINTABLE:'voztovoice' emailAddress :IA5STRING:'[email protected]]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /usr/src/openvpn-2. There are quite a few fields but you can leave some blank For some fields there will be a default value.org' Certificate is to be certified until Dec 10 15:13:18 2021 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified.8.members.1/easy-rsa/2. the field will be left blank. city) [SantaMarta]: Organization Name (eg. company) [VozToVoice]: Organizational Unit Name (eg. Se continua con la clave del servidor: . ----Country Name (2 letter code) [CO]: State or Province Name (full name) [Magdalena]: Locality Name (eg. commit? [y/n]y 364 .++++++ .'. . What you are about to enter is what is called a Distinguished Name or a DN. your name or your server's hostname) [clientea]:li212-33.linode.com ' name :PRINTABLE:'voztovoice' emailAddress :IA5STRING:'admin@voztovoice. ----Country Name (2 letter code) [CO]: State or Province Name (full name) [Magdalena]: Locality Name (eg... section) [changeme]:PBXB Common Name (eg.linode.members..1/easy-rsa/2.8.org' Certificate is to be certified until Dec 10 15:15:37 2021 GMT (3650 days) Sign the certificate? [y/n]:y 365 ....0/openssl-0.++++++ writing new private key to 'clientea..com Name [changeme]:voztovoice Email Address [[email protected] Check that the request matches the signature Signature ok The Subject's Distinguished Name is as follows countryName :PRINTABLE:'CO' stateOrProvinceName :PRINTABLE:'Magdalena' localityName :PRINTABLE:'SantaMarta' organizationName :PRINTABLE:'VozToVoice' organizationalUnitName:PRINTABLE:'PBXB' commonName :PRINTABLE:'li212-33. the field will be left blank..Write out database with 1 new entries Data Base Updated Para terminar se crea una clave para el cliente (el servidor Asterisk B): .key' ----You are about to be asked to enter information that will be incorporated into your certificate request.9./build-key clientea Generating a 1024 bit RSA private key .org]: Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: Using configuration from /usr/src/openvpn-2..++++++ .'.members. If you enter '. company) [VozToVoice]: Organizational Unit Name (eg.2.. There are quite a few fields but you can leave some blank For some fields there will be a default value.. city) [SantaMarta]: Organization Name (eg. init /etc/rc.201.178 --dport 1194 -j ACCEPT -A INPUT -p udp -m udp -s 69.2/sample-scripts/ cp openvpn.201. generator 2 This is going to take a long time Como para el servidor A./build-dh Generating DH parameters.conf Se copian las siguientes lineas: port 1194 proto udp 366 .178 --dport 1194 -j ACCEPT Se guardan los cambios y se reinicia iptables: service iptables restart Lo siguiente es instalar el script de arranque presente en las fuentes de OpenVPN: cd /usr/src/openvpn-2.1 out of 1 certificate requests certified. 1024 bit long safe prime. se abren los puertos en iptables para la IP del servidor A nano /etc/sysconfig/iptables # OpenVPN -A INPUT -p tcp -m state --state NEW -m tcp -s 69.2. commit? [y/n]y Write out database with 1 new entries Data Base Updated Se termina con la generación del parámetro Diffie Hellman .164.164.d/init.d/openvpn chkconfig --add openvpn chkconfig openvpn on Se crea la carpeta donde se guardarán los archivos de configuración de OpenVPN: mkdir /etc/openvpn Se crea el archivo de configuración para el servidor: cd /etc/openvpn nano server. log verb 3 management localhost 7505 Se guardan los cambios.0 ifconfig-pool-persist ipp.0 255. hay que crear una conexión cliente en cada uno.txt keepalive 10 120 comp-lzo max-clients 30 persist-key persist-tun log openvpn.0.key dh /usr/local/sbin/keys/dh1024.d/openvpn start En la configuración de red del servidor aparecerá un nuevo dispositivo: ifconfig Ahora que los dos servidores están configurados.crt • clienteb.key • La claves se copian en la carpeta /etc/openvpn del servidor B.crt cert /usr/local/sbin/keys/server.pem server 10.255. Se inicia OpenVPN /etc/init.255. Para eso hay que copiar las siguientes claves de un servidor a otro: Servidor A → Servidor B: • ca.10.crt • clienteb.dev tun ca /usr/local/sbin/keys/ca. Servidor B → Servidor A: 367 .crt key /usr/local/sbin/keys/server.log log-append openvpn. La diferencia con el archivo del Servidor A es que se utiliza otro rango de IP local. 228.key La claves se copian en la carpeta /etc/openvpn del servidor A.conf se copian las siguientes lineas: client dev tun proto udp remote 66.• • • ca. tendremos un nuevo dispositivo de red: 368 .crt clientea.216 1194 resolv-retry infinite nobind persist-key persist-tun ca /etc/openvpn/ca. Se guardan los cambios y se reinicia OpenVPN: service openvpn restart Si todo ha salido bien.crt cert /etc/openvpn/clientea.crt clientea.key comp-lzo verb 3 ns-cert-type server route-method exe route-delay 2 En la linea 4 se pone la dirección IP del servidor B y el puerto (1194).crt key /etc/openvpn/clientea. Ahora en el servidor A se crea el archivo de configuración cliente para conectarse al servidor B: cd /etc/openvpn nano client.49. 255.conf: nano /etc/asterisk/sip.8.Para que las llamadas puedan ser enrutadas correctamente por Asterisk.0 Se recarga la configuración SIP: asterisk -rx "sip reload" Se sigue el mismo procedimiento para el servidor B: cd /etc/openvpn nano client.0/255.conf se copian las siguientes lineas: client dev tun proto udp remote 96.255.0.255.125.conf Después del primer parámetro localnet se añade: localnet=10.126.112 1194 resolv-retry infinite nobind persist-key persist-tun ca /etc/openvpn/ca.0/255.0 localnet=10.crt cert /etc/openvpn/clienteb.crt key /etc/openvpn/clienteb.key comp-lzo verb 3 ns-cert-type server 369 .255.10. hay que añadir estas dos nuevas redes en la configuración del sip.0. Para crear la troncal podemos utilizar o el rango de IP 10.route-method exe route-delay 2 Se guardan los cambios y se reinicia OpenVPN: service openvpn restart Si todo ha salido bien.0/255.0. Esta vez utilizando la autentificación por IP.1 o el rango de IP 10.255.conf Después del primer parámetro localnet se añade: localnet=10.0.0.0/255.0 localnet=10.255. se crea una nueva troncal SIP entre los dos.conf al final del archivo se pone: [serverbvpn] 370 .255.0 Se recarga la configuración SIP: asterisk -rx "sip reload" Una vez terminada la configuración y la conexión OpenVPN entre los dos servidores.10.8. tendremos un nuevo dispositivo de red: Para que las llamadas puedan ser enrutadas correctamente por Asterisk.8. hay que añadir estas dos nuevas redes en la configuración del sip.10.1 Servidor A nano /etc/asterisk/sip.0.255.conf: nano /etc/asterisk/sip. 0.0. 0 offline] Servidor B: 371 . Se guarda los cambios y se pasa al servidor B.8. 0 offline Unmonitored: 0 online.8.6 disallow=all allow=g729 allow=alaw language=es qualify=yes dtmfmode = rfc2833 Importante destacar la dirección IP VPN del servidor B en el parámetro host y el contexto (vpn).0.type=peer context=vpn host=10.1 disallow=all allow=g729 allow=alaw language=es qualify=yes dtmfmode = rfc2833 Se recarga la configuración SIP en ambos servidores: asterisk -rx "sip reload" Se entra en la consola de ambos servidores y se averigua que la conexión este funcionando: asterisk -rvvvvvvvvvv Servidor A: CLI> sip show peers like serverbvpn Name/username Host Dyn Nat ACL Port Status Realtime serverbvpn 10.8.conf al final del archivo se pone: [serveravpn] type=peer context=vpn host=10.6 N 5060 OK (2 ms) 1 sip peers [Monitored: 1 online. Servidor B nano /etc/asterisk/sip. Dial(SIP/serverbvpn/${EXTEN}) same => n.CLI> sip show peers like serveravpn Name/username Host Dyn Nat ACL Port Status Realtime serveravpn 10. se modifica el dialplan acordándose que el contexto que se ha definido en la troncal es vpn.Hangup y en el contexto internas se pone: exten => 70.1 N 5060 OK (2 ms) 1 sip peers [Monitored: 1 online. no hace falta añadir la linea donde se modifica el CALLERID Servidor A nano /etc/asterisk/extensions.Answer same => n. hay que “engañar” Asterisk para que acepte la llamada ya que las extensiones configuradas en los dos servidores son las mismas.1. En el caso de servidores con números de extensiones distintas.hangup 372 .Playback(demo-congrats) same => n.Set(CALLERID(num)=openvpnb) same => n.Hangup y en el contexto internas se pone: exten => 70.1. 0 offline] Perfecto!! Para probar las llamadas entre los servidores.Playback(demo-congrats) same => n.Set(CALLERID(num)=openvpna) same => n. Como para la prueba con la conexión entre servidores Asterisk con el protocolo SIP. se crea el nuevo contexto vpn y se añaden las siguientes lineas: [vpn] exten => 70.Answer same => n. utilizando la red OpenVPN.conf antes del contexto internas. 0 offline Unmonitored: 0 online.Dial(SIP/serveravpn/${EXTEN}) same => n. se crea el nuevo contexto vpn y se añaden las siguientes lineas: [vpn] exten => 70.hangup Servidor B nano /etc/asterisk/extensions.0.conf antes del contexto internas.1.1.8. 5 Conectar dos Servidores Asterisk con TLS y SRTP En esta parte se verá como configurar una conexión SIP entre dos servidores Asterisk y utilizar el protocolo TLS para la señalización SIP y el cifrado media con el protocolo SRTP.Executing [70@externas:4] Dial("SIP/1000-00000045"...8.. "openvpna") in new stack -...members...... "CALLERID(num)=openvpna") in new stack -... Primero hay que crear los certificados para el servidor A y el servidor B.linode.. Desde el servidor A: mkdir /etc/asterisk/keys Primero se crea el certificado CA y el certificado para el servidorA: cd /usr/src/asterisk-1.....com -o serverA No config file specified./ast_tls_cert -d certs -C li374-112.. Esto se hace con una utilidad presente en las fuentes de Asterisk. "SIP/serverbvpn/70") in new stack == Using SIP RTP CoS mark 5 == Using SIP VRTP CoS mark 6 == Using UDPTL CoS mark 5 -.....key Generating RSA private key...11...++ ... se hace una prueba marcando desde la extensión 1000 del servidor A la extensión 70.Executing [70@externas:3] NoOp("SIP/1000-00000045". En la consola de Asterisk de servidor A debería aparecer: Executing [70@externas:1] NoOp("SIP/1000-00000045".......++ e is 65537 (0x10001) 373 ....SIP/serverbvpn-00000046 answered SIP/1000-00000045 La comodidad de tener las dos redes VPN es que se pueden configurar otros clientes OpenVPN en los computadores donde tenemos instalados los SoftPhone o los teléfonos que soportan este protocolo (ejemplo Yealink desde el modelo T26 para arriba). 18.Called serverbvpn/70 -. creating 'certs/tmp...Se guardan los cambios en ambos servidores y se recarga el dialplan asterisk -rx "dialplan reload" Para terminar....cfg' You can use this config file to create additional certs without re-entering the information for the fields in the certificate Creating certs/ca.. "") in new stack Executing [70@externas:2] Set("SIP/1000-00000045".0/contrib/scripts .. 4096 bit long modulus .. .key Generating RSA private key...++++++ .........................................................crt Signature ok subject=/CN=li374-112.......linode.......linode...../ast_tls_cert -d certs -C li291-216.............key: Creating certs/ca................ 4096 bit long modulus .............Enter pass phrase for certs/ca......crt Signature ok subject=/CN=li291-216..key: Verifying .....Enter pass phrase for certs/ca.......... 1024 bit long modulus .members.................++++++ e is 65537 (0x10001) Creating signing request Creating certs/serverA..........linode......crt Enter pass phrase for certs/ca.........++ e is 65537 (0x10001) Enter pass phrase for certs/ca.... .................crt Enter pass phrase for certs/ca...........members.....................key: Creating certs/serverB...........com/O=Asterisk Getting CA Private Key Enter pass phrase for certs/ca...key: Combining key and crt into certs/serverA............ 1024 bit long modulus .......key Generating RSA private key..pem En la opción -C se pone el nombre de dominio del servidor y cuando el script lo pide se ingresa una contraseña (por ejemplo servera) Luego se crea el certificado para el servidorB ....key: Verifying .....members.key: Creating certs/ca..........................++++++ e is 65537 (0x10001) Creating signing request Creating certs/serverB......key: Creating certs/serverA.Enter pass phrase for certs/ca....... creating 'certs/tmp..++++++ ......key Generating RSA private key.cfg' You can use this config file to create additional certs without re-entering the information for the fields in the certificate Creating certs/ca...++ .com/O=Asterisk Getting CA Private Key 374 ...com -o serverB No config file specified......... conf para activar el protocolo TLS y se crea la troncal para el servidorB con autentificación sobre IP: nano /etc/asterisk/sip.49.crt tlscapath=/etc/asterisk/keys tlsdontverifyserver=yes en tlsbindaddr se pone la dirección IP del servidorA al final del archivo se configura la troncal para el servidorB [serverbtls] type=peer context=from-tls host=66.126.125.crt /etc/asterisk/keys/ cp serverA.Enter pass phrase for certs/ca.pem /etc/asterisk/keys/ Para terminar se modifica la configuración del archivo sip.228.216 disallow=all allow=alaw language=es qualify=yes transport=tls encryption=yes Los parámetros importantes: • context: nombre del contexto donde entrarán las llamadas del servidoB 375 .key: Combining key and crt into certs/serverB.pem tlscafile=/etc/asterisk/keys/ca.112 tlscertfile=/etc/asterisk/keys/serverA.conf al final de la parte general se pone: tlsenable=yes tlsbindaddr=96.pem Cuando el script pide la contraseña. se pone la misma que se ha utilizado para crear las claves del servidorA (servera) Ahora se copian los siguientes archivos en la carpeta /etc/asterisk/keys del servidorA: cd certs cp ca. Set(CALLERID(num)=serveratls) same => n. si el valor es 0.1.Dial(SIP/serverbtls/${EXTEN}) same => n.216 --dport 5061 -j ACCEPT Se guardan los cambios y se reinicia iptables: service iptables restart En el dialplan se crea el nuevo contexto antes del contexto internas: nano /etc/asterisk/extensions.Noop(TLS = ${CHANNEL(secure_signaling)}. Si el valor es 1 significa que se están utilizando.• • • host: la dirección IP del servidorB transport: de define como trasporte de la señalización SIP el protocolo TLS encryption: se activa el cifrado del flujo media (protocolo SRTP) El protocolo TLS en Asterisk.49. SRTP = ${CHANNEL(secure_media)}) same => n. significa que no están activos en el canal en uso.Answer same => n.hangup Servidor B Se crea la carpeta para los certificados: 376 .Playback(tt-monkeys) same => n.conf [from-tls] exten => 71. En el contexto internas se añade. utiliza el puerto predefinido 5061 TCP. Hay que abrirlo en el firewall para la IP del servidorB nano /etc/sysconfig/iptables después de esta linea: -A INPUT -p tcp -m state --state NEW -m tcp --dport 5060 -j ACCEPT se pone: -A INPUT -p tcp -m state --state NEW -m tcp -s 66.Hangup Con la segunda linea se lee la variable CHANNEL para el cifrado de la señalización y del flujo media.1.228. exten => 71. 112 --dport 5061 -j ACCEPT 377 .crt tlscapath=/etc/asterisk/keys tlsdontverifyserver=yes en tlsbindaddr se pone la dirección IP del servidorB.112 disallow=all allow=alaw language=es qualify=yes transport=tls encryption=yes Se abre el puerto 5061 TCP en el firewall para la IP del servidorA nano /etc/sysconfig/iptables después de esta linea: -A INPUT -p tcp -m state --state NEW -m tcp --dport 5060 -j ACCEPT se pone: -A INPUT -p tcp -m state --state NEW -m tcp -s 96.125.126.49.216:/etc/asterisk/keys Esto suponiendo que la IP publica del servidorB sea 66. Al final del archivo se configura la troncal para el servidorA: [serveratls] type=peer context=from-tls host=96.228.conf: nano /etc/asterisk/sip.216 tlscertfile=/etc/asterisk/keys/serverB.mkdir /etc/asterisk/keys Se vuelve al servidor A y se copian las dos claves: scp ca.216:/etc/asterisk/keys scp serverB.49.126.49.125.pem tlscafile=/etc/asterisk/keys/ca.228.49.228.216 Se abre el archivos sip.crt [email protected] y al final de la parte general se pone: tlsenable=yes tlsbindaddr=66.pem root@66. Noop(TLS = ${CHANNEL(secure_signaling)}.Dial(SIP/serveratls/${EXTEN}) same => n.112 N 5061 OK (2 ms) N 5061 OK (1 ms) Ahora desde la extensión 1000 del servidorA se marca el numero 71 y se mira que pasa en la consola de ambos servidores: Servidor A: Executing [71@externas:1] Set("SIP/1000-00000022".1. SRTP = ${CHANNEL(secure_media)}) same => n.Se guardan los cambios y se reinicia iptables: service iptables restart Se pasa al dialplan: nano /etc/asterisk/extensions. "CALLERID(num)=serveratls") in new stack -.1.49.Executing [71@externas:2] Dial("SIP/1000-00000022".216 Se hace la misma operación en el servidorB: CLI> sip show peers serveratls 96.126.228.125.hangup Se guardan los cambios y se recarga la configuración de ambos servidores: service asterisk reload Se averigua en el servidorA que el servidorB esté conectado: asterisk -rvvvvvvvvvvvvvvv CLI> sip show peers serverbtls 66.Hangup En el contexto internas se pone: exten => 71.Playback(tt-monkeys) same => n.Set(CALLERID(num)=serverbtls) same => n.Answer same => n.conf Antes del contexto internas se pone: [from-tls] exten => 71. "SIP/serverbtls/71") in new stack 378 . SRTP = 1") in new stack -. "tt-monkeys") in new stack -.Executing [71@from-tls:3] Playback("SIP/serveratls-00000015". 379 . "") in new stack -. Esto quiere decir que la señalización y el flojo media serán cifrados.Servidor B: Executing [71@from-tls:1] Answer("SIP/serveratls-00000015".Executing [71@from-tls:4] Hangup("SIP/serveratls-00000015". Otra forma de averiguarlo es activar con Ngrep la captura en el puerto 5061 en uno de los dos servidores: ngrep -W byline port 5061 Aparecerán puros bloques cifrados.Executing [71@from-tls:2] NoOp("SIP/serveratls-00000015". "") in new stack Como se puede ver en la consola del servidorB la llamada que llega tiene activado el protocolo TLS (1) y el protocolo SRTP(1).ulaw' (language 'es') -.<SIP/serveratls-00000015> Playing 'tt-monkeys. "TLS = 1. . 0.pem .Capitulo XIX AMI y AGI 19.conf se conecte o se desconecte aparecerá una linea que lo notificará.tlsbindport=5039 .tlsprivatekey=/tmp/private. yes – añade una fecha en formato EPOCH para cada evento permite configurar unas variables que aparecerán cada vez que se genere un evento relacionado con un canal. el archivo http.channelvars = var1. De deja comentado no – no se activa el debug de la AMI de forma predefinida.var2. Para conectarse a la AMI como cliente.conf.0. Este parámetro define si por un usuario configurado en este archivo se aceptan una o más conexiones simultaneas. Al final de la tabla. Es posible activarlo y desactivarlo en cualquier momento desde la displayconnects timestampevents .0.0.conf y en el caso que se quiera utilizar también el protocolo HTTP. se puede utilizar un socket TCP (puerto predefinido 5038) o el protocolo HTTP (puerto predefinido 8088).pem allowmultiplelogin Descripción Etiqueta que indica el inicio de la configuración general del archivo yes – Se activa el acceso a la AMI yes = se activa el acceso a la AMI vía HTTP 5038 – el puerto predefinido para la conexión a la AMI de Asterisk vía TCP Dirección IP donde la AMI aceptará conexiones.var3 debug .tlsbindaddr=0. En negrita los valores de cada parámetro. la configuración completa del archivo. Valor yes yes – En la consola de Asterisk cada vez que un usuario configurado en el manager.tlscertfile=/tmp/asterisk.conf.tlsenable=no .0 . Parámetro [general] enabled webenabled port bindaddr . Se dejan comentados. En la tabla a seguir se indicarán los parámetros que se van a configurar con una breve descripción. Los parámetros presentes son parecidos a la configuración del protocolo TLS en el archivo sip.0 todas las direcciones IP presentes en el servidor Es posible configurar la AMI para que utilice el protocolo TLS. El AMI se configura en el archivo de configuración manager. Este tipo de configuración es aconsejado en el caso que se permita el acceso a la interfaz desde remoto.1 AMI (Asterisk Manager Interface) AMI (Asterisk Manager Interface) es una interfaz de monitoreo y gestión que interactúa con la PBX recibiendo eventos y/o enviando acciones que el sistema ejecutará. Valor 0. tiempo que la AMI esperará antes de cerrar la sesión con un cliente después de haber enviado una respuesta a la solicitud recibida Valor: 60 a partir de esta etiqueta se define el primer usuario que tendrá acceso a la AMI de Asterisk.0.0 (todas) con este parámetro se define un rango de IP que tendrán acceso a la AMI de Asterisk con las credenciales del usuario configurado. Valor 0.0. Valor en mili segundos que esperará Asterisk para enviar los datos al cliente conectado a la AMI. La contraseña que el usuario utilizará para conectarse a la AMI de Asterisk. que tiene un cliente para autenticarse. Valor: 20 define tres condiciones: 1. Para los eventos se pueden crear dos tipos de configuraciones: 1. Utilizar siempre contraseñas fuertes.1/255.255. Valor: 100 382 httptimeout [admin] secret deny permit . Valor 127. el tiempo máximo de vida del cookie http generado por la AMI 2.0. si el nombre del evento no empieza con un punto exclamativo. El valor entre corchetes es el nombre del usuario. el tipo de evento se enviará 2.Parámetro consola de Asterisk authtimeout authlimit Descripción es el tiempo.255. Para esta configuración de prueba el valor es sesamo con este parámetro se define un rango de IP que no podrán acceder a la AMI de Asterisk con las credenciales del usuario configurado.eventfilter=!Channel: DAHDI* writetimeout .0.255 En este caso solamente desde local.0/0.0. se filtrará y no será enviado al cliente conectado a la AMI de Asterisk Se dejan comentadas. si el nombre del evento empieza con un punto exclamativo.eventfilter=Event: Newchannel . el tiempo que esperará el servidor web de la AMI al recibir una acción de tipo “waitevent” antes de cerrar la solicitud 3. expresado en segundos. El parámetro eventfilter permite filtrar los eventos que recibirá el usuario una vez que esté conectado a la AMI de Asterisk. Valor 60 define el numero máximo de sesiones simultaneas no autenticadas que aceptará la AMI. Se utiliza en el caso que el cliente pierda la conexión con la AMI.0. falta definir los permisos que el mismo usuario tendrá al conectarse con la AMI de Asterisk. crear canales en la PBX call agent permite al usuario acceder a todos los datos Permite al usuario enviar acciones para relacionados con las colas de espera y los gestionar y monitorear el estado de las agentes colas y los agentes Recibe eventos relacionados con las extensiones y los usuarios Jabber (XMPP) Solo escritura Permite generar eventos relacionados con las extensiones configuradas Permite al usuario leer. recargar la configuración.conf permite al usuario recibir eventos cuando se modifica una variable o se crea una nueva extensión en el dialplan Solo escritura Solo lectura dialplan originate Permite al usuario crear una nueva llamada utilizando la acción Originate de la AMI 383 . actualizar y recargar los archivos de configuración de Asterisk Permite al usuario ejecutar comandos de la consola de Asterisk Solo lectura permite al usuario ejecutar acciones para recibir estadísticas y reportes del sistema user config command DTMF reporting cdr Solo escritura permite al usuario recibir los eventos relacionados con los tonos permite al usuario recibir reportes de la calidad de las llamadas permite al usuario recibir eventos Solo lectura relacionados con el registro de las llamadas según la configuración del archivo cdr_manager. etc) Permite al usuario modificar. Estos permisos son de dos tipos: • • lectura escritura En la tabla que sigue la lista completa y el significado de cada uno de ellos: Parámetro all system Read El usuario puede leer todos los eventos de la AMI El usuario recibe todos los eventos relacionados con el funcionamiento de la PBX Permite al usuario recibir informaciones relacionadas con los canales de la PBX Write El usuario tiene acceso a todas las acciones de la AMI El usuario puede enviar acciones de sistema (reiniciar la PBX.Una vez configurado el usuario. 0.channelvars = var1.conf y se copian las siguientes lineas: [general] enabled=yes webenabled=yes port=5038 bindaddr=0.eventfilter=Event: Newchannel 384 .255.0.conf.0.0.0 .1/255.pem allowmultiplelogin=yes displayconnects=yes timestampevents=yes .0. Se renombra el predefinido: mv /etc/asterisk/manager.var2.0.tlsbindaddr=0.old se crea uno nuevo: nano /etc/asterisk/manager.agi permite al usuario recibir eventos generados por la ejecución de un AGI permite al usuario recibir eventos relacionados con el sistema CCSS (rellamada) permite al usuario recibir eventos relacionados con AOC (advice of charge) es decir el costo de la llamada corriente Más Informaciones en la wiki de Asterisk Permite al usuario generar acciones para la gestión de los canales creados por un AGI en modo asíncrono Solo lectura cc aoc permite al usuario generar un mensaje AOC para una determinada llamada.tlsbindport=5039 .var3 debug=no authtimeout=60 authlimit=20 httptimeout=60 [admin] secret=sesamo deny=0.pem .0 permit=127.tlsenable=no .0/0.conf.0.255 .255.tlsprivatekey=/tmp/private. Ahora se puede crear el archivo manager.0.0 .0.tlscertfile=/tmp/asterisk.conf /etc/asterisk/manager.0. agent. Se guardan los cambios y se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvv Los comandos relacionados con la AMI de Asterisk: CLI> help manager manager reload Reload manager configurations manager set debug [on|off] Show.dtmf.cdr.command. Para conocer la sintaxis: CLI> manager show command Login 385 . El usuario admin está presente. aparecen los privilegios que se necesitan para ejecutarlo. Entre ellos está el comando Login que permite conectarse a la AMI de Asterisk y es el que se utilizará para hacer la primera prueba.eventfilter=!Channel: DAHDI* writetimeout=100 read=system.agent.otiginate. en la columna Privilege.agi.aoc En las dos lineas read y write. disable debugging of the manager code manager show command Show a manager interface command manager show commands List manager interface commands manager show connected List connected manager interface users manager show eventq List manager interface queued events manager show settings Show manager global settings manager show users List configured manager users manager show user Display information on a specific manager user Primero se recarga la configuración: CLI> manager reload luego se controla que el usuario configurado aparezca:: CLI> manager show users username -------admin ------------------1 manager users configured.aoc write=system.reporting.. enable.dialplan. se ponen todos los valores posibles.config.call.reporting. Con el comando: CLI> manager show commands aparecerá una lista de todos los comandos que se pueden utilizar desde la AMI de Asterisk.call.agi.user.cc. Por cada comando.user. 1. Secret Secret to login with as specified in manager. Después de la ultima linea la 386 . Will be returned. [Arguments] ActionID ActionID for this transaction.conf. Se abre otra consola de Linux y se instala telnet: yum install telnet Se inicia el programa: telnet y se crea la conexión a la AMI de Asterisk: telnet> o localhost 5038 Trying 127.1 Action: Login Username: admin Secret: sesamo Events: Off Después de cada linea..conf. [See Also] Not available Para conectarse a la AMI de Asterisk se utilizará el programa Telnet.. [Description] Login Manager. Escape character is '^]'. para pasar a la siguiente se presiona la tecla envío. Connected to localhost. Asterisk Call Manager/1.0. Username Username to login with as specified in manager.0.[Syntax] Action: Login [ActionID:] <value> Username: <value> [Secret:] <value> [Synopsis] Login Manager. 0. Escape character is '^]'. con Events:On.1 Action: Login Username: admin Secret: sesamo Events: On Response: Success Message: Authentication accepted Event: FullyBooted Privilege: system. Connected to localhost.. Connection closed by foreign host.0.0.1 == Manager 'admin' logged off from 127. se activa la recepción de todos los eventos generados por la AMI. Asterisk Call Manager/1..0.0.0.1.1 Otra prueba que se se puede hacer es ver la configuración de la extensión 1000 telnet telnet> o localhost 5038 Trying 127.all Status: Fully Booted En este caso. Luego se ejecuta la acción para ver la configuración de la extensión 1000 Action: SIPshowpeer Peer: 1000 387 .tecla envío se presiona dos veces. El resultado será: Response: Success Message: Authentication accepted Para salir de la AMI: Action: Logoff Response: Goodbye Message: Thanks for all the fish. En la consola de Asterisk aparecerá: == Manager 'admin' logged on from 127. Not Screened Callgroup: 1 Pickupgroup: 1 MOHSuggest: default VoiceMailbox: 1000@default TransferMode: open LastMsgsSent: -1 Maxforwards: 0 Call-limit: 2 Busy-level: 0 MaxCallBR: 384 kbps Dynamic: Y Callerid: "callerid=Fulano" <1000> RegExpire: -1 seconds SIP-AuthInsecure: no SIP-Forcerport: Y ACL: N SIP-CanReinvite: N SIP-DirectMedia: N SIP-PromiscRedir: N SIP-UserPhone: N SIP-VideoSupport: Y SIP-TextSupport: N SIP-T.Response: Success Channeltype: SIP ObjectName: 1000 ChanObjectType: peer SecretExist: Y RemoteSecretExist: N MD5SecretExist: N Context: externas Language: es Accountcode: 1000 AMAflags: Unknown CID-CallingPres: Presentation Allowed.38EC: FEC SIP-T.38Support: Y SIP-T.38MaxDtgrm: 400 SIP-Sess-Timers: Accept SIP-Sess-Refresh: uas SIP-Sess-Expires: 1800 SIP-Sess-Min: 90 SIP-RTP-Engine: asterisk SIP-Encryption: N SIP-DTMFmode: rfc2833 ToHost: Address-IP: (null) Address-Port: 0 388 . 11:13642.g729 Status: UNKNOWN SIP-Useragent: X-Lite 4 release 4.1 Action: Login Username: admin Secret: sesamo Events: On Response: Success Message: Authentication accepted Event: FullyBooted Privilege: system..0. 389 . Se verán toda una serie de informaciones relacionadas con la llamada.234. Una ultima prueba es conectarse a la AMI y mirar cuales eventos se generan a lo largo de una llamada entre la extensión 1000 y la extensión 1001: telnet localhost 5038 Trying 127. además aparecerán los eventos relacionados con el CCSS.1 stamp 63214 Reg-Contact: sip:[email protected]. Connected to localhost.all Status: Fully Booted Una vez conectado a la AMI desde la extensión 1000 se llama la extensión 1001 y se mira lo que aparece en la consola de Linux.1. Escape character is '^]'.Default-addr-IP: (null) Default-addr-port: 0 Default-Username: 1000 Codecs: 0x8010c (ulaw|alaw|g729|h263) CodecOrder: alaw. Ya se puede salir de la AMI: Action:Logoff Response: Goodbye Message: Thanks for all the fish. Asterisk Call Manager/1..0.rinstance=c25bb0cf558f37bb QualifyFreq: 60000 ms Parkinglot: SIP-Use-Reason-Header: Y Action: Logoff Connection closed by foreign host. Estas aplicaciones pueden estar escritas en distintos lenguajes de programación y de hecho existen librerías en Perl. De hecho hay soluciones que utilizan este tipo de conexión. Los tres estándar que se utilizan son: 390 . Ruby que simplifican su escritura. Como para la AMI. Python. En Linux. es posible interactuar con la AMI de Asterisk vía HTTP. PHP. Entre ellas hay que citar la GUI para Asterisk de Digium. espiar una llamada. también para el AGI es posible conocer los comandos disponibles desde la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvv y se escribe: CLI> help agi agi dump html Dumps a list of AGI commands in HTML format agi exec Add AGI command to a channel in Async AGI agi set debug [on|off] Enable/Disable AGI debugging agi show commands [topic] List AGI commands or specific help Para una lista de los comandos que se pueden utilizar en un AGI: CLI> agi show commands ¿Cómo Funciona? La comunicación entre Asterisk y el AGI se apoya a los “files descriptors” del sistema operativo Linux que permiten una comunicación entre el Kernel y la aplicación que quiere acceder a un determinado archivo/programa. De hecho existen muchas librerías que simplifican está operación: Entre ellas: • • • • • PHP: PHPagi Python: Starpy Perl: Asterisk-perl Java: Asterisk-java Ruby: Adhearsion Como se ha dicho al inicio de este párrafo. desde script bash hasta script en Ruby. 19. Normalmente se hace escribiendo código en distintos lenguajes de programación. ver la actividad de una cola.2 AGI (Asterisk Gateway Interface) El Asterisk Gateway Interface (AGI) permite desarrollar aplicaciones externas que pueden interactuar con Asterisk. cuya instalación se explicará en el capitulo XXVI. y FOP2 (Flash Operator Panel 2) que es un sistema que permite monitorear las actividad de las llamadas de Asterisk y al mismo tiempo efectuar algunas acciones entre las cuales: transferir una llamada.Connection closed by foreign host. Claramente utilizar la AMI de esta forma es poco practico. net/project/phpagi/phpagi/2. se utilizarán la librería PHPAGI y PHP.tgz se entra en la carpeta creada: cd phpagi-2. como ya se ha dicho.tgz Se descomprime: tar -xf phpagi-2.20. Para PHPAGI. primero se instala php: yum install php-* luego de descarga la librería: cd /usr/src wget http://downloads. Para los ejemplos a seguir. escribir el AGI utilizando prácticamente cualquier lenguaje de programación.20/phpagi-2.20.20 y se copian las dos librerías para AGI en la carpeta de agi-bin de Asterisk: cp phpagi.php /var/lib/asterisk/agi-bin 391 .sourceforge.php /var/lib/asterisk/agi-bin cp phpagi-asmanager.• • • STDIN STDOUT STDERR Visto de forma gráfica: Esto permite. php chmod 755 /var/lib/asterisk/agi-bin PHPAGI se apoya a un archivo de configuración que hay que crear en la carpeta /etc/asterisk.com hostname=li374-112.conf se copian las siguientes lineas: [phpagi] debug=false error_handler=true admin=fulano@gmail. para utilizar Festival como sistema de texto a voz.com tempdir=/var/spool/asterisk/tmp/ [asmanager] server=localhost port=5038 username=admin secret=sesamo [fastagi] setuid=true basedir=/var/lib/asterisk/agi-bin/ [festival] text2wave=/usr/bin/text2wave El primer bloque del archivo es dedicado al la configuración de PHPAGI para la ejecución de script AGI. En en segundo bloque [asmanager]. se indica la ubicación del archivo text2wave.php 392 . nano /etc/asterisk/phpagi. se configura los datos de acceso a la AMI de Asterisk para el usuario admin anteriormente creado.members.linode.se vuelven los archivos ejecutables: chmod 755 /var/lib/asterisk/agi-bin/phpagi. El tercer bloque es para la configuración de FastAGI (cuando se ejecutan los script AGI sobre una conexión TCP) Por ultimo. Se guardan los cambios y se crea el primer AGI: nano /var/lib/asterisk/agi-bin/pruebaudio. conf en el contexto internas se añade: exten => 250. error_reporting(E_ALL).1. $agi-> stream_file('demo-congrats'). returning 4 == Spawn extension (externas.php") in new stack -.php -. $agi-> answer().Executing [250@externas:1] AGI("SIP/1000-00000050". $agi-> hangup(). "pruebaudio.php').Launched AGI Script /var/lib/asterisk/agi-bin/pruebaudio.Agi(pruebaudio. $agi = new AGI(). 1) exited non-zero on 'SIP/1000-00000050' Si se activa el debug agi: CLI> agi set debug on 393 . 250.php) same => n.Hangup Se guardan los cambios.#!/usr/bin/php -q <?php require('phpagi. ?> Se vuelve ejecutable el archivo: chmod +x /var/lib/asterisk/agi-bin/pruebaudio..php Se modifica el dialplan para añadir el AGI: nano /etc/asterisk/extensions. En la consola aparecerá: -.arg1[..arg2[.Playing 'demo-congrats' (escape_digits=) (sample_offset 0) -.php completed. se entra en la consola de Asterisk y se recarga el dialplan: asterisk -rvvvvvvvvvvvv CLI> dialplan reload la sintaxis de la aplicación AGI: CLI> core show application agi [Syntax] AGI(command[.<SIP/1000-00000050>AGI Script pruebaudio..]]]) Desde la extensión 1000 se marca el numero 250. Executing [250@externas:1] AGI("SIP/1000-00000051".2 <SIP/1000-00000051>AGI Tx >> agi_callerid: 1000 <SIP/1000-00000051>AGI Tx >> agi_calleridname: callerid=Fulano <SIP/1000-00000051>AGI Tx >> agi_callingpres: 0 <SIP/1000-00000051>AGI Tx >> agi_callingani2: 0 <SIP/1000-00000051>AGI Tx >> agi_callington: 0 <SIP/1000-00000051>AGI Tx >> agi_callingtns: 0 <SIP/1000-00000051>AGI Tx >> agi_dnid: 250 <SIP/1000-00000051>AGI Tx >> agi_rdnis: unknown <SIP/1000-00000051>AGI Tx >> agi_context: externas <SIP/1000-00000051>AGI Tx >> agi_extension: 250 <SIP/1000-00000051>AGI Tx >> agi_priority: 1 <SIP/1000-00000051>AGI Tx >> agi_enhanced: 0. $agi = new AGI(). 394 .php <SIP/1000-00000051>AGI Tx >> agi_request: pruebaudio.El resultado será: -. returning 4 == Spawn extension (externas.php completed.81 <SIP/1000-00000051>AGI Tx >> agi_version: 1. antes de procesar el agi.php').<SIP/1000-00000051>AGI Script pruebaudio.Launched AGI Script /var/lib/asterisk/agi-bin/pruebaudio.8.8.Playing 'demo-congrats' (escape_digits=) (sample_offset 0) <SIP/1000-00000051>AGI Tx >> 200 result=0 endpos=313776 <SIP/1000-00000051>AGI Rx << HANGUP <SIP/1000-00000051>AGI Tx >> 200 result=1 -. $agi-> answer().php") in new stack -.0 <SIP/1000-00000051>AGI Tx >> agi_accountcode: 1000 <SIP/1000-00000051>AGI Tx >> agi_threadid: -1229980784 <SIP/1000-00000051>AGI Tx >> <SIP/1000-00000051>AGI Rx << ANSWER <SIP/1000-00000051>AGI Tx >> 200 result=0 <SIP/1000-00000051>AGI Rx << STREAM FILE demo-congrats "" 0 -. error_reporting(E_ALL). envía todas las variables relacionadas con el canal. 250. "pruebaudio.php <SIP/1000-00000051>AGI Tx >> agi_channel: SIP/1000-00000051 <SIP/1000-00000051>AGI Tx >> agi_language: es <SIP/1000-00000051>AGI Tx >> agi_type: SIP <SIP/1000-00000051>AGI Tx >> agi_uniqueid: 1331227067.php #!/usr/bin/php -q <?php require('phpagi. 1) exited non-zero on 'SIP/1000-00000051' Asterisk. Otro ejemplo podría ser devolver al llamante su CallerID nano /var/lib/asterisk/agi-bin/callerid. $callerid = $agi->request['agi_callerid'].Agi(callerid.voztovoice.org/tmp/wakeup.2.conf Se añaden las siguientes dos líneas en el contexto internas: 395 .0.php) same => n.Hangup asterisk -rvvvvvvvvvvvv CLI> dialplan reload Desde la extensión 1000 se marca 251.0 Se vuelve ejecutable el archivo wakeup.2. El ultimo ejemplo es un despertador que no utiliza la librería PHPAGI sino PHP “puro”: cd /usr/src wget http://www.php se copia en la carpeta agi-bin de asterisk: cp wakeup.1. $agi-> hangup().conf exten => 251. ?> chmod +x /var/lib/asterisk/agi-bin/callerid.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.0. $agi->text2wav("Hola extension $callerid").php: chmod +x wakeup.tar Se descomprime: tar -xf wakeup.2.tar Se entra en la carpeta: cd wakeup.php nano /etc/asterisk/extensions. X es “deprecated” y va sustituida con la normal aplicación AGI 19.3. utiliza un file descriptor para la creación de un flujo audio procedente del canal que ha llamado la aplicación. Estas son: • • • EAGI FastAGI Async AGI Hasta la versión 1.1 EAGI La gran diferencia entre AGI y EAGI es que el segundo. en el softphone aparecerá: 19.X de Asterisk existía también la aplicación DeadAGI que normalmente se utilizaba en un canal que había sido terminado. Esta aplicación desde la versión 1.agi(wakeup. ademas de comunicarse con Asterisk a través de STDIN y STDOUT.exten => 77. Una vez programado si desde la misma extensión se marca otra vez la extensión 77 se tendrá la opción de poder modificar la hora del despertador.Hangup Se guarda el archivo y se recarga el dialplan: asterisk -rvvvvvvvvvvv CLI> dialplan reload Ahora desde un extensión 1000 se marca el numero 77 y se siguen las instrucciones para programar el despertador.6.3 Las variantes AGI Ademas de la aplicación AGI que se acaba de ilustrar.Set(CHANNEL(language)=es) same => n. existen una variantes que se utilizan en algunos escenarios muy específicos.php) same=> n.1. Cuando llega la llamada del despertador. Algunos datos: CLI> core show application EAGI 396 .4. La sintaxis es: AGI(agi://IPservidorFastAGI:puerto) El puerto predefinido es el 4573 397 . This application sets the following channel variable upon completion: ${AGISTATUS}: The status of the attempt to the run the AGI script text string.. in the case of a net script.]]]) [Arguments] Not available [See Also] AGI(). etc. Executes an Asterisk Gateway Interface compliant program on a channel.3. play audio. Use the CLI command 'agi show commands' to list available agi commands. by communicating with the AGI protocol on *stdin* and *stdout*.-= Info about application 'EAGI' =[Synopsis] Executes an EAGI compliant application.2 FastAGI FastAGI trabaja sobre una conexión TCP que se realiza con un servidor FastAGI. Dialplan execution will continue normally.arg1[.. As of '1.6.0'. read DTMF digits. even upon hangup until the AGI application signals a desire to stop (either by exiting or. AGI allows Asterisk to launch external programs written in any language to control a telephony channel. this channel will not stop dialplan execution on hangup inside of this application. A locally executed AGI script will receive SIGHUP on hangup from the channel except when using DeadAGI. by closing the connection). A fast AGI server will correspondingly receive a HANGUP inline with the command dialog. one of: SUCCESS FAILURE NOTFOUND HANGUP [Syntax] EAGI(command[.. with incoming audio available out of band on file descriptor 3. DeadAGI() 19. Both of theses signals may be disabled by setting the ${AGISIGHUP} channel variable to 'no' before executing the AGI application.arg2[. El control sobre el canal se hace vía TCP y no requiere iniciar un nuevo proceso por cada llamada. [Description] Using 'EAGI' provides enhanced AGI. 0.accountcode = 1000 -.Executing [253@externas:3] Hangup("SIP/1000-00000011". Primero se modifica el dialplan: nano /etc/asterisk/extensions.0/agi/fastagi-test y se inicia: /usr/src/asterisk-1. Aparecerá: Consola Asterisk: -. "agi://127.callington = 0 398 .callerid = 1000 -.Hangup Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvvv CLI> dialplan reload Se cambian los permisos del servidor FastAGI: chmod 755 /usr/src/asterisk-1. "") in new stack -.11.1:4573 completed. 3) exited non-zero on 'SIP/1000-00000011' Consola del servidor FastAgi: AGI Environment Dump from 59836 --.En las fuentes de Asterisk es presente un servidor FastAGI para hacer una prueba.1:4573") in new stack -. returning 0 -.Executing [253@externas:1] NoOp("SIP/1000-00000011".1:4573) same => n.8. 253.<SIP/1000-00000011>AGI Script agi://127.callingtns = 0 -.0.0.11.1.Executing [253@externas:2] AGI("SIP/1000-00000011".callingpres = 0 -.callingani2 = 0 -.0.Noop same => n.8.0.0.AGI(agi://127.calleridname = callerid=Fulano -.conf En el contexto internas se añade el siguiente bloque: exten => 252. "") in new stack == Spawn extension (externas.0/agi/fastagi-test Desde la extensión 1000 se marca el numero 252. PASS (0) 6a.conf y se añade el bloque que sigue: 399 . cosa que se hizo cuando se configuró el usuario admin en el manager..0.network = yes -.request = agi://127.enhanced = 0.. 7 passed.PASS (0) 4..8.context = externas -. el usuario configurado en el manager. Testing 'sendfile'.-.21 -.extension = 253 -.conf.PASS (0) 6.. Testing 'sendimage'.8.3. Testing 'sendtext'...rdnis = unknown -.priority = 2 -.language = es -. De esta forma es posible abrir un canal y luego desde la AMI enviar los comandos al canal abierto...uniqueid = 1331242231.threadid = -1224852592 -.PASS (0) 2.type = SIP -.2 1. Para probar la funcionalidad de modifica el dialplan: nano /etc/asterisk/extensions. Testing 'saynumber'.PASS (0) 3. Testing 'waitdtmf'...3 Async AGI Async AGI permite el envío de los comandos a través de la AMI de Asterisk..0 -..1:4573 -.conf deber tener los permisos de lectura y escritura para el parámetro agi. 0 failed ================================================== Un “framework” que utiliza FastAGI es Adhearsion. Testing 'record' playback.0.PASS (0) ================== Complete ====================== 7 tests completed.PASS (0) 5.channel = SIP/1000-00000011 -.dnid = 253 -. 19. Testing 'record'. Desde el punto de vista del dialplan la sintaxis es muy sencilla: AGI(agi:async) Para poder enviar las acciones AGI a la AMI de Asterisk.version = 1... Escape character is '^]'.1.1.AGI(agi:async) same => n.exten => 253.1 Se autentica el usuario admin: Action:login Username:admin Secret:sesamo Events:off Response: Success Message: Authentication accepted Se ejecuta la primera acción agi para contestar el canal (el numero de canal aparece en la consola de Asterisk): Action:Agi Channel:SIP/1000-00000017 Command:Answer Response: Success Message: Added AGI command to queue Se envía la música de espera al canal: Action:Agi Channel:SIP/1000-00000017 Command:Exec startmusiconhold Response: Success Message: Added AGI command to queue 400 .Noop same => n. Asterisk Call Manager/1.Hangup Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvv CLI> dialplan reload Antes de marcar la extensión 253. se abre otra ventana terminal y se crea una conexión manual a la AMI de Asterisk: telnet localhost 5038 Trying 127.0. Connected to localhost..0.. "") in new stack -.AGI Script Executing Application: (startmusiconhold) Options: () 401 . "agi:async") in new stack <SIP/1000-00000017>AGI Tx >> agi_request: async <SIP/1000-00000017>AGI Tx >> agi_channel: SIP/1000-00000017 <SIP/1000-00000017>AGI Tx >> agi_language: es <SIP/1000-00000017>AGI Tx >> agi_type: SIP <SIP/1000-00000017>AGI Tx >> agi_uniqueid: 1331246894.0 <SIP/1000-00000017>AGI Tx >> agi_accountcode: 1000 <SIP/1000-00000017>AGI Tx >> agi_threadid: -1225098352 <SIP/1000-00000017>AGI Tx >> <SIP/1000-00000017>AGI Tx >> 200 result=0 -.8.8.27 <SIP/1000-00000017>AGI Tx >> agi_version: 1.2 <SIP/1000-00000017>AGI Tx >> agi_callerid: 1000 <SIP/1000-00000017>AGI Tx >> agi_calleridname: callerid=Fulano <SIP/1000-00000017>AGI Tx >> agi_callingpres: 0 <SIP/1000-00000017>AGI Tx >> agi_callingani2: 0 <SIP/1000-00000017>AGI Tx >> agi_callington: 0 <SIP/1000-00000017>AGI Tx >> agi_callingtns: 0 <SIP/1000-00000017>AGI Tx >> agi_dnid: 254 <SIP/1000-00000017>AGI Tx >> agi_rdnis: unknown <SIP/1000-00000017>AGI Tx >> agi_context: externas <SIP/1000-00000017>AGI Tx >> agi_extension: 254 <SIP/1000-00000017>AGI Tx >> agi_priority: 2 <SIP/1000-00000017>AGI Tx >> agi_enhanced: 0.Se para la música de espera en el canal: Action:Agi Channel:SIP/1000-00000017 Command:Exec stopmusiconhold Response: Success Message: Added AGI command to queue Se termina la llamada: Action:Agi Channel:SIP/1000-00000017 Command:hangup Response: Success Message: Added AGI command to queue En la consola de Asterisk aparecerá: -.Executing [254@externas:2] AGI("SIP/1000-00000017".Executing [254@externas:1] NoOp("SIP/1000-00000017". Stopped music on hold on SIP/1000-00000017 <SIP/1000-00000017>AGI Tx >> 200 result=0 <SIP/1000-00000017>AGI Tx >> 200 result=1 == Spawn extension (externas. class 'default'.-. on SIP/1000-00000017 <SIP/1000-00000017>AGI Tx >> 200 result=0 -. 2) exited non-zero on 'SIP/1000-00000017' 402 .AGI Script Executing Application: (stopmusiconhold) Options: () -.Started music on hold. 254. . se verán los siguientes datos: En orden: • • • • • • • • • • • • • • • • • • id: numero progresivo que identifica cada entrada de la tabla calldate: fecha y hora de la llamada clid: callerID del llamante src: numero de la extensión que ha iniciado la llamada dst: numero de la extensión de destino dcontext: contexto que se ha utilizado channel: nombre del canal de quien ha originado la llamada dstchannel: nombre del canal de destino lastapp: aplicación utilizada lastdata: opciones de la aplicación utilizadas duration: duración total de la llamada billsec: duración de la llamada después de que ha sido contestada disposition: resultado de la aplicación ejecutada (en este caso BUSY) amaflags: parámetro utilizado para la facturación de la llamada accountcode: numero de cuenta para facturación de la llamada peeraccount: cuenta del usuario (lado peer) uniqueid: numero único que identifica la llamada linkedid: numero único que identifica la llamada y que mantiene el mismo valor en el caso la llamada sea transferida. parqueada. Útil para hacerle seguimiento a la . etc.7 se ha visto como crear una base de datos MySQL y una tabla (cdr) para guardar los registros de las llamadas.. Mirando una entrada en la tabla CDR. Una parte están relacionados con las llamadas y otra parte con el funcionamiento de la PBX. enviada a una cola.Capitulo XX Los registros en Asterisk Asterisk guarda toda una serie de registros relacionados con su actividad en distintos archivos.conf 20.1 CDR (Call Detail Record) En el párrafo 1. En este capitulo se hablará de: • • • CDR (Call Detail Record) CEL (Channel Event Logging) Logger. Una primera cosa que se puede hacer es utilizar el campo userfield para guardar la IP de donde se originó la llamada.y algunas sub-carpetas (en negrita). En el campo userfield aparecerá la IP de donde se originó la llamada: Este tipo de solución puede ser muy útil para conocer en cualquier momento de donde las extensiones están originando sus llamadas y de esta forma monitorear si se están presentando ataques exitosos a la PBX.• llamada userfield: campo personalizable por el usuario. Para esta configuración se utiliza la función CHANNEL que permite leer muchos datos de un determinado canal.Set(CDR(userfield)=${CHANNEL(peerip)}) Con esta linea se asocia al campo userfield del CDR.conf y en el contexto internacio. Terminada la llamada se vuelve a Webmin y se mira la ultima entrada de la tabla CDR.1. entre ellos “peerip”. la IP del canal que está originando la llamada. Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvvv CLI> dialplan reload Ahora desde la extensión 1000 se llama un numero de teléfono fijo/celular. después de esta linea: exten => _00X.NoOp se añade: same => n. Los mismos datos se guardan también en distintos archivos CSV presentes en la la carpeta /var/log/asterisk. ls -l /var/log/asterisk total 192 drwxr-xr-x 2 root root 4096 Mar 22 11:42 cdr-csv drwxr-xr-x 2 root root 4096 Mar 20 10:11 cdr-custom 405 . Se abre el dialplan: nano /etc/asterisk/extensions.. conf.1 root root 18847 Mar 24 11:10 1000.1 root root 1059 Mar 22 17:45 1002.111111 redondeado = 11 406 endbeforehexten initiatedseconds .1 root root 149285 Mar 23 15:27 messages -rw-r--r-.1.1 root root 1113 Mar 23 16:26 marko2. Asterisk para determinar la duración de una llamada hace un calculo entre los segundos totales de la llamada menos los segundos desde que la llamada ha sido contestada. redondea a los números enteros.csv.csv -rw-r--r-.drwxr-xr-x 2 root root 4096 Mar 20 10:11 cel-custom -rw-r--r-.1 root root 24576 Mar 23 15:21 master. y un archivo por cada extensión/cuenta.db -rw-r--r-. Parámetro [general] enable unanswered Descripción Etiqueta que indica el inicio de la parte general de la configuración yes = se habilita el registro CDR yes = reporta todas las llamadas no contestadas con múltiples destinos y una sola origen.csv 20.222222 – segundos desde que se contestó 10.csv -rw-r--r-. total 72 -rw-r--r-.111111 = tiempo de conversación 10.csv -rw-r--r-.1 root root 2022 Mar 22 17:35 queue_log La carpeta cdr-csv contiene el archivo Master. Con yes el calculo tendrá en cuenta los micro segundos. Ejemplo: segundos de la llamada 20 – segundos desde que se contestó 10 = tiempo de conversación 10 Esto porque a pesar que guarde los datos en micro segundos.conf Lo que se guarda y como se guardan los datos en el CDR depende de la configuración del archivo cdr.1 root root 8055 Mar 22 17:44 1001.1 root root 261 Mar 21 11:09 Mengano.csv -rw-r--r-. yes = se guardan antes de la extensión h (si presente). En negrita el valor asignado a cada parámetro. no = reporta todas las llamadas incluyendo la no contestadas siempre y cuando el destino sea un solo numero/extensión no = los datos se guardan en el CDR cuando ambos canales se hayan terminado.csv -rw-r--r-. Ejemplo: segundos de la llamada 20.1 cdr. Ejemplo: cuando desde una extensión se marca a un grupo de extensiones.1 root root 32149 Mar 24 11:10 Master. En la tabla que sigue los distintos parámetros con una descripción. que contiene la lista de todas las llamadas efectuadas. los datos en el buffer se perderán. . Se deja comentado.safeshutdown=yes [csv] usegmtime loguniqueid loguserfield accountlogs Se renombra el archivo predefinido: mv /etc/asterisk/cdr. la PBX antes de cerrarse guardará los registros CDR presentes en el buffer de memoria En este bloque se define como se guardarán los registros CDR en los archivos csv.old se crea uno nuevo: nano /etc/asterisk/cdr. Si la PBX va en error o el proceso se termina.scheduleronly=no . Para un valor inferior a 10 se pone igual a yes. Utilizar con cuidado. se deja comentado.conf /etc/asterisk/cdr.Parámetro Descripción Esto resuelve el desenlace que a veces se encuentra entre la duración de la llamada presente en el CDR y la duración que factura el proveedor VoIP. este parámetro se pone igual a no. estos se guardarán en los distintos archivos/base de datos. si el parámetro size es mayor que 10.size=100 . cuando en el buffer de memoria se alcancen 100 registros. Se deja comentado. Este parámetro tiene prioridad sobre el parámetro size.conf y se copial las lineas que siguen: [general] enable=yes unanswered=no 407 . yes = los datos se guardan en un buffer de memoria y se escriben solamente cuando se alcance el numero o el tiempo definidos en el próximos dos parámetros. yes = si se para Asterisk.conf.time=300 . no = no se guarda la hora en GMT sino en el huso horario configurado en el servidor yes = en el archivo csv se guarda el campo uniqueID yes = en el archivo csv se guarda el campo userfield yes = se creará un archivo para cada accountcode configurado en Asterisk. cada cuantos segundos guardar los registros del CDR presentes en el buffer de memoria. Valor: yes batch no = los datos se guardan en el CDR cada vez que una llamada termine. 2 cdr_manager.safeshutdown=yes [csv] usegmtime=no loguniqueid=yes loguserfield=yes accountlogs=yes Se guardan los cambios y se recarga la configuración de Asterisk: service asterisk reload Se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvvvv y se revisa la configuración con el comando: CLI> cdr show status Call Detail Record (CDR) settings ---------------------------------Logging: Enabled Mode: Simple Log unanswered calls: No * Registered Backends ------------------mysql csv cdr_sqlite3_custom cdr-custom Adaptive ODBC 20.endbeforehexten=no initiatedseconds=yes batch=no .time=300 .conf Como se ha visto en el parrafo 19.1.scheduleronly=no . entre los permisos que se pueden configurar. Por defecto esta funcionalidad no está activada. en la AMI de Asterisk. en la configuración del los usuarios en el manager. Para volverla disponible.conf. los eventos relacionados con los registros CDR. se abre el siguiente archivo: 408 . hay el parámetro “cdr” que permite recibir.1.size=100 . conf y se modifica esta linea: enabled=no para que quede: enabled=yes Se guardan los cambios y se reinicia el modulo desde la consola de Asterisk: CLI> module reload cdr_manager. entre los distintos eventos.so Si se controla el estado del CDR se notará que la nueva funcionalidad está activada (en negrita): CLI> cdr show status Call Detail Record (CDR) settings ---------------------------------Logging: Enabled Mode: Simple Log unanswered calls: No * Registered Backends ------------------cdr_manager mysql csv cdr_sqlite3_custom cdr-custom Adaptive ODBC Se puede hacer una prueba entrando en la AMI de asterisk: telnet localhost 5038 autenticándose: Action:Login Username:admin Secret:sesamo y efectuando una llamada desde la extensión 1000 a la extensión 1001. Al terminar la llamada.nano /etc/asterisk/cdr_manager. en la AMI aparecerá: 409 . lastapp varchar(80) NOT NULL default ''. dcontext varchar(80) NOT NULL default ''. pronto ese modulo no estará disponible para la instalación.hHkKtTwWxX StartTime: 2012-03-23 17:34:26 AnswerTime: 2012-03-23 17:34:29 EndTime: 2012-03-23 17:34:39 Duration: 13 BillableSeconds: 11 Disposition: ANSWERED AMAFlags: DOCUMENTATION UniqueID: 1332542066.937863 AccountCode: 1000 Source: 1000 Destination: 1001 DestinationContext: externas CallerID: "callerid=Fulano" <1000> Channel: SIP/1000-00000008 DestinationChannel: SIP/1001-00000009 LastApplication: Dial LastData: SIP/1001.8 ha sido etiquetado como “deprecated”. channel varchar(80) NOT NULL default ''. calldate datetime NOT NULL default '0000-00-00 00:00:00'.1. lastdata varchar(80) NOT NULL default ''.all Timestamp: 1332542079. Para probarlo. dst varchar(80) NOT NULL default ''. Para obviar este problema.Event: Cdr Privilege: cdr. 410 . src varchar(80) NOT NULL default ''. dstchannel varchar(80) NOT NULL default ''. una solución es utilizar el modulo cdr_adaptive_odbc que permite utilizar el conector ODBC para conectarse a una tabla de una base de datos y guardar los registros de las llamadas.45.3 CDR adaptive Como el modulo cdr-mysql en la ultima versión de la rama 1.10 UserField: 20. primero se crea una segunda tabla en la base de datos asteriskcdr: mysql -u root -psesamo mysql> use asteriskcdr mysql> CREATE TABLE cdr2 ( id bigint(20) NOT NULL auto_increment. clid varchar(80) NOT NULL default ''. billsec int(11) NOT NULL default '0'. se copian las siguientes lineas: [asteriskcdr] enabled => yes dsn => asteriskcdr username => asterisk password => sesamo pre-connect => yes sanitysql => select 1 idlecheck => 3600 connect_timeout => 10 411 . accountcode varchar(20) NOT NULL default ''.duration int(11) NOT NULL default '0'. Se sale del cliente MySQL y se configura el odbc. peeraccount varchar(20) NOT NULL default ''. linkedid varchar(80) NOT NULL default ''. amaflags int(11) NOT NULL default '0'. uniqueid varchar(32) NOT NULL default ''.ini: mysql> quit nano /etc/odbc.conf y al final del archivo. PRIMARY KEY (`id`). userfield varchar(255) NOT NULL default ''. disposition varchar(45) NOT NULL default ''.ini Al final del archivo se añaden las siguientes lineas: [asteriskcdr] Description = MySQL AsteriskCDR Driver = MySQL Database = asteriskcdr Server = localhost User = asterisk Password = sesamo Port = 3306 Option = 3 Se pasa al archivo res_odbc: nano /etc/asterisk/res_odbc. KEY callerid (clid) ). conf': == Found [Mar 27 15:40:32] NOTICE[11036]: res_odbc.c:1511 odbc_obj_connect: res_odbc: Connected to asteriskcdr [asteriskcdr] [Mar 27 15:40:32] NOTICE[11036]: res_odbc.old se crea uno nuevo: nano /etc/asterisk/cdr_adaptive_odbc. El campo calldate no existe.c:902 load_odbc_config: Registered ODBC class 'asterisk' dsn->[asterisk] [Mar 27 15:40:32] NOTICE[11036]: res_odbc.conf.c:902 load_odbc_config: Registered ODBC class 'asteriskcdr' dsn->[asteriskcdr] 412 . cuando se contesta y cuando se termina.c:1481 odbc_obj_connect: Connecting asteriskcdr [Mar 27 15:40:32] NOTICE[11036]: res_odbc.Por ultimo se configura el archivo cdr_adaptive_odbc. Esto se hace indicando un alias y definiendo que el campo calldate contendrá el valor del campo start de cdr_adaptive (cuando la llamada inicia).conf mv /etc/asterisk/cdr_adaptive_odbc.c:1511 odbc_obj_connect: res_odbc: Connected to asterisk [asterisk] [Mar 27 15:40:32] NOTICE[11036]: res_odbc.conf Reloading module 'res_odbc.conf y se copian las siguientes lineas: [cdr2] connection=asteriskcdr table=cdr2 alias start => calldate • • • • [cdr2]: un nombre que se le asigna a la conexión connection=asteriskcdr: en este parámetro hay que poner la etiqueta que define el bloque creado en res_odbc. answer y end.conf /etc/asterisk/cdr_adaptive_odbc. Se guardan los cambios y se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvv se recarga el moudlo res_odbc y luego el modulo cdr adaptive: CLI> module reload res_odbc.c:1481 odbc_obj_connect: Connecting asterisk [Mar 27 15:40:32] NOTICE[11036]: res_odbc.so' (ODBC resource) == Parsing '/etc/asterisk/res_odbc. Los nombres de estos campos son respectivamente start.conf table=cdr2: la tabla MySQL donde se guardarán los datos alias start => calldate: en cdr_adaptive hay tres campos donde se guardan diferentes momentos de la llamada: cuando inicia. Por este motivo para que este campo contenga un valor hay que escoger unos de los tres que crea cdr_adaptive. '1000'.10) > Found disposition column with type 12 with len 45. and numlen (0. and numlen (0.'Dial'.3.src.'"callerid=Fulano" <1000>'. octetlen 255. and numlen (0. octetlen 80.dst. Al terminar la llamada.CLI> module reload cdr_adaptive_odbc.'1000'.0) > Found dcontext column with type 12 with len 80.0) > Found linkedid column with type 12 with len 80.dcontext.12. and numlen (0.'SIP/1001. and numlen (0.0) > Found duration column with type 4 with len 10.'SIP/100100000010'.channel. > Found id column with type -5 with len 19.lastapp. and numlen (0.0) > Found amaflags column with type 4 with len 10.0) > Found userfield column with type 12 with len 255.10) > Found clid column with type 12 with len 80.0) > Found uniqueid column with type 12 with len 32. and numlen (0. en la consola de Asterisk aparecerá: [INSERT INTO cdr2 (calldate.0) > Found lastapp column with type 12 with len 80.conf': == Found -.linkedid) VALUES ({ ts '2012-03-27 15:49:17' }. Otra cosa que se puede hacer con el modulo CDR Adaptive 413 .amaflag s.so Reloading module 'cdr_adaptive_odbc. octetlen 80.billsec. and numlen (0.dstchannel. octetlen 20. octetlen 19. and numlen (0.10. and numlen (0.0) > Found src column with type 12 with len 80.duration. and numlen (0.clid. octetlen 10.0) Ahora se puede efectuar una primera prueba. octetlen 80. and numlen (0. octetlen 80. and numlen (0. octetlen 80.lastdata. and numlen (0. octetlen 45.'1332881357. and numlen (0.disposition.10) -. octetlen 80. octetlen 10.0) > Found peeraccount column with type 12 with len 20.'ANSWERED'.45.0) > Found dstchannel column with type 12 with len 80.10) > Found accountcode column with type 12 with len 20.Found adaptive CDR table cdr2@asteriskcdr.'SIP/1000-0000000f'.'externas'.Found alias start for column calldate in cdr2@asteriskcdr > Found calldate column with type 93 with len 19. octetlen 20.17'.accountcode. octetlen 32.0) > Found channel column with type 12 with len 80. octetlen 80. Desde la extensión 1000 se marca a la extensión 1001.'1001'.0) > Found dst column with type 12 with len 80. octetlen 19.so' (Adaptive ODBC CDR backend) == Parsing '/etc/asterisk/cdr_adaptive_odbc. and numlen (0.hHkKtTwWxX'.uniqueid.'13328813 57. octetlen 80. and numlen (0.10) > Found billsec column with type 4 with len 10. En la tabla: La misma entrada estará en la tabla CDR.17')] Que indica que los datos de la llamada se han guardado en la tabla CDR2. and numlen (0. and numlen (0. octetlen 10.0) > Found lastdata column with type 12 with len 80. octetlen 80. es filtrar los datos que se van a guardar en la tabla. channel varchar(80) NOT NULL default ''.conf Al final del archivo se añade el siguiente bloque: [cdr3] connection=asteriskcdr table=cdr3 alias start => calldate filter src => 1000 414 . lastapp varchar(80) NOT NULL default ''. disposition varchar(45) NOT NULL default ''. calldate datetime NOT NULL default '0000-00-00 00:00:00'. userfield varchar(255) NOT NULL default ''. Se sale del cliente MySQL: mysql> quit Luego se modifica el archivo cdr_adaptive_odbc. src varchar(80) NOT NULL default ''.conf: nano /etc/asterisk/cdr_adaptive_odbc. accountcode varchar(20) NOT NULL default ''. PRIMARY KEY (`id`). En el ejemplo que sigue se guardarán en una nueva tabla solamente las llamadas originadas por la extensión 1000. clid varchar(80) NOT NULL default ''. dstchannel varchar(80) NOT NULL default ''. KEY callerid (clid) ). lastdata varchar(80) NOT NULL default ''. dst varchar(80) NOT NULL default ''. dcontext varchar(80) NOT NULL default ''. amaflags int(11) NOT NULL default '0'. peeraccount varchar(20) NOT NULL default ''. duration int(11) NOT NULL default '0'. linkedid varchar(80) NOT NULL default ''. mysql -u root -psesamo mysql> use asteriskcdr mysql> CREATE TABLE cdr3 ( id bigint(20) NOT NULL auto_increment. uniqueid varchar(32) NOT NULL default ''. billsec int(11) NOT NULL default '0'. 'SIP/1000-00000015'.'133288211 2.uniqueid. la llamada no se guardará en la tabla CDR3.'1000'. Al finalizar la llamada en la consola aparecerá: > CDR column 'src' with value '1001' does not match filter of '1000'. Como el campo src tiene como valor 1001 y el filtro se ha creado para el valor 1000.src.'SIP/100100000016'. Esto porque su lógica se basa en tres eventos principales: • • • inicio de la llamada duración de la conversación finalización de la llamada El tiempo que se facturará es la diferencia entre la duración total de la llamada y el duración de la conversación. Cancelling this CDR.hHkKtTwWxX'.disposition.'1332882112.channel.dst.'ANSWERED'.'externas'.'"callerid=Fulano" <1000>'.2 CEL (Channel Event Logging) Aunque parezca que el CDR responda a todas las necesidades de los administradores de la PBX.dcontext.clid.so Con la consola abierta desde la extensión 1001 se llama la extensión 1000.dstchannel.amaflag s.'SIP/1001.'1001'.23')] Los datos de la llamada se guardarán en la tabla CDR3 20. El problema es que con este tipo de lógica. tiene unas cuantas limitaciones.duration.23'. Algunos ejemplos: • • transferencia de la llamada a otra extensión transferencia de la llamada a una conferencia 415 .lastapp.8.billsec.lastdata.3.'Dial'.linkedid) VALUES ({ ts '2012-03-27 16:01:52' }.• filter src => 1000: en la tabla se guardarán solamente los registros de las llamadas originadas por la extensión 1000 Se guardan los cambios y se entra en la consola de Asterisk: asterisk -rvvvvvvvvvvvvvvvvvvv En este caso se recarga solamente el modulo CDR adaptive: CLI> module reload cdr_adaptive_odbc. es muy complicado tener una traza de todos los eventos que se pueden presentar a lo largo de la llamada. Si ahora desde la extensión 1000 se llama la extensión 1001: [INSERT INTO cdr3 (calldate.11.accountcode.'1000'.45. Todos estos tipos de eventos.conf. El CEL. De esta forma es posible tener un registro mucho más detallado de las llamadas. dificultan una correcta facturación y seguimiento de llamada. no sustituye el CDR. En la tabla que sigue los distintos parámetros con una descripción. El CEL a diferencia del CDR. En negrita el valor asignado a cada parámetro. en su desarrollo actual. sin embargo la combinación de los dos permite un control y monitoreo de las llamadas muchos más detallado y completo. Parámetro [general] enable apps Descripción inicia la parte general de la configuración del archivo yes = se activa el registro de los eventos del modulo CEL en este parámetro se especifica la lista de las aplicaciones por las cuales se quiere recibir los eventos. En este párrafo se ilustrará la configuración del modulo y como guardar los eventos en una tabla de una base de datos utilizando el conector ODBC. separados por una coma.queue.8 de Asterisk se ha añadido un nueva funcionalidad: el CEL (Channel Event Logging). Lo primero es configurar el archivo cel. Si se indica “all” se recibirán los eventos de todas las aplicaciones. basa su lógica sobre el canal de la llamada y va guardando todos los eventos que se van generando en ese canal.park. Utilizar con cuidado ya que puede afectar el rendimiento de la PBX Valor: dial.• • parqueo y/o captura de la llamada por otra extensión ejecución de un AGI a lo largo de la llamada. de los que se quieres tener traza Estos son: • ALL: todos • CHAN_START: fecha en que se ha creado el canal • CHAN_END: fecha en que el canal se ha terminado • ANSWER: fecha en que el canal ha sido contestado • HANGUP: fecha en que se ha presentado un Hangup (cierre del canal) • CONF_ENTER: fecha en que un canal ha sido enviado a una conferencia audio • CONF_EXIT: fecha en que un canal ha salido de una conferencia audio • CONF_START: fecha en que el primer usuario ha entrado a una conferencia • CONF_END: fecha en que el ultimo usuario presente ha dejado una conferencia audio (y posiblemente apagado todas las luces :) • APP_START: fecha en que la aplicación se ha iniciado • APP_END: fecha en que la aplicación ha terminado • PARK_START: fecha en que el canal ha sido parqueado events 416 . Es por eso que desde la versión 1.meetme En este parámetro se indica una lista de eventos. Valor: All dateformat [manager] enabled El formato de la fecha presente por cada evento. se puede crear el archivo de configuración para CEL.conf y se añaden las siguientes lineas: [general] enable=yes apps=dial.conf.Parámetro • Descripción PARK_END: fecha en que el canal ha sido sacado del “slot” de parqueo • BRIDGE_START: fecha en que el canal ha sido conectado con otro canal • BRIDGE_END: fecha en que ha terminado la conexión con otro canal • 3WAY_START: fecha en que ha iniciado una conferencia a 3 (normalmente con una transferencia asistida) • 3WAY_END: fecha en que una conferencia a 3 ha sido terminada • BLINDTRANSFER: fecha en que ha iniciado una transferencia ciega • ATTENDEDTRANSFER: fecha en que ha iniciado una transferencia asistida • TRANSFER: fecha en que se ha iniciado una transferencia • HOOKFLASH: fecha en que se ha iniciado un “descolgado relampago” en un canal DAHDI (normalmente utilizado para contestar llamadas en espera o para activar la conferencia a 3) • USER_DEFINED: evento personalizado que se puede enviar desde el dialpla a través de la aplicación CELGenUserEvent Para esta prueba se recibirán todos los eventos. Se renombra el predefinido: mv /etc/asterisk/cel.park.queue.conf /etc/asterisk/cel.old se crea uno nuevo: nano /etc/asterisk/cel.meetme events=all dateformat=%F %T [manager] 417 . Valor: %F %T a partir de esta etiqueta inicia la configuración de CEL para la AMI de Asterisk yes = se activa el envío de los eventos a la AMI de Asterisk Con estos datos. userfield VARCHAR( 255 ) NOT NULL .enabled=yes Se guardan los cambios y se recarga la configuración de Asterisk: service asterisk reload Ahora falta crear la tabla y luego crear una conexión a la misma a través de ODBC. appdata VARCHAR( 80 ) NOT NULL . exten VARCHAR( 80 ) NOT NULL . cid_dnid VARCHAR( 80 ) NOT NULL . mysql> GRANT ALL PRIVILEGES ON asteriskcel. cid_num VARCHAR( 80 ) NOT NULL .* TO 'asterisk'@'localhost' IDENTIFIED BY 'sesamo'. cid_ani VARCHAR( 80 ) NOT NULL . uniqueid VARCHAR( 150 ) NOT NULL . userdeftype VARCHAR( 255 ) NOT NULL . Se entra en cliente mysql: mysql -u root -psesamo Se crea la base de datos. la tabla y el usuario con los permisos: mysql> create database asteriskcel mysql> use asteriskcel mysql> CREATE TABLE cel( eventtime TIMESTAMP NOT NULL . cid_rdnis VARCHAR( 80 ) NOT NULL . Se sale del cliente: mysql> quit Ahora los pasos a seguir son: 418 . linkedid VARCHAR( 150 ) NOT NULL . amaflags INT NOT NULL . peeraccount VARCHAR( 20 ) NOT NULL . appname VARCHAR( 80 ) NOT NULL . peer VARCHAR( 80 ) NOT NULL ). accountcode VARCHAR( 20 ) NOT NULL . channame VARCHAR( 80 ) NOT NULL . cid_name VARCHAR( 80 ) NOT NULL . context VARCHAR( 80 ) NOT NULL . ini y al final se añade el siguiente bloque: [asteriskcel] Description = MySQL AsteriskCEL Driver = MySQL Database = asteriskcel Server = localhost User = asterisk Password = sesamo Port = 3306 Option = 3 Se guarda los cambios y se prueba la nueva conexión: isql asteriskcel asterisk sesamo +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL> quit Se pasa al archivo res_odbc.conf: nano /etc/asterisk/res_odbc.conf Configurar el archivo cel_odbc.conf se añade el siguiente bloque: [asteriskcel] enabled => yes dsn => asteriskcel username => asterisk password => sesamo pre-connect => yes 419 .conf Se abre el archivo odbc.ini: nano /etc/odbc.ini Crear un nuevo bloque en el archivo res_odbc.• • • Crear uno nuevo bloque en el archvo odbc. so Se averigua que haya conexión con ODBC: CLI> odbc show ODBC DSN Settings ----------------Name: asterisk DSN: asterisk Last connection attempt: 1969-12-31 19:00:00 Pooled: No Connected: Yes Name: asteriskcdr 420 .ini Por ultimo se modifica el archivo cel_odbc.conf /etc/asterisk/cel_odbc.conf.old nano /etc/asterisk/cel_odbc.so: CLI> module reload res_odbc.conf Se copian las siguientes lineas: [CEL1] connection=asteriskcel table=cel • • • CEL1:nombre que se le quiere asignar a la conexión asteriskcel: tiene que ser el mismo valor con que inicia el bloque que se ha configurado en el archivo res_odbc.conf cel: nombre de la tabla que se ha creado y donde se guardarán los nuevos registros Se guarda los cambios y se entra en la consola de Asteirsk: asterisk -rvvvvvvvvvvvv Se recarga primero el module res_odbc.conf: mv /etc/asterisk/cel_odbc.sanitysql => select 1 idlecheck => 3600 connect_timeout => 10 El valor que aparece en el parámetro dns tiene que ser el mismo con que inicia el bloque que se acaba de configurar en el archivo odbc. 421 .so CLI> module reload cel_odbc.uniqueid.appdata.so Ahora desde la extensión 1001 se llama la extensión 1000 y utilizando el botón “Transfer” del softphone 3CX se transfiere la llamada a la conferencia numero 3500.DSN: asteriskcdr Last connection attempt: 1969-12-31 19:00:00 Pooled: No Connected: Yes Name: asteriskcel DSN: asteriskcel Last connection attempt: 1969-12-31 19:00:00 Pooled: No Connected: Yes Se recarga el modulo cel_odbc. desde la extensión 1001 se marca el mismo numero de conferencia (3500). El resultado en la tabla CEL será: CLI> quit mysql -u root -psesamo mysql> use asteriskcel mysql> select eventtime.context.channame.exten. Una vez que las dos extensiones estén en la conferencia. Cuando la extensión 1000 esté en la conferencia.linkedid from cel.appname. primero cuelga la 1000 y luego la 1001. Valor no define si se quiere guardar o no las estadísticas de las colas de espera en un archivo. Para evitarlo se pueden “rotar” y con este parámetro se define que tipo de rotación se va a utilizar: • secuential – se renombran los archivos siguiendo un orden donde el más reciente tendrá un numero más alto. • rotate – se renombran los archivos siguiendo un orden donde el más viejo tendrá el numero más alto • timestamp – se renombran los archivos añadiendo al nombre la fecha en que se archivaron esta etiqueta define el inicio de la configuración de los archivos de registro. En negrita el valor asignado a cada parámetro. se define en el archivo logger. Valor queue_log yes = las estadísticas de las colas se siguen guardando en el archivo queue_log aunque estén configuradas en Realtime. Parámetro [general] dateformat appendhostname queue_log queue_log_name queue_log_to_file rotatestrategy Descripción inicia la parte general de la configuración del archivo formato de la fecha. Cada archivo puede contener los siguientes valores: • debug • notice • warning • error • verbose • dtmf • fax (desde la versión 1. Valor yes El nombre del archivo donde guardar las estadísticas de la colas de espera.conf.8 de Asterisk) debug – se crea un archivo donde se guardará solamente el debug de 422 [logfiles] debug => . En la tabla que sigue los distintos parámetros con una descripción.%F %T si se quiere añadir o no al nombre del archivo el nombre del dominio del servidor. Normalmente los archivos de Log pueden alcanzar un tamaño considerable que dificulta su consulta. Predefinido ISO 8601 . es posible tener traza del funcionamiento de Asterisk (errores. Que tipo de archivos y que tipo de registros se quieren guardar. advertencias) en archivos de texto que se guardan en la carpeta /var/log/asterisk.20.3 Logger.conf Además de las llamadas. Parámetro la actividad de Asterisk verbose => fax => console => Descripción verbose – se crea un archivo donde guardar muy en detalle los registros de la actividad de Asterisk fax – se crea un archivo donde se guardarán los registros de actividad del envío/recepción de FAX notice.dtmf. Se indica que tipo de registros aparecerán en la consola de Asterisk.old y se crea uno nuevo: nano /etc/asterisk/logger. Para definir estas políticas hay que instalar el programa Logrotate que se encarga de este tipo de tarea. yum install logrotate 423 . messages => error => Para crear el nuevo archivo.dtmf error => error Se guardan los cambios y se pasa a la definición de las política de rotación de los archivos de registro.error.fax El archivo console no es propiamente un archivo.conf Se copian las siguientes lineas: [general] dateformat=%F %T appendhostname=no queue_log=yes queue_log_name=queue_log queue_log_to_file=yes rotatestrategy=rotate [logfiles] debug => debug verbose => verbose fax => fax console => notice.dtmf.warning.dtmf En el archivo messages se guardarán solamente los registros relacionados con noticias. se renombra el predefinido: mv /etc/asterisk/logger. advertencias.warning.conf.debug.debug.warning.warning.conf /etc/asterisk/logger. notice. DTMF y fax error En el archivo error se guardarán solamente los errores.error.fax messages => notice. debug y verbose La rotación será diaria y se crearán un máximo de 7 archivos secuenciales (archivo.2 .conf en asterisk.d logrotate -fv asterisk Para aplicar los cambios desde la consola de Asterisk: asterisk -rvvvvvvvvvvvvvv 424 .). etc. Después de la rotación (postrotate) se actualiza la configuración del archivo logger. En este caso el archivo rotará cuando alcanzará un tamaño de 1000 Kbyte y se creerán un máximo de 5 archivos secuenciales.1 archivo. El más antiguo tendrá el numero secuencial más alto. Para testar el archivo de configuración creado el procedimiento es: cd /etc/logrotate.Una vez instalado se crea un nuevo archivo donde se va a definir la rotación de los archivos de Log de Asterisk: nano /etc/logrotate. El segundo bloque define la política de rotación del archivo de registro queue_log (las estadísticas de las colas de espera). error.d/asterisk Se copian las siguientes líneas: /var/log/asterisk/messages /var/log/asterisk/error /var/log/debug /var/log/verbose { 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=1000k postrotate /usr/sbin/asterisk -rx 'logger reload'> /dev/null 2> /dev/null endscript } El primer bloque define la rotación para los archivos messages. NOTICE WARNING DTMF Console Enabled .------------/var/log/asterisk/error File Enabled . 425 . Esto se hace con un comando especifico: asterisk -rvvvvvvvvvvvvvvvvvvvvv CLI> core set debug 9 El nivel de debug va de 0 (ningún debug) a 9 (máximo debug). se puede utilizar este archivo para encontrar eventuales errores. De esta forma las informaciones que se reciben acerca de las operaciones efectuadas por Asterisk son mucho más detalladas y en la mayoría de los casos permite solucionar el problema.se escribe: CLI> logger reload Para ver la configuración del archivo: CLI> logger show channels Channel Type Status Configuration ---------. Como en el logger.FAX /var/log/asterisk/debug File Enabled .DEBUG NOTICE WARNING ERROR DTMF FAX /var/log/asterisk/fax File Enabled . hay la posibilidad de aumentar el nivel de debug de la consola para buscar el tipo de problema que está afectando el funcionamiento de la PBX.conf y se podrán revisar los errores en el archivo error: nano /var/log/asterisk/error De esta forma en cualquier momento se tendrá bajo control el funcionamiento de Asterisk. ademas de la consola.3.ERROR /var/log/asterisk/messages File Enabled .DEBUG /var/log/asterisk/verbose File Enabled . 20.-----.1 Debug Cuando algo no está funcionando en Asterisk.VERBOSE CLI> quit Se reinicia Asterisk service asterisk restart En la carpeta /var/log/asterisk estarán presentes los archivos configurados en logger.conf se ha definido que el debug se guardará en el archivo “debug”. se puede utilizar también la utilidad ngrep. Para buscar algo especifico se puede utilizar el programa “cat” junto al programa “grep”. 426 . troncal: CLI> sip set debug peer justvoip Como se ha visto en el párrafo 3. Un ejemplo: cat /var/log/asterisk/debug | grep odbc De esta forma todas la lineas del archivo debug que contengan la palabra odbc aparecerán en la ventana terminal.De hecho si se vuelve a desactivar el debug: CLI> core set debug 0 se sale de la consola de Asterisk: CLI> quit y se abre el archivo: nano /var/log/asterisk/debug se verá que ese archivo contiene todo el debug generado desde que se ha activado en la consola. desde la consola se puede activar el debug de este protocolo con el siguiente comando: asterisk -rvvvvvvvvvvvvvvvvvvvvv CLI> sip set debug on Si se quiere limitar el debug solamente a una determinada extensión. El primero lee un archivo y devuelve su contenido en la ventana terminal de Linux. La consulta de estos archivos puede ser bastante complicada si se ha generado una cantidad considerable de registros.4 . grep permite buscar una determinada palabra o frase en un archivo. Si se quiere enviar el resultado a un archivo: cat /var/log/asterisk/debug | grep odbc > odbc En el caso el problema sea con la señalización SIP. . conf el parámetro alwaysauthreject=yes.4. 7. 4. no aceptar llamadas entrantes de invitados. recibirá como respuesta que la extensión no existe. configurar Iptables de modo que acepte el trafico solo desde determinadas direcciones IP. un programa que lee los registros de Asterisk del archivo /var/log/asterisk/messages y si hay un numero determinado de intentos de conexión sin éxito.sourceforge. configurar en la parte general del sip..4/fail2ban0. En el caso que se necesite utilizar el AMI desde remoto.net/project/fail2ban/fail2ban-stable/fail2ban-0. Si se decide aceptar llamadas entrantes de invitados (sin autentificación).bz2 . Esto se configura con el parámetro allowguest=no en la parte general del sip. Utilizar números o nombres de extensiones largos y no fácilmente memorizables.200. interactuando con iptables (cortafuegos).4.200 -j ACCEPT Con esta linea se podrá conectar desde remoto al AMI de Asterisk solamente la maquina con IP 192. es posible instalar en el servidor Asterisk Fail2Ban. Un ejemplo es esta linea: -A INPUT -p tcp -m state --state NEW -m tcp --dport 5038 -s 192. el contexto definido en la parte general del sip. 21.168.tar.tar. Ademas de estas 7 reglas. 2.8. No permitir el acceso al AMI de Asterisk desde remoto (teniendo cerrado el puerto 5038 TCP del servidor Linux.142. De esta forma cualquier intento de registro a extensiones existentes en la centralita.8. Utilizar las funciones GROUP y GRUP_COUNT para limitar las llamadas salientes de las extensiones. bloquea la IP de donde se han originados. Otra forma es utilizar el protocolo TLS.2 Fail2ban Se descarga el programa: cd /usr/src wget http://downloads.168.1 Reglas de oro Hay una reglas de oro que se necesita seguir en la configuración de Asterisk. evitando dar trazas al atacante 5.conf.8. 6.conf no debe permitir el acceso a troncales SIP y/o lineas telefónicas tradicionales. Estas reglas permiten mejorar la seguridad de la PBX y evitar ataques exitosos: 1. no utilizar la misma contraseña para todas las extensiones 3. utilizar siempre contraseñas bastantes largas y difíciles de memorizar.bz2 se descomprime: tar -xf fail2ban-0.Capitulo XXI Seguridad en Asterisk 21.142. *) NOTICE.4 y se instala: python setup.Wrong password NOTICE.local #before = common.* .*' failed for '<HOST>(:[0-9]{1.*: Host <HOST> failed MD5 authentication for '.*: Registration from '.*' \(from <HOST>\) NOTICE.* .se entra en la carpeta: cd fail2ban-0.*: Registration from '.6}:)?(?P<host>\S+) # Values: TEXT # failregex = NOTICE.4/files/redhat-initd /etc/init.* .*' failed for '<HOST>(:[0-9]{1.5})?' .*' (.*'$ NOTICE. If any customizations available -.* .: regex to match the password failures messages in the logfile.*' failed for '<HOST>(:[0-9]{1.*@<HOST>.* .* NOTICE.*: <HOST> failed to authenticate as '.*' failed for '<HOST>(:[0-9]{1.* 429 .5})?' .Peer is not supposed to register NOTICE.read them from # common.*: No registration for peer '.* .Device does not match ACL NOTICE.* .conf [Definition] #_daemon = asterisk # Option: failregex # Notes.5})?' .*: Sending fake auth rejection for device .* .d/fail2ban chkconfig --add fail2ban chkconfig fail2ban on Se configura para que lea los registros de Asterisk: cd /etc/fail2ban/filter.conf y se añaden estas líneas: # Fail2Ban configuration file # [INCLUDES] # Read common prefixes. The # host must be matched by a group named "host".*@<HOST>.*: Registration from '.*' failed for '<HOST>(:[0-9]{1.d nano asterisk.5})?' .* .py install Se activa el script para arrancarlo como servicio: cp /usr/src/fail2ban-0.*: Failed to authenticate user .5})?' .No matching peer found NOTICE.8.* .Username/auth name mismatch NOTICE.8.*: Registration from '.*: Registration from '. The tag "<HOST>" can # be used for standard IP/hostname matching and is only an alias for # (?:::f{4. # 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. Con esta configuración cuando se verifiquen 5 ataques del mismo tipo procedentes de la misma IP. fail2ban está configurado con Sendmail.org] logpath = /var/log/asterisk/messages 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. the line is ignored.org se pone fail2ban@nombrededominio del servidor donde está instalado Asterisk. Se termina modificando el archivo de configuración general de fail2ban: cd /etc/fail2ban nano jail. Para enviar los correos. en lugar de fail2ban@pbx. En la configuración hay que modificar la dirección de correo electrónico.d/fail2ban start Starting fail2ban: [ OK ] 430 . If this regex matches. protocol=all] sendmail-whois[name=ASTERISK. [email protected] Se inicia fail2ban: /etc/init.# Option: ignoreregex # Notes.: regex to ignore. sender=fail2ban@pbx. En lugar de root@localhost se pone la dirección de correo electrónico donde se quiere recibir las notificaciones.dyndns.conf en la siguiente linea esté presente el valor notice (configuración predefinida): messages => notice. Fail2ban bloqueará el IP insertando una nueva linea en el archivo de configuración de Iptables y la mantendrá bloqueada por 1800 segundos. Para que funcione hay que averiguar que en el archivo de configuración de Asterisk nano /etc/asterisk/logger. En sender.conf al final del archivo se añaden las lineas que siguen: [asterisk-iptables] enabled = true filter = asterisk action = iptables-allports[name=ASTERISK.warning.dyndns. 431 . la única forma de quitar el bloqueo es parar y reiniciar Iptables o reiniciar el servidor Linux.log Si se quiere hacer una prueba se configura en X-lite una extensión que no existe en el sistema y se intenta registrarla a Asterisk: La IP de donde se está intentando registrarse será bloqueada.Se averigua que no haya errores en el log de fail2ban: tail -f /var/log/fail2ban. Accediendo a la consola del servidor remoto desde otra dirección IP con el comando: iptables -L se verá la IP bloqueada: Desde el log de fail2ban: Si por error se bloquea la IP de un computador. . monit /etc/init.tar.d/monit chmod +x /etc/init.2.3. archivos.gz cd monit-5.com/monit/dist/monit-5.tar.3.gz tar -xf monit-5.1 Monit Monit es un programa Open Source para la gestión y el monitoreo de procesos. carpetas y particiones de un sistema Linux./configure --prefix=/usr make make install Se termina la instalación con la copia y activación del script de inicio de monit: cd contrib cp rc.2 Se compila y se instala: .2.3. programas. 22.Capitulo XXII Monitorear Asterisk En este capitulo se ilustrará como monitorear Asterisk y el servidor Linux a través de dos distintos programas: • • Monit Nagios y el protocolo SNMP Se ilustrará también como monitorear la calidad de las llamadas directamente desde la consola de Asterisk y a través del programa VoIPmonitor.d/monit chkconfig --add monit . Se instalará desde las fuentes: cd /usr/src wget http://mmonit. Permite programar tareas de mantenimiento y de corrección de errores cuando se verifiquen problemas en el sistema. log # Nombre del archivo donde se guardarán todos los registros de Monit set idfile /var/. nano /etc/monitrc set daemon 60 # Indica cada cuantos segundos Monit controla los servicios (en este caso cada 60) with start delay 30 # Al iniciar el programa el primer ciclo se ejecutará después de 30 segundos set logfile /var/log/monit. aquí se pone la configuración general del programa Services. donde se configuran los servicios Includes: permite incluir a la configuración de Monit otros archivo que contienen a su vez la configuración de otros procesos.chkconfig monit on Ahora se modifica el archivo de configuración para monitorear los siguientes programas: • • • • Sendmail MySQL Asterisk la troncal Justvoip El archivo de configuración de Monit se divide en tres bloques: • • • Global Section.org Subject: monit alerta -. Cuando el servidor volverá a funcionar.$EVENT $SERVICE Message: $EVENT Servicio $SERVICE Fecha: $DATE Accion: $ACTION 434 .id # Nombre de la carpeta y archivo donde se guardará el numero del proceso de Monit set mailserver localhost # nombre del host del servidor de correo electrónico que Monit utilizará para enviar las alertas set eventqueue basedir /var/monit slots 100 # Si por alguna razón el servidor de correo electrónico no esté funcionando podemos decirle a Monit de # guardar todas las alerta en una determinada carpeta.monit. todas las # alertas serán enviada siguiendo el orden cronológico en que se guardaron set mail-format { From: monit@libroasterisk. pid start program = "/etc/init.com maxforward 10 then alert # SendMail check process sendmail with pidfile /var/run/sendmail.d/asterisk start" with timeout 60 seconds stop program = "/etc/init.com # Con esta línea se define el correo electrónico que recibirá todas las alertas (personalizar) set httpd port 2812 allow admin:sesamo # Monit viene con un servidor Web. Monit } # Con el bloque de arriba. En las dos lineas de arriba se activa en el puerto 2812 # (que hay que abrir en el cortafuegos) y se define nombre de usuario y contraseña para ingresar a la # pagina # Servidor Linux check system cursoasterisk.d/sendmail stop" if failed port 25 protocol smtp then restart if 5 restarts within 5 cycles then timeout 435 .justvoip.1 port 5038 then restart if 5 restarts within 5 cycles then timeout # Troncal SIP check host Justvoip with address sip.pid group mail start program = "/etc/init. se define como tiene que ser enviado el correo electrónico de alerta set alert [email protected]/sendmail start" stop program = "/etc/init.justvoip.0.Host: $HOST Descripcion: $DESCRIPTION Tu devoto empleado.com if failed port 5060 type udp protocol SIP and target [email protected]/asterisk stop" with timeout 60 seconds if failed host 127.0.org if loadavg (1min) > 4 then alert if loadavg (5min) > 2 then alert if memory usage > 75% then alert if cpu usage (user) > 70% then alert if cpu usage (system) > 30% then alert if cpu usage (wait) > 20% then alert # Asterisk check process asterisk with pidfile /var/run/asterisk/asterisk. d/mysqld start" stop program = "/etc/init. hay que abrir el puerto 2812 TCP para tener acceso al servidor Web interno de Monit: nano /etc/sysconfig/iptables antes de este bloque: # DUNDi -A INPUT -p udp -m udp --dport 4520 -j ACCEPT se añade: # Monit -A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT Se guardan los cambios y se reinicia iptables service iptables restart Después de unos minutos se puede acceder a la pagina de administración de Monit: http://ipservidor:2812 436 .# MySQL check process mysql with pidfile /var/run/mysqld/mysqld.d/mysqld stop" if failed port 3306 protocol mysql then restart if 5 restarts within 5 cycles then timeout Se guardan los cambios y se cambian los permisos del archivo de configuración: chmod 700 /etc/monitrc Se inicia Monit: /etc/init.pid group database start program = "/etc/init.d/monit start En el cortafuegos. Nombre de usuario: admin Contraseña: sesamo Una vez entrados en la Web de Monit. el pagina principal aparecerán todos los procesos/programas monitoreados: y en el caso del servidor Linux: 437 . Cualquier problema se presente con el servidor y/o con los procesos/programas configurados. se recibirá una notificación al correo electrónico configurado. Se sale de la consola de Asterisk: 438 . SNMP permite a los administradores supervisar el funcionamiento de la red.” De hecho a través de este protocolo se monitorean servidores. buscar y resolver sus problemas. y planear su crecimiento. 22. Asterisk implementa el protocolo SNMP y a través de ese protocolo es posible monitorear muchos parámetros de la PBX. Para empezar se averigua si el modulo res_snmp está instalado y cargado en Asterisk: asterisk -rvvvvvvvvvvvvvvv CLI> module show like snmp Significa que el modulo está instalado. switch y casi cualquier tipo de aparado conectado a la red (local o remota).2 SNMP Una definición del protocolo SNMP tomada de wikipedia: “El Protocolo Simple de Administración de Red o SNMP es un protocolo de la capa de aplicación que facilita el intercambio de información de administración entre dispositivos de red. router. Es parte de la familia de protocolos TCP/IP. XXX.conf.old nano /etc/asterisk/res_snmp.org/tmp/digium-mib. cd /usr/share/snmp/mibs wget http://www.CLI> quit Se configura el modulo: mv /etc/asterisk/res_snmp.voztovoice.conf /etc/asterisk/res_snmp. Ejemplo: se puede conocer el numero de llamadas totales cursadas por la centralita desde su ultimo arranque.old y se crea uno nuevo: nano snmpd.voztovoice.conf donde se ponen las siguientes líneas: master agentx agentXPerms 0660 0550 root root com2sec local localhost public com2sec remote XXX.XXX. Un OID (identificador de objeto) es una cadena alfanumérica que se utiliza para identificar de forma única un objeto que en el caso del protocolo SNMP representa un determinado parámetro del dispositivo que se quiere monitorear.conf snmpd.org/tmp/asterisk-mib.conf.XXX public group asterisk v1 local group asterisk v2c local 439 .txt Ahora se configura SNMP de modo que pueda interactuar con Asterisk: cd /etc/snmp Se renombra el archivo de configuración predefinido: mv snmpd.conf Se añaden las siguientes lineas: [general] subagent = yes enabled = yes Se guardan los cambios y se descargan los OID de Asterisk en la carpeta de SNMP.txt wget http://www. 7 = STRING: DAHDI Se anotan los valores que aparecen en negrita y el tipo de canal asociado. Luego se definen dos comunidades.1 access asterisk "" any noauth exact all none none access NetWork "" any noauth exact all none none Una explicación. Hay que sustituir XXX.3. es decir: SIP 4 IAX2 6 DAHDI 7 Se pasa a la instalación y configuración de Nagios. 440 .1.4 = STRING: SIP ASTERISK-MIB::astChanTypeName.4. Se guardan los cambios y se reinicia Asterisk: /etc/init.d/asterisk restart se inicia snmp: /etc/init.XXX.6 = STRING: IAX2 ASTERISK-MIB::astChanTypeName. las que interesan son estas tres: ASTERISK-MIB::astChanTypeName.1.22736 De todas las lineas que aparecen. Luego se definen dos grupos y que tipo de consultas pueden hacer (en este caso SNMP versión 1 y versión 2c.1.XXX con la ip del servidor remoto. Se define el tipo de objetos que pueden consultar (en este caso todos) y los permisos que cada grupo tiene.group NetWork v1 remote group NetWork v2c remote view all included .d/snmpd start se vuelve el arranque automático: chkconfig snmpd on Para ver los resultados con la descripción de los OID en lugar de los números de los objetos: export MIBS=all Ahora ya se puede hacer una consulta utilizando el OID raiz de Asterisk: snmpwalk -OT -c public -v 2c localhost . Primero se define el agente y los permisos de acceso. Una tiene acceso local y otra remoto (útil si se quiere hacer consultas desde otro servidor).6.XXX. 5.i386 : Console monitor for Nagios nsc.i386. un archivo para la integración con el servidor Web (apache).3 Nagios Para la instalación de Nagios desde los paquetes precompilados.i386 : Nagios Remote Plug-ins Execution daemon nagios-nsca.2-2.i386 : Logfile check plugin for nagios icinga. libraries and development documentation for nagios nagios-nrpe.i386 : Open Source host. los plugins.i386 : Host/service/network monitoring program plugins for Nagios nagios-plugins-nrpe.i386 : Authenticated RSS alerts for nagios Se instalan los siguientes paquetes: el programa.Nagios object configuration parsing perl-Nagios-Plugin.org/rpmforge-release/rpmforge-release-0. Una vez terminada la instalación. una aplicación para el envío de los correo electrónicos desde Nagios utilizando una linea de comando. hay que instalar el repositorio rpmforge: cd /usr/src wget http://pkgs.i386 : Host/service/network monitoring program plugins for Nagios requiring setuid ndoutils. una utilidad para guardar los registros de Nagios en una base de datos.i386 : Header files.i386 : Nagios Service Check Acceptor nagios-nsca-client.22.el5. se empieza con la configuración de Nagios.2-2.cfg y se encuentra en 441 .el5.rf.rpm Ahora se controlan los paquetes disponibles para Nagios: yum search nagios check_logfiles.i386 : Nagios plugin to store Nagios data in a relational database nsc.rf.5.i386 : Open Source host.noarch : Nagios::Object .noarch : Console monitor for Nagios perl-Nagios-Object.rpm rpm -ivh rpmforge-release-0. Se creará el grupo y usuario Nagios. unas carpetas donde se guardarán los registros y los archivo necesarios para que Nagios funcione. yum install nagios nagios-plugins perl-Net-Jabber perl-IO-Socket-SSL ndoutils mailx httpd CentOS se hará cargo de instalar también todas las dependencias necesarias.i386 : nagios send_nsca nagios-plugins. El archivo principal donde se definen los parámetros para el programa es nagios. service and network monitoring program nagios-devel.repoforge.i386. unas librerías en Perl para utilizar el protocolo XMPP. service and network monitoring program nagios.i386 : Nagios plug-in for NRPE nagios-plugins-setuid.noarch : Family of perl modules to streamline writing Nagios rss4nagios. Para este tipo de instalación no hace falta hacer algún tipo de modifica es ese archivo. Se guardan los cambios y se abre el archivo templates. hace referencia a un template definido en el archivo templates.cfg: nano /etc/nagios/objects/contacts.cfg define contact{ 442 . Nagiosadmin es el nombre del administrador predefinido en Nagios.cfg.cfg. Cada vez que aparece una línea que empieza con “use”.cfg En este archivo se cambian estas líneas: define contact{ contact_name nagiosadmin use generic-contact alias Nagios Admin email nagios@localhost } para que queden: define contact{ contact_name nagiosadmin use generic-contact alias Nagios Administrador email fulano@gmail. Address1 es el usuario GoogleTalk donde Nagios enviará las notificaciones vía mensaje instantáneo.la carpeta /etc/nagios.cfg contact.cfg Se inicia con contact.cfg localhost. Los archivos de configuración de Nagios que hay que modificar son los siguientes y se encuentran en la carpeta /etc/nagios/objects: • • • • commands.com address1 fulano } fulano@gmai. En este archivo el bloque del genericcontact es: nano /etc/nagios/objects/templates.com es la dirección de correo electrónico donde Nagios enviará las notificaciones (personalizar).cfg template. Hay una explicación de estos parámetros en la documentación oficial de Nagios 3.pl.voztovoice. Por eso al final del archivo se añade el siguiente bloque que define que para todos los servicios de Asterisk el control se hará cada 2 minutos (se puede personalizar): define service{ name asterisk use generic-service max_check_attempts 4 normal_check_interval 2 retry_check_interval 1 register 0 } Ahora se modifica el tercer archivo (commands.0 En el servidor hay servicios que no son críticos y que se pueden monitorear cada 5 minutos (el tiempo predefinido en Nagios).voztovoice. Se entra en la carpeta /usr/lib/nagios/plugins y se descargan los plugin que hacen falta: cd /usr/lib/nagios/plugins wget http://www.notify-service-jabber host_notification_commands notify-host-by-email.pl Se cambian los permisos para que se pueda ejecutar: chmod +x check_asterisk_peers 443 . check_asterisk. se descargará un plugin del repositorio de Nagios y por ultimo.s service_notification_commands notify-service-by-email.org/campus/a2b/check_asterisk_peers wget http://www.f.cfg) donde se definen los comandos que luego se utilizarán para la configuración del monitoreo del servidor local. Para monitorear las troncales.f.u.org/campus/a2b/notify_via_jabber. se usará el plugin check_snmp y otro que viene en la carpeta /usr/lib/nagios/plugins/contrib. Esto para enviar las notificaciones también vía GoogleTalk.u. para enviar las notificaciones via GoogleTalk se descargará otro plugin.r.r. Los plugins de Nagios se instalan en /usr/lib/nagios/plugins.name generic-contact service_notification_period 24x7 host_notification_period 24x7 service_notification_options w. a veces. Para Asterisk. Para monitorear Asterisk.c.s host_notification_options d.notify-host-jabber can_submit_commands 1 register 0 } En este bloque se añaden las dos partes en negrita. estos cinco minutos pueden ser demasiados. En este archivo se configura el usuario de GoogleTalk que enviará las notificaciones. Esto se hace para los servidores (en este caso uno) y los servicios. Esto quiere decir que para que el sistema funcione se necesita tener dos cuentas de GoogleTalk. El usuario configurado en el contact. Después del bloque notify-service-by-email se añade: # 'host-notify-by-jabber' command definition define command{ command_name notify-host-jabber command_line /usr/lib/nagios/plugins/notify_via_jabber.cfg serà él que las recibe siempre y cuando añadirá el usuario configurado en el plugin en su lista de amigos. se modificará el archivo commands. para que queden: my $username = "sutano".pl $CONTACTADDRESS1$ "Host '$HOSTALIAS$' is $HOSTSTATE$ .pl Notify_via_jabber. my $password = "password". sutano es el usuario googletalk y password su contraseña (no hace falta poner @gmail. Se abre: nano notify_via_jabber.pl se modifican estas dos lineas: my $username = "usuarioGoogleTalk".cfg Primero se configura el comando para enviar las notificaciones vía mensaje instantáneo.pl es el único que tiene que ser modificado. my $password = "password". Para conocer la sintaxis de un plugin de Nagios el comando es: cd /usr/lib/nagios/plugins . El plugin funciona de la siguiente manera.com) Una paréntesis.Info: $HOSTOUTPUT$" } # 'service-notify-by-jabber' command definition define command { command_name notify-service-jabber 444 .cfg nano /etc/nagios/objects/commands./check_snmp -h Para añadir los comandos en Nagios.chmod +x notify_via_jabber. pl $CONTACTADDRESS1$ "$NOTIFICATIONTYPE$ $HOSTNAME$ $SERVICEDESC$ $SERVICESTATE$ $SERVICEOUTPUT$ $LONGDATETIME$" } IMPORTANTE: todo lo que aparece en la linea command-line debe estar en la misma linea Se continua con el plugin check_snmp para monitorear Asterisk a través del protocolo SMNP. Nagios enviará una notificación por correo electrónico y 445 .cfg • check_snmp – Nombre del plugin • -H $HOSTADDRESS$ – la opción –H define el servidor que se va a consultar y $HOSTADDRESS$ es una macro (variable) predefinida que contiene el nombre del servidor como se definirá luego en localhost.command_line /usr/lib/nagios/plugins/notify_via_jabber.conf • -o – la OID que se consultará • -P 2c – versión de SNMP utilizada para la consulta • -l la etiqueta que luego se definirá • -w – está por Warning • -c – está por Critical • $ARG1$ $ARG2$ $ARG3$ ARG4$ son las macros (variables) cuyo valor será asignado desde la configuración de localhost.cfg Al verificarse el evento Warning y/o Critical.cfg • -C public – es la comunidad que se va a utilizar para la conexión al agente como definido en el archivo /etc/snmp/snmp. Se buscan estas lineas: # 'check_snmp' command definition define command{ command_name check_snmp command_line $USER1$/check_snmp -H $HOSTADDRESS$ $ARG1$ } y se modifican para que queden: define command{ command_name check_snmp command_line $USER1$/check_snmp -H $HOSTADDRESS$ -C public -o $ARG1$ -P 2c -l $ARG2$ -w $ARG3$ -c $ARG4$ } IMPORTANTE: todo lo que aparece en la linea command-line debe estar en la misma linea Command name: nombre del comando Command line: los parámetros que pasaremos al comando: • La macro (variable) $USER1$ contiene el valor /usr/lib/nagios/plugins como especificado en el archivo /etc/nagios/resource. cfg.pl -h $HOSTADDRESS$ -m mgr -u nagios -p sesamo } nagios y sesamo indican respectivamente el usuario y la contraseña para conectarse al AMI de Asterisk. se busca este bloque: # 'check_ssh' command definition define command{ command_name check_ssh command_line $USER1$/check_ssh $ARG1$ $HOSTADDRESS$ } y se modifica para que quede: # 'check_ssh' command definition define command{ command_name check_ssh command_line $USER1$/check_ssh -p $ARG1$ $HOSTADDRESS$ } El ultimo plugin que se define en el archivo command.conf de Asterisk: Como el servidor SSH está escuchando en el puerto 15000. Como se puede ver este plugin se activa con el programa sudo que permite ejecutar un comando con los permisos del usuario root. es el que permite monitorear las troncales: define command{ command_name check_justvoip command_line sudo /usr/lib/nagios/plugins/check_asterisk_peers -t sip -p $ARG1$ } Se guardan los cambios.bash_profile 446 . Para que pueda hacerlo hay que modificar el archivo sudousers que es donde se definen los usuarios que pueden ejecutar comandos con los permisos de root. El segundo plugin se define de la siguiente forma (añadir las lineas después del bloque anterior): define command{ command_name check_asterisk command_line $USER1$/contrib/check_asterisk. luego hay que modificar el manager. Para modificar este archivo con el editor nano hay que seguir este procedimiento: cd /root nano . Esto porque el programa Nagios se inicia con usuario nagios y ese usuario no tiene los permisos para ejecutar el plugin.vía mensaje instantáneo. Para definirlos. otiginate.0.255 read=system.255.cc write=system.0.0/0.config.bash_profile Ahora se puede modificar el archivo sudousers con nano con el comando: visudo primero se modifica esta linea: Defaults requiretty para que quede: # Defaults requiretty luego se añade al final del archivo: nagios ALL=(ALL) NOPASSWD: /usr/lib/nagios/plugins/check_asterisk_peers Se guardan los cambios.pl funciona conectándose a la AMI de Asterisk.0.command. Como se había dicho el plugin check_asterisk.0.cfg.user.0.reporting.agi.conf de Asterisk: nano /etc/asterisk/manager.user.agent.agent.dialplan.al final del archivo se añade la siguiente linea: export EDITOR=/usr/bin/nano Se guardan los cambios y se recarga el perfile de la shell bash: source .1/255. Se mueve el predefinido: 447 .255.call.agi Se guardan los cambios y se actualiza la configuración de Asterisk: /etc/init.reporting.d/asterisk reload Para terminar la configuración de Nagios se modifica el archivo localhost.call.cdr.0 permit=127. Para que funcione hay que modifica el archivo manager.conf Al final del archivo se añade: [nagios] secret = sesamo deny=0.0.dtmf. si son mas de 16 un CRITICAL.1 } define service{ use asterisk host_name CursoAsterisk service_description SIP check_command check_snmp!ASTERISK-MIB::astChanTypeChannels.0.old se crea uno nuevo: nano /etc/nagios/objects/localhost.4!"Canales SIP Activos"!8!16 } Si los canales SIP activos son más de 8 se recibirá un WARNING.cfg.0.cfg Se añaden las siguientes lineas: define host{ use linux-server host_name CursoAsterisk alias CursoAsterisk address 127. Se continua copiando las lineas que siguen: define service{ use asterisk host_name CursoAsterisk service_description IAX2 check_command check_snmp!ASTERISK-MIB::astChanTypeChannels.cfg /etc/nagios/objects/localhost.6!"Canales IAX2 Activos"!4!8 } define service{ use asterisk host_name CursoAsterisk service_description DAHDI check_command check_snmp!ASTERISK-MIB::astChanTypeChannels.mv /etc/nagios/objects/localhost.7!"Canales DAHDI Activos"!4!8 } define service{ use asterisk host_name CursoAsterisk service_description Asterisk_check check_command check_asterisk } 448 . 0. los respectivos valores separados por el caracter ! Las OID se toman interrogando Asterisk con SNMP como hemos visto en el párrafo anterior. En el bloque que sigue se utiliza el plugin check_asterisk.60% } define service{ use local-service host_name CursoAsterisk service_description Current Users check_command check_local_users!20!50 } define service{ use local-service host_name CursoAsterisk service_description Total Processes check_command check_local_procs!250!400!RSZDT } 449 . En el primer bloque se define el nombre del servidor. etc…). IAX2 y DAHDI activos.0.1 o localhost).pl y a través del AMI de Asterisk se controla que esté corriendo. que se han visto al momento de la configuración del comando ($ARG1$ $ARG2$ $ARG3$ ARG4$).cfg que se utiliza para estos comandos. se añaden estas líneas: define service{ use local-service host_name CursoAsterisk service_description PING check_command check_ping!100.20%!500. procesos. En la segunda linea de cada bloque aparece el parámetro “use asterisk” que representa el template (la plantilla) configurada en templates. un alias y la dirección IP (en este caso siendo Nagios y Asterisk instalados en el mismo servidor se indica 127. En los tres bloques que siguen se controla a través del plugin check_snmp. Si se quiere controlar también algunos servicios básicos del servidor (usuarios. Se asignan a las cuatros macros (variables).0. El ultimo bloque se utilizan para monitorear la troncal SIP Justvoip.0. los canales SIP.define service{ use asterisk host_name CursoAsterisk service_description Troncal_Justvoip check_command check_justvoip!justvoip } Una pequeña explicación. carga. 0.0.users que contendrá los datos de acceso para el usuario predefinido nagiosadmin (en este caso la contraseña es sesamo) Se configuran Nagios para que arranque en automático: chkconfig nagios on Se reinicia apache y luego se inicia Nagios: /etc/init.0 } define service{ use local-service host_name CursoAsterisk service_description SSH check_command check_ssh!15000 } Antes de iniciar Nagios hay una forma para controlar que todos los archivos de configuración estén exentes de errores: nagios -v /etc/nagios/nagios.3.0.0!10.d/nagios start 450 .cfg Si la respuesta termina con: Total Warnings: 0 Total Errors: 0 Things look okay .4.users nagiosadmin sesamo Adding password for user nagiosadmin Este comando creará una archivo htpasswd.4.define service{ use local-service host_name CursoAsterisk service_description Current Load check_command check_local_load!5.6.0. de la siguiente forma: htpasswd -bc /etc/nagios/htpasswd.No serious problems were detected during the pre-flight check Significa que la configuración está bien. En caso contrario Nagios indicará el archivo y la línea donde se encuentra el error. nagiosadmin. El acceso a la pagina Web de administración de Nagios está protegido y para poder acceder hay que configurar la contraseña del usuario predefinido.d/httpd start /etc/init. Aparece la pagina inicial de Nagios: 451 . hay que abrir el puerto 80 TCP (servidor WEB) en Iptables: nano /etc/sysconfig/iptables Antes de este bloque: # Monit -A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT se añade: # HTTP -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT Se guardan los cambios y se reinicia Iptables: service iptables restart Para entrar en la pagina de Nagios: http://IPservidor/nagios Aparecerá una ventana donde habrá que insertar las credenciales de acceso es decir: usuario: nagiosadmin contraseña: sesamo Se presiona el botón Aceptar.Antes de entrar a la pagina de administración de Nagios. 22. 452 .En la derecha se selecciona el enlace Hosts para ver el servidor configurado: Se selecciona Services para ver los servicios monitoreados: Todos están bien.1 NDOutils NDOutils permite guardar todos los datos de Nagios en una base de datos MySQL. Lo primero que hay que hacer es crear la base de datos: mysql -u root -psesamo mysql> create database nagios.3. cfg nano /etc/nagios/nagios. Primero se modifica nagios. mysql> quit Se crean las tablas en la base de datos nagios desde un archivo instalado con el paquete NDOutils: mysql -u root -psesamo nagios < /usr/share/ndoutils/mysql.cfg al final del archivo se añaden las siguientes lineas: event_broker_options=-1 broker_module=/usr/libexec/ndomod-3x.d/ndoutils start 453 .cfg y ndo2db.sql Ahora falta modificar dos archivos de configuración: nagios.lock en db_user y db_password se pone: db_user=nagios db_pass=sesamo se guardan los cambios y se inicia NDOutils: /etc/init.se asigna al usuario nagios los permisos para la base de datos creada: mysql> GRANT ALL PRIVILEGES ON nagios.cfg: nano /etc/nagios/ndo2db.cfg Después de estas dos lineas: ndo2db_user=nagios ndo2db_group=nagios se añade: lock_file=/var/nagios/ndo2db.* TO 'nagios'@'localhost' IDENTIFIED BY 'sesamo'.o config_file=/etc/nagios/ndomod.cfg que permiten a Nagios conectarse a la librería de NDOutils y enviar todos los datos de configuración y los eventos: Se guardan los cambios y se continua con el ndo2db. mysql> flush privileges.cfg. y se reinicia Nagios: /etc/init. por ejemplo. La primera es desde la consola de Asterisk: 22.1 Monitoreo calidad llamadas desde la consola de Asterisk Se entra en la consola de Asterisk: 454 .4 Monitoreo calidad llamadas Como se ha dicho al inicio de este capitulo.4. es posible monitorear la calidad de las llamadas de distintas formas. la tabla nagios_commands: Todo está funcionando como debería.log Las lineas que interesan son: En Webmin se puede controlar que las tablas se ha ido llenando de nuevas entradas como. Hay disponibles distintos tipos de consultas de las tablas en la carpeta /usr/share/ndoutils/queries/ 22.d/nagios restart se averigua que en el log de Nagios haya conexión con la librería NDOutils: tail -f /var/log/nagios/nagios. Entre el 1 y el 5%.4. Se contesta la llamada y después de unos segundos se cuelga. Cuando las dos extensiones están hablando. la calidad de la llamada es muy buena. En la consola aparecerán todas una serie de datos relacionados con la llamada. 22. se vuelve a ejecutar el comando: CLI> sip show channelstats En las lineas aparecen todos los datos relacionados con la llamadas corrientes (en este caso una): • • • • • • • • • • • Peer: la IP de las extensiones Call ID: el identificador único de llamada para cada extensión Duration: la duración de la llamada hasta el momento (en segundos) Recv: Pack: paquetes recibidos por Asterisk de las dos extensiones Lost: paquetes perdidos de la extensiones a Asterisk %: porcentaje de paquetes perdidos Jitter: Jitter entre las extensiones y Asterisk Send: Pack: paquete enviados por Asterisk Lost: paquetes perdidos de Asterisk a las extensiones %: porcentaje de paquetes perdidos Jitter: Jitter entre Asterisk y las extensiones Si el porcentaje de los paquetes perdidos se mantiene por abajo del 1%. CLI> rtcp set stats on RTCP Stats Enabled Para ver como funciona.2 Monitoreo calidad llamadas con VoIPMonitor VoIPmonitor es un programa que permite guardar todos los datos relacionados con la calidad de las llamadas en una base de datos. Una Open Source sin parte 455 . aceptable. De este programa existen dos versiones.asterisk -rvvvvvvvvvvvvvvvvvv Si activan las estadísticas del protocolo RTCP (Real Time Control Protocol) definido en el RFC 3550. se vuelve a marcar desde la extensión 1000 la extensión 1001. desde la extensión 1000 se llama la extensión 1002. Otra forma de hacerlo es con el comando: CLI> sip show channelstats para verlo en acción. para ambos canales.tar. guarda los siguientes datos: • • • • • • • • • • • • • Fecha de la llamada Duración CallerID llamante CallerID llamado Quien de los dos canales ha colgado Codec Llamante Codec Llamado Paquetes recibidos.2.1 .2. una comercial que incluye la parte Web. De cada llamada.tcpdump. perdidos Jitter canal llamante Jitter canal llamado Jitter promedio de la llamada MOS (Mean Opinion Score) llamante MOS (Mean Opinion Score) llamado Pre requisitos para la compilación e instalación: • • una versión de Libpcap >= 1.0 Librería MySQL++ Primero se averigua la versión de libpcap instalada: yum info libpcap Como el numero de versión es inferior a 1.org/release/libpcap-1.tar.gz tar -xf libpcap-1. El programa analiza y captura todos los paquetes SIP (señalización) y RTP (flujo media).gz cd libpcap-1.1. enviados. hay que instalar la librería desde la fuentes: cd /usr/src wget http://www./configure --prefix=/usr make make install 456 .Web para ver la estadísticas desde un Navegador.2.1. 0.* to 'voipuser'@'localhost' IDENTIFIED BY 'sesamo'.1.1.0 .gz tar -xf mysql++-3.Se continua con MySQL++ cd /usr7src wget http://tangentsoft.sql Se crea un archivo de configuración para el programa: 457 .net/mysql++/releases/mysql++-3.0./configure --prefix=/usr make make install Instalados los pre requisitos ya se puede compilar e instalar VoIPMonitor.sourceforge. mysql> GRANT ALL PRIVILEGES ON voipmonitor.net/svnroot/voipmonitor/trunk voipmonitor-svn Se entra en la carpeta creada: cd voipmonitor-svn Se compila y se instala: make make install Se crea la carpeta donde se guardarán todos los datos de las llamadas (archivo pcap. archivo audio de la llamada si se utiliza el codec audio G711): mkdir /var/spool/voipmonitor Se crea la base de datos donde se guardarán los datos de las llamadas: mysql -u root -psesamo mysql> create database voipmonitor. Primero se descarga: svn co https://voipmonitor. mysql> quit Se cargan las tablas en la base de datos: mysql -u root -psesamo voipmonitor < cdrtable.tar.tar.1.svn. mysql> flush privileges.gz cd mysql++-3. Se indica uno por linea # ringbuffer=10 # Parámetro valido solamente para versiones del Kernel >= 2. los mensajes de REGISTER nocdr=no # VoIPMonitos guardará los CDR de las llamadas savesip=yes # VoIPMonitos guardará los datos SIP en un archivo savertp=yes #VoIPMonitor guardará los paquetes RTP en un archivo savegraph=plain # Se guardarán los datos de los graficos en un archivo (en el caso se utilice la GUI) spooldir=/var/spool/voipmonitor # Carpeta donde se guardarán los datos de las llamadas mysqlhost=localhost # dirección IP o nombre de dominio del servidor MySQL mysqldb=voipmonitor # Nombre de la base de datos mysqltable=cdr # Nombre de la tabla mysqlusername=voipuser # Nombre del usuario MySQL con los permisos para la base de datos mysqlpassword=sesamo # Password del usuario voipuser Se guardan los cambios y se instala lo script para iniciar el servicio en automático: 458 .6.conf Se copian las lineas que siguen: [general] # inicia la parte general de la configuración interface=any # el programa se pondrá a la escucha en todas las tarjetas de red presentes en el servidor managerport=5029 # puerto TCP para gestionar el programa sipport=5060 sipport=5061 # puertos SIP donde voipmonitor se pondrá a la escucha.nano /etc/voipmonitor.31 jitterbuffer_f1=yes jitterbuffer_f2=yes jitterbuffer_adapt=yes # tipos de jitterbuffer utilizados para el calculo del MOS rtp-firstleg=no # se capturará el flujo media de ambos canales sip-register=no # no se guardarán en la captura SIP. Terminada la llamada se mira las entradas en la base de datos (serán dos).d/voipmonitor /etc/init. 459 .cp config/init.d/ chmod +x /etc/init.d/voipmonitor chkconfig --add voipmonitor chkconfig voipmonitor on Se inicia el servicio: service voipmonitor start e se efectúa una llamada desde la extensión 1000 a la extensión 1001. . 11.X se han implementados dos nuevos protocolos: • • SIP TLS para el cifrado de la señalización SIP SRTP para el cifrado del flujo media. no tendría mucho sentido. etc.1 Creación de los certificados El primer paso es crear los certificado cliente. secretos industriales.Capitulo XXIII Conectar un Softphone (Blink) de forma segura: SIP TLS y SRTP En algunos contextos la privacidad de las comunicaciones es un factor importante para el desarrollo de las actividades de la empresa. Antes de instalarlo hay que configurar Asterisk para activar el protocolo SIP TLS y SRTP. Las conversaciones seguras eran importantes en las comunicaciones tradicionales y más aun lo son en la voz sobre IP. El único Softphone con una versión gratuita que soporta los protocolos SIP TLS Y SRTP es Blink.0/contrib/scripts/ Primero se crea el certificado de la autoridad de certificación y del servidor Asterisk: . podrá tener acceso a las claves y de esta forma descifrar el flujo media. datos de cuentas bancarias. por las siguientes razones: • • Si se utiliza solamente el protocolo SIP TLS. el flujo media seguirá viajando en claro y podrá ser interceptado Las claves que intercambian el cliente y el servidor para instaurar el cifrado del flujo media. Si no se utiliza el cifrado del protocolo SIP y alguien logra interceptar este trafico. servidor y de la autoridad de certificación.com -O "Campus VozToVoice" -d /etc/asterisk/keys • • con la opción -C se indica el nombre de dominio o la IP del servidor Asterisk con la opción -O se indica el nombre de la empresa o de la institución . Aunque se puedan utilizar separadamente. MAC OS y Windows. Se crea la carpeta donde se guardarán las claves: mkdir /etc/asterisk/keys y se entra en la carpeta de las fuentes de Asterisk que contiene uno script para la generación de los certificados: cd /usr/src/asterisk-1. se envian a través de la señalización SIP..members.8. Con la versión de Asterisk 1. más aun si los datos que se intercambian a lo largo de las conversaciones son datos sensibles tipo: números de tarjetas de crédito.. 23.linode./ast_tls_cert -C li374-112.8. De este producto existen versiones para Linux. ..pem Cuando el sistema lo solicita...li374112... se indica una contraseña que tiene que ser la misma a lo largo de todo el proceso.key: Creating /etc/asterisk/keys/asterisk..cfg' You can use this config file to create additional certs without re-entering the information for the fields in the certificate Creating /etc/asterisk/keys/ca..key: Creating /etc/asterisk/keys/ca..crt Signature ok subject=/CN=li374-112....key: Verifying ....members............ Como en este caso el computador desde donde se conectará el softphone no tiene un nombre de dominio o una IP fija. creating '/etc/asterisk/keys/tmp..++ e is 65537 (0x10001) Enter pass phrase for /etc/asterisk/keys/ca..++++++ ...../ast_tls_cert -m client -c /etc/asterisk/keys/ca.. En este caso se utilizará la contraseña server..com -O "Campus VozToVoice" -d /etc/asterisk/keys -o blink1 • • • • con la opción -m se indica el tipo de certificado.key: Combining key and crt into /etc/asterisk/keys/asterisk.....key Generating RSA private key...... En este caso un certificado cliente con la opción -c se indica la ruta del certificado de la autoridad de certificación con la opción -k se indica la ruta de la clave del certificado de la autoridad de certificación con -C se indica el nombre de dominio o la IP de donde se conectará el softphone.....key Generating RSA private key.... 1024 bit long modulus .• con la opción -d se indica la ruta donde se guardarán los certificados .++ .......Enter pass phrase for /etc/asterisk/keys/ca.... se pone un nombre que identifique el softphone y al mismo tiempo el dominio del servidor con la opción -O se indica el nombre de la empresa o de la institución 462 • ..linode..................com -O "Campus VozToVoice" -d /etc/asterisk/keys No config file specified.++++++ e is 65537 (0x10001) Creating signing request Creating /etc/asterisk/keys/asterisk...........key -C blink1. El segundo paso es crear la clave del softphone utilizando la misa autoridad de certificación: .. 4096 bit long modulus ....com/O=Campus VozToVoice Getting CA Private Key Enter pass phrase for /etc/asterisk/keys/ca..........members.crt -k /etc/asterisk/keys/ca...crt Enter pass phrase for /etc/asterisk/keys/ca............members./ast_tls_cert -C li374-112.......linode.. Con esta operación se crearán el certificado de la autoridad de certificación con relativa clave y el certificado del servidor Asterisk con relativa clave.linode........ li374-112..0 tlscertfile=/etc/asterisk/keys/asterisk...0. server..com/O=Campus VozToVoice Getting CA Private Key Enter pass phrase for /etc/asterisk/keys/ca.....0... se indica que el servidor Asterisk no deberá verificar el certificado del cliente Al final del archivo se crea una nueva extensión: [1005] 463 ..... creating '/etc/asterisk/keys/tmp. con este parámetro en yes.. Una vez creados los certificados se modifica la configuración del archivo sip.crt tlscapath=/etc/asterisk/keys tlsdontverifyserver=yes • • • • • • Linea 1: se activa el protocolo SIP TLS Linea 2: Asterisk se pondrá a la escucha en todas las direcciones IP presentes en el servidor Linea 3: ruta y nombre del certificado del servidor Asterisk Linea 4: ruta y nombre del certificado de la autoridad de certificación Linea 5: ruta donde se encuentran todos los certificados de las distintas autoridades de certificación Linea 6: como el softphone no utiliza un nombre de dominio propio. 1024 bit long modulus .linode. es decir.crt Signature ok subject=/CN=blink1...conf al final de la parte general se añaden las siguientes lineas: tlsenable=yes tlsbindaddr=0. se ingresa la misma contraseña utilizada en la fase anterior..members.conf de Asterisk: nano /etc/asterisk/sip...• con la opción -d se indica la ruta donde se guardarán los certificados No config file specified.++++++ e is 65537 (0x10001) Creating signing request Creating /etc/asterisk/keys/blink1...key Generating RSA private key.pem tlscafile=/etc/asterisk/keys/ca..key: Combining key and crt into /etc/asterisk/keys/blink1.cfg' You can use this config file to create additional certs without re-entering the information for the fields in the certificate Creating /etc/asterisk/keys/blink1.pem Cuando el sistema lo solicite.++++++ .. entre las varias lineas aparecerá: SSL certificate ok Como el protocolo SIP TLS utiliza el puerto 5061 TCP. Asterisk aceptará solamente conexiones con el protocolo SIP TLS y el cifrado del flujo media. Se guardan los cambios y se recarga la configuración SIP: asterisk -rvvvvvvvvvvvvv CLI> sip reload Si todo sale bien.type=friend accountcode=1005 language=es secret=pbx9095 qualify=yes mailbox=1005@default host=dynamic dtmfmode=rfc2833 context=externas directmedia=no callerid=Perengano <1001> callgroup=1 pickupgroup=1 disallow=all allow=ulaw allow=alaw allow=g729 allow=h263 cc_agent_policy=generic cc_monitor_policy=generic transport=tls encryption=yes Las ultimas dos lineas indican que para la extensión 1005. hay que abrirlo en el cortafuegos: nano /etc/sysconfig/iptables Después de esta linea: -A INPUT -p tcp -m state --state NEW -m tcp --dport 5060 -j ACCEPT se pone: -A INPUT -p tcp -m state --state NEW -m tcp --dport 5061 -j ACCEPT 464 . Bajo Linux el comando scp. Ahora se puede descargar el Softphone Blink según el sistema operativo utilizado.Se guardan los cambios y se reinicia iptables: service iptables restart Para terminar esta primera parte. Una vez descargado se instala y se inicia la configuración entrando en el menú Blink → Accounts → Add Account: 465 . en Windows se puede utilizar el programa winscp.pem Para esta operación. 23. Los archivos que hay que descargar son: • • ca.crt blink1.2 Configuración Softphone Blink Asterisk ya está configurado para el soporte SIP TLS y SRTP. hay que trasferir los certificado en el computador donde se instalará el Softphone Blink. En la pestaña “Server settings”: se configura como aparece en la imagen de arriba y se continua con la pestaña “Advanced”: Se selecciona el certificado blink1.pem descargado del servidor Asterisk y se selecciona la casilla “Verify server”. Se pasa al icono Advanced: 466 . En la pestaña “Media”: Se selecciona el protocolo SRTP como obligatorio “mandatory”.• • • Display name: un nombre que se le asigna a la cuenta SIP address: numero de extensión y dominio del servidor Asterisk Password: contraseña de la extensión 1005 Se presiona el botón ADD y se va al menú Blink → Account → Manage accounts. hHkKtTwWxX) same => n.45.1.Hangup En la primera linea se lee el valor asociado a la variable de canal “secure_signaling” Si es ugual a 1 significa que la llamada ha sido iniciada por una extensión configurada con el protocolo SIP TLS.4-5].Se selecciona el certificado de la autoridad de certificación descargado del servidor Asterisk: Se vuelve a la pantalla principal del softphone y se averigua en la consola de Asterisk que esté registrado: CLI> sip show peers Prueba llamadas Para probar la configuración.45.Macro(voicemail) same => n. hay que modificar el dialplan: nano /etc/asterisk/extensions. Si es igual a 1 significa que la llamada ha sido iniciada por una extensión configurada con el protocolo SRTP activado. Se guardan los cambios y se recarga el dialplan: asterisk -rvvvvvvvvvvvvvvvvv CLI> dialplan reload Ahora se hacen dos llamadas: 1.1.conf Se modifica este bloque: exten => _100[0-2. En la segunda linea se lee el valor asociado a la variable de canal “secure_media”.Dial(SIP/${EXTEN}.Noop(Protocolo SIPTLS = ${CHANNEL(secure_signaling)}) same => n.Dial(SIP/${EXTEN}.hHkKtTwWxX) same => n. desde la extensión 1000 a la extensión 1005 467 .4].Noop(Protocolo SRTP = ${CHANNEL(secure_media)}) same => n.Macro(voicemail) same => n.Hangup para que quede: exten => _100[0-2. las dos variable de canal estarán vacías.Executing [1000@externas:2] NoOp("SIP/1005-00000014". Para el flujo media depende de la configuración del parámetro directmedia y si las extensiones se registran detrás de un NAT o no. Lo mismo vale para el segundo caso.hHkKtTwWxX") Como la extensión 1000 (Softphone X-Lite) no soporta SIP TLS y SRTP.RTP 468 .45. "Protocolo SRTP = 1") in new stack -. "Protocolo SIPTLS = ") in new stack -. Esto implica que es posible que se presenten estos escenarios: SIP TSL . Asterisk siempre está en el medio de una llamada para la señalización SIP.2. las dos variables de canal tendrán el valor 1.Executing [1000@externas:1] NoOp("SIP/1005-00000014".Executing [1000@externas:3] Dial("SIP/1005-00000014".45. "Protocolo SIPTLS = 1") in new stack -.hHkKtTwWxX") Como la extensión 1005 (Softphone Blink) soporta SIP TLS y SRTP.SRTP SIP . -. "Protocolo SRTP = ") in new stack -. "SIP/1005. desde la extensión 1005 a la extensión 1000 Los resultados: Executing [1005@externas:1] NoOp("SIP/1000-00000010".RTP SoftPhone Blink ---------------------> Asterisk -------------------------> SoftPhone X-Lite o: SIP TSL . Consideraciones finales Como se ha comentado en otro modulo. "SIP/1000. no implica que no se deban implementar los protocolo SIP TLS y SRTP cuando sea posible. SIP . aunque la segunda pata de la llamada no es segura.SRTP SoftPhone X-Lite ---------------------> Asterisk -------------------------> SoftPhone Blink El el primer caso.Executing [1005@externas:2] NoOp("SIP/1000-00000010".Executing [1005@externas:3] Dial("SIP/1000-00000010". . 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.0-openjdk* Terminada la instalación se controla la versión instalada: java -version java version "1.Capitulo XXIV Openfire y Asterisk 24. su multiplicidad de funciones y la posibilidad de ser integrado con Asterisk.tar.10.0_20" OpenJDK Runtime Environment (IcedTea6 1.gz se descomprime tar -xf openfire_3_7_1. Entre tantos servidores con protocolo XMMP Openfire se destaca por la sencillez de la instalación.1.6.0 .9.org/downloadServlet?filename=openfire/openfire_3_7_1. Esto implica tener una red de mensajería instantánea privada.0-openjdk-1.9. ¿Porque Openfire?.el5_7-i386) OpenJDK Client VM (build 19.10) (rhel-1.0-b09.1 Instalación de Openfire Openfire es un servidor Jabber. Openfire es escrito en java y.gz Se entra en la carpeta bin cd /opt/openfire/bin Se modifica el script de inicio: nano openfire modificando esta linea: # INSTALL4J_JAVA_HOME_OVERRIDE= para que quede: INSTALL4J_JAVA_HOME_OVERRIDE=/usr/lib/jvm/java-1.23. fácilmente manejable y segura gracias al uso del protocolo TLS.6.igniterealtime.6. mixed mode) Se descarga el servidor jabber Openfire: cd /opt wget http://www.0. la administración desde una página Web.tar.6. Con Openfire instalado se tendrá un servidor de mensajería instantánea sin tener que acudir a servicios de terceros. /openfire status Si aparece: The daemon is running.00 sec) mysql> quit Bye sesamo es la contraseña del usuario openfire Ahora se importan las tablas para la base de datos mysql openfire < /opt/openfire/resources/database/openfire_mysql. En este caso se usará MySQL. Query OK. Ahora hay que configurarlo. 0 rows affected (0. Openfire para registrar los datos puede utilizar una base de datos interna o externa.* TO 'openfire'@'localhost' IDENTIFIED BY 'sesamo'. 0 rows affected (0.Se guardan los cambios y se inicia: . 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.01 sec) mysql> flush privileges. Query OK./openfire start Se averigua que esté corriendo . El servidor está funcionando.sql -u root -psesamo 471 . si se tiene un dominio registrado. nano /etc/sysconfig/iptables Después de este bloque: # Monit -A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT Se añade: # Openfire -A INPUT -p tcp -m state --state NEW -m tcp --dport 5222:5223 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 5269 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 5275 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 7070 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 7443 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 9090 -j ACCEPT -A INPUT -p tcp -m state --state NEW -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.Para que Openfire sea accesible desde afuera de la red local hay que abrir unos puertos en el cortafuegos. el nombre (Ej. En la barra de la direcciones del navegador se escribe: http://IPservidor:9090 en lugar de IPservidor se pone la dirección IP del servidor Linux o. www.ejemplo.com) aparecerá una pagina de configuración: 472 . 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á: 473 . Se configura el acceso a MySQL y la base de datos: En seteos de perfil se elige la opción “por defecto” 474 . 475 .Se configura el correo electrónico y la cuenta del administrador: El servidor está listo para funcionar. crear usuarios. Para probar la conexión el cliente predefinido de Openfire es Spark (en este caso para Windows). y se presiona Login: Después de unos segundos: 476 . Hay que descargarlo.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 Ahora se puede configurar el servidor. instalar plugins. que es el que se ha creado a lo largo de la configuración de Openfire. crear conferencias y otras cuantas funciones. Se pone come usuario admin. instalarlo y abrirlo. pid" OPENFIRE_LOGDIR="/var/log" 477 .pid" #OPENFIRE_LOGDIR="/some/where/logs" #OPENFIRE_OPTS="-Xmx1024m" #JAVA_HOME=/usr/java/default para que queden OPENFIRE_HOME="/opt/openfire" OPENFIRE_USER="root" OPENFIRE_PIDFILE="/var/run/openfire.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/redhat nano openfire-sysconfig Se modifican estas lineas: #OPENFIRE_HOME="" #OPENFIRE_USER="daemon" #OPENFIRE_PIDFILE="/var/run/openfire. 2 Instalar el Plugin SIPPhone en Openfire En este párrafo se verá come instalar el plugin SIPPhone para Openfire. Luego se instala el mismo plugin en el cliente Spark y desde éste se podrán efectuar llamadas usando el dialplan configurado en Asterisk.d/openfired status openfire is running 24. 478 .d/openfired se vuelve ejecutable: chmod +x /etc/init. Desde un navegador Web entramos en la pagina de administración.0.6.0-openjdk-1. Este plugin permite asociar a un usuario registrado en Openfire una cuenta SIP o extensión Asterisk.0 Se guardan los cambios y se copia el archivo en la carpeta /etc/sysconfig: cp openfire-sysconfig /etc/sysconfig/openfire Ahora se instala el servicio: cp openfire /etc/init.d/openfired y se añade a los servicios: chkconfig --add openfired chkconfig openfired on Para averiguar si Openfire arranca en automático se hace un un reboot de la maquina Linux.6. reboot Se vuelve a entrar en el servidor y se averigua que openfire esté corriendo: /etc/init.OPENFIRE_OPTS="-Xmx256m" JAVA_HOME=/usr/lib/jvm/java-1. En la segunda línea del menú habrá un nuevo menú: “Phone”. aparecerá una lista de los plugins disponibles entre los cuales: Se presiona el botón a la derecha del plugin para instalarlo. Se presiona el botón Server en la barra del menú. Dependiendo de los plugins que ya se instalaron.En el menú Plugins se escoge Available Plugins en el menú de la izquierda. Se escoge “Agregar nuevo mapeo” y se rellenan los campos: 479 . Se presiona para entrar en el menú de configuración del plugin. Se repite la misma operación para todos los usuarios que se quiere asociar a una extensión de Asterisk. se pone aquí el numero Se presionas el botón “Crear” para guardar la configuración.• • • • • • • • Nombre de usuario XMPP : el nombre del usuario openfire Nombre de usuario : el numero o nombre de la extensión Usuario de Autorización : el numero o nombre de la extensión Numero de teléfono a mostrar : el numero que aparecerá al llamado Clave: la contraseña asociada a la extensión Servidor: el nombre del dominio o IP del servidor Asterisk Outbound Proxy : si se utiliza un proxy para conectarse al servidor Asterisk hay que indicarlo aquí sino se pone la dirección IP o el nombre de dominio del servidor Asterisk Numero Correo de voz : como en el dialplan se ha definido que para acceder al buzón de voz se utiliza la extensión 97. Se abre el cliente Spark y se abre una conexión con el nombre de usuario configurado arriba (en este caso admin). Una vez terminado hay que configurar el cliente Spark que es el único que funciona con este plugin. En el menú del cliente Spark se elige Spark → Plugins y en Plugins disponibles Phone client y se instala: 480 . Spark debería empezar a timbrar: 481 .Cuando se termina de descargar el plugin. Ahora se puede hacer una primera prueba. En el menú acciones se elige Phone Enabled. Aparecerá el cliente SIP en una nueva línea del menú de Spark y se podrá empezar a usarlo para hacer llamadas. se cierra el cliente y se vuelve a iniciar. Desde la extensión 1001 se marca la extensión 1000. 0.0 permit=127.0/0. esta es una buena solución.0.0.agi. De este modo cuando esa extensión está hablando. como se verá en el próximo párrafo.conf Al final del archivo se añade un nuevo usuario: [openfire] secret = sesamo deny=0.conf: nano /etc/asterisk/manager.dtmf.1/255.3 El Plugin Asterisk-IM Asterisk-IM permite asociar a cada usuario Openfire una extensión SIP configurada en sip. monitorear las extensiones.agi.d/asterisk reload 482 .conf haber configurado un usuario en el archivo manager. hacer llamadas VoIP y.255 read=system.aoc Se actualiza la configuración de Asterisk: /etc/init.reporting.call.0.user.cdr.0. en el cliente jabber Spark el estado del usuario Openfire asociado con la extensión cambiará de disponible a “on the phone”.conf Se modifica el archivo manager.command.user.Si se quiere usar un único programa para chatear.0.dialplan. 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.reporting. 24.call.agent.agent.conf.cc.config.otiginate.aoc write=system.255.255. Se presiona el menú “Available Plugins” Para instalarlo se presiona el botón que aparece al fondo de la línea del plugin. Se configura siguiendo las pautas indicadas en la imagen que sigue: 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 483 . Una vez instalado en el barra de los menú.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. Asterisk IM. habrá una nueva voz. Se escoge el menú Asterisk-IM y luego General Settings. En la pagina que aparece se configura como en la imagen que sigue: • • • • • Server Name: un nombre que se quiere asignar al servidor Server Address: dirección IP o nombre de dominio del servidor Asterisk (en este caso como se encuentra en el mismo servidor Linux.conf Password: la contraseña configurada en el manager.conf Se presiona el botón “Create Server”. Para averiguar que efectivamente el usuario Openfire esté conectado al Asterisk Manager se entra en la 484 . La bolita verde a la izquierda indica che hay conexión con Asterisk. se pone localhost Port: el puerto para conectarse a la AMI de Asterisk Username: el nombre de usuario definido en el archivo manager. consola de Asterisk: asterisk -rvvvvvvvvvvvvvv se digita el comando: CLI> manager show connected Username openfire IP Address Start Elapsed FileDes HttpCnt Read Write 127. Para guardar los cambios.1 1323817682 79 10 0 04079 04851 Se guardan los cambios y se entra en el menú Phone Mappings: Se configuran todos los usuarios de Openfire que se quiere asociar con una extensión SIP presente en el servidor Asterisk. se presiona el botón “Add”. Desde el cliente Spark se abre una conexión con el usuario admin que se ha configurado en Phone Mappings.0. en el cliente Spark cambiará el estado del usuario admin: Como cambiará en el cliente X-Lite: 485 . Desde el cliente Spark se marca el 97 para entrar en la buzón de voz.0. 24. etiqueta que define la conexión (importante para las funciones Jabberstatus y Jabbersend de Asterisk) type=client .1). Asterisk actuará como un cliente (las opciones son cliente. Se empieza con la modifica del archivo jabber.4 Asterisk como cliente en Openfire La configuración de Asterisk como cliente jabber en Openfire es parecida a la de GoogleTalk (párrafo 5. se copian las siguientes lineas: [asterisk] . Usar el protocolo TLS usesasl=yes . el nombre de dominio o IP del servidor Openfire username=asterisk@localhost/openfire . la contraseña priority=10 . Usar el protocolo SASL 486 .conf Al final del archivo.conf presente en la carpeta /etc/asterisk. nano /etc/asterisk/jabber. el nivel de prioridad que tiene en cliente en caso de conflictos (ej: dos conexiones simultaneas del mismo usuario) port=5222 . componente y server) serverhost=localhost . el puerto TCP del servidor Openfire usado para conectarse usetls=yes . Nombre del usuario Openfire del servidor asterisk secret=sesamo . la lista de amigos. un mensaje personalizado del usuario timeout=100 . uno por línea statusmessage=Asterisk server .conf (sesamo) Confirm Password: otra vez la contraseña 487 .buddy=admin@localhost . Desde un navegador Web se entra en la pagina de administración de Opnefire En la barra de menú se escoge “Users/Groups” y luego en el menú vertical en la izquierda “Create New User” • • • • • Username: el nombre de usuario Openfire Name: el nombre completo o un apodo Email: la dirección del correo electrónico del usuario (personalizar) Password: la contraseña creada en el jabber. Se guardan los cambios y antes de actualizar la configuración de Asterisk se configura este usuario en Openfire. Se termina presionando el botón “Create User”.Connected Se inicia el cliente Spark y se añade el usuario asterisk. 488 . Ya se puede recargar la configuración de Asterisk: /etc/init.d/asterisk reload Se averigua el resultado desde la consola de Asterisk asterisk -rvvvvvvvvvvvv CLI> jabber show connected Jabber Users and their status: User: asterisk@localhost/openfire Para ver la lista de amigos: CLI> jabber show buddies Client: asterisk@localhost/openfire Buddy: admin@localhost Resource: None En el menú “Sessions” de Openfire: . members.com • • Primero: si hay un cortafuegos por el medio.linode.linode.5 Conectar dos servidores Openfire Si se conectan dos servidores Openfire entre ellos. 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 → 489 .com Openfire B dominio: li340-16.members.El resultado será: 24. 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 dominio: li115-178. Server Settings → Server to Server Se configura la página como sigue: Luego se pasa al menú Server > Server settings > Security settings y bajo el cuadro Server Connection Security se selecciona la casilla: 490 . se añade a la lista de amigos el usuario servidorb: 491 .com en la White List.Se guardan los cambios y se sigue el mismo procedimiento en el servidor B indicando el dominio: li340-16. Se guardan los cambios. Para probarla en el servidor B se crea un nuevo usuario (menú Users/Groups → Create New User): Ahora desde el cliente Spark conectado al servidor A. La conexión se activa solamente cuando de un servidor se envía una solicitud a otro servidor.linode.members. Se entra en el menú Sessions > Server Session de ambos servidores donde debería aparecer: Servidor A: Servidor B: 492 . com. Se pueden instalar uno o más Connection Manager según el numero de usuarios. Escape character is '^]'.16.linode. Los clientes tendrán que conectarse a ese servidor y luego serán enrutados por el Connection Manager al servidor Openfire. </stream:stream>Connection closed by foreign host.Si no aparece ninguna conexión se puede usar el programa Telnet para averiguar si el puerto 5269 TCP esté efectivamente abierto. Si aparece la expresión en negrita todo está bien. Para tres o más servidores Openfire. se sigue el mismo procedimiento. que queremos conectar entre ellos. hay que recurrir al Connection Manager.members. El esquema de funcionamiento es el que aparece en la imagen que sigue: En ese ejemplo hay tres Connection Managers instalados que reciben los registros de los usuarios y a su vez están conectados con el servidor Openfire.115. 24.linode..com 5269 Trying 96.126. Este programa se configura delante del servidor Openfire y gestiona las conexiones y las autenticaciones de los usuarios.6 Openfire Connection Manager Si hay que manejar un numero considerable de usuarios (más de 1000 en linea a la vez). Desde la consola de Linux del servidor A se escribe: yum install telnet telnet telnet> o -a li340-16.members.. Se descarga el programa: 493 . Cada Connection Manager es capaz de manejar cinco mil usuarios. Connected to li340-16. xml cd /opt/connection_manager/conf nano manager. interface: dirección IP o nombre de dominio donde el Connection Manager aceptará las conexiones.voztovoice.gz Se entra en la carpeta de configuración y se modifica el archivo manager.xml Las líneas que hay que modificar son: • • • domain: el nombre de dominio del servidor Openfire (ej: miodominio.gz Se descomprime: tar -xf connection_manager_3_6_3.org/tmp/connection_manager_3_6_3. Para terminar se instala el “script” para iniciar Connection Manager en automático: cd /opt/connection_manager/bin/extra nano cmanagerd Se modifican las siguientes líneas: export CMANAGER_HOME=/opt/connection_manager export CMANAGER_USER=root 494 . • • • Se guardan los cambios.tar.cd /opt wget http://www.tar.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 se quiere asignar a el Connection Manager (muy útil si se tiene planeado instalar más de uno). CMD=".d/ chmod +x /etc/init.sh $1" Se guardan los cambios y se termina: cp cmanagerd /etc/init./cmanager. En la pagina que aparece se activa el servicio. Ahora se puede arrancar el Connection Manager. Desde la pagina di administración del servidor Openfire bajo el menú “Server settings” se elige “Connection Manager”.d/cmanagerd status running pid is 5747 Connection Manager 3. 2010 5:02:17 AM] y en la pagina de administración de Openfire se verifica que está conectado: 495 . Se abre el puerto 5262 TCP en el cortafuegos. En el servidor Linux donde se instaló se escribe: /etc/init. se escoge el puerto y se define una contraseña.d/cmanagerd start Se averigua que esté corriendo: /etc/init. Se presiona el botón “Save Settings”.6.d/cmanagerd chkconfig –add cmanagerd chkconfig cmanagerd on Antes de arrancar el Connection Manager hay que modificar la configuración del servidor Openfire.3 [Feb 6. 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 496 . . En este tipo de escenario hay disponible una funcionalidad de MySQL. Ahora se quiere tener una copia de la base de datos actualizada en tiempo real para hacer frente a cualquier tipo de evento que pueda afectar la integridad de los registros de las llamadas o de las configuraciones en Realtime. habrá que escoger el tipo que se quier implementar 25. La replicación master-slave no es una copia de backup de la base de datos. Hay dos formas de replicar los datos: • • configurar una replicación master-slave (maestro-esclavo) configurar una replicación master-master (maestro-maestro) Como no se pueden tener los dos tipos de configuraciones activas a la vez. ¿Como funciona la replicación MySQL Master-slave? • • • El Maestro registra los cambios en un registro binario (Binary log) El esclavo copia los eventos en un registro propio (Relay log) El esclavo lee y repite los eventos presentes en el Relay log en la base de datos Una imagen que explica el funcionamiento: . antes de empezar. Un ejemplo puede ser cuando se generan reportes mensuales de las llamadas.Capitulo XXV Asterisk y alta disponibilidad El servidor Asterisk ya está instalado y trabajando. se hacen en el esclavo.1 Replicación MySQL Master-Slave En este párrafo se verá como crear una replicación MySQL Master-Slave. Es buena practica usar una conexión dedicada para el intercambio de datos entre el maestro y el esclavo para evitar que hayan retrasos considerables en la actualización de la base de datos. automáticamente se borrará también en el esclavo. de hecho si se borra una entrada en el MySQL maestro. la posibilidad de replicar los datos en un servidor MySQL instalado en otro computador. En vez de hacer las consultas en el maestro. Se puede usar el esclavo para consultas desde otros programas y de esta manera no cargar demasiado el Maestro. La idea es tener siempre una copia de backup y además crear la replicación maestro-esclavo. El escenario que se va a presentar es el siguiente: ServidorA: IP LAN: 192.168.128.145 Esclavo Base de datos replicada: asteriskcdr Servidor A: Se crea una carpeta donde guardar los Binary log: mkdir /var/log/mysql Se cambian los permisos de modo que MySQL pueda escribir y leer en esa carpeta: chown mysql:mysql /var/log/mysql Se entra en el cliente mysql mysql -u root -psesamo y se crean los privilegios de replicación para un nuevo usuario que luego se configurará en el servidorB: 499 .144 Base de datos a replicar: asterisk Master ServidorB: IP LAN: 192.128.168. 145' IDENTIFIED BY 'sesamo'.168. Aumenta la carga del Master a cambio de una replicación más precisa Se guardan los cambios y se reinicia MySQL /etc/init.128.myslq> GRANT REPLICATION SLAVE ON *.cnf Bajo la etiqueta [mysqld] se añaden las siguientes líneas: server-id = 10 log_bin = /var/log/mysql/mysql-bin. mysql> quit Ahora se modifica el archivo de configuración de MySQL para configurar los parámetros necesarios para la replicación: nano /etc/my.d/mysqld restart Considerando que el servidor Asterisk tiene tiempo trabajando hay que crear una copia de la base de datos para luego importarla en el servidor MySQL esclavo: mysql -u root -psesamo Primero se selecciona la base de datos asteriskcdr: mysql> use asteriskcdr 500 .log expire_logs_days = 10 max_binlog_size = 100M binlog_do_db = asteriskcdr sync_binlog=1 Una pequeña explicación de los parámetros: • • • • • • server-id: identifica el servidor MySQL log_bin: nombre del archivo donde se guardará el Binary log expire_log_days: especifica que los archivos Binary log más viejos de 10 días se pueden borrar max_binlog_size: el tamaño máximo de un Binary log binlod_do_db: el nombre de la base de datos que se va a replicar sync_binlog: cada evento generado en el Master será escrito inmediatamente en el Binary log. Se actualizan los privilegios y se sale del cliente MySQL: mysql> flush privileges.* TO 'asterisk'@'192. 00 sec) Se anotan los datos que aparecen en la columna File (mysql-bin.145:/tmp Se cierra esta ventana y se vuelve a la primera. no está instalado se instala: yum install mysql mysql-server mysql-devel Se inicia: /etc/init. se abre otra ventana terminal o otra conexión al servidor Linux y se crea una copia de la base de datos asteriskcdr: cd /tmp mysqldump -u root -psesamo asteriskcdr > asteriskslave.sql root@192. Aparecerá algo por el estilo: +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.sql se copia el archivo en el servidoB en la carpeta tmp: scp asteriskslave.000001) y en la columna Position (98). y se sale del cliente: mysql> quit Servidor B Si MySQL.128.d/mysqld start 501 . Se desbloquean las tablas: mysql> UNLOCK TABLES.Segundo se bloquea la lectura de todas las tablas de todas las bases de datos: mysql> FLUSH TABLES WITH READ LOCK.168. Sin cerrar esta ventana. Por ultimo se mira el estado del Master: mysql> SHOW MASTER STATUS.000001 98 | asteriskcdr | | +------------------+----------+--------------+------------------+ 1 row in set (0. cada 60 segundos intentará restablecerla replicate-do-db: la base de datos que vamos a replicar skip_slave_start: evita que el esclavo se reinicie en el caso de un crash del servidor read_only: no permite a la mayoría de los usuarios del servidor MySQL esclavo cambiar las tablas Se guardan los cambios y se reinicia MySQL: /etc/init.cnf bajo la etiqueta [mysqld] se pone: server-id=20 master-connect-retry=60 replicate-do-db=asteriskcdr skip_slave_start read_only Los parámetros: • • • • • server-id: numero que identifica el servidor MySQL del servidorB master-connect-retry: si el esclavo pierde la conexión con el maestro. 502 .128.Se crea una contraseña para el usuario root: mysqladmin –u root password sesamo Se modifica el archivo de configuración de MySQL nano /etc/my.sql A este punto se crean los datos de acceso al servidor MySQL Master: mysql -u root -psesamo mysql> CHANGE MASTER TO MASTER_HOST='192.168.144'.d/mysqld restart Se crea la base de datos asteriskcdr: mysqladmin -u root -psesamo create asteriskcdr se recuperan tablas y datos de la copia que está en la carpeta /tmp: cd /tmp mysql -u root -psesamo asteriskcdr < asteriskslave. En MASTER_LOG_FILE Y MASTER_LOG_POS. Antes de iniciar el esclavo.000001'. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192. se ponen los datos del servidor MySQL A que se habían anotado.145 --dport 3306 -j ACCEPT Se guardan los cambios y se reinicia iptables: service iptables restart Se vuelve a la ventana del servidorB y se inicia el esclavo: mysql> START SLAVE. MASTER_PASSWORD='sesamo'.000002 Relay_Log_Pos: 235 Relay_Master_Log_File: mysql-bin. hay que abrir el puerto TCP 3306 en el servidor A.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes 503 . MASTER_LOG_FILE='mysql-bin.168.128. Se hace indicando que la única IP que podrá conectarse será la del Servidor B: nano /etc/sysconfig/iptables Después de este bloque: # Monit -A INPUT -p tcp -m state --state NEW -m tcp --dport 2812 -j ACCEPT Se pone: # MySQL -A INPUT -p tcp -m state --state NEW -m tcp -s 192.MASTER_USER='asterisk'.000001 Read_Master_Log_Pos: 98 Relay_Log_File: mysqld-relay-bin.168. MASTER_LOG_POS=98.142.248 Master_User: fulano Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin. Se controla el estado de la conexión con el Master: mysql> SHOW SLAVE STATUS\G *************************** 1. En éste se verá como utilizar la replicación MySQL Master-Master para la base de datos asteriskcdr solamente para la tabla CDR.128.144) ha enviado tress paquetes al servidorB (192.00 sec) Se sale del cliente: mysql> quit Ahora se efectúa una llamada de prueba.168. se cierra la captura de paquetes y se mira que contiene el archivo /tmp/esclavo El servidorA (192. Antes de hacerlo se activa en el servidorB la captura de paquetes con Ngrep para el puerto 3306 y la red local: ngrep -d eth0:1 -W byline port 3306 > /tmp/esclavo Terminada la llamada.2 Replicación MySQL Master-Master En el párrafo anterior se ha visto como usar la replicación MySQL Master-Slave para la base de datos de asteriskcdr.168. ¿Qué diferencia hay entra una replicación Maestro-Esclavo y una Maestro-Maestro? 504 . 25. CDR2 y CDR3 de la base de datos asteriskcdr del servidor B.145) para actualizar las tablas CDR.Replicate_Do_DB: asteriskcdr Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 1 row in set (0.128. Desde la extensión 1000 conectada al servidorA se llama el buzón de voz. En el segundo caso la configuración se utiliza para la alta disponibilidad en Asterisk.144 Base de datos a replicar: asteriskcdr – Tabla: cdr MasterA SlaveA ServidorB: IP 192.128.145 Base de datos a replicar: asteriskcdr – Tabla: cdr MasterB SlaveB La tabla CDR en el ServidorA ya existe y tiene unos cuantos datos registrados. En este escenario se pueden generar conflictos entre los datos de las dos tablas y errores de replicación porque los dos presentan entradas con el mismo ID en la clave primaria de la tabla (siendo progresivo).En el primer caso se tiene una copia de todos los registros en otro servidor y se pueden efectuar estadísticas usando el Esclavo sin sobrecargar el Maestro. este empieza a grabar nuevas entradas en la misma tabla. Ejemplo: el servidorA se cae y toma su lugar el servidorB. se necesitará configurar otros programas. además de la replicación Master-Master. Ejemplo: hay dos servidores Asterisk: A y B.168. Cuando A vuelve a funcionar.128. El problema principal de la replicación Master-Master es el conflicto que se puede presentar en las entradas de la tabla.calldate from cdr where dst=1000. para la alta disponibilidad en Asterisk. Mientras el servidorA vuelve a funcionar y antes que el servidorB pueda actualizar los datos de la tabla CDR en el servidorA. Como se verá en los próximos párrafos. B vuelve a ser el servidor de respaldo. +----+---------------------+ | id | calldate | +----+---------------------+ | 21 | 2011-12-14 13:21:42 | 505 .168. Para solucionar este tipo de problema se usarán estos dos parámetros: • • auto_increment_increment auto_increment_offset ServidorA Se entra en el cliente MySQL y se consultan las fechas de las llamadas de la extensión 1000: mysql -u root -psesamo mysql> use asteriskcdr mysql> select id. Escenario: ServidorA: IP 192. Si A se cae B toma su lugar. Se registran unos cuantos datos en la tabla cdr del servidorB. 168.145' IDENTIFIED BY 'sesamo'.* TO 'masterb'@'192.128.cdr sync_binlog =1 Los parámetros: • • Con auto_increment_increment a 10 cada entrada en la tabla cdr tendrá un ID progresivo que irá de 10 en 10.| 55 | 2011-12-15 09:01:57 | | 56 | 2011-12-15 09:03:10 | | 57 | 2011-12-15 09:03:28 | | 58 | 2011-12-15 09:03:56 | +----+---------------------+ 5 rows in set (0. Con auto_increment_offset a 1 cada entrada usará el entero 1 506 .log expire_logs_days = 10 max_binlog_size = 100M replicate-do-table =asteriskcdr.00 sec) Se crea una carpeta donde guardar los Binary log de MySQL y se cambia usuario y grupo que tiene los permisos en la carpeta creada: mkdir /var/log/mysql chown mysql:mysql /var/log/mysql Se regresa al cliente MySQL y se crean los privilegios de replicación para un nuevo usuario: mysql -u root -psesamo mysql> GRANT REPLICATION SLAVE ON *. mysql> quit Se modifica el archivo de configuración de MySQL: nano /etc/my.cnf bajo la etiqueta [mysqld] se pone: server-id = 10 auto_increment_increment = 10 auto_increment_offset = 1 log_bin = /var/log/mysql/mysql-bin. mysql> flush privileges. sql se copia el archivo en el servidorB en la carpeta tmp: 507 .00 sec) Se anotan los datos que aparecen en la columna File (mysql-bin. Aparecerá algo por el estilo: +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 98 | asterisk | | +------------------+----------+--------------+------------------+ 1 row in set (0.d/mysqld restart Considerando que el servidor Asterisk tiene tiempo trabajando hay que crear una copia de la base de datos para luego importarla en el servidorB: mysql -u root -psesamo Primero se selecciona la base de datos asterisk: mysql> use asteriskcdr Segundo se bloquea la lectura de todas las tablas de todas las bases de datos: mysql> FLUSH TABLES WITH READ LOCK. Por ultimo se mira el estado del Master: mysql> SHOW MASTER STATUS.000001) y en la columna Position (98). se abre otra ventana terminal o otra conexión al servidor Linux y se crea una copia de la base de datos asteriskcdr: cd /tmp mysqldump -u root -psesamo asteriskcdr > cdr.En el caso de tres entradas en la tabla el resultado será: ID 1 ID 11 ID 21 • Con replicate-do-table se define que la replicación es solamente para la tabla cdr de la base de datos asteriskcdr Se reinicia mysql: /etc/init. sin cerrar esta ventana. scp cdr.sql Se averigua que efectivamente las tabla y los datos presentes se han guardado: mysql -u root -psesamo mysql> use asteriskcdr mysql> select id.calldate from cdr where dst=1000.145:/tmp Se cierra esta ventana y se regresa a la primera. Se desbloquean las tablas: mysql> UNLOCK TABLES. +----+---------------------+ | id | calldate | +----+---------------------+ | 21 | 2011-12-14 13:21:42 | | 55 | 2011-12-15 09:01:57 | | 56 | 2011-12-15 09:03:10 | 508 .128. mysql> quit Se importa la tabla cdr: cd /tmp mysql -u root -psesamo asteriskcdr < cdr. y se sale del cliente: mysql> quit ServidorB Se crea la carpeta para guardar los Bynary log con los permisos para el usuario mysql: mkdir /var/log/mysql chown mysql:mysql /var/log/mysql Se entra en el cliente mysql y se crea la base de datos asterisk: mysql -u root -psesamo mysql> create database asteriskcdr.sql [email protected]. En el caso de tres entradas el ID sería: ID 2 ID 12 ID 22 Como se puede ver. mysql> quit Ahora se modifica el archivo de configuración de MySQL: nano /etc/my. de esta forma no se presentarán conflictos en las entradas de la tabla CDR.* TO 'mastera'@'192.168.00 sec) Aparecerán las mismas entradas del servidorA. 509 .144' IDENTIFIED BY 'sesamo'.cdr sync_binlog =1 El auto_increment_offset es igual a 2.128.| 57 | 2011-12-15 09:03:28 | | 58 | 2011-12-15 09:03:56 | +----+---------------------+ 5 rows in set (0. mysql> flush privileges. Se crea un nuevo usuarios con los permisos de replicación: mysql> GRANT REPLICATION SLAVE ON *. Se reinicia Mysql: /etc/init.cnf bajo la etiqueta [mysqld] se pone: server-id = 20 auto_increment_increment = 10 auto_increment_offset = 2 log_bin = /var/log/mysql/mysql-bin.d/mysqld restart Y ahora como para el servidorA se mira el Binary log y se anotan los datos: mysql -u root -psesamo mysql> FLUSH TABLES WITH READ LOCK.log expire_logs_days = 10 max_binlog_size = 100M replicate-do-table =asteriskcdr. MASTER_LOG_FILE='mysql-bin.00 sec) y se mira el resultado: mysql> SHOW SLAVE STATUS\G *************************** 1. Query OK. hay que abrir el puerto TCP 3306 solamente para esa IP local: nano /etc/sysconfig/iptables En la sección filter se añade: # MySQL -A INPUT -p tcp -m state --state NEW -m tcp -s 192. 0 rows affected (0.000001 | 98 | | | +------------------+----------+--------------+------------------+ 1 row in set (0. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.144'. MASTER_USER='masterb'. +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.144 --dport 3306 -j ACCEPT Se reinicia el servicio: service iptables restart Ahora se conecta el servidorB al servidorA: mysql -u root -psesamo mysql> CHANGE MASTER TO MASTER_HOST='192. MASTER_PASSWORD='sesamo'.00 sec) mysql> quit Para dar acceso a la base de datos al servidorA. 0 rows affected (0.168.168.000001'. Query OK.128.168. MASTER_LOG_POS=98.128.248 510 .00 sec) Se inicia el esclavo: mysql> START SLAVE.mysql> SHOW MASTER STATUS.142. mysql> SHOW SLAVE STATUS\G 511 . MASTER_PASSWORD='sesamo'. 0 rows affected (0. MASTER_LOG_POS=98.128.00 sec) Se sigue el mismo procedimiento para el ServidorA: mysql -u root -psesamo mysql> CHANGE MASTER TO MASTER_HOST='192.Master_User: masterb Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001'.145'.000001 Read_Master_Log_Pos: 98 Relay_Log_File: mysqld-relay-bin.000002 Relay_Log_Pos: 235 Relay_Master_Log_File: mysql-bin. MASTER_LOG_FILE='mysql-bin. MASTER_USER='mastera'. Query OK.cdr Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 1 row in set (0.168.10 sec) mysql> START SLAVE.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: asteriskcdr. 168.90 Master_User: mastera Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin. El resultado en la base de datos: mysql -u root -psesamo mysql> use asteriskcdr 512 .000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: asterisk.000001 Read_Master_Log_Pos: 98 Relay_Log_File: mysqld-relay-bin.00 sec) La prueba Se para el MySQL del servidorB y se efectúan dos llamadas desde la extensión 1000 del Asterisk A al buzón de voz.146.cdr Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 98 Relay_Log_Space: 235 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 1 row in set (0. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.000002 Relay_Log_Pos: 235 Relay_Master_Log_File: mysql-bin.*************************** 1. +----+---------------------+ | id | calldate | +----+---------------------+ | 32 | 2011-12-14 18:06:06 | | 54 | 2011-12-15 08:51:20 | | 61 | 2011-12-15 09:33:23 | | 71 | 2011-12-15 09:33:48 | | 72 | 2011-12-15 09:38:07 | | 82 | 2011-12-15 09:39:14 | +----+---------------------+ 6 rows in set (0.00 sec) El ID progresivo en el servidorB cambia con saltos de 10 y cada entrada termina con el numero 2.calldate from cdr where dst=97.calldate from cdr where dst=97. Terminada la operación. se para MySQL en el servidorA y se inicia MySQL en el servidorB efectuando dos llamadas al buzón de voz usando el Asterisk del servidorB.00 sec) Mientras antes el ID era progresivo.calldate from cdr where dst=97. +----+---------------------+ | id | calldate | +----+---------------------+ | 32 | 2011-12-14 18:06:06 | | 54 | 2011-12-15 08:51:20 | | 61 | 2011-12-15 09:33:23 | | 71 | 2011-12-15 09:33:48 | +----+---------------------+ 4 rows in set (0. las ultimas dos entradas tienen un salto de 10 y cada una termina con el numero 1. +----+---------------------+ 513 . El resultado en la base de datos: mysql -u root -psesamo mysql> use asteriskcdr mysql> select id. Ahora se inicia MySQL en el servidorA y se mira que pasa en los dos servidores: ServidorA mysql -u root -psesamo mysql> use asteriskcdr mysql> select id.mysql> select id. 00 sec) ServidorB mysql -u root -psesamo mysql> use asteriskcdr mysql> select id. Al momento de configurar el servidor Linode. Lo mismo se puede hacer con dos servidores locales con las modificaciones oportunas. se han creado 4 particiones: 514 .calldate from cdr where dst=97. Funciona en el mismo modo de un sistema RAID1 con la sencilla diferencias que las copias de los datos se hacen a través de la red usando el protocolo TCP. +----+---------------------+ | id | calldate | +----+---------------------+ | 32 | 2011-12-14 18:06:06 | | 54 | 2011-12-15 08:51:20 | | 61 | 2011-12-15 09:33:23 | | 71 | 2011-12-15 09:33:48 | | 72 | 2011-12-15 09:38:07 | | 82 | 2011-12-15 09:39:14 | +----+---------------------+ 6 rows in set (0.00 sec) Los datos se han replicado y no hubo ningún tipo de conflicto en la tabla cdr gracias al uso de: • • auto_increment_increment auto_increment_offset 25.3 DRBD . Se verá como instalar DRBD en dos servidores VPS en Linode y de esta forma crear un sistema de alta disponibilidad para Asterisk.| id | calldate | +----+---------------------+ | 32 | 2011-12-14 18:06:06 | | 54 | 2011-12-15 08:51:20 | | 61 | 2011-12-15 09:33:23 | | 71 | 2011-12-15 09:33:48 | | 72 | 2011-12-15 09:38:07 | | 82 | 2011-12-15 09:39:14 | +----+---------------------+ 6 rows in set (0.Raid1 vía TCP DRBD es un programa que permite conectar particiones presentes en distintos servidores y tenerlas sincronizadas. members.members.linode.linode. Servidor A IP publico: 69.145): icmp_seq=3 ttl=64 time=0.168.126.168.linode.168.com Se guardan los cambios y se averigua que efectivamente se logra localizar el servidor B: ping li340-16. Claramente las mismas particiones tienen que ser creadas el en segundo servidor de respaldo.145): icmp_seq=2 ttl=64 time=0.com Servidor B IP publico: 96.members.com (192.128.16 IP Lan: 192.144 Dominio: li115-178.145 Dominio: li340-16.La ultimas dos es las que se utilizarán para DRDB.linode. tendremos los dos servidores Linode listos para la instalación y configuración de DRBD.linode.128.479 ms 515 .145) 56(84) bytes of data.com PING li340-16.members.145 li340-16.members.128.168.linode.405 ms 64 bytes from li340-16.128.members.168.members. 64 bytes from li340-16.164.168.144 li115-178.com Se inicia la configuración de los dos servidores para que cada uno sepa a que dirección IP encontrar el otro: Servidor A nano /etc/hosts Al final de archivo se añaden las siguientes líneas: 192. Una vez terminada esta operación.128.com (192.128.128.com (192.linode.430 ms 64 bytes from li340-16.671 ms 64 bytes from li340-16.145): icmp_seq=1 ttl=64 time=0.115.linode.168.168.members.178 IP Lan: 192.201.com (192.members.members.168.128.128.com 192.com (192.linode.linode.145): icmp_seq=4 ttl=64 time=0. linode.386 ms 64 bytes from li115-178.gz tar -xf drbd-8.3.128.7.386/0.com (192.64 bytes from li340-16.members.128.168.linode.members.168.542 ms 64 bytes from li115-178.144): icmp_seq=1 ttl=64 time=0.tar.128.com (192.linode.members.168.168.li340-16.linode.linode.linode.128./configure --prefix=/ --with-km --with-xen Se compila utilizando la ultimas versión de las fuentes del Kernel-XEN instalado en el servidor.168.3.168.linode.com ping statistics --6 packets transmitted.members.145): icmp_seq=5 ttl=64 time=0.483 ms --.128.518 ms 64 bytes from li340-16. 0% packet loss.com/drbd/8.587/0.com ping statistics --6 packets transmitted.members.128.linbit. 6 received.128.128.members.com (192. time 4997ms rtt min/avg/max/mdev = 0.com (192.members.480/0.3.405/0.144 li115-178.com (192.168.com 192.145 li340-16.422 ms 64 bytes from li115-178.com (192.gz cd drbd-8.144): icmp_seq=4 ttl=64 time=0. 0% packet loss.144): icmp_seq=2 ttl=64 time=0. time 4996ms rtt min/avg/max/mdev = 0.144) 56(84) bytes of data.members.128.7 .linode.089 ms Se efectua el mismo procedimiento en el servidor B Servidor B nano /etc/hosts Se añaden las siguientes líneas: 192.li115-178.076 ms Una vez terminada esta parte se prepara el sistema para la instalación de DRBD: Las operaciones que siguen hay que ejecutarlas en ambos servidores: cd /usr/src wget http://oss.tar.com (192.linode.com (192.members.com ping li115-178.144): icmp_seq=3 ttl=64 time=0.members. 64 bytes from li115-178.128.7.144): icmp_seq=6 ttl=64 time=0.members.linode.168.members.420 ms 64 bytes from li115-178.members. es 516 .linode.525 ms --.linode.128.671/0.168.168.linode.587 ms 64 bytes from li115-178. 6 received.144): icmp_seq=5 ttl=64 time=0.145): icmp_seq=6 ttl=64 time=0.members.168.com (192.linode.497/0.com PING li115-178.3/drbd-8. } } De esta forma se crean dos nodos primarios usando el protocolo C y se nombra este recurso creado 517 .144:7789.members. } on li340-16.1.168.6.conf.com { device /dev/drbd1.old se crea una nueva: nano /etc/drbd.1. } startup { become-primary-on both. address 192.el5-xen-i686 make install Se mueve la configuración predefinida que viene con la instalación de DRBD mv /etc/drbd.com { device /dev/drbd1. address 192. } resource data { net { allow-two-primaries. } on li115-178.18-308. meta-disk /dev/xvdd[0].1.conf /etc/drbd.1.18-308.linode.linode.el5xen make KDIR=/usr/src/kernels/2.decir: uname -r 2.6. meta-disk /dev/xvdd[0]. } common { protocol C.128.members.145:7789.conf Se copian las lineas que siguen en ambos servidores: global { usage-count yes.128.168. disk /dev/xvdc. disk /dev/xvdc. members.144 Se utilizarán las dos particiones creadas (xvdc y xvdd) una para las copia de los datos y la otra como meta disco para guardar los datos que DRBD crea al momento de conectarse y sincronizarse con el segundo nodo.“data”. Ahora se crean los meta-datos en la partición xvdd de ambos servidores: drbdadm create-md data Normalmente sale este error: Found ext3 filesystem This would corrupt existing data..168.. you need to zero out the first part of the device (destroy the content).com cuya IP local es 192. El nodo 1 será li115-178.2176 seconds. You should be very sure that you mean it.128. initializing activity log NOT initializing bitmap New drbd meta data block successfully created.linode.com cuya IP local es 192. 1.168. El nodo 2 será li340-16. Operation refused. success Se configurara el programa para que el servicio arranque en automático: chkconfig --add drbd chkconfig drbd on Para crear una primera sincronización entre los datos de las dos particiones de los dos servidores se 518 . If you want me to do this. 110 MB/s Se ejecuta otra vez el comando: drbdadm create-md data Writing meta data.145.members. Command 'drbdmeta 1 v08 /dev/xvdd 0 create-md' terminated with exit code 40 Se soluciona destruyendo todos los datos presentes en la partición: dd if=/dev/zero of=/dev/xvdd bs=1M count=128 128+0 records in 128+0 records out 134217728 bytes (134 MB) copied.128.linode. .carga el modulo DRBD en el Kernel: modprobe drbd se averigua que efectivamente esté corriendo: lsmod | grep drbd drbd 251364 0 Ahora se crea la conexión entre los dos servidores: drbdadm attach data drbdadm syncer data drbdadm connect data Se efectuá una primera sincronización de los datos: Servidor A drbdadm -.linode.members.3...com.--overwrite-data-of-peer primary data Esta operación puede durar bastante tiempo dependiendo del tamaño de los discos.linode... Se puede controlar en cualquier momento a que punto ha llegado con el comando: cat /proc/drbd version: 8. aparecerá: cat /proc/dbd version: 8. 2011-12-15 11:24:58 build by root@li115- 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r---519 .3.] sync'ed: 1.com.7 (api:88/proto:86-91) GIT-hash: ea9e28dbff98e331a62bcbcc63a6135808fe2917 178..... 2011-12-15 11:24:58 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---ns:3672 nr:0 dw:0 dr:3672 al:0 bm:0 lo:6 pe:0 ua:6 ap:0 ep:1 wo:b oos:815528 [>....0% (815528/819200)K finish: 0:42:28 speed: 252 (244) K/sec Cuando el proceso termine..7 (api:88/proto:86-91) GIT-hash: ea9e28dbff98e331a62bcbcc63a6135808fe2917 build by [email protected].. se copian 520 .ns:819200 nr:0 dw:0 dr:819200 al:0 bm:50 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0 Se reinician ambos servidores: reboot Servidor A Se crea una nueva carpeta donde se copiarán los datos que se quiere sincronizar: mkdir /home/data Se monta la partición de los datos: mount /dev/drbd1 /home/data se crean unos cuantos archivos de prueba: touch /home/data/file1 touch /home/data/file2 touch /home/data/file3 ls /home/data file1 file2 file3 lost+found Se desmonta la partición: umount /home/data y se averigua el resultado en el servidor B Servidor B mkdir /home/data mount /dev/drbd1 /home/data ls /home/data file1 file2 file3 lost+found umount /home/data En el caso que se quiera tener sincronizados los archivos de configuración de Asterisk. No hace falta dejar la partición montada en ninguno de los dos servidores porque.directamente la carpeta de esta forma: Servidor A mount /dev/drbd1 /home/data mkdir /home/data/etc cd /etc mv asterisk /home/data/etc/asterisk Para terminar se crea un enlace simbólico a la nueva carpeta: ln -s /home/data/etc/asterisk asterisk Lo mismo con DAHDI: mv dahdi /home/data/etc/dahdi ln -s /home/data/etc/dahdi dahdi umount /home/data Servidor B mount /dev/drbd1 /home/data cd /etc rm -fr asterisk rm -fr dahdi ln -s /home/data/etc/asterisk asterisk ln -s /home/data/etc/dahdi dahdi umount /home/data Ya está configurado y funcionando DRBD. Heartbeat se encargará de hacerlo según el servidor que esté activo en ese momento. 25. como se verá en el próximo párrafo.4 Heartbeat 521 . Para resumir: Servidor A IP publico: 69.168. el slave toma el control cargando la partición de DRBD donde hemos guardado los datos de configuración de Asterisk.144 Servidor B IP publico: 96.178 IP Lan: 192.168. Una vez comprado.145 Primero se compra en Linode un segundo IP publico para el servidor A (costo: un dólar al mes) que será el IP “virtual” que compartirán los dos servidores. habrá un IP publico compartido que es él que se utilizará para registrar las extensiones.3.128.0 173.191 es la nueva IP adquirida.255. Se reinicia el servidor: reboot Luego en la pagina de administración de Linode del servidor B se configura el failover. En el caso de una red publica y de Linode sería algo parecido: IP Servidor Asterisk Master IP Asterisk Publico IP servidor Asterisk Slave Se utilizará la misma configuración que se presentó en el párrafo 25.191 NETMASK=255.164.16 IP Lan: 192. En el menú “Remote Access” de la pagina de administración del Linode: 522 .196. poniendo activo el IP compartido y arrancando dahdi y asterisk.128.201.115.126. Cuando se utiliza Asterisk alta disponibilidad con este tipo de configuración.Se termina el capitulo dedicado a Asterisk y alta disponibilidad con la instalación y configuración de Heartbeat.196. Esto permite que al caerse el servidor A.255. hay que configurarlo en una nueva tarjeta de red virtual: nano /etc/sysconfig/network-scripts/ifcfg-eth0:2 Se copian las siguientes lineas: DEVICE=eth0:2 BOOTPROTO=none ONBOOT=yes IPADDR=173. Cuando el master se cae.255.255. el servidor B tomará la gestión de ese IP. Heartbeat se necesita para que los dos servidores sepan el estado del otro. repos.centos.repo se modifica este bloque: [extras] name=CentOS-$releasever .Extras mirrorlist=http://mirrorlist.Se escoge el enlace “IP Failover”.centos. En la nueva pagina: Se selecciona la nueva IP adquirida y se presiona el botón “Save Changes”.org/?release=$releasever&arch=$basearch&repo=extras #baseurl=http://mirror.org/centos/$releasever/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 Se guardan los cambios y se instala Heartbeat: yum install heartbeat Por algún raro motivo hay que repetir el comando dos veces: 523 .org/centos/$releasever/extras/$basearch/ gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5 para que quede: [extras] name=CentOS-$releasever .d/CentOS-Base. Ahora hay que instalar Heartbeat.centos. Para activarlos: nano /etc/yum. Este programa es presente en los repositorios "extras” de CentOS.org/?release=$releasever&arch=$basearch&repo=extras baseurl=http://mirror.centos.Extras mirrorlist=http://mirrorlist. Servidor A: nano /etc/ha.128.com Ahora en ambos servidores se crea el archivo que utilizará Heartbeat para el intercambios de llaves de autentificación y el archivo donde se indicará la IP virtual compartida y los servicios que heartbeat 524 .cf • authkeys • haresources Se empieza con el que se encarga de controlar el estado de los servidores.members.128.com Servidor B: nano /etc/ha.linode.linode.linode.members.145 udpport 694 auto_failback on node li115-178.168.168.com node li340-16.members.cf se pegan las siguientes líneas: debugfile /var/log/ha-debug logfile /var/log/ha-log logfacility local0 keepalive 2 deadtime 120 initdead 120 ucast eth0 192.linode.cf debugfile /var/log/ha-debug logfile /var/log/ha-log logfacility local0 keepalive 2 deadtime 120 initdead 120 ucast eth0 192.d/ha.yum install heartbeat Ahora hay que crear tres archivos de configuración: • ha.d/ha.members.144 udpport 694 auto_failback on node li115-178.com node li340-16. Ahora hay que cambiar los permisos de este archivo para que sea accesible (en lectura y escritura) solamente para el usuario root: chmod 600 /etc/ha.d/resource. Estos archivos tienen que ser iguales en ambos servidores: nano /etc/ha.d/asterisk asterisk ln -s /etc/init.196.d/resource. Se resuelve de la siguiente forma: nano /etc/ha.linode.com y se indica como IP virtual la que se acaba de comprar. Por ultimo se indican los servicios que Heartbeat tiene que iniciar. en este caso dahdi y asterisk.d.members. en este caso /dev/drbd1.d/dahdi dahdi Ahora el problema.d/authkeys Para terminar el archivo de los recursos: nano /etc/ha. Revisando las cosas el script drbddisk (que viene con la instalación de Heartbeat) estaba mal configurado.191 drbddisk::data Filesystem::/dev/drbd1::/home/data::ext3 dahdi asterisk IMPORTANTE: tiene que estar todo el la misma línea Se define como servidor Master li115-178. drbddisk es el script que se encarga de montar la partición donde se han guardado los archivos de configuración de Asterisk.members.com IPaddr2::173.deberá gestionar. Estos servicios tienen que ser indicados en la carpeta etc/ha.d/drbddisk 525 .d/authkeys auth 3 3 md5 sesamo Se usa como método de cifrado MD5 y después se pone la contraseña que se quiere utilizar (en este caso sesamo).d ln -s /etc/init. Todo parecía funcionar bien pero heartbeat no montaba la partición /dev/drbd1 y Asterisk no podía funcionar.d/resource.d/haresources Se pone: li115-178.linode. Para hacerlo se crea un enlace simbólico: cd /etc/ha.255. 168. chkconfig --add heartbeat chkconfig heartbeat on Se abre el puerto UDP 694 que permite a los servicios Hertbeat instalados en los dos servidores de comunicarse entre ellos: Servidor A nano /etc/sysconfig/iptables después de este bloque: # HTTP -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT se añade: # Heartbeat -A INPUT -p udp -m udp -s 192.conf" indicando donde efectivamente se encuentra el archivo de configuración de drbd.128.145 --dport 694 -j ACCEPT Se reinicia iptables: service iptables restart Servidor B nano /etc/sysconfig/iptables después de este bloque: 526 .Se cambia esta linea: DEFAULTFILE="/etc/default/drbd" para que quede: DEFAULTFILE="/etc/drbd. Para terminar la configuración los últimos cambios en ambos servidores: chkconfig asterisk off chkconfig dahdi off Esto porque es Heartbeat que se encarga de iniciar los dos programas. linode.# HTTP -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT se añade: # Heartbeat -A INPUT -p udp -m udp -s 192. es decir: 173.128.145:54002 -> 192.168. automáticamente el servidor B tomará su lugar. Si en algún momento el servidor A se cae.128. Todas las extensiones tendrán que conectarse a la nueva IP compartida.168.191. 527 .128.members.07 1/189 8883 ttl=3 auth=3 3fe72eec1f8c4df616b8067ce368f847 <<< Donde Heartbeat comunica al Servidor B su estado.07 0.255.196.168.144:694 >>> t=status st=active dt=1d4c0 protocol=1 src=li340-16. puerto 694: ngrep -d eth0:1 -W byline port 694 Se verán una serie de paquetes de este tipo: U 192.com (1)srcuuid=9ku7IyMqS7uMVmJpcNsTCg== seq=274 hg=4eea4a62 ts=4eea4ec9 ld=0.144 --dport 694 -j ACCEPT Se reinicia iptables: service iptables restart Con esta ultima operación se ha terminado la configuración de Heartbeat.06 0. Solo falta reiniciar los dos servidores y mirar si todo funciona: reboot Si se hace una captura de paquetes en el Servidor A. . asterisk.1./configure make make install Para terminar con la instalación hay que modificar dos archivos de configuración de Asterisk. se añade solamente al final del archivo el nuevo usuario): nano /etc/asterisk/manager.org/svn/asterisk-gui/branches/2. para evitar de perder el trabajo que se ha hecho hasta el momento. Al arrancar la GUI. Simplifica el manejo de Asterisk siempre y cuando se tenga un conocimiento básico del funcionamiento de la PBX.CAPITULO XXVI Asterisk GUI Asterisk GUI es una interfaz gráfica desarrollada para la gestión y la configuración de Asterisk desde un navegador Web.0/ Se compila y instala: .conf (si ya se ha configurado como indicado en el párrafo 19.0 Se entra en la carpeta: cd 2. yum install subversion cd /usr/src Se descargan los archivos de la GUI svn co http://svn.conf Se averigua que todos los parámetros que siguen tengan el valor indicado: [general] enabled=yes webenabled=yes port=5038 . Primero el manager. ésta añade macros y extensiones al plan de llamadas pero no lee totalmente la configuración ya presentes en la carpeta /etc/asterisk. 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/ Para descargar la ultima versión disponible hay que instalar el programa SUBVERSION. reporting.0.0.var2.agi.otiginate.0 .d/asterisk restart Ahora hay que abrir el puerto 8088 TCP en el cortafuegos nano /etc/sysconfig/iptables Después de este bloque: # Apache 530 .dtmf.conf /etc/asterisk/http.tlsbindport=5039 .call.var3 debug=no authtimeout=60 authlimit=20 httptimeout=60 Se crea un usuario que sera él que se usará para entrar en la pagina de administración de la GUI de Asterisk [asterisk] secret=sesamo writetimeout=100 read=system.user.pem allowmultiplelogin=yes displayconnects=yes timestampevents=yes .dialplan.0 bindport=8088 Se guardan los cambios y se reinicia Asterisk /etc/init.conf [general] enabled = yes enablestatic = yes bindaddr=0.old nano /etc/asterisk/http.cc.0.agent.0 .agi.config.aoc Se guardan los cambios y se sigue con el archivo http.conf.tlsprivatekey=/tmp/private.command.reporting.0.pem .conf mv /etc/asterisk/http.tlsbindaddr=0.tlsenable=no .agent.cdr.0.aoc write=system.user.bindaddr=0.tlscertfile=/tmp/asterisk.channelvars = var1.call.0. linode.linode.com:8088/asterisk/static/config/index. Username: Asterisk Password: sesamo Se presiona el botón “Login” Después de unos segundos aparecerá: 531 .members.-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT Se añaden las siguientes linea: # Asterisk GUI -A INPUT -p tcp -m state --state NEW -m tcp --dport 8088 -j ACCEPT Se guardan los cambios y se reinicia el cortafuegos: service iptables restart Ahora se averigua que todo esté bien configurado make checkconfig * Checking for http.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 --.html Desde un navegador Web se visita la pagina de administración de la GUI de Asterisk. la dirección exacta es: http://li115-178.com:8088/static/config/index.Everything looks good --* GUI should be available at http://li115-178.members.html A pesar que aparezca la linea en negrita como dirección para acceder a la GUI.conf: OK * Checking for manager. Las extensiones configuradas en el sip.conf no aparecerán porque Asterisk GUI las lee y guarda en el archivo users. conferencias) desde los archivos presentes en la carpeta /etc/asterisk.conf Aquí van algunas imágenes de la interfaz gráfica El orden para configurar la GUI es: • • • Crear las troncales en el menú Trunks Crear los contextos para las llamadas saliente en el menú Outgoing Calling Rules Crear el dialplan en el menú Dial Plans 532 .Se vuelve a la ventana terminal del servidor y se para y reinicia Asterisk: service asterisk stop service asterisk start Se vuelve a la pagina de administración de Asterisk y se presiona el Botón Aceptar. El Asterisk GUI leerá algunas configuraciones (colas de espera. Se vuelve a poner Username y password presionando el botón “Login”. Para pequeñas instalaciones con configuraciones básicas.d/asterisk restart La diferencia entre esta GUI y otras es que no utiliza muchos recursos del sistema para funcionar porque no necesita un servidor Web externo (Apache). se copian los dos archivos modificados y se recarga la configuración guardada: cd /etc/asterisk cp manager.conf /tmp/asterisk cp http.• Crear las extensiones en el menú Users Una vez que que se ha probado la GUI de Asterisk y se quiere volver a la configuración anterior. es la más indicada. 533 .conf /tmp/asterisk rm -fr * cp /tmp/asterisk/* /etc/asterisk /etc/init. . 4 .tar. si no se ha ya instalado.13.tar.4/mpg123-1.13. se instala ahora junto al servidor Apache y el modulo mod_ssl.sourceforge.bz2 cd mpg123-1.net/project/mpg123/mpg123/1./configure --prefix=/usr make make install Se cambia el usuario y grupo predefinido del servidor WEB de apache a asterisk: sed -i "s/User apache/User asterisk/" /etc/httpd/conf/httpd. Antes.4.conf sed -i "s/Group apache/Group asterisk/" /etc/httpd/conf/httpd. se remueve el paquete rpmforge-release: yum remove rpmforge-release yum install php-* httpd mod_ssl Se añade el usuario Asterisk con home directory /var/lib/asterisk: useradd -c "Asterisk PBX" -d /var/lib/asterisk asterisk useradd: aviso: el directorio personal ya existe.13.bz2 tar -xf mpg123-1.CAPITULO XXVII FreePBX Personalmente no soy partidario de la instalaciones de Asterisk con Interfaz gráfica.13. No se copia ningún fichero del directorio skel en él. si se quiere utilizar archivos mp3 hay que instalar mpg123 (si ya no se ha hecho en el párrafo 10. Como entiendo que a muchos puede interesar el tema. si se ha instalado.1) que se encargará de convertir los archivos mp3 en wav: cd /usr/src wget http://downloads. Como la GUI se basa en PHP.4.conf . en este capitulo se verá como instalar la GUI FreePBX. Cambiamos los permisos en todas las carpetas creadas por la instalación de Asterisk asignándolos al usuario asterisk que se acaba de crear: chown -R asterisk /var/run/asterisk chown -R asterisk /var/log/asterisk chown -R asterisk /var/lib/asterisk/moh chown -R asterisk /var/lib/php/session chown -R asterisk /var/spool/asterisk chown -R asterisk /etc/asterisk Como para la música en espera Asterisk + FreePBX utilizan archivos en formato wav. 9. Query OK.Para prevenir problemas de acceso se modifica el parámetro AllowOverride de All a None: sed -i "s/AllowOverride All/AllowOverride None/" /etc/httpd/conf/httpd.0. 1 row affected (0. 0 rows affected (0.tar. Query OK.00 sec) mysql> flush privileges. Type '\c' to clear the buffer. Query OK. 0 rows affected (0.00 sec) mysql> GRANT ALL PRIVILEGES ON asteriskcdrdb. Your MySQL connection id is 5 Server version: 5. 0 rows affected (0.* TO asteriskuser@localhost IDENTIFIED BY 'sesamo'.0. Query OK.tar.gz Se descomprime el paquete y se entra en la carpeta creada: tar -xf freepbx-2.freepbx.conf Se entra en el cliente MySQL y se crean dos bases de datos y los respectivos permisos (si no existen): mysql -u root -psesamo Welcome to the MySQL monitor.* TO asteriskuser@localhost IDENTIFIED BY 'sesamo'. mysql> create database asterisk.77 Source distribution Type 'help.0.0 Se crean las tablas para las bases de datos asterisk y asteriskcdrdb: mysql -u root -psesamo asterisk < SQL/newinstall.9. Query OK. or \g.gz cd freepbx-2.00 sec) mysql> quit Bye Se descarga la ultima versión estable de FreePBX: cd /usr/src wget http://mirror.02 sec) mysql> create database asteriskcdrdb.sql 536 .org/freepbx-2.00 sec) mysql> GRANT ALL PRIVILEGES ON asterisk.9.' or '\h' for help. 1 row affected (0. Commands end with . sql Se reinicia Asterisk: /etc/init.mysql -u root -psesamo asteriskcdrdb < SQL/cdr_mysql_table.d/asterisk restart Se reinicia el servidor Apache y se configura para que arranque en automático: service httpd restart chkconfig httpd on Se lanza el script de instalación de FreePBX: ./install_amp Se insertan los datos como aparecen en la imagen y al terminar se para FreePBX: /usr/sbin/amportal stop Se entra en el archivo de configuración de FreePBX y se modifican estas tres líneas (password para el administrador de la pagina de los buzones de voz personales. tipo de autentificación para acceder a la 537 . local /usr/sbin/amportal start Se guardan los cambios y se entra a la pagina web para administrar FreePBX utilizando la siguiente dirección: http://IPservidor Se escoge el enlace “FreePBX Adminsitration”: 538 .xx.xx para que queden: ARI_ADMIN_PASSWORD=sesamo AUTHTYPE=database AMPWEBADDRESS=IPservidor (poner la IP publica del servidor Linux) Se guardan los cambios y se inicia nuevamente FreePBX: /usr/sbin/amportal start En el archivo rc.local se copia esta línea para que el arranque sea automático: nano /etc/rc. respectivamente): nano /etc/amportal.xx.conf ARI_ADMIN_PASSWORD=ari_password AUTHTYPE=none AMPWEBADDRESS=xx.pagina de administración del FreePBX y la dirección IP publica del servidor Linux. Se averigua si hay actualizaciones y se instalan: 539 . Luego desde el menú izquierdo se selecciona “Module Admin”. Primero en el menú “Adminisitrators” se cambia la contraseña del usuario admin: Se pone la nueva contraseña y se presiona el botón “Submit Changes”.Se pone como usuario admin y como contraseña admin. errores de configuración: Una vez que se hayan corregido todos los avisos/errores: Ya se puede empezar con la configuración de Asterisk a través de la GUI FreePBX. 540 . Se selecciona el menú “FreePBX System Status” y se controla que no hayan avisos.De la misma forma se pueden instalar los módulos que se necesiten. . ca/5.8-i386-netinstall. Esta maquina se puede utilizar como laboratorio para trabajar con el libro.8 32bit en un maquina virtual creada con el sistema de virtualización VirtualBOX.8 en una maquina virtual con VirtualBox En esta guía se ilustrará como instalar el sistema operativo CentOS 5.virtualbox. En la ventana que aparecerá. Para iniciar se descarga Virtualbox desde esta pagina: https://www.arcticnetwork.8/isos/i386/CentOS-5.org/wiki/Downloads Luego se instala y se continua con la descarga de la ISO de CentOS: http://centos.iso Una vez terminada la descarga se crea la maquina virtual: Se abre VitualBox y se presiona el icono “Nueva”.Apéndice A Instalar CentOS 5. se selecciona el botón “Siguiente” y se siguen los pasos mostrados en las imágenes: Nombre: CentOSLocal Sistema Operativo: Linux Versión: Red Hat . hay que poner por lo menos 512 Mb.En la memoria RAM para el sistema huésped. mejor aun seleccionar 1GB (1024 Mb) 543 . Si el sistema lo permite. 544 . 545 . 546 . Debe quedar: 547 .Se selecciona el icono marcado con el circulo y en la ventana que aparece se escoge la iso de CentOS que se acaba de bajar. Para terminar se presiona el botón “Aceptar”.Se pasa a la configuración de red: Se habilita un Adaptador y se escogen las opciones como aparecen en la pagina. ya se puede iniciar la maquina. En Nombre hay que poner la tarjeta de red instalada en el computador. 548 . Se continua presionando la tecla Enter (Envío): 549 . Se escoge el idioma. El tipo de teclado. 550 . El tipo de instalación (vía HTTP): Se activa la tarjeta de red para las direcciones Ipv4 551 . 8/os/i386 Terminada la primera fase se iniciará la configuración del sistema: 552 .Nombre del sitio Web: mirror.centos.org Directorio CentOS: /centos/5. Se borran todos los datos del disco virtual creado: Se crean las particiones predefinidas: 553 . Se confirma: Se modifica la configuración de la tarjeta de red. 554 . Configurando una IP fija. 555 . puerta de enlace (normalmente la IP del router) y DNS primario (la IP del router). Se crea un nombre de dominio. Se escoge la zona horaria: Se crea una contraseña para el usuario root: 556 . Se escoge el tipo de instalación (Sever) y se personalizan los paquetes que se instalarán: Se entra en el menú Servidores y se dejan seleccionados solo los paquetes que aparecen en la imagen: 557 . Se inicia la instalación del sistema operativo: 558 . para que quede: 559 . Se cierra la ventana y en la configuración de la maquina virtual se entra en el menú Almacenamiento: Se selecciona el icono evidenciado y en el menú que aparece se escoge la opción “Eliminar disco de la unidad virtual”.Cuando termine se presiona el botón reiniciar. El sistema se reiniciará y como el Cd todavía está presente. volverá a presentar la pagina de instalación del sistema operativo. Al primer arranque aparecerá el siguiente menú: Se entra en la configuración del cortafuegos: 560 .Ahora se puede iniciar nuevamente la maquina virtual. se activa una DMZ en el router para la IP del servidor Linux.Se deshabilita el cortafuegos y Selinux. Un ejemplo: 561 . Para terminar. Se sale de la herramienta de configuración. 562 .Se vuelve a la maquina virtual y se actualiza el sistema: yum -y update Se reinicia el servidor reboot Ya se puede retomar el libro desde la pagina 9 con la creación de la clave RSA. . 0.0:5060 tcpenable=yes tcpbindaddr=0.0:5060 tcpauthtimeout=30 tcpauthlimit=100 srvlookup=yes maxexpiry=3600 minexpiry=60 defaultexpiry=120 mwiexpiry=3600 maxforwards=70 qualifyfreq=60 preferred_codec_only=no disallow=all allow=ulaw allow=alaw mohinterpret=default mohsuggest=default parkinglot=default language=es sendrpid=ye rpid_update=yes prematuremedia=no useragent=VozToVoice v.realm=mydomain.tld udpbindaddr=0.Apéndice B Archivos de configuración sip.conf [general] allowguest=no context=default allowtransfer=yes .0. 1.0.0 sdpsession=asterisk sdpowner=asterisk dtmfmode=rfc2833 videosupport=yes maxcallbitrate=384 callevents=yes authfailureevents=yes alwaysauthreject=yes use_q850_reason=yes rtptimeout=60 rtpholdtimeout=300 rtpkeepalive=0 allowsubscribe=yes .0. 0.255.provider1.mwi => 1234:[email protected] externaddr= .0/255.125.com:5061 .provider1.externhost=prueba.255.0.subscribecontext=subscribe notifyringing=yes notifyhold=yes callcounter=yes t38pt_udptl=yes.pem tlscafile=/etc/asterisk/keys/ca.0.0/255.provider1.10.com/1234 [1000] accountcode=1000 language=es type=friend secret=pbx9090 qualify=yes mailbox=1000@default host=dynamic dtmfmode=rfc2833 context=externas directmedia=no callerid=callerid=Fulano <1000> callgroup=1 pickupgroup=1 disallow=all 565 .0 localnet=10.fec.com/1234 registertimeout=20 registerattempts=10 .com .8.media_address=0.0.register => fulano:[email protected]=180 nat=force_rport directmedia=no .register => fulano:[email protected] => fulano:contraseñ[email protected] .dyndns.255.0 rtcachefriends=no rtupdate=yes tlsenable=yes tlsbindaddr=96.crt tlscapath=/etc/asterisk/keys tlsdontverifyserver=yes register => serverA:pass1@IPserverB/serverB .maxdatagram=400 faxdetect=yes localnet= localnet=10.112 tlscertfile=/etc/asterisk/keys/serverA. allow=alaw allow=g722 allow=g729 allow=h263 cc_agent_policy=generic cc_monitor_policy=generic [1001] type=friend accountcode=1001 language=es secret=pbx9091 qualify=yes mailbox=1001@default host=dynamic dtmfmode=rfc2833 context=externas directmedia=no callerid=zutano <1001> callgroup=1 pickupgroup=1 disallow=all allow=alaw allow=g722 allow=g729 allow=h263 cc_agent_policy=generic cc_monitor_policy=generic [int-locales](!) type=friend language=es qualify=yes host=dynamic dtmfmode=rfc2833 context=locales directmedia=no callgroup=1 pickupgroup=1 disallow=all allow=alaw allow=g722 allow=g729 allow=h263 [1002](int-locales) accountcode=1002 566 . justvoip.com fromdomain=sip.secret=pbx9092 mailbox=1002@default callerid=Mengano <1002> cc_agent_policy=generic cc_monitor_policy=generic [justvoip] type=peer host=sip.justvoip.com fromuser= defaultuser= secret= qualify=yes dtmfmode=rfc2833 context=from-justvoip directmedia=no language=es nat=no disallow=all allow=alaw allow=g729 [spa3102] type=friend secret=password qualify=yes nat=yes host=dynamic directmedia=no context=from-spa3102 dtmfmode=rfc2833 language=es callerid=LineaTel <NumTel> allowtransfer=yes allowsubscribe=yes subscribecontext=subscribe callcounter=yes disallow=all allow=alaw allow=g729 [serverB] type=friend remotesecret=pass2 context=internas qualify=yes 567 . 216 disallow=all allow=alaw language=es qualify=yes transport=tls encryption=yes [1005] type=friend accountcode=1005 language=es secret=pbx9095 qualify=yes mailbox=1005@default host=dynamic dtmfmode=rfc2833 context=externas directmedia=no callerid=Perengano <1001> callgroup=1 pickupgroup=1 disallow=all allow=ulaw allow=alaw allow=g729 568 .228.6 disallow=all allow=g729 allow=alaw language=es qualify=yes dtmfmode = rfc2833 [serverbtls] type=peer context=from-tls host=66.host=dynamic language=es disallow=all allow=gsm allow=ulaw allow=alaw [serverbvpn] type=peer context=vpn host=10.49.0.8. conf [general] bindport=4569 bindaddr=0.0.0 nochecksums=no delayreject=yes amaflags=documentation srvlookup=yes language=es mohinterpret=default mohsuggest=defautl bandwidth=high disallow=all allow=alaw allow=alaw minregexpire=60 maxregexpire=60 encryption=yes forceencryption=no trunkmaxsize=128000 trunkmtu=1240 autokill=yes codecpriority=host rtcachefriends=no rtupdate=yes parkinglot=default calltokenoptional=0.0.0.linux-support.register => marko:[key]@tormenta.0/0.linux-support.register => joe@remotehost:5656 .0.allow=h263 cc_agent_policy=generic cc_monitor_policy=generic transport=tls encryption=yes iax.0.net .0.0 requirecalltoken=auto .register => marko:[email protected] [marko] type=friend host=dynamic secret=pbx9094 context=externas mailbox=1234@default 569 . Goto(IVR.1.agi.228..1.%H:%M)}.".2) same => n.216 trunk=yes context=internas qualify=yes [server1] type=user dbsecret=dundi/secret context=servera-local qualify=yes disallow=all allow=ulaw allow=alaw extensions.conf [general] static=yes writeprotect=yse autofallthrough=yse extenpatternmatchnew=yse clearglobalvars=no [globals] 1000=SIP/1000 JUST=SIP/justvoip marko=IAX2/marko DYNAMIC_FEATURES=test1#blindxfer#automon#disconnect#atxfer#parkcall#automixmon [from-didvoztovoice] exten => s.Answer same => n."${CALENDAR_EVENT(summary)} a las ${STRFTIME($ {CALENDAR_EVENT(start)}.Gotoif($[${ISNULL(${CALENDAR_EVENT(location)})} = 0 & "$ {CALENDAR_EVENT(summary)}" = "Conferencia"]?conf) same => n.es) 570 .49.Agi(googletts.qualify=yes callerid=marko requirecalltoken=auto [serverb] type=friend host=66.Hangup [calendario] exten => cal.s.NoOp(Llamada desde el calendario) same => n. same => n.n.Playback(hello-world) exten => 20.Dial(IAX2/iaxmodem2) same => n.1.Answer() exten => 20.Answer same => n.1.Noop(FAXSTATUS ${FAXSTATUS}.Hangup same => n(conf).agi.Answer same => n.1.Confbridge(${CALENDAR_EVENT(location)}.1.cM(default)) same => n.tif.Answer same => n.es) same => n. SRTP = ${CHANNEL(secure_media)}) same => n. FAXERROR ${FAXERROR}) same => n.Wait(6) same => n."${CALENDAR_EVENT(description)}".Hangup exten => 1235.Dial(SIP/justvoip/${EXTEN}) same => n.1.Answer same => n.Hangup exten => 1234.Hangup [internas] exten => *30.Hangup exten => h.1.Hangup [test] switch => Realtime [fax] exten => _X.Receivefax(/tmp/${UNIQUEID}.n.Playback(goodbye) same => n.Playback(demo-congrats) same => n..Playback(tt-monkeys) same => n.Wait(1) same => n.Hangup [from-tls] exten => 71.df) same => n.45) exten => fax.Dial(SIP/1000.Hangup() [dundi-remoto] switch => DUNDi/serverb [vpn] exten => 70.CallCompletionRequest 571 .1.1.Noop(TLS = ${CHANNEL(secure_signaling)}.Agi(googletts.1.hangup [servera-local] exten => 20. Agi(googletts.Playback(agent-loginok) same => n.1.Set(num=1) same => n.Hangup exten => *70.Hangup exten => *72.1.Hangup exten => *31.Hangup exten => *73.Set(fin=$[${EPOCH}+10800]) same => n.Agi(googletts.Hangup exten => _*1XXX.Hangup 572 ."a las ${STRFTIME(${CALENDAR_QUERY_RESULT(${id}.UnpauseQueueMember(ventas.Playback(beep) same => n.same => n.${EPOCH}.es) same => n.summary.agi.While($[${numeve} > 0]) same => n.Set(numeve=$[${numeve}-1]) same => n.Noop(Idioma Servidor ${PBX}) same => n.1.start.Dial(SIP/serverB/${EXTEN:1}."Rellamada activada".Set(numeve=${CALENDAR_QUERY_RESULT(${id}.Removequeuemember(ventas.es) same => n.Set(id=${CALENDAR_QUERY(campusvoztovoice.1..SIP/${CALLERID(num)}) same => n. Set(CALLERID(num)=serverA) same => n.Agi(googletts."${CALENDAR_QUERY_RESULT(${id}.Playback(agent-loggedoff) same => n.Hangup() exten => _*1100X.30) same => n.SIP/${CALLERID(num)}) same => n.$ {num})}.1.es) same => n.CallCompletionCancel same => n.agi.Set(num=$[${num}+1]) same => n.Hangup exten => *71.Playback(beep) same => n.Addqueuemember(ventas.SIP/${CALLERID(num)}) same => n.PauseQueueMember(ventas.${fin})}) same => n.1.Hangup exten => 51.getnum)}) same => n.Dial(IAX2/serverb/${EXTEN:2}) same => n.Agi(googletts.Set(PBX=${ENV(LANG)}) same => n.1.%H:%M)}".Hangup exten => 50.${num})}"."Rellamada anulada".agi.es) same => n.Noop(Consulta en el calendario) same => n.1.SIP/${CALLERID(num)}) same => n.1.agi.Endwhile same => n. Dial(SIP/serverbtls/${EXTEN}) same => n.Hangup exten => 98.Hangup 573 .1.Set(CALLERID(num)=serveratls) same => n.Answer same => n.Noop same => n.hangup exten => 71.1) exten => 77.MusicOnHold(mp3.1.com.Hangup exten => 100.1.agi(wakeup.Hangup exten => 99.Hangup exten => 200.s.Hangup exten => 97.Wait(1) same => n.Directory(default.1.Hangup exten => 150.1.voztovoice.Set(CHANNEL(language)=es) same => n.Echo same => n.Dumpchan same => n.Playback(hello-world) same => n.Answer same => [email protected] same => n.e) same => n.Playback(demo-echodone) same => n.internas.Dial(SIP/1000&SIP/1001&SIP/1002.Answer same => n.30) same => n.hangup exten => 75.1.php) same=> n.Estamos escuchando MP3) same => n.Playback(demo-echotest) same => n.1.Dial(SIP/serverbvpn/${EXTEN}) same => n.VoiceMailMain(${CALLERID(num)}@default) same => n.Jabbersend(campus.1.Goto(IVR.Answer same => n.Answer same => n.1.1.Hangup exten => 123.60) same => n.exten => 70.Set(CALLERID(num)=openvpna) same => n. Hangup exten => _200[012].1.Hangup exten => 251.Noop(Protocolo SIPTLS = ${CHANNEL(secure_signaling)}) same => n.Festival(Ningun empleado encontrado.0.4-5].Dial(IAX2/marko.1.Hangup exten => 252.1.Macro(voicemail) same => n.Noop same => n.1.Dial(SIP/${EXTEN}.Festival(El nombre del empleado es ${EMPNAME}.) same => n.) same => n.Wait(2) same => n.Hangup exten => 1234.Answer() same => n.Answer same => n.1:4573) same => n.exten => 250.4) same => n.Hangup exten => 670.1.Hangup exten => 1235.Agi(pruebaudio.Hangup() exten => 660.Read(EMPNUM.) same => n.GotoIf($[${EXISTS(${EMPNAME})}]?nombre) same => n.Festival(Asterisk y Festival trabajan junto.s.AGI(agi:async) same => n.1.1.0.Agi(callerid.Noop same => n.Hangup exten => 253.Set(EMPNAME=${ODBC_Empleados(${EMPNUM})}) same => n.30) same => n.1.1.beep.php) same => n.Hangup exten => 650.Dial(IAX2/marko2.1.Hangup same => n(nombre).Agentlogin(${EXTEN}) 574 .Noop(Protocolo SRTP = ${CHANNEL(secure_media)}) same => n.php) same => n.AGI(agi://127. Chevere!!!) same => n. Hasta luego.Festival(Por favor ingrese los 4 digitos de la matricula del empleado.Macro(voicemail) same => n.Macro(voicemail) same => n.30) same => n.1) same => n.Goto(encuesta.hHkKtTwWxX) same => n.Hangup exten => _100[0-2.45. Hasta luego.1. 1.Dial(SIP/1000.Hangup exten => _8.Wait(2) same => n.Voicemail(1000@default) same => n.1.Dial(DAHDI/R1/${EXTEN:1}.Gotoif($[${DIALSTATUS} = ANSWER)]?contestada) same => n.1.Queue(ventas.Page(SIP/1001&SIP/1002.Hangup exten => _9[12456789]XXXXXXX!..hangup same => n(contestada).Hangup exten => _66XX.Dial(SIP/spa3102.1.Hangup exten => 502.Hangup exten => 3000.R) same => n.Queue(ventas) same => n.Hangup exten => 3510.1.Wait(2) same => n.Hangup [conferencias] exten => 501.DM(default)) same => n.Record(/tmp/prompt${EXTEN:2}:wav) same => n.Set(CALLERID(num)=CampusVozToVoice) same => n.1.Hangup() exten => 6500.1.Answer same => n.15) same => n.Meetme(${EXTEN}.Answer same => n.1.Hangup exten => 3001.Meetme(.1.same => n.Playback(/tmp/prompt${EXTEN:2}) same => n.Hangup exten => _350[012].Wait(2) same => n.Answer() same => n.45.Busy(3) same => n.45) same => n.scM(default)) same => n.Page(SIP/1001&SIP/1002) same => n.Hangup 575 .Dial(SIP/justvoip/0057XXXXXXXXXX) same => n.d) same => n.1.Set(CALLERID(name)=Calendario) same => n.D(${EXTEN:1})) same => n. ${var3}.Macro(meetme) same => n.1.Festival(Pregunta uno) same => n.Hangup [subscribe] exten => 1000.10) same => n.exten => 3520.IAX2/marko exten => marko2.$ {var2}.Hangup exten => _500[01].Festival(Pregunta cuatro) same => n.Festival(Pregunta dos) same => n.park:705@parkedcalls exten => 706.IAX2/marko2 exten => 701.Answer same => n.10) same => n.hint.1.1..4) same => n.Playback(thank-you-cooperation) same => n.park:707@parkedcalls 576 .SIP/1001 exten => 1002.SIP/1004 exten => marko..Read(var3.txt.NoOP same => n.hint..1.hint...park:704@parkedcalls exten => 705.park:703@parkedcalls exten => 704.park:701@parkedcalls exten => 702.Read(var1.Hangup exten => 3530.Set(ODBC_Encuesta()=${STRFTIME(${EPOCH}.Wait(2) same => n..Set(confmax=10) same => n.%y%m%d%H%M%S)}.Hangup [encuesta] exten => s.hint.1.park:706@parkedcalls exten => 707.SIP/1000 exten => 1001.hint.1.hint.ConfBridge(3530.Authenticate(/tmp/pin.Dial(SIP/justvoip/${EXTEN}) same => n.Answer same => n.1.1.Meetme(${EXTEN}) same => n.park:702@parkedcalls exten => 703.Mcs) same => n.Read(var4.SIP/1002 exten => 1004.hint.hint.Festival(Pregunta tres) same => n.hint...${var1}.hint.Hangup [auten] exten => _00.1..hint.10) same => n.10) same => n.Read(var2.am.${var4}) same => n..hint.hint. Gotoif($[${extsal} > 2 | ${trunksal} > 2]?busy) same => n.voztovoice.Set(trunksal=${GROUP_COUNT(justvoip@voip)}) same => n.summary.Hangup [from-pstn] exten => s.com) same => n.Set(CALENDAR_WRITE(llamadas.20)}) same => n.park:708@parkedcalls exten => 709.hint.exten => 708.1.NoOp same => n.${EPOCH}) same => n.Llamada desde la extension ${CALLERID(num)} al numero $ {EXTEN}.Hangup same => n(busy). bienvenido en VozToVoice) same => n.voztovoice/+${EXTEN}@voice.IP = ${CHANNEL(peerip)}.30) same => n.SendText(Espera un momento mientras te comunicamos con un operador) same => n.google.google.hint.Como te llamas?) same => n.Dial(SIP/1000.Playback(all-outgoing-lines-unavailable) same => n.NoOp same => n..Set(CALLERID(name)=${nombre}) same => n.Set(GROUP(salida)=${CALLERID(num)}) same => n.description.Set(nombre=${JABBER_RECEIVE(campus.Dial(SIP/1000.Set(extsal=${GROUP_COUNT(${CALLERID(num)}@salida)}) same => n.1.Dial(SIP/justvoip/${EXTEN}) same => n.Hangup 577 .n.voztovoice/+${EXTEN}@voice.Wait(2) same => n.SendText(Hola ${nombre}.45) exten => s.Hangup() [from-spa3102] exten => s..location.1.1.NoOp( Call from Gtalk ) same => n.SendText(Hola.com) same => n.1.Set(GROUP(voip)=justvoip) same => n.park:709@parkedcalls [google-in] exten => s.1.Hangup exten => _1XXXXXXXXXX.Dial(SIP/1000) same => n.start)=Llamada de $ {CALLERID(num)} a ${EXTEN}.Set(CDR(userfield)=${CHANNEL(peerip)}) same => n.Hangup [internacio] exten => _00X.${CALLERID(name)}.Dial(gtalk/campus.Hangup exten => _NNXX.NoOp(Hay ${extsal} llamadas desde la extension ${CALLERID(num)} y ${trunksal} con el proveedor Justvoip) same => n.Dial(gtalk/campus. 1.Voicemail(${MACRO_EXTEN}@default.Busy exten => s.n.es) same => n.1.Set(estado=${DEVICE_STATE(SIP/${MACRO_EXTEN})}) exten => s.MacroExit [macro-calendario] exten => s.Hangup exten => _s-.Gotoif($["${estado}" = "NOT_INUSE"]?5) exten => s.n."la extensión se encuentra ocupada.1. Gracias".MacroExit same => n(calendario).1.GotoIf($[${MACRO_EXTEN} = 1000]?calendario) same => n.Goto(s-${DIALSTATUS}.Noop(${MACRO_EXTEN}) same => n.Agi(googletts.Voicemail(${MACRO_EXTEN}@default.1.Hangup [macro-meetme] exten => s. llame mas tarde.agi..[externas] include => internas include => internacio include => parkedcalls include => test include => conferencias include => dundi-remoto [locales] include => internas include => auten include => parkedcalls include => test include => conferencias include => dundi-remoto [macro-disponible] exten => s.count) 578 .Hangup [macro-voicemail] exten => s.Hangup exten => s.u) same => n.Noop(Estado = ${estado}) same => n.n.MeetMeCount(${MACRO_EXTEN}.b) same => n.Hangup exten => s-CONGESTION.1.Hangup exten => s-CANCEL.Set(estado=${CALENDAR_BUSY(campusvoztovoice)}) same => n.1) exten => s-BUSY.1.MacroExit same => n(ocupado).Congestion same => n.Gotoif($[${estado} = 1]?ocupado) same => n.n.1. s.Goto(internas.1.hangup exten => t.2.Playback(invalid) exten => i.1) exten => h.Hangup [IVR2] exten => s.2.goto(IVR2.Set(CHANNEL(language)=es) 579 .2) exten => i.2.s.1) exten => 2.2) exten => h.1) exten => i.goto(IVR1.2.1.3.1.1.Set(TIMEOUT(digit)=7) exten => s.2.Playback(pls-wait-connect-call) exten => 3.Playback(demo-echotest) exten => 1.Set(TIMEOUT(digit)=7) exten => s.Goto(IVR1.Set(CHANNEL(language)=es) exten => s.Set(CHANNEL(language)=en) exten => s.Set(TIMEOUT(response)=10) exten => s.WaitExten() exten => 1.4.3.goto(IVR.Hangup exten => t.100.3.4.Echo() exten => 2.3.1.Set(TIMEOUT(response)=10) exten => s.WaitExten() exten => 1.1.BackGround(custom/prompt03) exten => s.s.same => n.Hangup same => n(llena).D) same => n.s.s.1.Set(TIMEOUT(digit)=7) exten => s.1) exten => i.goto(IVR1.MeetMe(${MACRO_EXTEN}.Gotoif($[${count} > ${confmax}]?llena) same => n.3.5.5.s.Hangup [IVR1] exten => s.1.MusicOnHold exten => 3.1.Wait(1) exten => s.Set(TIMEOUT(response)=10) exten => s.1.Hangup #include IVR IVR [IVR] exten => s.1.1.BackGround(custom/prompt01) exten => s.Playback(conf-invalid) same => n.1.2.6.1) exten => i.Goto(IVR.1.Playback(invalid) exten => i.2. goto(IVR2.s.Echo() exten => 2.2.100.MusicOnHold exten => 3.BackGround(custom/prompt02) exten => s.hangup exten => t.3.1.4.Goto(internas.exten => s.Playback(demo-echotest) exten => 1.2.Hangup 580 .s.1.1.1) exten => i.1.1) exten => i.Playback(invalid) exten => i.1.2.Goto(IVR2.WaitExten() exten => 1.1.5.1) exten => h.Playback(pls-wait-connect-call) exten => 3. . A "Modified Version" of the Document means any work containing the Document or a portion of it. 2008 Free Software Foundation. royalty-free license. because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. regardless of subject matter or whether it is published as a printed book. You accept the license if you copy. with or without modifying it. APPLICABILITY AND DEFINITIONS This License applies to any manual or other work. This License is a kind of "copyleft". refers to any such manual or work. 0. textbook. <http://fsf. this License preserves for the author and publisher a way to get credit for their work. unlimited in duration. modify or distribute the work in a way requiring permission under copyright law. A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall . Any member of the public is a licensee. Secondarily. or with modifications and/or translated into another language. 3 November 2008 Copyright (C) 2000. We have designed this License in order to use it for manuals for free software. that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. 2007. 1. it can be used for any textual work. which is a copyleft license designed for free software. It complements the GNU General Public License. and is addressed as "you".Apéndice C Licencia GNU FDL GNU Free Documentation License Version 1. in any medium. 2002. which means that derivative works of the document must themselves be free in the same sense. 2001. either commercially or noncommercially.org/> Everyone is permitted to copy and distribute verbatim copies of this license document. or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it. The "Document". but changing it is not allowed. PREAMBLE The purpose of this License is to make a manual.3. But this License is not limited to software manuals. We recommend this License principally for works whose purpose is instruction or reference. Such a notice grants a world-wide. either copied verbatim. while not being considered responsible for modifications made by others. below. to use that work under the conditions stated herein. Inc. (Thus. An image format is not Transparent if used for any substantial amount of text. that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor. If the Document does not identify any Invariant Sections then there are none.subject (or to related matters) and contains nothing that could fall directly within that overall subject. represented in a format whose specification is available to the general public. plus such following pages as are needed to hold. Texinfo input format. The "publisher" means any person or entity that distributes copies of the Document to the public. The "Invariant Sections" are certain Secondary Sections whose titles are designated. for a printed book. Examples of transparent image formats include PNG. philosophical. and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. commercial. "Title Page" means the text near the most prominent appearance of the work's title. The Document may contain zero Invariant Sections. and the machine-generated HTML. a Secondary Section may not explain any mathematics. Examples of suitable formats for Transparent copies include plain ASCII without markup. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. XCF and JPG. in the notice that says that the Document is released under this License. as being those of Invariant Sections. For works in formats which do not have any title page as such. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors. in the notice that says that the Document is released under this License. has been arranged to thwart or discourage subsequent modification by readers is not Transparent. A "Transparent" copy of the Document means a machine-readable copy. SGML or XML for which the DTD and/or processing tools are not generally available. PostScript or PDF designed for human modification. ethical or political position regarding them. if the Document is in part a textbook of mathematics. A Front-Cover Text may be at most 5 words. or of legal. preceding the beginning of the body of the text. SGML or XML using a publicly available DTD. the title page itself. The "Title Page" means. The "Cover Texts" are certain short passages of text that are listed. the material this License requires to appear in the title page. PostScript or PDF produced by some word processors for output purposes only. and a Back-Cover Text may be at most 25 words. as Front-Cover Texts or Back-Cover Texts.) The relationship could be a matter of historical connection with the subject or with related matters. and standard-conforming simple HTML. legibly. A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following 583 . or absence of markup. LaTeX input format. A copy made in an otherwise Transparent file format whose markup. A copy that is not "Transparent" is called "Opaque". The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. you must enclose the copies in covers that carry. 2. can be treated as verbatim copying in other respects. "Dedications". provided that this License. either commercially or noncommercially. or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document. or "History". and the license notice saying this License applies to the Document are reproduced in all copies. you should put the first ones listed (as many as fit reasonably) on the actual cover. the copyright notices. 3. (Here XYZ stands for a specific section name mentioned below. The front cover must present the full title with all words of the title equally prominent and visible. and the Document's license notice requires Cover Texts. If you distribute a large enough number of copies you must also follow the conditions in section 3. numbering more than 100. you must either include a machine-readable Transparent copy along with each Opaque copy. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. all these Cover Texts: Front-Cover Texts on the front cover. as long as they preserve the title of the Document and satisfy these conditions. If you publish or distribute Opaque copies of the Document numbering more than 100. under the same conditions stated above. and you may publicly display copies. If the required texts for either cover are too voluminous to fit legibly. You may add other material on the covers in addition. COPYING IN QUANTITY If you publish printed copies (or copies in media that commonly have printed covers) of the Document. and continue the rest onto adjacent pages. you may accept compensation in exchange for copies. You may also lend copies. clearly and legibly. However.text that translates XYZ in another language. you must take reasonably prudent steps. free of added material. and that you add no other conditions whatsoever to those of this License. If you use the latter option. Both covers must also clearly and legibly identify you as the publisher of these copies. VERBATIM COPYING You may copy and distribute the Document in any medium. These Warranty Disclaimers are considered to be included by reference in this License. Copying with changes limited to the covers. to ensure 584 . "Endorsements". when you begin distribution of Opaque copies in quantity.) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition. and Back-Cover Texts on the back cover. such as "Acknowledgements". if any) a title distinct from that of the Document. State on the Title page the name of the publisher of the Modified Version. in the form shown in the Addendum below. B. to give them a chance to provide you with an updated version of the Document. It is requested. In addition. unless they release you from this requirement. For any section Entitled "Acknowledgements" or "Dedications". Include. C. F. Preserve the Title of the section. but not required. Preserve all the copyright notices of the Document. and preserve in the section all 585 . E.that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. and publisher of the Document as given on its Title Page. Preserve its Title. J. authors. and likewise the network locations given in the Document for previous versions it was based on. a license notice giving the public permission to use the Modified Version under the terms of this License. Use in the Title Page (and on the covers. Include an unaltered copy of this License. if any. and from those of previous versions (which should. K. H. as the publisher. I. You may use the same title as a previous version if the original publisher of that version gives permission. year. given in the Document for public access to a Transparent copy of the Document. You may omit a network location for a work that was published at least four years before the Document itself. if it has fewer than five). MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above. be listed in the History section of the Document). Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. one or more persons or entities responsible for authorship of the modifications in the Modified Version. Preserve the network location. and publisher of the Modified Version as given on the Title Page. thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. 4. then add an item describing the Modified Version as stated in the previous sentence. if there were any. new authors. you must do these things in the Modified Version: A. List on the Title Page. create one stating the title. together with at least five of the principal authors of the Document (all of its principal authors. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. or if the original publisher of the version it refers to gives permission. immediately after the copyright notices. G. with the Modified Version filling the role of the Document. as authors. These may be placed in the "History" section. If there is no section Entitled "History" in the Document. year. and add to it an item stating at least the title. that you contact the authors of the Document well before redistributing any large number of copies. D. provided that you release the Modified Version under precisely this License. Preserve the section Entitled "History". and multiple identical Invariant Sections may be replaced with a single copy. you may not add another. Preserve any Warranty Disclaimers. to the end of the list of Cover Texts in the Modified Version. make the title of each such section unique by adding at the end of it. unmodified. These titles must be distinct from any other section titles. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. and list them all as Invariant Sections of your combined work in its license notice. You may add a section Entitled "Endorsements". or else a unique number. the substance and tone of each of the contributor acknowledgements and/or dedications given therein. Section numbers or the equivalent are not considered part of the section titles. provided that you include in the combination all of the Invariant Sections of all of the original documents. You may add a passage of up to five words as a Front-Cover Text. Delete any section Entitled "Endorsements". Preserve all the Invariant Sections of the Document.L. you may at your option designate some or all of these sections as invariant. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. N. under the terms defined in section 4 above for modified versions. statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. M. on explicit permission from the previous publisher that added the old one. the name of the original author or publisher of that section if known. 5. To do this. in parentheses. Such a section may not be included in the Modified Version. provided it contains nothing but endorsements of your Modified Version by various parties--for example. previously added by you or by arrangement made by the same entity you are acting on behalf of. and a passage of up to 25 words as a Back-Cover Text. If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document. If the Document already includes a cover text for the same cover. add their titles to the list of Invariant Sections in the Modified Version's license notice. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section. 586 . but you may replace the old one. COMBINING DOCUMENTS You may combine the Document with other documents released under this License. If there are multiple Invariant Sections with the same name but different contents. unaltered in their text and in their titles. and that you preserve all their Warranty Disclaimers. O. The combined work need only contain one copy of this License. Otherwise they must appear on printed covers that bracket the whole aggregate. you must combine any sections Entitled "History" in the various original documents. COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License. provided you insert a copy of this License into the extracted document. then if the Document is less than one half of the entire aggregate.In the combination. or the electronic equivalent of covers if the Document is in electronic form. but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You must delete all sections Entitled "Endorsements". 6. and any Warranty Disclaimers. is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate. You may include a translation of this License. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer. and replace the individual copies of this License in the various documents with a single copy that is included in the collection. and distribute it individually under this License. AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works. forming one section Entitled "History". Replacing Invariant Sections with translations requires special permission from their copyright holders. in or on a volume of a storage or distribution medium. 7. and all the license notices in the Document. You may extract a single document from such a collection. provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. If the Cover Text requirement of section 3 is applicable to these copies of the Document. TRANSLATION Translation is considered a kind of modification. this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. the original version will prevail. provided that you also include the original English version of this License and the original versions of those notices and disclaimers. 587 . likewise combine any sections Entitled "Acknowledgements". and follow this License in all other respects regarding verbatim copying of that document. so you may distribute translations of the Document under the terms of section 4. and any sections Entitled "Dedications". the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate. 8. Each version of the License is given a distinguishing version number. Any attempt otherwise to copy. you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. or "History". RELICENSING 588 . modify. If the Document specifies that a particular numbered version of this License "or any later version" applies to it. the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. Such new versions will be similar in spirit to the present version. "Dedications". If your rights have been terminated and not permanently reinstated. sublicense. and you cure the violation prior to 30 days after your receipt of the notice. if you cease all violation of this License. if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. sublicense. but may differ in detail to address new problems or concerns. your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means. or distribute it is void. 10. If the Document does not specify a version number of this License. then your license from a particular copyright holder is reinstated (a) provisionally. this is the first time you have received notice of violation of this License (for any work) from that copyright holder. you may choose any version ever published (not as a draft) by the Free Software Foundation.org/copyleft/.gnu. receipt of a copy of some or all of the same material does not give you any rights to use it. 9.If a section in the Document is Entitled "Acknowledgements". that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Document. and will automatically terminate your rights under this License. revised versions of the GNU Free Documentation License from time to time. and (b) permanently. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. modify. FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new. If the Document specifies that a proxy can decide which future versions of this License can be used. unless and until the copyright holder explicitly and finally terminates your license. However. Moreover. 11. See http://www. TERMINATION You may not copy. or distribute the Document except as expressly provided under this License. no Front-Cover Texts. California. as well as future copyleft versions of that license published by that same organization. The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1. ADDENDUM: How to use this License for your documents To use this License in a document you have written. Front-Cover Texts and Back-Cover Texts.. If you have Invariant Sections. as part of another Document. or some other combination of the three. Version 1. Permission is granted to copy. "Incorporate" means to publish or republish a Document. to permit their use in free software. and with the Back-Cover Texts being LIST. A public wiki that anybody can edit is an example of such a server. with the Front-Cover Texts being LIST. and subsequently incorporated in whole or in part into the MMC. An MMC is "eligible for relicensing" if it is licensed under this License. distribute and/or modify this document under the terms of the GNU Free Documentation License. such as the GNU General Public License. and if all works that were first published under this License somewhere other than this MMC.. a not-for-profit corporation with a principal place of business in San Francisco. we recommend releasing these examples in parallel under your choice of free software license.Texts. and no Back-Cover Texts. A "Massive Multiauthor Collaboration" (or "MMC") contained in the site means any set of copyrightable works thus published on the MMC site. merge those two alternatives to suit the situation.3 or any later version published by the Free Software Foundation. 2009. (1) had no cover texts or invariant sections. 2008. provided the MMC is eligible for relicensing. A copy of the license is included in the section entitled "GNU Free Documentation License". with no Invariant Sections. in whole or in part. and (2) were thus incorporated prior to November 1."Massive Multiauthor Collaboration Site" (or "MMC Site") means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works.0 license published by Creative Commons Corporation. If you have Invariant Sections without Cover Texts. "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3. replace the "with. include a copy of the License in the document and put the following copyright and license notices just after the title page: Copyright (c) YEAR YOUR NAME. If your document contains nontrivial examples of program code. 589 ." line with this: with the Invariant Sections being LIST THEIR TITLES.
Copyright © 2024 DOKUMEN.SITE Inc.