Arquivos
Google Speech + Python + Asterisk
Olá Povo que acompanha o blog
Ainda falando sobre reconhecimento da fala utilizando o google, enviei uma mensagem na lista AsteriskBrasil onde expressava minhas idéias de como utilizar o serviço de reconhecimento de fala do google em tempo real com o Asterisk, já se passou quase uma semana sem se quer um suspiro de interesse, então resolvi seguir sozinho !
A idéia é utilizar EAGI para controle do canal de entrada de áudio em conjunto com o File Descriptor, o Asterisk entrega o áudio em formato RAW diretamente no File Descriptor 3, então podemos utilizar esta informação da maneira que acharmos conveniente, para este caso a manipulação se torna muito prática, o que me desprende totalmente das APP’s prontas para gravações inseridas no Asterisk Ex. Record, nada melhor do que ser livre para voar, é claro várias análises se tornam possíveis com isso e o leque de aplicações possíveis se tornam infinitas.
Você certamente já pensou em ter um PABX com funcionalidade para reconhecimento da fala então certamente irá precisar partir para soluções cooporativas e caras certo???
A Partir de hoje não !
Tudo que irá precisar é ter internet para acessar o google o Script possue algumas dependencias:
https://github.com/ederwander/Asterisk-Google-Speech-Recognition/blob/master/README
Estou usando novamente o módulo audiolab para efetuar o encode do áudio em FLAC, caso exista alguma dificuldade para a instalação deste módulo poderei pensar em adaptar o código para uso externo do sox ou flac.
Como ele funciona?
- Atende uma ligação
- O usuário tem no máximo 10 segundos para efetuar a fala
- Caso nao encontre atividade de voz encerra com timeout
- Estratégia para atividade de voz verdadeira para os seguintes valores RMS > 15 e Pitch > 75
- Se atividade for encontrada o usuário poderá falar por no máximo 10 segundos
- O script verifica blocos em tempo real com amostras de 1 em 1 segundo e verifica se a fala cessou
- Caso sim o script interrompe a gravação automáticamente e envia o que foi gravado para o google
- Caso não o script continua o seu curso até seu máximo de 10 segundos
- Apos encontrada a resposta da fala no google o script seta a variável “GoogleUtterance”
Telas:
Source em:
https://github.com/ederwander/Asterisk-Google-Speech-Recognition
Sip Host is Alive ??
Olá Pessoal!
Hoje precisava saber se um determinado host SIP estava vivo, pensei como posso descobrir isso??
ping?
R: não, preciso saber se a porta SIP esta respondendo
Tentar conexão com o netcat na porta UDP 5060?
Então porque não enviar o inicio do método register para ver se pego algum retorno ..
Assim:
echo “REGISTER sip:vono.net.br SIP/2.0″ | netcat -u vono.net.br 5060
Retorno:
SIP/2.0 400 Invalid RequestURI
CSeq: 0 REGISTER
humm olha ae já consegui uma comunicação entre os lados, com isso já sei que ponta esta respondendo algo e consequentemente ela está viva…
Então porque não transformar isso em algo útil, acho que muitos precisam de algum tipo de check para saber se um provedor, servidor VOIP, está de pé, não apenas de pé como entendendo e respondendo requisições SIP na porta UDP 5060.
Desenvolvi um script bem simples que faz isso!
O script trabalha com 3 métodos de request (invite, Register, Options) se algum destes métodos responder é porque existe na outra ponta um servidor SIP rodando e funcionando na porta 5060!
Coloquei o script aqui:
http://josephlol.orgfree.com/ederwander/Sip_Alive_Test.pl
Fui
Eng Eder de Souza
Decodificar teclas de telefone via Microfone!!
Olá pessoal!
Já faz algum tempo que escrevi um pequeno script em python para decodificar teclas de telefone pressionadas via microfone ou via entrada de audio atraves de sua placa de som, o script nada mais faz do que capturar a entrada de audio do seu equipamento transformar o sinal de entrada em um vetor e aplicar o algoritmo de Goertzel no sinal capturado, o script ainda necessita de muitos filtros para captura de teclas em sequencia, principalmente no que se diz respeito a falsos positivos quando o mesmo é submetido em conjunto com muitos ruidos, audios, músicas de fundo, vozes de muitas pessoas em público, etc, etc…
Mesmo assim ele possui uma porcentagem de acerto consideravelmente boa!
Segue uma pequena amostra dele funcionando!
Fui
SMS Tim Free
Ae povao atualizei o script para envio grátis de SMS para operadora Tim Segue:
req = urllib2.Request(url)
req.add_header(‘Referer’, url)
f = urllib2.urlopen(req)
data = f.read()
f.close()
find = re.search(‘ss=(\d+)’, data)
codcaptcha = find.group(1)
s = base64.decodestring(‘aHR0cDovL3d3dy5zYnJvYm91cy5jb20vY2FwdGNoYS5waHA/c3M9′)
url = s + codcaptcha
req = urllib2.Request(url)
req.add_header(‘Referer’, url)
cj = ClientCookie.MozillaCookieJar()
opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
ClientCookie.install_opener(opener)
data = ClientCookie.urlopen(req).read()
cj.save(“infer”, ignore_discard=True, ignore_expires=True)
find = re.findall(‘>(\d+)<’, data)
captcha = find[0] + find[1]
cj = ClientCookie.MozillaCookieJar()
cj.load(“infer”, ignore_discard=True, ignore_expires=True)
opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
ClientCookie.install_opener(opener)
url = “http://www.sbrobous.com/ser_tim_sb.php”
req = urllib2.Request(url)
req.add_header(‘Referer’, url)
data = {‘ddd’: ddd, ‘rmsisdn’: NUM, ‘sms’: MSG, ‘nome’: NOME, ‘code’: captcha, ‘ss’: codcaptcha}
req.add_data(urllib.urlencode(data))
f = opener.open(req)
data = f.read()
if “sucesso” in data:
[]‘s
Sip Protocol Danger
Olá !!
Dia do SysAdmin então pq não falar de segurança !
Quem nunca se deparou com tentativas de ataque que atire a primeira pedra rsrs. No mundo da voz sobre IP a coisa não poderia ser diferente, meu Alerta vai para a comunidade Asterisk já faz alguns meses que resolvi colocar a prova como se comporta o protocolo SIP.
E o review que consegui foi alarmante, imagine você descobrir remotamente via porta SIP quais ramais existem em seu PBXIP e pior que isso ainda poder usar dicionários para chutar as senhas, pois bem isso é possóvel e grave..
Vamos aos meus testes:
-Configurar um Server Asterisk
-Criar ramais
-Deixar a porta 5060 (SIP) em listem para a internet
-Criar um script Perl para conectar na porta 5060 UDP e enviar o método de registro documentando pela arquitetura SIP e pegar o Retorno.
Detalhe conseguia saber os ramais existentes remotamente analisando a simples resposta do protocolo …
Testando ramais não existentes no Servidor Asterisk a resposta foi:
Retorno ‘SIP/2.0 404 Not found …..”
Segue tela do retorno
No Servidor que recebe o ataque em meus logs tenho
[Jul 30 18:50:08] NOTICE[2941] chan_sip.c: Registration from ‘sip:ramal@IP_server <sip:ramal@IP_server>’ failed for ‘Ip_remoto’ – No matching peer found
Owww já sei que este ramal nao existe no servidor entao resolvi colocar um existente e recebo na tela :
Retorno ‘SIP/2.0 100 Trying
Pronto temos um padrão retorno 100 ramal Existente retorno 404 ramal Inexistente.
Parece perigoso o pior de tudo isso é que apos isso vc pode passar via Socket tentativas de senha e verificar o retorno, novamente perigo eminente…
bom para quem quer testar seus servidores vou colocar o script aqui ..
#!/usr/bin/perl
use Socket;
sub envia {
$servidor_ip = shift;
$ramal = shift;
$sip_to = shift;
$sip_from = “asterisk”;
$tm = time();
$call_id = $tm . “msgto$sip_to”;
$httptime = `date -R`;
$MESG =
“REGISTER sip:$servidor_ip SIP/2.0
Via: SIP/2.0/UDP 127.0.0.1:60576;branch=z9hG4bK-d87543-061cb00346133471-1–d8754 3-;rport
Max-Forwards: 70
Contact: <sip:$ramal\@127.0.0.1:60576;rinstance=f0265fa8a56b482e>
To: sip:$ramal\@$servidor_ip <sip:$ramal\@$servidor_ip>
From: <sip:$ramal\@127.0.0.1>;tag=3f0fc020
Call-ID: c355bd6a0c2dda04MGY1MmU2YjE2MjY4ZTk1YjNiMWE4ZGQxYzdhZDU2MTA.
CSeq: 5 REGISTER
Expires: 3600
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INF O
User-Agent: X-Lite release 1002tx stamp 29712
Content-Length: 0
“;
$proto = getprotobyname(‘udp’);
socket( SOCKET, PF_INET, SOCK_DGRAM, $proto );
$iaddr = inet_aton(“$servidor_ip”);
$paddr = sockaddr_in( 5060, $iaddr );
bind( SOCKET, $paddr );
$port = 5060;
$hisiaddr = inet_aton($servidor_ip);
$hispaddr = sockaddr_in( $port, $hisiaddr );
print “Enviado\n”;
if ( send( SOCKET, $MESG, 0, $hispaddr ) ) {
print “envio para “, “$servidor_ip”, ” com sucesso”, “\n”;
my $ptime;
my $src = recv(SOCKET, $ptime, 128, 0);
print “\nRetorno ‘”, $ptime,”‘\n”;
}
else { print “envio”, “$servidor_ip”, ” falhou”, “\n”; }
}
envia(“IP_REMOTO_AQUI”, “RAMAL_REMOTO_AQUI”, “1005″);
exit;
[]‘s
Eng Eder de Souza
Portabilidade
Olá galera!
Seguinte ano passado postei um source em python para pegar a portabilidae de números Telefonicos via site consultanumero.abr.net.br, o tempo passou e o script parou de funcionar pois o sistema em jboss deles foi atualizado, o povo começou a mandar email pedindo ajuda e querendo de certa forma utilizar esse serviço de forma automatizada, resolvi perder 30 minutos e reescrever o source para o sistema Atual.
Lembrando que o método usa reconhecimento de caracteres para tentar quebrar o captcha, digamos que ele é pouco eficiente para uso amplo em produção, claro se alguem dispor de tempo pode treinar uma base de dados consistente para que ele funcione melhor.
tela dele funcionando:
O Poder do FreeSwitch
Ano passado descobri como o novo FreeSwtich é prático, simples e rasteiro, bem mais organizado que o Asterisk e o que é melhor forte como rocha!
Tarefas que antes eram complicadas de tratar foram simplificadas, Ura’s complexas podem ser feitas de maneira simples !
Em meus testes percebi o quando é fácil e agradável construir URAS com a linguagem LUA
Segue um Source na qual pode ser aplicado para qualquer finalidade:
–Estrutura
–URA que permite teclas de 1 a 5 “tres” tentativas em caso de teclas erradas (0, 6, 7, 8 ou 9) após isso hangup
–Digite 1 para falar com RH
–Digite 2 para falar com compras
–Digite 3 para falar com Diretoria
–Digite 4 para falar com Administração
–Digite 5 para falar com Eventos
–ou aguarde na linha para ser atendido
session:setAutoHangup(false)
digito = “Eng Eder de Souza”;
contador =0;
while (session:ready() == true) do
while ((digito >= “6″) or (digito <= “0″)) do
contador = contador + 1;
freeswitch.consoleLog(“info”, “contando as entradas = “.. contador ..”\n”);
if digito == “” then
freeswitch.consoleLog(“info”, “vc nao digitou nada “.. digito ..”\n”);
session:execute(“transfer”,”9000″);
break;
end
if contador == 3 then
session:hangup();
break;
end
digito = session:playAndGetDigits(1, 1, 1, 10000, “#”, “/usr/local/freeswitch/sounds/URA_INICIO.wav”, “”, “\\d+”);
end
if (digito == “5″) then
freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
session:execute(“transfer”,”9000″);
end
if (digito == “4″) then
freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
session:execute(“transfer”,”4444″);
end
if (digito == “3″) then
freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
session:execute(“transfer”,”3333″);
end
if (digito == “2″) then
freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
session:execute(“transfer”,”2222″);
end
if (digito == “1″) then
freeswitch.consoleLog(“info”, “tecla digitada: “.. digito ..”\n”);
session:execute(“transfer”,”1111″);
end
end
AGI Portabilidade para números móveis em Asterisk
Postei estes dias um source em python para descobrir a portabilidade de números móveis na comunidade Asterisk e meu email começou a lotar sobre perguntas de como construir um AGI para rotear as chamadas por um gateway GSM etc etc.
Cada um tem um cenário diferente do outro vou postar a essencia do Script em Perl + Agi para descobrir para qual operadora um número móvel pertence a partir disso é simples, mas se precisarem de ajuda para algo estamos ae …
Já tem nego me Perguntado pq nao fez em Python o AGI??
R: Acordei com vontade de fazer em perl …
Script Perl
#!/usr/bin/perl -w
use Asterisk::AGI;
use WWW::Mechanize;
use MIME::Base64;
my $AGI = new Asterisk::AGI;
my %input = $AGI->ReadParse();
my @operadoras = (“Eder”, “Claro”, “Tim”, “Vivo”, “Telemig”, “Oi”, “Nextel”, “Brasil telecom”, “Sercomtel”, “CTBC”);
my $num_saida = $AGI->get_variable(‘EXTEN’);
$num_saida = substr($num_saida,3,10);
$m = WWW::Mechanize->new();
my $data = decode_base64(‘aHR0cDovL3dlYnNlcnZpY2VzLnR3d3dpcmVsZXNzLmNvbS5ici9yZWx1emNhcC93c3JlbHV6Y2FwL’ . ‘mFzbXg=’);
$m->add_header(Referer => $data);
my $s = $data . “/VerOperadora?celular=55″ . $num_saida;
$m->get($s);
$c = $m->content;
$c =~ m/>(\d+)</;
$AGI->exec(“NoOp”,”$num_saida”);
$AGI->exec(“NoOp”,”$operadoras[$1]“);
# O codigo se adapta conforme o cenario de cada um, mudar o DIAL para rotear a saida da operadora em questao
####$AGI->exec(“Dial”,”SIP/MUDE AQUI PARA SUA SAIDA SIP ou GSM ou ZAP ou DAHDI ou UNICALL ou DVG etc etc|10″);
# FIM
Extensions.conf
minha linha para a chamada do AGI de testes
exten => _999.,1,agi,pega.pl
ou seja só discar no seu telefoneIP ou sftphone “999+num_do_celular”
Tela:
Fui
Eng Eder de Souza
Portabilidade DBO Operadoras de Celulares
Salve a todos ano novo ta chegando resolvi postar mais um source para descobrir a portabilidade somente para números móveis, funciona que é uma beleza bem rápido por sinal, para um AGI funciona perfeitamente, logo postarei uma outra versão mais robusta, neste novo ano espero ter mais tempo
.
Source bem enxutinho em python :
import urllib2
import urllib
import re
import sys
def getop(ddd,NUM):
url = “http://www.sbrobous.com/operadora.php“
req = urllib2.Request(url)
req.add_header(‘Referer’, ‘http://www.sbrobous.com/operadora.php’)
data = {‘ddd’: ddd, ‘numero’: NUM, ‘a’: ‘enviar’}
req.add_data(urllib.urlencode(data))
f = urllib2.urlopen(req)
data = f.read()
f.close()
if “<b>” in data:
data = data.replace(‘</b>’,”)
find = re.search(‘<b>(.*)’, data)
operadora = find.group(1)
print operadora
tel=sys.argv[1]
ddd = tel[:2]
NUM = tel[2:10]
getop(ddd,NUM)
Incrivel como python reduz as linhas de programação !!!
Segue uma tela:
[]‘s
Eng Eder de Souza
Portabilidade + DBO + Descobrir Operadoras
Já faz um bom tempo que tento rotear chamadas de acordo com a operadora na qual o número discado pertence, as rotas ficaram uma bagunça com a chegada da portabilidade, como não tenho dinheiro para pagar um DBO tentei improvisar.
O Script feito em Python ainda falha algumas vezes, mas já é um começo o correto seria treinar o banco de dados do gocr para capturar o captcha com mais precisão mas nao estou tendo tempo de brincar com isso…
# -*- coding: iso-8859-1 -*-
#Eder de Souza 23/11/2009
import re
import ClientCookie
import commands
import sys
import os
import re
inc = 0
MaxTentativas = 15
tel=sys.argv[1]
while inc < MaxTentativas:
inc = inc + 1
cj = ClientCookie.MozillaCookieJar()
opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
ClientCookie.install_opener(opener)
r = ClientCookie.urlopen(“http://consultanumero.abr.net.br:8080/consultanumero/jCaptcha.do?metodo=carregar“)
fp = open(‘Captcha.jpg’,'w’)
fp.write(r.read())
fp.close()
cj.save(“infer”, ignore_discard=True, ignore_expires=True)
commands.getoutput(‘convert Captcha.jpg Captcha.png’)
commands.getoutput(‘pngtopnm Captcha.png > Captcha.pnm’)
commands.getoutput(‘ppmchange -remainder black -closeness 20 rgbi:.91/.8/.58 white rgbi:.8/.8/.91 white rgbi:.69/.91/.91 white Captcha.pnm > Captcha_End.pnm’)
captcha = commands.getoutput(‘gocr -C a-zA-Z0-9 -m 2 -a 90 -d 2 Captcha_End.pnm’)
rmspace = captcha.replace(‘ ‘, ”)
rmreturn = rmspace.replace(‘\n’, ”)
rmunderline = rmreturn.replace(‘_’,”)
res = re.search(‘([a-zA-Z0-9]+)’, rmunderline)
result = res.group(1)
cj = ClientCookie.MozillaCookieJar()
cj.load(“infer”, ignore_discard=True, ignore_expires=True)
opener = ClientCookie.build_opener(ClientCookie.HTTPCookieProcessor(cj))
ClientCookie.install_opener(opener)
pagina = opener.open(‘http://consultanumero.abr.net.br:8080/consultanumero/consultarTnSemLogin.do?tn=’+tel+’&captcha=’+result+’&metodo=consultar’).read()
if “Nome da prestadora” in pagina:
pagina = pagina.replace(‘<br>’,”)
find = re.search(‘Nome da prestadora: (.*)’, pagina)
operadora = find.group(1)
print operadora
sys.exit()
segue uma tela dele funcionando:
Até mais
Eder







