Aplicaciones Básicas

De Asterisk Wiki
Saltar a: navegación, buscar

El mundo de las Aplicaciones en Asterisk es tan extenso que merece ser tratado independientemente. Concretamente existen una serie de aplicaciones que son utilizadas recurrentemente, y es importante que sean vistas y tratadas de manera especifica, como parte del formato de construcción de nuestros Planes de Marcación.

Logo Asterisk

Aplicación Answer

Traducción directa de "Responder". La función de esta aplicación básicamente es la de descolgar la llamada entrante. Puede resultar trivial, pero hay que entender que en función de las aplicaciones que vengan a continuación es posible que sea necesario que nuestra máquina Asterisk ya tenga el control sobre el canal entrante (mediante el uso de esta aplicación), o no lo requiera de momento.

A nivel de mensaje SIP ejecutar esta aplicación es lo mismo que enviar un mensaje al par que llama de OK. Hay que considerar que en el momento que lanzamos esta aplicación al descolgar la llamada, ya comenzaría el ciclo de facturación del llamante por lo que eventualmente, a no ser que sea estrictamente necesario, no es una buena idea incluirla en nuestro dialplan por sistema o costumbre. Tenemos que saber si las aplicaciones sucesivas, realmente requieren que el canal este "contestado" para que funcionen correctamente.

Puede recibir un solo parámetro Answer(<retraso>), numérico en milisegundos, tiempo que esperara antes de recepcionar la llamada. Es equivalente a poner la aplicación Wait previa a esta, por lo que no es muy común, dado que "complica" un poco el código.

Aplicación Progress

Contrariamente a la aplicación Answer, es posible enviar un mensaje llamado 183 Session Progress. Es considerado una forma de enviar "Audio por adelantado" y solo funciona evidentemente en entornos donde este mensaje sea permitido como SIP e IAX. Con este mensaje lanzado, podríamos a continuación ejecutar alguna aplicación o recurso que necesite este mensaje "Early Audio" como laMúsica en Espera

Aplicación Playback

La sintaxis especifica es: PlayBack(archivo1[&archivoN],opciones)

Sirve para reproducir una pista de audio contenida en un fichero dentro de nuestra máquina. El método de seleccion de esta pista, si solo especificamos el nombre, lo consultará en el directorio asociado al lenguaje que estemos utilizando para el canal especifico. Si en nuestro fichero de configuración SIP, definimos por defecto el lenguaje Español (es), y es un dispositivo SIP el que accede a la extensión que ejecuta esta aplicación de reproducción entonces consultaría en el directorio especifico de pistas en español (var/lib/asterisk/sounds/es/), y si no lo encuentra, consultaría en el directorio general (var/lib/asterisk/sounds/).

Durante la reproducción, la aplicación tiene el control del canal, esto quiere decir, que no se permiten lanzar otras Aplicaciones simultáneamente.

Esta aplicación ademas de recibir el archivo a reproducir, también puede recibir opciones. Las más comunes:

  • skip: solo se reproducirá la pista, única y exclusivamente, si antes se ha ejecutado la aplicación Answer, sino, saltaría sin reproducir nada.
  • noanswer: en este caso, si el tipo de canal soporta "Early Audio", lanza la pista, sin descolgar la llamada.

Sin opciones por defecto, descuelga la llamada, reproduce el mensaje

Aplicación Hangup

Simplemente, cuelga la llamada. No es necesario pasarle ningún parámetro especifico.

Al contrario de la aplicación Answer, esta aplicación si resulta interesante posicionarla al final de un proceso de una extensión, dado que si por ejemplo, el destinatario de la llamada, después de establecer contacto, cuelga la llamada, a nosotros no se nos colgaría, a no ser que lo hagamos expresamente en nuestro dispositivo. En cambio si esta aplicación esta disponible, al colgar la llamada, se lanzaría la aplicación y nos llevaría a la extension "h" según podemos ver en Introducción Dialplan, y a continuación si se nos colgaría la llamada automáticamente.

Aplicaciones para Depuración de Errores

Aplicación NoOp

Significa literalmente No Operation, es decir, Sin Operación, así que esta aplicación no hace nada. ¿Utilidad? Se puede insertar cualquier mensaje a voluntad, inclusive variables y se visualizarían directamente durante el registro de detalle en nuestra interfaz CLI. Es muy práctica para saber por ejemplo el estado de una variable en un momento determinado si estamos teniendo algún tipo de problema que no somos capaces de resolver, por tanto es una gran aplicación para Depuración en tiempo real.

Considerar también que es una muy buena práctica poner esta aplicación, en la prioridad numero 1. Ya que al no hacer nada especial, directamente podemos empezar a poner aplicaciones a voluntad en las siguientes prioridades utilizando el sistema de conteo automático (n, n+1) y podemos luego alterar el orden o incluir nuevas aplicaciones a voluntad en el futuro sin que afecte al orden de prioridades.

Ejemplo. Si tenemos la siguiente secuencia:

exten => 111,1,Answer()
same => n,Dial(...)
same => n,Hangup()

Si queremos introducir una aplicación al principio, tendríamos que modificar bastante código:

exten => 111,1,Wait(3)
same => n,Answer()
same => n,Dial(...)
same => n,Hangup()

En cambio si hubieramos tenido una operación NoOp() al principio, hubiera sido muy fácil insertarlo

exten => 111,1,NoOp()
same => n,Answer()
same => n,Dial(...)
same => n,Hangup()

Solamente agregando una linea a la secuencia. Puede resultar insignificante, pero es un sistema para mantener un código con mayor flexibilidad y calidad.

exten => 111,1,NoOp()
same => n,Wait(3)
same => n,Answer()
same => n,Dial(...)
same => n,Hangup()

Aplicación Verbose

Es exactamente igual que la aplicación NoOp con la diferencia que NoOp siempre imprime en el nivel de detalle (verbose) número 3 o superior, y esta aplicación puede especificar el nivel concreto.

Recordar que los niveles de Detalle (verbose) se pueden especificar tanto al cargar la interfaz CLI con el parámetro -v (-vvv 3 niveles por ejemplo), tanto por defecto en el archivo asterisk.conf

Aplicación DumpChan

Muestra información sobre el canal en curso. Puede recibir un parámetro DumpChan(<nivel>) siendo al igual que la aplicación Verbose, el nivel desde el cual podríamos ver esta información.

Aplicaciones para el Control de Flujo

Estas son las aplicaciones clásicas para obtener los comportamientos esenciales de todo lenguaje de programación. Principalmente hablamos de los eventos condicionales y los bucles. Para ello se aplica un sistema muy parecido al de Ensamblador, con bucles basados en GOTO y condicionales basados en GOTOIF.

Aplicación GoTo

Su funcionamiento estándar es el de enviar un canal en un momento determinado (prioridad) de la extensión en la que se encuentra a otro lugar diferente dentro del plan de marcación.

La sintaxis para esta "redirección" es la siguiente: Goto(<contexto>,<extensión>,<prioridad>/<etiqueta>)

  • Si solo se definen dos valores, estos hacen referencia a <extensión>,<prioridad>/<etiqueta>
  • Si solo se define un valor, entonces hace referencia a una <prioridad> o <etiqueta> de esa extensión

Supongamos que tenemos dos contextos [dia] y [noche], ambos con la extensión 111 por igual. Si queremos ir supongamos a la etiqueta "publico" de la extensión 111 despues cualquier parte de la etensión 111 del contexto día podriamos hacerlo de la siguiente forma:

Archivo: /etc/asterisk/extensions.conf
[dia]
exten => 111,1,...
same => n,...
same => n,Goto(noche,111,publico) --->

[noche]=> 111,1,...
same => n,...
same => n(publico),... <---


Aplicación GoToIf

Muy parecida a la aplicación esta constituye el formato condicional para que se produzca la redirección. Consideremos que GoTo se ejecuta siempre, pero en este caso, si utilizamos una expresión regular como podemos ver en Introducción Dialplan, que devuelva un valor Booleano (0 o 1), entonces redirigiremos el canal hacía un punto del dialplan, u otro (o simplemente dejaremos que la llamada continue su curso).

En este caso la sintaxis es la siguiente: Gotoif(<expresion_regular_condicional>?<redirección_si_verdadero:<redireccion_si_falso>).

  • Si no especificamos la redirección en el caso que no se cumpla la condición (si falso), entonces la extensión continua en la siguiente prioridad por su cauce.
  • Las opciones <redireccion_si_verdadero/falso> siguen la misma estructura de redirección que la utilizada en el apartado GoTo.

Con esto, y como ejemplo vamos a diseñar un pequeño bucle muy sencillo de tipo FOR (bucle con contador, que va pasando secuencialmente por todos los valores del mismo):

Archivo: /etc/asterisk/extensions.conf
[bucle]
exten => 111,1,Set(i=1)
same => n(for),GoToIf($[${i}>10?fin_for)
same => n,NoOp(El valor de i es: ${i})
same => n,Set(i=$[${i}+1])
same => n,GoTo(for)
same => n(fin_for),...


Con esta estructura tenemos potencial para hacer todo tipo de algoritmos, considerando que el "valor" de entrada que manipulamos es la llamada. Esto es muy práctico sobre todo cuando realizamos las funciones que por doquier suelen ser más complejas en los sistemas de marcación, los IVR (Interactive Voice Response), sistemas de respuesta de voz interactiva, en las que el llamante, va interactuando con la máquina para obtener determinadas funcionalidades (por ejemplo saber el saldo de su cuenta de crédito, realizar autentificación en sistemas seguros, comprar un producto sin ser atendido, etc). Esto se ve más a fondo en el apartado Dialplan Avanzado.

Aplicación GoToIfTime

Haciendo una combinación aún más allá, existe una variante de GoToIf, y es especificando un momento concreto como expresión de la condición. Por lo demás todo es igual.

La sintaxis sería la siguiente: Gotoiftime(<condicion_temporal>?<redireccion_si_verdadero>:<redireccion_si_falso>)

Evidentemente vamos a enfocar en la condicion temporal, si alguna vez hemos utilizado el sistema CRONTAB de *NIX es muy parecida la notación:

  • Para considerar validas todas las posibilidades de cualquier parámetro mostrado a continuación, se especificaría con un Asterisco (*)
  • Para cada valor incluso se pueden considerar múltiples posibilidades para que se cumpla la condición utilizando una barra vertical (|), sería algo así como un condicional OR.
  • Se pueden además especificar intervalos entre dos posibles parámetros con un guión (-), por ejemplo en caso de un día del mes a otro, sería 10-20.
  • El primer parámetro sería el tiempo horario, en horas y minutos. Ejemplo: 11:00.
  • El segundo parámetro sería el día de la semana, primeras tres letras del día de la semana en inglés.[1] Ejemplo: Thursday sería thu.
  • El tercer parámetro sería el día del mes. Ejemplo, el 25.
  • El cuarto y último parámetro, sería el nombre del mes, primeras tres letras del nombre en inglés. [2]

Con esto, si por ejemplo nuestro horario de oficina el día 12 de Octubre (día de la Hispanidad, festivo en España), es solo por la mañana de 10:00 a 14:00 podríamos indicarlo así:

Archivo: /etc/asterisk/extensions.conf
exten => 111,1,Gotoiftime(10:00-14:00,*,12,oct?abierto:cerrado,s,1)

.

Nos llevaría a la etiqueta de abierto o a la extensión s del contexto cerrado fuera de ese horario. El problema puede suceder, cuando por ejemplo, queremos utilizar (como suele ser frecuente), esta aplicación para establecer el horario de nuestras oficinas (o incluso a nivel departamental). Nos veríamos teniendo que modificar el Dialplan constantemente para tenerlo actualizado.

En la versión 1.8 existe una ampliación a esta funcionalidad, que en vez de utilizar Gotoiftime, utilizando GotoIf y un nuevo módulo de tipo Recurso para la sincronización con Calendarios de diversos tipos, entre los que se incluyen, Exchange Server, iCalendar, CalDAV o Google Calendar a través de URL), así podriamos crear un sistema no necesariamente modificable en el Dialplan, y ofrecer toda la parte de manipulación a los mismos.

Aplicación Background

Esta aplicación sirve para lanzar una pista de audio mientras se espera para la captura de tonos de marcación. Es muy común utilizarla con la aplicación WaitExten que está descrita a continuación, dado que es importante establecer una restricción de tiempo, ya que al llegar esta, los digitos marcados serán los que se utilicen para realizar una combinación que casara con una extensión de nuestro DialPlan.

A priori, esta combinación se asociara con una extensión dentro del mismo contexto en el que la aplicación Background fue ejecutado.

Veamos su sintaxis: Background(<archivo_de_sonido>[&archivo_de_sonidoN],<opciones_varias>,<seleccion_de_idioma>,<otro_contexto>).

  • Solo es necesario 1 archivo de sonido, el resto son opcionales
  • Podemos especificar varios archivos de sonido para que vayan sonando secuencialmente, práctico si queremos componer un "Menú" de audio combinando varias pistas
  • Como opciones tenemos:
    • s: Si el canal todavia no respondido con la aplicación Answer (u otra que forzara la respuesta), entonces este Background no se aplicaría
    • n: Trata de no responder al canal utilizando el sistema "Early Audio" hasta que no se detecta la primera marcación
    • m: Tan pronto detecta una asociación con una extensión para el mensaje de audio. Esto es MUY práctico cuando queremos hacer un menú que consta de pulsaciones de un solo dígito, ya que no obligamos a que transcurra el tiempo completo impuesto por la Aplicación WaitExten
  • Si seleccionamos un idioma concreto, la aplicación buscara en el directorio correspondiente a dicho idioma antes de elegir un archivo de audio predefinido que coincida con el nombre del mismo.
  • Si queremos que busque la extensión marcada en otro contexto diferente al que se encuentra la aplicación Background la definimos como último parámetro.

Supongamos que tenemos un menú de Voz que indica: "Pulse 1 para hablar con Ventas, Pulse el 2 para hablar con Posventa". Podemos tener este menu en un contexto concreto (por motivos de seguridad del Dialplan por ejemplo). Podríamos crear la siguiente pequeña operadora automática:

Archivo: /etc/asterisk/extensions.conf
[operadora]

exten => s,1,Background(menu_bienvenida&ventas&posventa,m,es,menu_operadora)
same => n,WaitExten(3)

exten => t,1,Goto(s,1)

[menu_operadora]

exten => 1,1(ventas),Goto(...)
exten => 2,1(posventa),Goto(...)


Aplicación WaitExten

Complementaria a la aplicación Background, sirve para especificar un intervalo de tiempo de espera, antes de realizar la combinación de dígitos marcados para una asociación con una extensión.

Vista desde la perspectiva del proceso, realmente no son complementarias, ya que podríamos simplemente lanzar WaitExten al "vacío" y especificar un tiempo para esperar a que se marquen unos dígitos específicos. Pero es tan común ver estas dos aplicaciones juntas, que ya se consideran una combinación.

La sintaxis especifica de WaitExten es: WaitExten(<tiempo_en_segundos>,<parámetro>)

  • Solo tiene un parámetro opcional, m: ofrece la posibilidad de ofrecer simplemente una pista de audio de Música en Espera.

En caso que se cumpla el tiempo sin marcaciones, el resultado dirigirá a la extensión estándar t. Si la marcación no existe, redirige a la extensión estándar para extensiones inexistentes, s.

Si no especificamos tiempo en segundos, cogerá el tiempo relativo definido por la Función TIMEOUT.

Aplicación Dial

Esta aplicación sirve para realizar la llamada a un dispositivo concreto, pasándole argumentos o lo que es más común, una marcación concreta. Esta es la clásica función que realizan la mayor parte de las PBX, recibir una llamada, y pasarla a otro dispositivo (sea un troncal, una linea de un operador, o sencillamente un teléfono) utilizando un comando de este tipo.

Lo curioso de esta aplicación, es que no importa desde que origen entre el canal, podemos lanzar la llamada a otro origen del mismo medio, totalmente diferente (por ejemplo, una llamada entrante de un teléfono móvil, pasarela a un dispositivo basado en el protocolo IAX que se conecta a nuestra central). Toda la traducción y transcodificación de medios si es que hubiere, se realiza utilizando las características que nos ofrece nuestro sistema Asterisk.

La sintaxis de esta Aplicación tiene bastantes combinaciones.

Dial(Tipo_Dispositivo/Nombre_Dispositivo[&Tipo_DispositivoN/Nombre_DispositivoN],<tiempo_de_intento>,<parametros>,<url>)

  • Se puede utilizar esta aplicación solo especificando un dispositivo (o varios), y simplemente realizara la llamada al mismo (o los mismos) hasta que la cojan (o si es a traves de la PSTN, siguiendo las restricciones de la misma).
  • Al especificar varios dispositivos todos serán llamados simultáneamente pero en el momento que uno establezca la comunicación el resto dejaran de ser llamados.
  • El tiempo de intento sirve para restringir el intento de llamada a un tiempo en segundos concreto
  • La URL sirve para enviar una dirección URL al dispositivo comunicado en el momento en el que se establece la comunicación. Esto esta enfocado para los medios SIP, ya que algunos teléfonos IP admiten esta funcionalidad.
  • En cuanto a las opciones, existen gran variedad, vamos a definir las más populares.
    • Considerar que hay muchas opciones en mayúsculas y en minúsculas que hacen lo mismo, solo que en el caso de la opción en mayúsculas afecta al llamante (al que realiza la llamada), y la opción en minúsculas afecta al llamado (al que recibe la llamada)
    • A(<nombre_pista>): lanzamos una pista de audio en el momento de establecerse la llamada
    • H/h: permite colgar la llamada utilizando un botón del teléfono definido en features.conf por defecto *
    • K/k: permite aparcar la llamada utilizando un botón del teléfono definido en features.conf por defecto #700
    • L(x:y:z): sirve para limitar la llamada a un intervalo de tiempo, x es el intrevalo en 'ms', lanza una advertencia cuando falten y 'ms', y la va repitiendo cada z 'ms'.
    • M(<nombre_macro>^valor1[^valorN]>: lanza un Macro en el momento que se recepciona la llamada. Los valores de entrada se especifican utilizando el caracter ^ detrás del nombre del Macro
    • m: pone una Música en Espera al llamante, mientras espera a ser comunicado con el otro par.
    • r: simula un tono de marcado ejecutado por Asterisk. Sin esta opción se ajustara a los parámetros de la red en este sentido.
    • T/t: permite transferir la llamada utilizando un botón del teléfono definido en features.conf por defecto #
    • W/w: permite grabar la llamada utilizando un botón del teléfono definido en features.conf por defecto *1
    • X/x: permite grabar la llamada con la característica AutoMixMonitor utilizando un botón del teléfono definido en features.conf por defecto *1

Es importante saber, que en el caso que utilicemos la Aplicación Dial, en conjunto al protocolo IAX tenemos una funcionalidad aún más "poderosa". Podríamos ser capaces, de no solo llamar a una extensión del plan de Marcación del host remoto, sino que además podríamos llamar a un contexto y extensión especifica del mismo. Ese contexto tiene que estar dentro del "campo de visión" del contexto "permitido" en la especificación de contexto del Par del otro equipo, pero así podemos evitar ambigüedades típicas, por ejemplo del uso de inclusiones anidadas. El formato especifico sería:

  • Dial(IAX2/Nombre_Dispositivo/<extensión>@<contexto>)

Referencias

  1. Días de la Semana en Ingles, Artículo en Wikipedia
  2. Meses del Año en Ingles, Artículo en Wikipedia

Véase también

Enlaces Externos