terça-feira, 20 de abril de 2021

Asterisk Extension Language - AEL (Parte 01)


A Sangoma Digium, por meio da sua equipe de desenvolvimento do Asterisk® SCF™, vem recebendo fortes pressões para adicionar recursos ao extensions.conf de modo a torná-lo mais parecido com uma linguagem de programação. O fato é que o AEL tem como objetivo fornecer uma linguagem de programação real que pode ser usada para escrever um Dialplan (Plano de Marcação, como não se faz mais uso de aparelhos de pulso com discos, não faz sentido traduzir para Plano de Discagem. Até porque em Telefones IP, e destinado a POTS temos teclas, e as marcamos ao invés de discar.). 

Começando:


O analisador AEL (pbx_ael.so) é completamente separado do módulo que analisa o extensions.conf (pbx_config.so). Para suar o AEL, a única coisa que deve ser feita é que o módulo pbx_ael.so deve ser carregado pelo Asterisk® SCF™. Isso será feito automaticamente se usar "autoload=yes" (que não é recomendado) em /etc/asterisk/modules.conf. Quando o módulo for carregado, ele procurará por extensions.ael em /etc/asterisk/. Ambos extensions.conf e extensions.ael pode ser usados em conjunto um com o outro, se isso for desejado. Alguns Engenheiros de Sistemas em Telecomunicações NGN, podem querer manter extensions.conf para usar os recursos que são configurados na seção "[GENERAL]".

Recarregando extensions.ael:

Para recarregar o extensions.ael, o seguinte comando pode ser emitido no *CLI>. 
*CLI> ael reload

Depurando:

  • Habilitar depuração de contextos do AEL;
    • *CLI> ael debug contexts
  • Habilitar depuração de macros do AEL;
    • *CLI> ael debug macros
  • Habilitar depuração de leitura do AEL;
    • *CLI> ael debug read
  • Habilitar depuração de tokens do AEL;
    • *CLI> ael debug tokens
  • Desativar mensagens de depuração do AEL;
    • *CLI> ael no debug

Comentários:

As linhas que começam com barra dupla (//) são comentários.
Exemplo: // Este é um comentário. 

Contexto:

Os contextos em AEL representam um conjunto de extensões da mesma forma que o fazem em extensions.conf (CONF).

context internal_pbx_extensions {

};

OBS: A chave de abertura deve aparecer como acima. Movê-la para a linha seguinte pode ter consequências desastrosas.

Extensões:

Para especificar uma extensão em um contexto, a seguinte sintaxe é usada. Se mais de um aplicativo for chamado em uma extensão, eles podem ser listados em ordem dentro de um bloco.



context internal_pbx_extensions {
    _10XX => {
            Verbose(Comutação Interna entre Extensions);
            Wait(0.2);
            Dial(PJSIP/${EXTEN},45,rTtHhKkwo);
            if("${DIALSTATUS}"=="BUSY") {
                Playback(call-sorry&is-in-use&call-goodbye);
            };
            HangUp();
    };

    _80XX => {
            Dial(PJSIP/${EXTEN},45,rTtHhKkwo);
            Verbose(Comutação entre servidores);
            Dial(PJSIP/TRUNK-SRV-SP/${EXTEN},45,rTtHhKkwo);
            if("${DIALSTATUS}"=="BUSY") {
                Verbose(Encaminhamento Incondicional);
                Playback(one-moment-please);
                goto internal_pbx_extensions|5099|1;
            };
            HangUp();
    };
    
    _5XXX => {
            Verbose(Comutação para a Telefonista);
            Dial(IAX2/TRUNK-SRV-SP/${EXTEN},45,rTtHhKkwo);
            if("${DIALSTATUS}"=="BUSY") {
                Playback(call-sorry&is-in-use&call-goodbye);
                HangUp();
            };
            HangUp();
    };

    h => {
            Verbose(//----> Chamada encerrada...: ORIG-${CALLERID(num)});
    };
};

Inclui:

Os contextos podem ser incluídos em outros contextos. Todos os contextos incluídos são listados em um único bloco.

context internal_pbx_extensions {
        includes { 
                chamadas_local;
                chamadas_ddd;
                chamadas_ddi;
        };
};

Dialplan Switches:

Os switches são listados em seu próprio bloco dentro de um contexto.

context internal_pbx_extensions {
        switches {
                DUNDi/e164;
                IAX2/TRUNK-SRV-SP;
        };

        eswitches {
                IAX2/context@${CURSERVER};
        };
};

Ignore Padrão (ignorepat):

ignorepat pode ser usado para instruir os drivers de canal a não cancelar o tom de marcação ao receber um determinado padrão (pattern). O exemplo mais comumente usado é '9'.

context chamadas_local {
        ignorepat=> 9;
};

OBS: A chave de abertura deve aparecer como acima. Movê-la para a linha seguinte pode ter consequências desastrosas.

Variáveis:

As variáveis no Asterisk® SCF™ não têm um tipo, então para definir uma variável, ela só precisa ser especificada com um valor. 

As variáveis podem ser definidas nas extensões. 

context chamadas_local {
        _92929XXXX => {
            Set(ignore_pattern=9); // definindo uma variável.
            ignorepat=> ${ignore_pattern}; // usando a variável.
        }
};

Variáveis globais são definidas em seu próprio bloco.

globals {
        CONSOLE=Console/dsp;
        TRUNK-GOIP=DAHDI/g2;
};

OBS: A chave de abertura deve aparecer como acima. Movê-la para a linha seguinte pode ter consequências desastrosas.


.

quinta-feira, 25 de fevereiro de 2021

Protocolo SIP - Mensagens 180 x 183 x Early Media

 

Uma chamada SIP básica, estabelecida com sucesso, quando aceita pelo receptor, tem a resposta final 200 OK, a negociação do CODEC é feita e a chamada entra na sessão de mídia com ambas as extremidades conhecendo as capacidades uma da outra. Acredito que você não tenha, nenhuma dúvida sobre este mecanismo básico e principal.

Fonte em referencias.

Mas isso não tem nada a ver com o momento em que a mídia realmente inicia, às vezes você pode perceber que o outro lado está reproduzindo um IVR para pedir a entrada de um dígito sem atender sua chamada.

Portanto, o fluxo de mídia antes do estabelecimento da chamada é considerado mídia inicial. Não é a voz da pessoa com quem você deseja falar, mas sim tons do sistema, anúncios ou qualquer som que o outro lado deseja que você ouça, mesmos que muitas vezes você não ouça, por não ter uma tratativa em seu Dialplan. Isto ocorre com frequência, e se seu Dialplan, não tem uma tratativa correta, o app_dial.c vai estacionar a chamada, ou seja vai executar o res_musiconhold.c.


Uma implementação de alguma forma semelhante ao PSTN pode ser encontrada quando seu telefone celular tenta alcançar um número fora do sinal:
O número discado não está disponível no momento, tente novamente mais tarde.
Isso pode ser o que você ouve como resultado e, neste caso, seu provedor de serviços de telefonia não atendeu a sua chamada nem cobrou a tarifa da chamada.

180 Ringing

Conforme declarado na Bíblia SIP RFC3261, 180 é usado para alertar o UA chamador que recebeu um INVITE e está tocando.

A resposta 180 na maioria das vezes não carrega o corpo SDP, e o dispositivo que recebe essa resposta geralmente inicia um toque de retorno local para o usuário final. Isso quer dizer que o tom de toque que você ouve ao esperar que o receptor atenda não é uma viagem pela rede, mas sim configurável em seu dispositivo terminal (endpoint).

Vale ressaltar que as mesmas coisas acontecem quando alguma mensagem do tipo  4XX, 5XX, 6XX é recebido, seu dispositivo deve gerar alguns tipos de áudios informativos, para que o usuário possa notar que a chamada falhou, ou que foi sem sucesso, antes de desligar completamente.

183 Session Progress

A resposta 183 (Progresso da sessão) é usada para transmitir as informações. Os campos de cabeçalho ou corpo SDP, neste caso, podem ser usados para transmitir mais detalhes sobre o andamento da chamada.
Fonte em referencias - Early Media with SIP 183 response.

A resposta 183 contém corpo SDP e é geralmente usada em 3 casos:
  1. Fazendo um RINGBACK da viagem na rede: o dispositivo que executa o UAC reproduzirá o fluxo de mídia enviado pelo UAS ao usuário para indicar que o receptor está sendo alertado.
  2. Simplesmente reproduzir um som de mensagem de erro e, em seguida, desligar como afirmei acima.
  3. Para a implementação de uma resposta de voz interativa: os tons DTMF podem ser reunidos junto com os pacotes de mídia.
É sobre a mídia antiga, simples, não é?

Detecting Early Media

Isso é sobre a mídia inicial, é simples,  acima está a definição SIP sobre a mídia inicial, posso dizer que é bastante simples, mas na verdade, o UAC não poderia retransmitir as respostas SIP recebidas para decidir se inicia o local do RINGBACK ou para reproduzir a mídia da extremidade remota. Só porque a sinalização SIP e a mídia RTP estão em seu próprio caminho, o UAS pode iniciar a resposta 183 que contém o corpo SDP sem enviar nenhum pacote de mídia.

Fora isso, alguma implementação anexa ao corpo da resposta 180 o SDP e entra na primeira sessão de mídia sem respostas 183.

Portanto, para detectar a mídia inicial, o UAC também precisa verificar se os pacotes de mídia estão chegando em um determinado momento.

E graças ao RFC3960, algumas políticas para essas bagunças são recomendadas:
  1. A menos que uma resposta 180 (toque) seja recebida, nunca gere toque local (RINGING);
  2. Se um 180 (RINGING) foi recebido, mas não há pacotes de mídia de entrada, gere toque local (RINGING);
  3. Se um 180 (RINGING) foi recebido e há pacotes de mídia de entrada, reproduza-os e não gere toque local (RINGING).
Essas políticas não são definidas como padrão a ser seguido em todos os dispositivos SIP, mas simplesmente afirmam:
Qualquer UA deve reproduzir pacotes de mídia de entrada (e interromper a geração de tom de toque local se estiver sendo executado).

Por último, mas não menos importante, quando a chamada deixa o estado de mídia inicial ao ser atendida, a resposta SDP no 200 OK deve corresponder à resposta SDP no 183/180 anterior, ou seja, nenhuma alteração na capacidade de mídia quando a chamada muda de sessão de mídia antecipada para sessão de mídia oficial (Early Media).

Bem, é isso, espero que faça sentido para você. Se possível, faça alguns rastreamentos com SNGREP/Wireshark de uma chamada SIP com Early Media podem ajudá-lo a entender com mais clareza. 

Referências:




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

quarta-feira, 6 de janeiro de 2021

Novo repositorio key para WineHQ - Debian e seus Forks

Eu faço uso do NotePad++ em cima do Ubuntu 20.4 (Fork do Debian), ocorre que sempre que vai haver uma atualização recebia o erro a seguir:

Erro GPG: https://dl.winehq.org/wine-builds/ubuntu bionic InRelease: As assinaturas a seguir não puderam ser verificadas devido à chave pública não estar disponível: NO_PUBKEY 76F1A20FF987672FThe repository 'https://dl.winehq.org/wine-builds/ubuntu bionic InRelease' is not signed.

Para resolver este erro, faça um acesso a sua pasta root (ou o lugar onde se encontra o arquivo winehq.key

Caso não saiba onde se encontra esse arquivo execute o comando a seguir:

# find / -name winehq.key
/root/winehq.key 

Uma vez tendo o local do arquivo remova ele de seu sistema: Atenção! Tenha muito cuidado ao usar este comando e tenha em mente que está digitando corretamente o comando.

# rm -rf  /root/winehq.key 

Devido a migração para compilações OBS ter sido concluída, a chave do repositório WineHQ foi alterada. Então os usuários do Debian e do Ubuntu que usam a chave antiga (release.key ou winehq.key), necessita baixar a nova (winehq.key) e adicioná-la ao sistema APT, ou você continuara a receber a mensagem de erro sobre a chave ausente.

Para baixar e instalar a nova chave:

# cd /root
# wget -nc https://dl.winehq.org/wine-builds/winehq.key
# sudo apt-key add winehq.key
ok
#

Recebendo o OK, execute:

# sudo apt update && apt upgrade && apt dist-upgrade

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