Asterisk 101++ o Trabajando en un Dialplan e introducción

Anuncio
Asterisk 101++ o Trabajando en un Dialplan e introducción a AGI
Breve resumen del charla anterior
Apartir de esto podemos decir que en corazón de asterisk (*) es el dialpan que
se define en el archivo extension.conf.
Como habíamos hablado cada dispositivo se le define un contexto que es
donde comienza a trabajar ese dispositivo.
Veamos un ejemplo de una entrada de telefonía (zap) y 2 teléfonos SIP
En zaptel.con tengo algo como:
[channels]
transfer=yes
cancallforward=yes
signalling=fxs_ks
context=from-pstn
rxgain=2.0
txgain=4.0
callprogress=yes
usecallerid=yes
callerid=asreceived
group=0
channel=> 1
Esta es una famosa X100 placa que es un WinModem con un chipset Ambient
de Intel. Lo mas importante es que la definí en el contexto from-pstn.
Luego en el sip.conf tenemos lo siguiente:
[general]
context=from-local
bindport=5060
bindaddr=0.0.0.0
[100]
type=friend
host=dynamic
username=100
secret=XXXXXXX
[101]
type=friend
host=dynamic
username=101
secret=XXXXXXX
Una muestra de lo que es un dialplan básico seria:
[from-local]
exten => 100,1,Dial(SIP/100)
exten => 101,1,Dial(SIP/101)
exten => _9.,1,Dial(Zap/1/${EXTEN:1})
[from-pstn]
exten => s,1,Answer
exten => s,2,Playback(welcome)
exten => s,3,Dial(SIP/101,15,t)
exten => s,4,Dial(SIP/102,15,t)
exten => s,5,Playback(nobody)
exten => s,6,Voicemail(101)
exten => s,7,Hangup
Hace falta explicar un par de cosas acerca de esto:
Primeramente el archivo extension.conf tiene como casi todos un [general] que
es para definiciones básicas las mas importantes son 2 definiciones: static y
writeprotect ambas por defecto en NO.
Sirve solo si static es Yes y writeprotect es No. Pero esto es un detalle menor
Hay una parte de [global] donde se definen variables globales y lo que se
puede decir que una variable se define en este lugar así:
VARIABLE => Zap/1
Y se usa ${VARIABLE} o ${Variable} o ${variable}.
Pero ahora definamos extensiones, cada extensión es:
exten => extensión,prioridad,Comando(parámetros)
Primeramente veamos extensión, la cual puede ser literales, patrones o
predefinidas, Las primeras son aquellas en las cuales definimos el numero que
se marca por ejemplo 101 o 100 en los cuales hacemos cosas especificas para
cada uno de estos números.
Los Patrones nos aquellos que match con el numero discado, comienzan con _
y pueden contener:
X
Z
N
[24-7]
.
!
números del 0 al 9
números del 1 al 9
números del 2 al 9
números específicos en este caso 2,4,5,6,7
uno o mas números
cero o mas números
Un ejemplo seria que tenemos diferentes proveedores para diferentes
provincias y un dial plan puede ser:
_0351.
Córdoba
_0352.
Santa Fe
etc.....
o si se disca:
_4XXXXXX
Un numero común loca acá en Córdoba
Hay que tratar de no usar cosas como _. porque esto machearia con cualquier
cosa, es mejor _X.
También podemos usar cosas un poco mas complejos como discar algo solo si
el caller id machea con algún patrón:
123/4892233
Entra al contexto discando 123 desde el teléfono 4892233
Y podemos remplazar todo por los patrones antes definidos.
Las extensions predefinidas son las siguientes:
i extensión invalida.
Un contexto tiene un limitado números que un usuario puede marcar y si
marco otro podemos tomar ese error y hacer algo, por ejemplo
[from-local]
exten => 100,1,Dial(SIP/100)
exten => 101,1,Dial(SIP/101)
exten => _9.,1,Dial(Zap/1/${EXTEN:1})
exten => i,1,Playback(discadoinvalido)
exten => i,2,Hungup
h corte de la extensión
Es cuando un cliente corta la comunicación y generalmente se usa para cobrar
o loguear llamadas.
a asterisco
Es para determinar que se presiono el asterisco
s para llamadas no conocidas
Es generalmente cuando las llamadas entran y no conocemos que puede
llegan a discar.
t máximo tiempo de respuesta
Esto es para dar un tiempo especifico a las respuestas de un cliente sobretodo
en los IVRs
[from-local]
exten => 100,1,Dial(SIP/100)
exten => 101,1,Dial(SIP/101)
exten => _9.,1,Dial(Zap/1/${EXTEN:1})
exten => t,1,Playback(muchotiempotecorto)
exten => t,2,Hungup
exten => i,1,Playback(discadoinvalido)
exten => i,2,Hungup
T máximo tiempo de llamada
Es para controlar cuanto tiempo la llamada del cliente esta activa, por defecto
el tiempo absoluto de llamada esta en 0 o sea que no se controla.
Hay otros como fax, que es obvio y solo se usa con drivers ZAP. Los demás son
de poco uso o nos vamos a poner a discutir un monton.
Hay un problema con el orden de los patrones en cada contexto. Veamos el
siguiente ejemplo:
[demo]
exten => _450.,1,Dial(SIP/100)
exten => _X.,1,Dial(SIP/102)
exten => h,1,Hungup
Cuando hagamos un show dialplan vemos como asterisk lo ordeno:
1 _X.
2 _450.
3h
No importa lo que hagamos en este contexto todo va salir por la opción _X.
Para cambiar el orden debemos usa un trampa para el parser.
[demo]
include => demo-uno
exten => _450.,1,Dial(SIP/100)
exten => h,1,Hungup
[demo-uno]
exten => _X.,1,Dial(SIP/102)
Si dentro de un contexto encontramos un include sera parceado al final del
contexto y en el orden de los include, para nuestro ejemplo queda:
1 _450
2h
3 _X.
Que era lo que nosotros queríamos
Hasta acá todo acerca de extensiones, ahora hablaremos de prioridades.
En nuestro ejemplo primigenio teníamos un buen ejemplo de prioridades:
[from-pstn]
exten => s,1,Answer
exten => s,2,Playback(welcome)
exten => s,3,Dial(SIP/101,15,t)
exten => s,4,Dial(SIP/102,15,t)
exten => s,5,Playback(nobody)
exten => s,6,Voicemail(101)
exten => s,7,Hangup
Las prioridades son el orden que debe tener para cada extensión. Cual es la
otra función además de darle un orden estos números de prioridad, para ser
usados con funciones como GotoIf.
exten => s,6,GotoIf($[ ${x} < 3 ]?2:5)
A partir de la versión 1.2 podemos escribir
[from-pstn]
exten => s,n,Answer
exten => s,n,Playback(welcome)
exten => s,n,Dial(SIP/101,15,t)
exten => s,n,Dial(SIP/102,15,t)
exten => s,n,Playback(nobody)
exten => s,n,Voicemail(101)
exten => s,n,Hangup
En la cual se entiende que el orden de esta extensión esta dado por el orden
que la hemos escrito. Pero entonces perdimos el tema de los GotoIf, no se
pueden escribis cosas feas como:
exten => s,n(start),Answer
Y entoces podemos hacer:
exten => s,n,Goto(start)
Hay un par de cosas mas acerca de la prioridad pero voy muy atrasado.
Hay 2 cosas que que nos faltan que son los comandos y la variables, los
comandos son mas simples y uno de los mas importante es Dial.
Dial(tipo/identificador,timeout,opciones,URL)
tipo puede ser cualquiera de los canales definidos (Zap, SIP, IAX2, h323, oh323,
ooh323)
identificador depende mucho de la definición del canal. Ya que como venimos
poniendo en nuestros ejemplos SIP/100 depende de que en el sip.con hayamos
definido un dispositivo SIP con el label 100. Pero También podremos hacer una
llamada a un teléfono SIP ignoto con SIP/${EXTEN}@145.12.22.30.
timeout es el tiempo que dial intentara discar dado en segundos, luego
terminara la función y prenderá la opción de t.
opciones tiene una gran cantidad, como por ejemplo t en la cual permite a esta
llamada poder hacer transferencia de llamadas, pueden llegar a tener cosas
como cambiar de tipo de ring, determinar como va ser la llamada, entre otras.
URL este es opcional y es para ciertos canales que permiten URLs
Answer(delay)
Generalmente se pone en los contexto que toman llamadas desde fuera de
nuestro Asterisk y podemos hacer esperar un tiempo determinado en segundos
Playback(file,option)
Backgroud(file,option)
Emite el mensaje de voz almacenado en file.
Playback emite el mensaje y devuelve el control a la aplicación, En cambio
Backgroud emite el mensaje de voz y si algun DTMF es regitrado y machea con
el contexto lo ejecuta.
Los archivos de audio lo busca en /var/lib/asterisk/sound, por defecto, en
instalacion estan los sonidos en Ingles. Pero uno en la misma estructura agrega
el directorio es y dentro los mismos sonido pero en español y setea la vriable
de lenguaje SetLanguage en es y vera solo los sonidos dentro del directorio es.
Goto(contex,extension,priority)
Goto(extension,priority)
Goto(priority)
Goto(contex,extension,label)
Goto(extension,label)
Goto(label)
Es un salto a un contexto, extension, prioridad o label especifico.
SayDigits(numeros)
Muy util, solo dice los numeros, si dentro de numeros esta 123, el comando
dice uno, dos, tres.
SayNumber(numeros,genero)
Hace lo mismo pero dice el numero por ejemplo 123 dice ciento veintitres y en
genero va “m” por male, “f” por female o “c” por computer. Pero se torna
indomito para el manejo multilenguaje.
Con esto podemos armar nuestro primer IVR.
[from-pstn]
exten => s,n,Answer
exten => s,n,Playback(bienvenidos)
exten => s(menu0),n,Background(opcionesmenu0)
exten => 1,n,goto(menu1)
exten => 2,n,goto(menu2)
exten => a,n,Playback(graciasporcomunicarse)
exten => a,n,hungup
exten => i,n,Playback(ingresoinvalido)
exten => i,n,goto(menu0)
exten => t,n,Playback(marqueunaopcion)
exten => t,n,goto(menu0)
[menu1]
exten =>
exten =>
exten =>
exten =>
exten =>
exten =>
s,n,Playback(ingresedni)
t,n,Playback(porfavor)
t,n,goto(menu1)
XXXXXXX.,n,SayDigits(${EXTEND})
XXXXXXX.,n,Goto(from-pstn,a)
i,n,Goto(from-pstn,i)
Falta obviamente el contexto menu2 pero puede ser algo muy parecido.
De todas maneras quiero poner 2 comandos mas:
NoOp()
Que como su nombre lo indica no hace nada pero sirve como printf para debug
basico.
Macro(nombremacro,arg1,arg2,...,argN)
Ejecuta un contexto llamado macro-nombremacro y pasa los argumentos que
se necesitan al nuevo contexto. Usa todas las variables ademas de
MACRO_EXTEN, MACRO_CONTEXT and MACRO_PRIORITY den donde es
llamado, por ejemplo:
exten => s,n,macro(internacional,${EXTEND})
[macro-internacional]
exten => s,n,Dial(Sip/${ARG1}@11.12.12.12,20)
exten => s,n,Dial(oh323/${ARG1}@123.1.1.15,20)
exten => s,n,Playback(nohaylinea)
exten => s,n,Congestion
Toda la info sobre los comandos los podemos encontrar en:
http://www.voip-info.org/wiki/view/Asterisk+-+documentation+of+application+commands
Ya entrando en la interface de programacion de Asterisk nos encontramos con
2 que son las unicas que utilice, AGI y FastAGI.
AGI (script.agi|arg1|arg2|....|argN)
y se ejecuta:
exten => s,n,AGI(dialRadius.agi)
El archivo dialRadius.agi debe estar en /var/lib/asterisk/agi-bin debe ser
ejecutable y leible por el usuario que corre Asterisk y puede ser uno de los
varias interfaces que hay a diferentes lenguajes, y hay para todo Java, Perl,
Python, Ruby, PHP, C, C# y bash.
Yo lo he usado en Perl y alli solo se hace:
use Asterisk::AGI;
$AGI = new Asterisk::AGI;
%input = $AGI->ReadParse();
$AGI->set_callerid($number)
$AGI->exec('Dial', 'SIP/' . $number . '@' . $someip);
$AGI->exec('Hungup');
Es una interface de comandos que al dar exect ejecutamos funciones del
dialplan, o podemos setear variables. Es para integrar Arterisk a Bases de
datos pero con programacion incluida, como los programas de Prepagos. No
creo que haya mucho mas que esto. El resto hay que dedicarse a leer.
Descargar