sábado, 22 de junho de 2013

Voice translation-rules e Voice translation-profiles

Inicio o post pedindo desculpas pelo longo período sem atualizações. Uma combinação de trabalho, férias e preguiça fizeram com que eu deixasse o Blog de lado por alguns meses. Durante esse tempo, algumas coisas importantes aconteceram... a Cisco anunciou o CCIE Collaborations e a descontinuidade do CCIE Voice. Houve uma manifestação na Internet, e a Cisco mudou o track, permitindo que os atuais CCIEs Voice virassem CCIE Collab com apenas uma prova escrita. Menos mal!
E outra coisa bacana foi a parceria formada com o blog AVVID.net, liderado pelo Leonardo Nunes, mas que conta também com a colaboração de outros profissionais da área, como o Guilherme Villarinho, Elvis Araújo, Leonardo Santana, Ligia Vidal, Rafael Souza, Leonardo Silva e Paulo Souza. Um excelente blog para quem busca conhecimentos diversos na área de UC, e o mais importante, em Portugues! É ótimo ver o pessoal compartilhando conhecimento na nossa língua. Valeu pessoal!!!

Bom, voltando agora ao assunto do post, estava pensando em algo para escrever, que fosse um conhecimento extremamente necessário a qualquer candidato ao CCIE Voice. E o assunto que me veio na cabeça foi o das voice translation-rules e voice translation-profiles no gateway. Sim, é um tema relativamente simples, mas é fundamental que você domine isso por um simples motivo: procure fazer todas (TODAS!) as manipulações de dígitos possíveis no router quando o gateway for H.323. O motivo disso é que provavelmente você vai querer que todas as chamadas continuem funcionando em SRST, certo? Isso vai te poupar muito trabalho. Se o gateway for MGCP, aí whatever...
E essa ideia também é aplicável na vida real pelo mesmo motivo. Imagine que você fez uma Route Pattern no Call Manager para chamadas DDD, e essa Route Pattern inclui o código de operadora antes de mandar para o Gateway. Quando o site entrar em SRST, essa manipulação de dígito não vai existir, e as suas chamadas vão falhar.

Para começarmos a criar as nossas regras, é preciso lembrar que toda chamada tem uma call-leg de entrada e uma call-leg de saída no Voice Gateway, que são configuradas através das Dial-Peers. Podemos aplicar as manipulações de dígito em qualquer um dos sentidos, ou seja, nas dial-peers de entrada ou nas dial-peers de saída. E dentre as manipulações possíveis, podemos mudar o número de origem e o número de destino (ok, podemos mudar também o redirect, mas para esse post, focado mais em Call Routing, vamos desconsiderar isso). Com isso, temos as seguintes manipulações possíveis:
- Mudar a origem (ANI) em uma dial-peer de entrada
- Mudar o destino (DNIS) em uma dial-peer de entrada
- Mudar a origem (ANI) em uma dial-peer de saída
- Mudar o destino (DNIS) em uma dial-peer de saída

Vale lembrar que para ver se uma chamada é entrante ou sainte no gateway, coloque-se no lugar do roteador:



Por isso, é extremamente importante que você tenha claro nas suas configurações quem é a dial-peer de entrada e quem é da dial-peer de saída de cada chamada. Para exemplificar, vou criar as seguintes dial-peers:

dial-peer voice 1 voip
 description *** Dial-Peer de Entrada VOIP de chamadas vindas do CUCM ***
 incoming called-number .
 codec g711ulaw

dial-peer voice 2 voip
 description *** Dial-Peer de Saída VOIP para o CUCM ***
 destination-pattern 2...
 session-target ipv4:10.1.1.10
 codec g711ulaw
 no vad

dial-peer voice 3 pots
 description *** Dial-Peer de Entrada POTS de chamadas vindas da PSTN ***
 incoming called-number .
 direct-inward-dial

dial-peer voice 4 pots
 description *** Dial-Peer de Saída POTS para a PSTN (Emergencia) ***
 destination-pattern 0[1][9].
 port 0/0/0:15

dial-peer voice 5 pots
 description *** Dial-Peer de Saída POTS para a PSTN (Local) ***
 destination-pattern 0[2-9].......
 port 0/0/0:15

Eu poderia ter juntado a dial-peer 1 e 2 em uma só, de repente. Mas para fins de demonstração, deixarei separado para explicitar melhor o raciocínio. E as dial-peers de saída POTS costumam ser mais do que essas (chamadas de emergência, local, DDD, DDI, 0X00, etc), mas no exemplo deixaremos apenas essas duas: emergência e local.

Ok, agora vamos começar a pensar nas manipulações de dígito! Eeee! \o/

1. Call-Leg de Entrada VOIP
Começaremos pelo lado VOIP, ou seja, nas call legs que fazem a comunicação com o CUCM. Na entrada é quando um IP Phone faz uma chamada para a PSTN, certo? O CUCM manda os dígitos para o gateway, e por isso é Entrante no gateway. O que poderíamos mudar aqui?
Vamos pensar em um caso. O ramal 2000 fez uma chamada para 0190 (polícia).
ANI: 2000
DNIS: 0190


Faz sentido mudarmos o ANI aqui? Bom, até poderíamos de repente transformar o número do ramal 2000 para um formato globalizado, como 551123232000... Porém, é melhor fazermos isso antes de mandar para a PSTN, nas dial-peers de saída POTS, pois isso nos permitiria maior controle... Se aplicarmos uma translation aqui na entrada VOIP, ela vai valer para todas as chamadas que entrarem no gateway pelo CUCM. E se por acaso tivermos que modificar o ANI para 23232000 em chamadas locais e 1123232000 em chamadas de emergência? Por isso é melhor deixarmos para fazer na saída. Além disso, se fizermos aqui no lado VOIP, a regra não vai funcionar em SRST, porque a chamada não vai estar vindo do CUCM. Então não vamos mexer nada aqui.

Faz sentido mudarmos o DNIS? Também não, né? Para quê vou querer mudar o 0190 aqui? Posso deixar para fazer isso também na dial-peer de saída POTS, se tiver necessidade, onde eu tenho maior controle. Senão, de novo, as alterações surtiriam efeito para qualquer chamada que entrasse no Gateway vindas do CUCM, independente de ser de emergência, local, ou qualquer outra.

Ou seja, nada para se manipular aqui. :(

2. Call-Leg de Saída VOIP
A saída VOIP é quando a PSTN faz uma chamada entrante para um IP Phone. A PSTN manda os dígitos para o gateway, e o gateway envia para o CUCM, por isso é Sainte no lado VOIP.
Por exemplo, o número da PSTN (11) 2255-4000 faz uma chamada para o nosso ramal 2000, e a operadora manda:
ANI: 1122554000
DNIS: 2000

Faz sentido mudarmos alguma coisa aqui?

Primeiro o ANI. Vamos supor que eu não quero que o número de origem apareça como 1122554000. Eu quero que fique 022554000, para que o usuário possa dar um "Dial" direto da lista de chamadas perdidas e recebidas. Ok, tem maneiras mais elegantes de se fazer isso, mas é um caso onde poderíamos querer mudar o ANI. Na verdade, o mais lógico seria até configurar essa tradução na entrada POTS, porque aqui sim queremos que tenha efeito para qualquer chamada entrante vinda da PSTN. Mas tudo bem, é só um exemplo.

Agora o DNIS. Primeiro que a minha dial-peer está com o destination-pattern 2..., então se a operadora mandar algo diferente disso, a chamada vai dar match. Mas imagine que no Call Manager, o ramal está configurado no formato 23232XXX. Então uma das formas de isso funcionar, é fazer com que o Gateway mande nesse formato para o CUCM, e aí precisaríamos de uma translation, mudando de 2XXX para 23232XXX. Mas pense bem... se eu fizer isso, o SRST não vai funcionar para receber chamadas da PSTN, porque o telefone vai se registrar no Gateway com o ramal 23232XXX. E como colocamos a translation na saída VOIP, ela não será ativada, já que o gateway não vai mandar a chamada para o CUCM estando em SRST, certo? Por isso, esse tipo de translation também seria mais interessante de se fazer na entrada POTS, que teria efeito independente de o site estar ou não em SRST. Mas qual o problema de fazer isso? É que mudando na entrada POTS, o DNIS passa a ser 23232XXX, e não daría match na nossa dial-peer de saída VOIP. Olha que confusão... então para isso, teríamos que mudar o destination-pattern da dial-peer de saída VOIP para 23232... Acompanhou o raciocínio? Sugiro pegar um papel e caneta e tentar desenhar. Para não complicar muito, consideremos que o ramal é 2XXX mesmo.

Então não faremos a manipulação do DNIS. Aqui vamos mudar apenas o ANI de 1122554000 para 022554000. Peraí que já vamos configurar tudo isso!

3. Call-Leg de Entrada POTS
A entrada POTS é quando a PSTN faz uma chamada entrante para um IP Phone, mas dessa vez estamos vendo a call-leg do lado da PSTN.
Vamos usar o mesmo exemplo de cima:
ANI: 1122554000
DNIS: 23232000


Podemos mudar o ANI? Opa, poderíamos sim... mas a gente já decidiu que vai fazer isso na call-leg de saída VOIP, né? Então deixa assim... Eu particularmente faria essa translation aqui, mas vamos seguir com o exemplo.

E o DNIS? Aqui sim... Veja que a PSTN está mandando 23232000, sendo que a nossa dial-peer para o CUCM é 2..., e os nossos ramais no CUCM estão configurados como 2XXX. Logo quando a chamada entrar no roteador, eu quero que ele mude de 23232000 para 2000. Assim, é o DNIS 2000 que vai dar match com a call-leg de saída VOIP, que tem o destination-pattern 2... Faz sentido? Pelo fluxo da chamada, primeiro ela vai dar match nessa dial-peer 3 (entrada POTS), que vai transformar o DNIS 23232000 para 2000, e só então ela vai dar match na dial-peer 2 (saída VOIP), com o DNIS 2000.

Ou seja, aqui vamos mudar o DNIS de 23232000 para 2000.

4. Call-Leg de Saída POTS
A saída POTS é quando um IP Phone faz uma chamada para a PSTN, porém na call-leg da PSTN. O CUCM manda os dígitos para o gateway, e o gateway manda para a PSTN, por isso é sainte no lado POTS. Usando o exemplo acima:
ANI: 2000
DNIS: 0190



O que podemos mudar aqui? Hmmm, aqui podemos mudar as duas coisas. Podemos mudar o ANI, transformando ele por exemplo de 2000 para 23232000. E podemos mudar o DNIS, marcando o plan e type da chamada. Opa, isso é novo, né? Sim, e específico para o CCIE, porque no Brasil não usamos isso... na prova eles te pedem para marcar duas flags do ISDN chamadas Plan e Type. O Plan é sempre ISDN ou Unknown, e o Type pode ser Unknown, Subscribe (para chamadas locais), National (para DDD) ou International (para DDI). Você pode marcar esses campos na Route Pattern ou Route List, mas de novo... faça a marcação sempre no Gateway quando for H.323, pelo mesmo motivo do SRST... esse é um motivo clássico que as pessoas perdem ponto em High Availability! Na parte de call routing eles te pedem uma marcação específica, mas aí quando o seu site entra em SRST, as chamadas todas funcionam, porém não saem marcadas de acordo, porque o cara configurou tudo no Call Manager. Cuidado!
Bom, então aqui vamos mudar o ANI de 2000 para 23232000. E no DNIS, vamos marcar as chamada de emergência com Plan ISDN e Type Unknown, e chamadas locais com Plan ISDN e Type Subscribe.

5. Montando as expressões regulares
Finalmente entramos na parte mais interessante, que é a configuração. A ideia é primeiro criar uma voice translation-rule, onde especificaremos as regras usando expressões regulares. E depois aplicaremos essas regras a translation-profiles. E por fim, aplicaremos os translation-profiles nas dial-peers.
A parte mais complicada aqui são as regras. Existem várias expressões regulares que você pode usar... mas vamos simplificar as coisas, né? Vamos usar apenas algumas, que podem parecer complicadas a primeira vista, mas se você entender, conseguirá fazer qualquer manipulação...
As regras são:

^: começa com
$: fim da string
( ): definição de um grupo de caracteres
\: caractere de escape
.: um dígito
/: início e fim de uma expressão
.*: um dígito qualquer seguido de 0 ou mais ocorrências. Ou seja, "qualquer coisa".

Ok, vamos usar o seguinte exemplo. Eu quero transformar 44445555 em 55554444123. Uma transformação realmente sem pé nem cabeça, mas que vai nos ajudar a entender. Vamos construir a expressão regular aos poucos, passo a passo.

Primeiro, vou criar 2 expressões:
// //
O primeiro // é no que eu vou dar o match, e o segundo // é no que eu quero transformar. Lembrando que cada / é o início e fim de uma expressão. Ou seja, todo o resto vou ter que colocar dentro dos /.

Ok, agora vamos começar com o primeiro //, onde eu vou dar o match na string que eu quero transformar. Poderíamos fazer algo como /44445555/, certo? Vai dar match... Mas a string 99944445555 também daria match. Então vamos dar uma melhorada nisso:
/^44445555$/
Hmmm, ficou melhor... agora só quando começar com 44445555 e acabar nisso que vai dar match. 99944445555 não vai mais, porque não começa com 4, e 44445555999 também não vai dar, porque temos o delimitador de fim de string $ lá na regra. Ok, mas o nosso objetivo é inverter o 5555 com 4444 e depois colocar um 123 no final, certo? Então podemos juntar o 4444 em um grupo e o 5555 em outro grupo, assim:
/^(4444)(5555)$/
Ta ficando bom... mas tem um problema. O ( e o ) são caracteres especiais, e precisamos dizer para a fórmula interpretá-los para terem o sentido de delimitadores de um grupo. Para fazer isso, colocamos o caractere de escape \. Dica: Sempre coloque \ antes de ( ou ), aí não tem erro:
/^\(4444\)\(5555\)$/
Vamos colocar uma mudança aqui nos requisitos. Ao invés de ser só 44445555, digamos que a gente queira transformar qualquer número no formato 4XXX5XXX para 5XXX4XXX123. Simples:
/^\(4...\)\(5...\)$/
Veja que separamos a string em dois grupos, o 4XXX e o 5XXX. Chamaremos respectivamente de grupo 1 e grupo 2.

Agora vamos pensar no segundo //, que é no que eu quero transformar.
Eu quero então pegar a string que eu dei match, e inverter o grupo 1 com o grupo 2, e depois colocar 123 no final, certo? Olha que legal, se eu fizer \1, eu referencio o grupo 1, e se eu fizer \2, eu referencio o grupo 2. Então fica fácil:
/\2\1/
Com isso, eu transformei a string inicial em 55554444, ou seja, coloquei o grupo 2, e depois o grupo 1. Agora é só colocar 123 no final:
/\2\1123/
Então a nossa regra final ficou assim:
/^\(4...\)\(5...\)$/ /\2\1123/

6. Configurando o exemplo
Finalmente vamos por a mão na massa e configurar o nosso exemplo.

Na Call-Leg de Entrada VOIP, nada a se fazer.

Na Call-Leg de Saída VOIP, vamos mudar o ANI (calling number) de 1122554000 para 022554000:

voice translation-rule 1
 rule 1 /^11\(........\)$/ /0\1/

voice translation-profile ANI
 translate calling 1

dial-peer voice 2 voip
 description *** Dial-Peer de Saída VOIP para o CUCM ***
 destination-pattern 2...
 session-target ipv4:10.1.1.10
 codec g711ulaw
 no vad
 translation-profile outgoing ANI

Ok, aqui cabe uma explicação
Primeiro eu criei a regra, você pode ter até 15 regras dentro de um translation-rule. Note que eu peguei a parte que me interessa da String e coloquei em um grupo (Grupo 1). E na manipulação eu apenas coloquei um 0 e concatenei com o grupo 1. Com a regra criada, eu crio um translation-profile, que pode ter qualquer nome, mas sugiro colocar um intuitivo. No profile eu digo qual rule vou usar, e especifico se ele vai manipular o calling ou o called number.
E por fim, chamo o profile na dial-peer, especificando se o sentido da regra é incoming (entrada) ou outgoing (saída). Cuidado que a IOS deixa você colocar qualquer coisa no nome do profile... e é case-sensitive. Ou seja, se você criar um profile chamado ANI, e na dial-peer você chamar o profile ani, não vai dar erro na IOS, mas não vai funcionar.

Na Call-Leg de Entrada POTS, vamos mudar o DNIS (called number) de 23232000 para 2000.

voice translation-rule 2
 rule 1 /.*\(....\)/ /\1/

voice translation-profile DNIS
 translate called 2

dial-peer voice 3 pots
 description *** Dial-Peer de Entrada POTS de chamadas vindas da PSTN ***
 incoming called-number .
 direct-inward-dial
 translation-profile incoming DNIS

Decore essa regra! Eu poderia ter criado uma assim /^2323\(....\)$/ /\1/, certo? Mas não preciso ser tão específico... com certeza você vai usar essa regra na prova e na vida, então simplifique. Não interessa o 2323, o que você quer é pegar qualquer string, e arrancar os últimos 4 dígitos dela. Essa regra é bem genérica, e você pode usar independente do dial-plan. O que essa regra faz é justamente isso, pegar os 4 últimos dígitos de qualquer string.

E finalmente, na Call-Leg de Saída POTS, vamos mudar o ANI (calling number) de 2000 para 23232000, e vamos marcar as chamada de emergência com Plan ISDN e Type Unknown (called number), e as chamadas locais com Plan ISDN e Type Subscribe.

voice translation-rule 3
 rule 1 /^\(2...\)$/ /2323\1/

voice translation-rule 4
 rule 1 // // type any unknown plan any isdn

voice translation-rule 5
 rule 1 // // type any subscribe plan any isdn

voice translation-profile OutPSTN-Emergencia
 translate calling 3
 translate called 4

voice translation-profile OutPSTN-Local
 translate calling 3
 translate called 5

dial-peer voice 4 pots
 description *** Dial-Peer de Saída POTS para a PSTN ***
 destination-pattern 0[1][9].
 port 0/0/0:15
 translation-profile outgoing OutPSTN-Emergencia

dial-peer voice 5 pots
 description *** Dial-Peer de Saída POTS para a PSTN ***
 destination-pattern 0[2-9].......
 port 0/0/0:15
 translation-profile outgoing OutPSTN-Local

Esse profile manipulou tanto o calling como o called. Veja que no called, não houve alteração nos dígitos, fizemos apenas a marcação do ISDN.

7. Verificações
O melhor jeito de verificar se as suas regras estão certas, é através do comando test voice translation-rule. É só colocar a string de dígitos, que a IOS vai te mostrar como que vai ficar ele traduzido, por exemplo:

router#test voice translation-rule 3 2000
Matched with rule 1
Original number: 2000    Translated number: 23232000
 
E também tem o debug voice translation-rule, para ver se as suas traduções estão certas em tempo real.


8. Dica para a prova
Se você entendeu tudo isso, pratique. Pratique muito, muito, muito!!! Use o test voice translation-rule e fique brincando, testando seus conhecimentos, inventando exemplos malucos.
E outra dica que eu dou, agora mais para a prova mesmo, é sempre criar um profile para cada dial-peer POTS. Mesmo que você nem use, deixe criado... Por exemplo

voice translation-rule 1
 rule 1 // //
voice translation-rule 11
 rule 1 // //
voice translation-profile 1
 translate calling 1
 translate called 11
dial-peer voice 1 pots
 translation-profile outgoing 1

Crie esse template no notepad, e faça todas as dial-peer seguindo ele. Conforme você vai lendo a seção de Call Routing, vá preenchendo as regras... tudo no notepad mesmo! Veja que tem uma regra para calling e outra para called... então é só ir preenchendo. E nem precisa dar nome bonito para os profiles não. Deixe o nome dele como sendo o mesmo que a tag da dial-peer correspondente. Dessa forma, você vai terminar a parte de Call Routing no gateway em alguns poucos minutos... e depois para arrumar alguma coisa é facinho, porque se você mexer em uma regra, é certeza que só está alterando aquela dial-peer. Enfim, fica a dica! :)

8 comentários:

  1. Otimo post Bruno! Ficou bem didático.

    Abs
    Alan

    ResponderExcluir
    Respostas
    1. Valeu Alan! :)
      Acho que foi um dos mais difíceis de escrever! hahaha

      Excluir
  2. Bruno, sobre essa parte:
    "Primeiro o ANI. Vamos supor que eu não quero que o número de origem apareça como 1122554000. Eu quero que fique 022554000, para que o usuário possa dar um "Dial" direto da lista de chamadas perdidas e recebidas. Ok, tem maneiras mais elegantes de se fazer isso, mas é um caso onde poderíamos querer mudar o ANI."

    Qual outra sugestão você tem para esse mesmo cenário? Estou pensando em implantar isso aqui e como você disse que existe uma maneira mais elegante de o fazer, gostaria de saber.

    Obrigado.

    ResponderExcluir
  3. Opa, a forma mais elegante seria usando Transformation Patterns (http://ccievoicebrasil.blogspot.com.br/2013/07/translation-pattern-ou-transformation.html). Basicamente, você criaria Calling Party Transformation Patterns e aplicaria no inbound do Gateway/Trunk no CUCM. Veja os meus posts sobre isso que eu falo exatamente sobe esse exemplo. :)
    Ou, mais elegante ainda, seria usar o ISDN Type da chamada. Também comento sobre isso nesse link acima.
    Abraços!

    ResponderExcluir
    Respostas
    1. Hmmm, vou dar uma lida novamente na parte do transformation, ainda não entendi 100%.

      Excluir
  4. Meu cenário é igual porém uso asterisk no lugar do CUCM depois um gw cisco, bom post!

    ResponderExcluir