Escolar Documentos
Profissional Documentos
Cultura Documentos
O dialplan é verdadeiramente o coração de qualquer sistema Asterisk, já que define como o Asterisk
manipula os telefonemas que chegam e que são enviados. Em resumo, o dialplan consiste de uma
lista de instruções ou passos que o Asterisk irá seguir. Estes passos são totalmente personalisaveis.
Sintaxe do dialpan
Contextos
O dialplan é dividido em seções chamadas de contexto, tais contextos evitam que partes diferentes
do dialplan interajam umas com as outras. Assim, uma extensão (as funções de um grupo) definida
em um contexto é completamente isolada das extensões de outro contexto, a não ser que a interação
seja especificamente permitida.
Os contexto são denotados pela colocação do nome de contexto dentro de colchetes [], por
exemplo, [incoming]. Todas as instruções colocadas depois da definição de um contexto fazem
parte do contexto até que seja definido outro contexto.
Um dos mais importantes usos de contextos é garantir a segurança. Pelo uso correto dos contextos, é
possível permitir a determinadas pessoas acesso a algumas funções que não serão disponibilizadas a
outras.
Extensões
Uma extensão é uma instrução que o Asterisk irá seguir e é incluída dentro de cada contexto. A
extensão é acionada por uma chamada de entrada ou por dígitos sendo discados em um canal. Então
as extensões especificam o que acontece às chamadas enquanto seguem seu caminho pelo dialplan.
A sintaxe para uma extensão é a palavra exten seguida por uma seta formada pelo sinal de igual e
de maior que:
exten =>
Uma extensão completa é formada pelos seguintes componentes:
● O nome (ou número) da extensão;
● A prioridade, na qual cada extensão pode incluir vários passos a ser executado na
chamada;
● Aplicação (ou comando) que executa alguma ação na chamada.
Esses três componentes são separados por vírgulas, da seguinte forma:
Um simples exemplo:
Neste exemplo, o nome da extensão é 123, a prioridade é 1 e a aplicação é Answer().
O nome da extensão. Quando lidamos com sistemas telefônicos, temos a tendência de usar
números que devemos digitar para fazer outro telefone tocar, mas no Asterisk é possível fazer
muito mais, tal como colocar nomes.
Prioridades
Cada extensão pode ter vários passos, chamados de prioridades. Cada prioridade é numerada
seqüencialmente e cada prioridade executa uma aplicação específica. Por exemplo, a seguinte
extensão pode responder a uma chamada (na prioridade 1) e então desligar (na prioridade 2):
As versões mais recentes do Asterisk, a partir da 1.2, é possível usar um truque para enumerar as
prioridades, como por exemplo usar o “n” que indica a próxima, ou seja, cada vez que o
Asterisk achar um “n” ele pega o número da prioridade anterior e acrescenta mais 1. Por exemplo:
É possível ainda acrescentar textos as prioridades, por exemplo:
Aplicações
As aplicações são os cavalos de batalha do dialplan. Cada aplicação executa uma ação
específica no canal em questão, tal como emitir um som, aceitar uma entrada toquetom ou desligar
a chamada. Algumas aplicações precisam de argumentos a serem passados juntos com as aplicações
para determinar como devem executar suas ações. Para passar argumentos às aplicações,
coloqueos entre os parênteses que se seguem ao nome da aplicação, separados por vírgulas.
Um simples exemplo de dialplan
Vamos criar um dialplan simples para entender como este funciona. Em nosso exemplo iremos criar
um diaplan para que quando a chamada chegar, o Asterisk irá responder à chamada, tocar um
arquivo de som e então desligar a chamada.
Antes de iniciar o dialplan, nós devemos explicar sobre uma extensão especial chamada de
extensão “s”, quando as chamadas entram num contexto sem uma extensão
específ ica de destino (por exemplo, uma linha FXO chamado), elas são automaticamente
manipuladas pela extensão “s”. O “s” indica início (start).
Nosso dialplan irá iniciar com a extensão “s” e executaremos três ações: responder, tocar um
arquivo de som e desligar:
[incoming]
A aplicação Answer() é utilizada para responder a um canal que está chamando, isso faz a
configuração inicial do canal que recebe a chamada que está entrando, Answer() não tem
argumentos.
A aplicação Hangup() desliga o canal ativo e quem está chamando recebe uma indicação que
a chamada foi desligada, devese utilizar essa aplicação ao final do contexto quando quiser terminar
a atual ligação para assegurar que o dialplan não continuará sendo utilizado. Essa aplicação não tem
argumento.
O dialplan até agora não tem muita utilidade é mais para entender a teoria e testes, caso os canais
estejam configurados é possível testálo. Vamos tornar o dialplan mais dinâmico.
Aplicações Background() e Goto()
Outra aplicação útil é Goto(), que é usada para enviar a chamada para outro
contexto, extensão e prioridade. A aplicação Goto() torna fácil se mover
programaticamente uma chamada entre duas partes diferentes do dialplan. A sintaxe para a
aplicação Goto() nos pede que passemos os argumentos do contexto, da extensão e da prioridade
para a aplicação, da seguinte forma:
Neste próximo exemplo, iremos tocar o arquivo de amostra de som chamado de vm-enter-num-
to-call.gsm. E depois adicionar duas extensões que serão acionadas pelo chamador ao inserir 1
ou 2 no telefone.
[incoming]
exten => s,1,Answer()
exten => s,2,Background(vm-enter-num-to-call)
exten => 1,1,Playback(digits/1)
exten => 1,2,Goto(incoming,s,1)
exten => 2,1,Playback(digits/2)
exten => 2,2,Goto(incoming,s,1)
Então quando os usuários chamam nosso dialplan, eles vão ouvir uma saudação, e devem inserir um
digito, se eles pressionarem 1, irão ouvir o número 1 e, se pressionarem o número 2, irão ouvir o
número 2. E o Goto() irá fazer tudo ser repetido.
Manipulando entradas inválidas e tempos decorridos
Bem com os exemplos anteriores temos um menu de voz, mas é preciso controlar algumas
anomalias, a primeira é a entrada inválida de um usuário, tal função é feita pela extensão “i”.
Outra situação é quando o usuário não digita uma entrada a tempo (o tempo provisório é
de 10 segundos), estas chamadas devem ser tratadas pela extensão “t” se o chamador demorar a
pressionar um digito depois que Background() tiver terminado de tocar o arquivo de som.
[incoming]
exten => s,1,Answer()
exten => s,2,Background(vm-enter-num-to-call)
exten => 1,1,Playback(digits/1)
exten => 1,2,Goto(incoming,s,1)
exten => 2,1,Playback(digits/2)
exten => 2,2,Goto(incoming,s,1)
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(incoming,s,1)
exten => t,1,Playback(vm-goodbye)
exten => t,2,Hangup()
Uso da aplicação Dial()
Uma das mais importantes características do Asterisk é sua habilidade para conectar diferentes
chamadores, uns com os outros. Isso é especialmente útil se os chamadores aplicarem diferentes
métodos de comunicação (SIP, H.323, PSTN, etc).
Neste exemplo assumimos que queremos chamar um canal ZAP chamando ZAP/1, que é um canal
FXS com um fone analógico conectado. A tecnologia é “Zap” e o recurso é “1”, e o 123 indica que
o Asterisk deve chamar o canal Zap/1 quando forem digitados 123.
Também é possível chamar vários canais ao mesmo tempo:
A aplicação Dial() irá ligar a chamada a aquele que atender primeiro.
Se a chamada for atendida antes do tempo decorrido, os canais são ligados e o dialplan será
concluído. Se o destino simplesmente não responder, Dial() vai para a próxima prioridade na
extensão. Se, entretanto, o canal de destino estiver ocupado, Dial() irá para a
prioridade n+101, se a prioridade existir (onde n é a prioridade onde a aplicação Dial() foi
chamada). Isso nos permite manipular chamadas não respondidas de maneira diferente das
chamadas cujos destinos estavam ocupados.
Vamos fazer agora um DialPlan que permita que falemos com John e Jane.
[incoming]
exten => s,1,Answer()
exten => s,2,Background(enter-ext-of-person)
exten => 101,1,Dial(Zap/1,10)
exten => 101,2,Playback(vm-nobodyavail)
exten => 101.3,Hangup()
exten => 101,102,Playback(tt-allbusy)
exten => 102,1,Dial(SIP/Jane,10)
exten => 102,2,Playback(vm-nobodyavail)
exten => 102,3,Hangup()
exten => 102,102,Playback(tt-allbusy)
exten => 102,103,Hangup()
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(incoming,s,1)
exten => t,1,Playback(vm-goodbye)
exten => t,2,Hangup()
Qualquer um desses argumento de Dial() podem ser deixados em branco.
Contexto para tratar as chamadas internas
Bem depois de entender como funciona basicamente o dialplan vamos entender como criar mais de
um contexto e fazer estes interagirem, lembre que é essa uma das funções do dialplan.
Então vamos criar um contexto chamado (ramais) internos e configurar a capacidade desses dois
ramais ligar um para o outro, este novo contexto vai se chamar [internal].
Nós iremos deduzir que já esteja configurado um canal FXS Zap (Zap/1) e um canal FXO (Zap/4)
que utilizam o canal [incoming] e um ou mais canal SIP (SIP/jane), que está configurado no
contexto [internal]
Nosso dialplan vai ser parecer da seguinte forma:
[incoming]
exten => s,1,Answer()
exten => s,2,Background(enter-ext-of-person)
exten => 101,1,Dial(Zap/1,10)
exten => 101,2,Playback(vm-nobodyavail)
exten => 101,3,Hangup()
exten => 101,102,Playback(tt-allbusy)
exten => 101,103,Hangup()
exten => 102,1,Dial(SIP/jane,10)
exten => 102,2,Playback(vm-nobodyavail)
exten => 102,3,Hangup()
exten => 102,102,Playback(tt-allbusy)
exten => 102,103,Hangup()
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(incoming,s,1)
exten => t,1,Playback(vm-goodbye)
exten => t,2,Hangup()
[internal]
exten => 101,1,Dial(Zap/1,,r)
exten => 102,1,Dial(SIP/jane,,r)
Neste exemplo, foi adicionado duas novas extensões ao contexto [internal]. Dessa forma, a
pessoa que estiver utilizando o canal Zap/1 pode pegar o fone e chamar a pessoa que está no canal
SIP/Jane discando 102. Pela mesma razão, o telefone registrado como SIP/Jane pode chamar Zap/1
discando 101.
Até agora só foi usado três dígitos, mas é possível utilizar até 80 caracteres, ou seja, também é
possível usar letras, é claro que o terminal vai ter de suportar caracteres.
[internal]
exten => 101,1,Dial(Zap/1,,r)
exten => john,1,Dial(Zap/1,,r)
exten => 102,1,Dial(SIP/jane,,r)
exten => jane,1,Dial(SIP/jane,,r)
Uso de variáveis
No Asterisk existem duas formas de referenciar uma variável. Para referenciar o nome da variável, é
necessário digitar simplesmente o nome da variável, tal como JOHN. Se, por outro lado for
necessário acessar o valor da variável, devese digitar um símbolo de dólar, abrir uma chave, o nome
da variável e fechar a chave. Exemplo ${JOHN}.
JOHN=Zap/1
exten => 555,1,Dial(${JOHN},,r)
que é igual á:
Existem três tipos de variáveis no Asterisk: globais, de canal e de ambiente.
Variáveis globais: Se aplicam a todas as extensões em todos os contextos, assim, é possível
utilizar as variáveis globais em qualquer lugar do dialplan.
[globals]
JOHN=ZAP/1
ou
[internal]
exten => 123,1,SetGlobalVar(JOHN=Zap/1)
Variáveis de Canal: É uma variável que é somente associada a uma chamada em
particular, ou seja, são definidas somente na duração da chamada atual e estão disponíveis
somente para o canal que está participando dessa chamada.
As variáveis de canal são definidas por meio da aplicação Set()
Existem variáveis de canal predefinidas em README.variables, mas veremos estas depois.
Adaptação de modelos
Felizmente, o Asterisk tem uma forma para solucionar isso: adaptação de modelos, que permite que
se utilize uma seção de código para muitos ramais diferentes.
Sintaxe da adaptação de modelos
Ao utilizar a adaptação de modelos, é necessário utilizar letras e símbolos para representar os
possíveis dígitos que queremos adaptar. Os modelos sempre começam com um sublinhado (_). Isso
diz ao Asterisk que estamos adaptando sobre um modelo, e não um nome de extensão.
Depois do sublinhado, devese utilizar um ou mais dos seguintes caracteres:
X Adapta qualquer dígito de 0 a 9.
Z Adapta qualquer dígito de 1 a 9.
N Adapta qualquer dígito de 2 a 9.
[17] Adapta qualquer dígito na faixa indicada. No caso do 1 ao 7.
Para utilizar a adaptação de modelos no dialplan, simplesmente é necessário colocar no lugar do
nome ou número da extensão a adaptação:
Neste exemplo, o modelo deve adaptar quaisquer ramais de 3 dígitos de 200 a 999 (lembrese o N
adapta qualquer dígito entre 2 e 9, e cada X entre 0 e 9. Isto que dizer que se um chamador digitou
qualquer ramal de 3 dígitos entre 200 a 999 nesse contexto, ele deverá ouvir o arquivo de som
atuth-tahkyou.gsm.
Se tiver mais do que um modelo que se adapte a chamada (ao ramal discado) o Asterisk utilizará o
mais específico. Digamos que tenhase digitado 5551212:
Neste caso, o chamador ouvirá o digito 2
Uso de variável de canal $(EXTEN)
Bem e se tivermos que saber quais números foram discados em uma adaptação de
contexto? Bem neste caso o Asterisk define a variável de canal ${EXTEN} para os dígitos que
foram discados. Nós podemos usar uma aplicação chamada SayDigits() para testar esta
funcionalidade.
Freqüentemente, é útil se manipular o ${EXTEN} removendo um certo número de dígitos da frente
da extensão. Isto é feito usandose a sintaxe ${EXTEN:x}, onde x ;e o número de dígitos que quer
se remover.
Por exemplo, se o valor de EXTEN é 95551212, então ${EXTEN:1} é 5551212.
Se o x for negativo será obtido os últimos dígitos x do ramal discado.
Habilitações de discagem de ligações externas
Agora que já foi apresentado a adaptação de modelos, podemos fazer ligações externas.
Então podemos acrescentar uma variável ao contexto [globals] para definir quais canais serão
utilizados para fazer ligações externas:
[globals]
JOHN=Zap/1
JANE=SIP/jane
OUTBOUNDTRUNK=Zap/4
Vamos criar um contexto para ligações externas, isto é necessário para colocar um pouco de
segurança, regular e controlar as ligações externas (quem pode fazer ligações externas).
Então vamos criar um contexto chamado [outbound-local]. Vamos usar o número 9 no início,
de forma que os usuários deveram usar o 9 para chamar um número externo.
[outbound-local]
exten => _9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten => _9NXXXXXX,2,Congestion()
exten => _9NXXXXXX,102,Congestion()
Então neste contexto anterior, nós acrescentamos uma variável global chamada OUTBOUNDTRUNK,
que irá controlar qual ramal será utilizado para fazer ligações externas.
Nós também adicionamos um contexto para ligações externas locais. Na prioridade 1, nós pegamos
o ramal discado, eliminando o 9 com a sintaxe ${EXTEN:1} e então tentamos discar aquele
número no canal significando pela variável OUTBOUNDTRUNK.
Se a chamada funcionar, o chamador é ligado ao canal de saída. Se a chamada falhar, por que o
canal está ocupado, ou porque o número não pode ser discado por qualquer razão, a aplicação
Congestion() é chamada e toca um “sinal de ocupado”, para permitir que o chamador saiba
que sua chamada falhou.
Ao discar o 9 não será fornecido realmente uma linha externa como em um sistema PBX
tradicional, mas sim aparecerá um silêncio, caso queirase um tom de discagem adicione ao
contexto:
ignorepat => 9
Que diz ao Asterisk para continuar a tocar o tom de discagem mesmo depois de o chamador discar o
9.
É sempre interessante permitir que o dialplan possa discar para números de emergência:
[outbound-local]
exten => _9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten => _9NXXXXXX,2,Congestion()
exten => _9NXXXXXX,102,Congestion()
Inclusos
Estrutura do include
A definição de include toma a seguinte forma, em que context é o nome do contexto remoto que
gostaríamos de incluir no contexto atual:
Quando existirem contextos dentro do contexto atual, é necessário observar a ordem em que
estamos incluindo os contextos, já que o Asterisk irá primeiro tentar corresponder a extensão do
contexto atual, se este falhar o Asterisk chamará o primeiro que aparecer e se der errado o próximo
e assim por diante, na ordem que forem incluídos.
Vamos ao último exemplo usando os inclusos:
[globals]
JOHN=Zap/1
JANE=SIP/jane
OUTBOUNDTRUNK=Zap/4
[incoming]
exten => s,1,Answer()
exten => s,2,Background(enter-ext-of-person)
exten => 101,1,Dial(Zap/1,10)
exten => 101,2,Playback(vm-nobodyavail)
exten => 101,3,Hangup()
exten => 101,102,Playback(tt-allbusy)
exten => 101,103,Hangup()
exten => 102,1,Dial(SIP/jane,10)
exten => 102,2,Playback(vm-nobodyavail)
exten => 102,3,Hangup()
exten => 102,102,Playback(tt-allbusy)
exten => 102,103,Hangup()
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(incoming,s,1)
exten => t,1,Playback(vm-goodbye)
exten => t,2,Hangup()
[internal]
include => outbound-local
exten => 101,1,Dial(Zap/1,,r)
exten => 102,1,Dial(SIP/jane,,r)
[outbound-local]
exten => _9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten => _9NXXXXXX,2,Congestion()
exten => _9NXXXXXX,102,Congestion()
Nós só abordamos funcionalidades básicas, existem muitas funcionalidades mais avançadas que
podem ser estudadas, mas os conceitos vistos aqui são conceitos básicos para qualquer dialplan e
através desses é possível implementar muitos sistemas Asterisk.