jueves, 6 de enero de 2011

Teoría de Contextos en Asterisk - Parte I

Amigos

Uno de los puntos más importantes para manejar adecuadamente una central Asterisk es la teoría de contextos.  Para mí el 80% de lo que se debe saber en Asterisk es: "Contextos".

A pesar de ser tan importante, su explicación en los recursos de la web no es tan explícita como se merece.  De hecho, gran parte de mi curva de aprendizaje inicial la ocupó el entender  bien lo que es un contexto, y la mejor manera de usarlos.  Por esta razón, he decido darles mi entendimiento de este punto. 

En primer lugar vamos a definirlo:

¿Qué es un Contexto?
Es una sección del dialplan (plan de discado), puede estar directamente en el archivo /etc/asterisk/extensions.conf o en un archivo incluido en el anterior.

¿Cómo reconozco un contexto?

Tienen dos partes:
1.    El límite superior es su nombre entre corchetes que puede estar compuesto de
    1. Letras de la A a la Z (mayúsculas o minúsculas),
    2. meros  del 0 al 9 y guiones (alto y bajo)
Por ejemplo: [Extensiones-Internas]
  1. Inmediatamente después del nombre del contexto encontramos instrucciones que forman parte de nuestra lógica de extensiones. Cada línea generalmente comienza con la clave exten =>  seguida de tres elementos claves:
    1. Nombre: es el patrón de la extensión, por ejemplo el número 123.
                                          i.    Nuestro ejemplo va por: exten => 123
    1. Prioridad: cada extensión puede tener varias instrucciones por lo que se tiene un número de prioridad que define el orden en el cual serán ejecutadas. 
                                          i.    Nuestro ejemplo va por:  exten => 123,1
    1. Aplicación: son las ejecutoras de diversas acciones en Asterisk. (Answer(), HungUp(),Dial()). 
                                          i.    Nuestro ejemplo va por:
exten => 123,1,Answer()
El límite inferior es el nombre del contexto siguiente.
Tenemos entonces que un ejemplo de un contexto puede ser:
[Extensiones-Internas]
exten => 123,1,Answer()
exten => 123,n,Playback(tt-monkeys)
exten => 123,n,Hungup()
[nacionales]
Seguro te estás haciendo la pregunta “¿Qué es esa n en la prioridad?”  Pues la n existe desde Asterisk 1.2 y significa “next” es decir, automáticamente Asterisk internamente asigna la prioridad que le corresponda.
En este caso, entonces, si alguien marca 123 en ese contexto, Asterisk le contestará y le reproducirá un sonido bien curioso y le colgará.
Ya sabemos lo que es un contexto, ahora bien,
¿Cómo funcionan los contextos?
Los contextos son una herramienta poderosa de seguridad que tiene Asterisk porque sólo las extensiones de un contexto se pueden llamar entre sí.  Me explico más a detalle:
           
Pertenencia del Dispositivo
Este punto es la clave, así que lee detenidamente.
Cada dispositivo (teléfono, softphone, canal digital, una caja Asterisk remota, etc) tiene un contexto asignado en su archivo de configuración correspondiente a su tipo de canal (SIP, IAX, Dahdi).
Por ejemplo en el /etc/asterisk/sip.conf puede haber un dispositivo SIP definido de la siguiente manera

[124]
type=friend
callerid="Pedro Pérez" <124>
username=tammari
host=dynamic
secret=********
canreinvite=yes
context=Extensiones-Internas

En este caso, el dispositivo SIP/124 pertenece al contexto “Extensiones-Internas, es decir, cuando este dispositivo marque dígitos, éstos serán comparados sólo con los patrones de extensiones del contexto mencionado.
Recordemos entonces el contexto en el extensions.conf

[Extensiones-Internas]
exten => 123,1,Answer()
exten => 123,n,Playback(tt-monkeys)
exten => 123,n,Hungup()

Nota: el hecho de que el dispositivo pertenezca al contexto, no significa que tenga que tener una definición de extensión en ese contexto.
Caso 1: Imaginemos entonces que el dispositivo SIP/124 disca 123.  ¿Que hace Asterisk?
Respuesta: Asterisk toma los dígitos marcados (123) y los compara con los patrones del contexto al cual pertenece el dispositivo que los marcó.  En este caso hará match y ejecutará la secuencia de instrucciones asignadas a ese patrón, es decir, contestará, reproducirá el sonido tt-monkeys y colgará.
Caso 2: Ahora el dispositivo SIP/124 disca 125.  ¿Qué hace Asterisk?
Respuesta: Asterisk toma los dígitos marcados (125) y los compara con los patrones del contexto al cual pertenece el dispositivo que los marcó.  En este caso NO hace match por lo que va a lo que se conoce como la extensión i o invalida.  En este caso no hará nada porque no hay nada definido en la extensión i.
Como resumen al punto de pertenencia del dispositivo, podemos decir que un dispositivo pertenece a un contexto y es en este contexto donde buscará sus patrones de extensiones.
Entendido este punto, vamos entonces a agregar algunas otras componentes.
Varios dispositivos, varios contextos
Imaginemos lo siguiente:
Tenemos cuatro dispositivos SIP: SIP/101, SIP/102, SIP/201 y SIP/202
Tenemos dos contextos: [compras] y [ventas]
Los dispositivos SIP/101 y SIP/102 están registrados en [compras].  SIP/201 y SIP/202 están registrados en [ventas]
Aquí están las partes relevantes de los archivos de configuración:
sip.conf

[101]
type=friend
username=101
host=dynamic
secret=********
context=compras


[102]
type=friend
username=102
host=dynamic
secret=********
context=compras


[201]
type=friend
username=201
host=dynamic
secret=********
context=ventas


[202]
type=friend
username=202
host=dynamic
secret=********
context=ventas

extensions.conf

[compras]
exten => 101,1,Dial(SIP/101)
exten => 102,1,Dial(SIP/102)

exten => i,1,Answer()
exten => i,n,Playbak(invalid)
exten => i,n,Hungup()


[ventas]
exten => 201,1,Dial(SIP/201)
exten => 202,1,Dial(SIP/202)

exten => i,1,Answer()
exten => i,n,Playbak(invalid)
exten => i,n,Hungup()
Gráficamente tenemos:

Caso 1: El dispositivo SIP/101 disca 102.  Asterisk buscará en el contexto compras, hará match con la extensión 102 y discará al dispositivo SIP/102.
Caso 2: El dispositivo SIP/101 disca 201. Asterisk buscará en el contexto compras, hará match con la extensión i y reproducirá el sonido “invalid” y colgará.
Viceversa, el dispositivo SIP/102 podrá llamar sólo al dispositivo SIP/101.

Inclusión de contextos
Si queremos que los dispositivos registrados en [compras] puedan llamar a las extensiones de [ventas] sólo tenemos que hacer un include.

[compras]
include => ventas
exten => 101,1,Dial(SIP/101)
exten => 102,1,Dial(SIP/102)

exten => i,1,Answer()
exten => i,n,Playbak(invalid)
exten => i,n,Hungup()

A partir de ese momento las extensiones de [ventas] son agregadas al contexto [compras] por tanto están disponibles para todos los dispositivos SIP registrados en [compras]
Gráficamente

SIP/101 y SIP/102 que antes se llamaban sólo entre ellos y no tenían acceso a las extensiones en ventas, podrán hacerlo ahora.  Pero no así para los dispositivos SIP/201 y SIP/202 quienes aún pueden llamarse sólo entre ellos. Aquí empieza el poder de los contextos.

Ahora pongo a prueba tu entendimiento, quitamos el include, imagina que ahora en el sip.conf registramos al dispositivo SIP/101 en el contexto [ventas]
Gráficamente:



¿Cuál será el comportamiento de esta configuración?
¿Quién puede llamar a quién?
¿Quién no puede llamar a quién?
Piensa tus respuestas… en el próximo post analizaremos este caso y otros un poco más complejos.

8 comentarios:

  1. Gracias esta bien explicado :D

    ResponderEliminar
  2. oye excelente explicacion, me surge una pregunta, en mi reporte cdr, hay una columna DCONTEXT con valores: from-did-direct,app-blackhole,ext-group
    ,ext-local,from-did-direct,from-internal,from-qeque, me imgaino que son referente a lo que explicas aca, pero no veo como trabajr con ellos ni se que quieren decir cada uno de esos valores. gracias por tu amable respuesta,

    ResponderEliminar
  3. Buenas hermano tengo un problema quiero conectar mi configuración de linea de comando con la que tengo configurada vía linea gráfica, como podría hacer esto.?????

    ResponderEliminar
  4. Muy buena explicacion. leeré todos los que tengas de asterisk....

    ResponderEliminar
  5. Muy bien explicado, les recomiendo esta lectura tambien:

    http://elastixteamcr.blogspot.com/2014/07/como-crear-contexto-para-salida-en-e1.html

    ResponderEliminar
  6. Buenas tardes Ramón Jimenez, soy nuevo en tu blog, la presente pedirte ayuda con un central asterix BiTecPBX Pro, quiero saber como programar la agenda telefónica en dicha central para que los teléfonos la puedan ver, actualmente tengo que hacerlo teléfono por teléfono y tengo 150 Teléfonos.

    En espera de tu ayuda...

    ResponderEliminar
  7. si quisiera hacer una llamada por extensión custom pero deseo se ejecute a X o Y hora?

    ResponderEliminar