O artigo irá falar sobre o PBX gratuito 
Askozia versão 6 . Ao desenvolver uma central telefônica, uma das primeiras tarefas foi a organização das chamadas realizadas.
Como foi
Na versão antiga do Askozia, modelos padrão de "plano de discagem" 
foram usados.
- X! - todos os números de telefone
- XXX - números de três dígitos
- .! - absolutamente todos os números de telefone
Um exemplo de contexto pode ser descrito esquematicamente:
[outgoing] exten => _XXXXXX!,1,NoOp(Start outgoing calling...) same => n,Dial… 
Pareceu-nos que essa abordagem não é suficientemente flexível. Não há como descrever a seguinte regra:
- O número começa em 79
- Segue 35 ou 26
- O restante do número tem 7 dígitos
Sob o corte, nossa abordagem e o resultado do desenvolvimento são descritos. 
Implementação atual
Decidimos implementar essa funcionalidade de maneira diferente, usando 
REGEX .
Exemplo de modelo:
 79(25|26)[1-9]{7} 
- (25 | 26) é 25 ou 26
- [0-9] - um dígito de 0 a 9, ocorrência da 1ª ou mais vezes
- {7} - número de ocorrências do caractere anterior
A sintaxe para a função REGEX é:
 REGEX("regular expression" string) Return '1' on regular expression match or '0' otherwise 
Um exemplo de uso no Askozia 6:
 [outgoing] exten => _X!,1,NoOp(Start outgoing calling...) same => n,Ringing() same => n,ExecIf($["${REGEX("^[0-9]{6}$" ${EXTEN})}" == "1"]?Gosub(SIP-PR-1-out,${EXTEN},1)) same => n,ExecIf($["${REGEX("^(7|8)[0-9]{10}$" ${EXTEN})}" == "1"]?Gosub(SIP-PR-2-out,${EXTEN},1)) same => n,Hangup() 
Para chamadas de saída, um ponto de entrada é organizado - o contexto "de 
saída ", a função " 
ExecIf " é chamada:
 ExecIf($["${REGEX("^[0-9]{6}$" ${EXTEN})}" == "1"] 
Se o número de telefone especificado na variável “ 
$ {EXTEN} ” corresponder ao padrão, a chamada será roteada para o 
sub-contexto usando a função “ 
Gosub ”.
Se a chamada não foi interrompida no 
sub-contexto , o aparelho seguirá a regra apropriada a seguir.
Dessa maneira, resolvemos o problema com linhas de canal único. Se a linha estiver ocupada, a chamada passará pela próxima até que seja atendida.
Exemplos de contexto:
 [SIP-PR-1] exten => _X!,1,ExecIf($["${number}x" == "x"]?Hangup()) same => n,Dial(SIP/PR-1/${EXTEN},600,TeK)) same => n,ExecIf($["${DIALSTATUS}" = "ANSWER"]?Hangup()) same => n,return [SIP-PR-2] exten => _X!,1,ExecIf($["${number}x" == "x"]?Hangup()) same => n,Dial(SIP/PR-2/${EXTEN},600,TeK)) same => n,ExecIf($["${DIALSTATUS}" = "ANSWER"]?Hangup()) same => n,return 
Obrigatório em " 
sub " - o contexto verifica " 
DIALSTATUS ". Se a chamada for atendida, depois da conversa o canal será encerrado usando a função “ 
Hangup () ”. Se isso não for feito, no final da chamada pelo cliente, poderá ocorrer uma nova discagem do número do cliente.
Uma sutileza importante, ao usar “ 
Gosub ” ou “ 
Goto ”, intencionalmente 
não alteramos $ {EXTEN} . Mesmo se você precisar modificar o número de telefone (adicionar / remover prefixo).
O fato é que, quando 
EXTEN é modificado, o Asterisk modifica o valor da variável 
CDR (dst) , o que levará a um resultado mal previsto na tabela de histórico de chamadas do CDR. Eu acho que é importante na história manter o número discado por um funcionário.
Tenha cuidado ao descrever uma expressão regular. Use os caracteres “ 
^ ”, o início da linha e “ 
$ ” - o final da linha, caso contrário, você poderá obter resultados inesperados.
Por exemplo, o padrão “ 
[0-9] {6} ” corresponderá a todos os números em que houver 6 ou mais dígitos. O padrão “ 
^ [0-9] {6} $ ” corresponde apenas a números de 6 dígitos.
Sumário
Temos um subsistema flexível para descrever o roteamento de saída para o PBX.
A lista de regras é exibida da seguinte maneira:

Um exemplo de um cartão "Regras" específico:
