Asterisk® SCF™ + LUA: Configuração do LUA Dialplan (parte 02)

Criado por Matthew Nicholson, modificado pela última vez por Rusty Newton, tradução técnica e adaptação para o Brasil por Angelo Delphini.


Interagindo com o Asterisk® SCF™ Dialplan LUA (aplicativos, variáveis ​​e funções)

A é feita com interação por meio de uma série de objetos predefinidos fornecidos por pbx_lua. A tabela app é usada para acessar aplicativos do Dialplan. Qualquer aplicativo do Asterisk® SCF™ pode ser acessado e executado como se fosse uma função anexada à tabela app. Variáveis ​​e funções do Dialplan são acessadas e executadas através da tabela channel.

Conflitos de nomenclatura entre LUA e Asterisk® SCF™

Aplicativos do Asterisk® SCF™, variáveis ​​ou funções cujos nomes entram em conflito com palavras reservadas de LUA ou contêm caracteres especiais devem ser referenciados usando o [ ] operador. Por exemplo, LUA 5.2 introduziu a GoTo instrução de controle que conflita com a aplicação GoTo() do Dialplan do Asterisk® SCF™. Então...

O seguinte fará com que pbx_lua.so falhe ao carregar com LUA 5.2 ou posterior porque GoTo é uma palavra reservada.

app.goto("default"10001)

A seguinte instrução funcionará com todas as versões LUA e o Dialplan do Asterisk® SCF™.

app["goto"]("default"10001)

Aplicativos do Dialplan

extensions.lua
app.playback("please-hold")
app.dial("SIP/100", nil, "m")
Qualquer aplicativo do Dialplan pode ser executado usando a tabela app. Os nomes dos aplicativos não diferenciam maiúsculas de minúsculas. Mas lembre que as melhores praticas de desenvolvimento de Dialplan, recomenda que seja app.HangUp( ) do que app.hangup( ). Os argumentos são passados ​​para aplicações do Dialplan assim como os argumentos são passados ​​para funções em LUA. Os argumentos de string devem ser colocados entre aspas, pois são strings LUA. Argumentos vazios podem ser passados ​​como strings vazias, nil ou empty.

Variáveis ​​de Canal

Definir uma variável
channel.my_variable = "my_value"
Depois disso, a variável de canal ${my_variable} contém o valor "my_value".

Lendo uma variável
value = channel.my_variable:get()
Qualquer variável de canal pode ser lida e configurada usando a tabela channel. Variáveis LUA, locais e globais podem ser usadas como normalmente fariam e não estão completamente relacionadas com variáveis ​​de canal.

A seguinte instrução NÃO funcionará.

value = channel.my_variable -- não funciona como o esperado --
-- (value:get() pode ser usado para obter o valor após esta linha) --

Se o nome da variável for uma palavra reservada para LUA ou contiver caracteres que LUA considera especiais, devemos usar o [ ] operador para acessá-los.

channel["my_variable"] = "my_value"
value = channel["my_variable"]:get()

Funções Dialplan

Escrevendo uma função no Dialplan
channel.FAXOPT("modems"):set("v17,v27,v29")
Lendo uma função do Dialplan
value = channel.FAXOPT("modems"):get()

Observe o uso do :operador com os métodos get() set().

Se o nome da função for uma palavra reservada para LUA ou contiver caracteres que LUA considera especiais, devemos usar o [ ] operador para acessá-los.

channel["FAXOPT(modems)"] = "v17,v27,v29"
value = channel["FAXOPT(modems)"]:get()

As seguintes instruções NÃO funcionarão.

channel.FAXOPT("modems") = "v17,v27,v29" -- erro de sintaxe --
value = channel.FAXOPT("modems")         -- não funciona como esperado -- 
-- (value:get() pode ser usado para obter o valor após esta linha) --

Os nomes das funções do Dialplan diferenciam maiúsculas de minúsculas.

Dialplan LUA, dicas e trunques

Operações de longa duração (AutoService)

Antes de iniciar operações de longa duração, um AutoService deve ser iniciado usando a função autoservice_start( ). Um AutoService garantirá que o usuário ouça um fluxo contínuo de áudio enquanto seu código LUA funciona em segundo plano. Este AutoService será interrompido automaticamente antes de executar aplicativos e funções do Dialplan e será reiniciado posteriormente. O AutoService pode ser interrompido usando autoservice_stop( ) e a função autoservice_status( ) retornará true um AutoService estiver em execução.

app.startmusiconhold()
 
autoservice_start()
do_expensive_db_query()
autoservice_stop()
 
app.stopmusiconhold()

No Asterisk® SCF™ 10 e posteriores, um AutoService é iniciado automaticamente para você por padrão.

Definindo Extensões Dinamicamente

Como as extensões são funções em pbx_lua, qualquer função pode ser usada, incluindo encerramentos. Uma função pode ser definida para retornar funções de extensão e usada para preencher a tabela de extensões.

extensions.lua
extensions = {}
extensions.default = {}
 
function sip_exten(e)
   return function()
      app.dial("SIP/" .. e)
   end
end
 
extensions.default[100] = sip_exten(100)
extensions.default[101] = sip_exten(101)

Criação de 'aliases' personalizados para construções integradas

Se você não gosta que a tabela app seja chamada de 'app' ou se acha que digitar 'channel' para acessar a tabela channel é muito trabalhoso, você pode renomeá-los.

Eu prefiro digitar menos
function my_exten(context, extensions)
   c = channel
   a = app
 
   c.my_variable = "minha nova variável de canal"
   a.dial("SIP/100")
end

Redefinindo a função print

LUA tem uma função "print" embutida que envia as coisas para o "stdout", mas para o Asterisk® SCF™, preferimos que a saída vá para o log detalhado. Para fazer isso, poderíamos reescrever a função print da seguinte maneira.

function print(...)
   local msg = ""
   for i=1,select('#', ...) do
      if i == 1 then
         msg = msg .. tostring(select(i, ...))
      else
         msg = msg .. "\t" .. tostring(select(i, ...))
      end
   end
 
   app.verbose(msg)
end

Dividindo a configuração em vários arquivos


O método require pode ser usado para carregar módulos LUA localizados em LUA_PATH. O método dofile  pode ser usado para incluir qualquer arquivo por nome de caminho.

Usando Módulos Externos

Os módulos LUA podem ser carregados usando o método require LUA padrão. Algumas das funcionalidades fornecidas por vários módulos LUA já estão incluídas no Asterisk® SCF™ (por exemplo, func_odbc que fornece o que LuaSQL fornece). Geralmente é melhor usar código embutido no Asterisk® SCF™ em vez de módulos LUA externos. Especificamente, o módulo func_odbc usa um pool de conexão para fornecer recursos de banco de dados, onde, como com LuaSQL, cada canal teria que fazer uma nova conexão com o banco de dados por conta própria.

Compilando extensions.lua

O programa luac pode ser usado para compilar seu arquivo extensions.lua em bytecode LUA. Isso aumentará um pouco o desempenho, pois o pbx_lua não precisará mais analisar extensions.lua durante o carregamento. O compilador luac também detectará e relatará quaisquer erros de sintaxe. Para usar luac, renomeie seu arquivo extensions.lua e execute o seguinte.

Suponha que você nomeie seu arquivo extensions.lua para extensions.lua.lua
luac -o extensions.lua extensions.lua.lua
O módulo pbx_lua reconhece automaticamente a diferença entre um arquivo de texto LUA e um arquivo de bytecode LUA.

Tkat's All Folks! (É por hoje é só, pessoal!).

 
Temos uma comunidade, ainda pequena no Telegram, para estudos exclusivos em Dialplan com LUA no Asterisk® SCF™, você é bem vindo! (Telegram: https://t.me/asteriskluabr).

Nenhum comentário

Toda vez que um homem supera os reveses, torna-se mentalmente e espiritualmente mais forte!

Tecnologia do Blogger.