Arquivo

Archive for the ‘Telecom’ Category

Google Speech + Python + Asterisk

janeiro 16, 2012 82 comentários

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 ??

agosto 2, 2011 3 comentários

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!

tela:

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

Categorias:Programação, Telecom

Decodificar teclas de telefone via Microfone!!

setembro 25, 2010 2 comentários

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

Categorias:DSP, Programação, Telecom

SMS Tim Free

agosto 25, 2010 3 comentários

Ae povao atualizei o script para envio grátis de SMS para operadora Tim Segue:

#Eng Eder de Souza
#data 25/08/2010
# -*- coding: iso-8859-1 -*-
import base64
import ClientCookie
import urllib2
import urllib
import re
import sys
import os
NOME = “Eder”
MSG = “teste de envio”
def sendsms(ddd,NUM):
url = “http://www.sbrobous.com/pan_tim_sb.php”
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&#8221;
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:
print “SMS Enviado com Sucesso”
else:
print “Problemas no Envio”
tel=sys.argv[1]
ddd = tel[:2]
NUM = tel[2:10]
sendsms(ddd,NUM)



[]’s

Eng Eder de Souza
Categorias:Programação, Telecom

Sip Protocol Danger

julho 30, 2010 3 comentários

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

maio 26, 2010 58 comentários

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:

Leia mais…

Categorias:Programação, Telecom

O Poder do FreeSwitch

fevereiro 11, 2010 2 comentários

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

janeiro 15, 2010 74 comentários

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:

UPDATE:

12/03/2014

É incrível a quantidade de emails que recebo pedindo para encontrar meios de mostrar números portados, hoje eu tive um tempinho e escrevi um novo código, se olharem no código vão perceber que eu inclui um proxy para enviar as requisições, o site é bem “esperto” e bloqueia todo o range de IP de sua rede pública se ocorrer muitos requests, (descobri isso  da pior maneira enquanto debugava o site), então vocês podem criar uma lista randômica com vários IPs que tenham proxy aberto para enviar as solicitações, código em https://gist.github.com/ederwander/9512693 !

Fui

Eng Eder de Souza

Portabilidade DBO Operadoras de Celulares

dezembro 30, 2009 1 comentário

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&#8217;)
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

novembro 26, 2009 7 comentários

Olá Povo !!

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&#8217;).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

Monitor Realtime + Asterisk

novembro 6, 2009 11 comentários

Bom só quem brincou com AMI no Asterisk sabe como é complicado, Eventos jogados na tela nada parece ter sentido uma avalanche de informações sem padrões definidos, construir aplicações genéricas se torna uma missão. 

Eu iniciei a pouco mais de dois anos um projeto monitor em Realtime a principio era para monitoramento só para verificar quem estava fazendo ou recebendo ligações, pensei “Moleza Delphi + Socket + AMI”. 

Dores e mais dores de cabeça na época tinha um link R2 com uma placa da digium rodando com o Unicall para quem tinha placa E1 Digium era a única saida de conversar com a sinalização R2. Então olhando o retorno do AMI iniciei um esboço de como pegar o retorno no buffer do meu Socket em Delphi 6.0 e montar algo bonitinho para usuários ficarem vendo tudo que acontece de atividade no canal Unicall do Asterisk !! 

Então vamos ver o que um core show channels verbose nos retorna !! 

Channel              Context              Extension        Prio State   Application  Data                      CallerID        Duration Accountcode BridgedTo
UniCall/16-1         default              1579                1 Up      Bridged Call SIP/6007-00f839c0         80151333623971                       SIP/6007-00f839c0
SIP/6007-00f839c0    default              80151333623971     22 Up      Dial         Unicall/g1/0151333623971  6007            00:02:40             UniCall/16-1
UniCall/14-1         default              1599                1 Up      Bridged Call SIP/6004-00d2fe00         80151938622970                       SIP/6004-00d2fe00
SIP/6004-00d2fe00    default              80151938622970     22 Up      Dial         Unicall/g1/0151938622970  6004            00:03:52             UniCall/14-1
UniCall/11-1         default              1599                1 Up      Bridged Call SIP/6006-00ea6650         80151335689403                       SIP/6006-00ea6650
SIP/6006-00ea6650    default              80151335689403     22 Up      Dial         Unicall/g1/0151335689403  6006            00:05:18             UniCall/11-1
SIP/6008-00e46a10    default                                  1 Up      Bridged Call UniCall/12-1              1938323241                           UniCall/12-1
UniCall/12-1         default              91000               3 Up      Queue        atendimento|r|||90        1938323241      00:06:10             SIP/6008-00e46a10
UniCall/10-1         default              1599                1 Up      Bridged Call SIP/6002-00f034c0         881895124                            SIP/6002-00f034c0
SIP/6002-00f034c0    default              881895124          22 Up      Dial         Unicall/g1/81895124       6002            00:06:37             UniCall/10-1
UniCall/13-1         default              1599                1 Up      Bridged Call SIP/6005-00f15800         808007771007                         SIP/6005-00f15800
SIP/6005-00f15800    default              808007771007       22 Up      Dial         Unicall/g1/08007771007    6005            00:09:02             UniCall/13-1
12 active channels
6 active calls

Bagunça !!!! 

Então a idéia seria filtrar essa bagunça e procurar por palavras chaves Criando uma funçao Busca para isso !!

Function BuscaTexto(Text,Busca : string) : string;
var n : integer;
begin
  for n := 1 to length(Text) do
    begin
       if Copy(Text,n,length(Busca)) = Busca then
          begin
             Result := ‘ok’;
             RetornoBuscaPos:=n;

          end;

    end;
end;

Agora eu poderia pegar dentro do Buffer do socket qualquer palavra chave como a “Unicall/g1”  e depois caminhar com um ponteiro para recortar isso em qualquer lugar e depois só teria que colocar o valor no GRID. 

Entao como ficaria: 

if BuscaTexto(Msg,’Unicall/g1/’) = ‘ok’ then
        begin
        if Copy(Msg,86,RetornoBuscaPos-79) = ‘Unicall’ then
          //pega o ramal que originou a chamada
          MainForm.StringGrid1.Cells[0,contador]:= Copy(Msg,5,RetornoBuscaPos-82);
          //pega o numero discado para fora destino ‘ ‘Unicall/g1/’
          MainForm.StringGrid1.Cells[1,contador]:= Copy(Msg,97,RetornoBuscaPos-71);

  
Extremamente Trabalhoso Marinheiro de Primeira viagem um colega de cuiaba o Juniou tbm embarcou nessa aventura ele mal dormia, por fim segue algumas telas depois de todo o trabalho …   

voip-monitor 

Tela com opção de verificar chamadas recebidas

programa-asterisk  

Monitor 

Assim tudo em AMI eu teria o retorno de 5 em 5 segundos do comando “core show channels verbose” na qual montaria a tela de ligações em um intervalo de 5 em 5 segundos…. 

Até a Proxima

Eng Eder de Souza

Protótipo: Asterisk + Visão Computacional = Monitoramento

/*

#    _
#   |_)\_/
#   |_) |
#
#
#    ___    _              _       ___
#   | __|__| |___ _ _   __| |___  / __| ___ _  _ _____ _
#   | _|/ _` / -_) ‘_| / _` / -_) \__ \/ _ \ || |_ / _` |
#   |___\__,_\___|_|   \__,_\___| |___/\___/\_,_/__\__,_|
Conecta Uma Web Cam e fica a espera de qualquer movimento detectado e faz
conexão com o Asterisk para iniciar Ligação …
Instruções de Compilação:
    DevC++: Tools > Compiler Options > Add linker -lhighgui -lcv -lcxcore
-lcvaux -lcvcam -lws2_32.
   
    Inserir todos os Includes do OpenCV e integrar ao compilador
   
————————————————————————————————————
Dependências:
    windows -> winsock2.h, WSDATA wsa_data, OpenCV.
    unix/linux -> <sys/types.h>, <sys/socket.h>, <arpa/inet.h>, OpenCV.
    comuns -> <iostream>, <unistd.h>, <string.h>, OpenCv
   
   
    Eng. Eder de Souza
    email: ederwan…@gmail.com, ederwan…@yahoo.com.br
   
     Data: 17-07-2009
    Visão Computacional + Asterisk para monitoramento via Web Cam
    Monitoramento de áreas sem presença de movimentos, se alguma percepção de
movimento for encontrado Servidor Asterisk Liga para comunicação …
   
*/
#include <stdlib.h>
 
// OpenCV includes.
#include <cv.h>
#include <highgui.h>
//
#include <iostream>
#include <process.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
#ifdef unix
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#else
#include <winsock2.h>
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
WSADATA wsa_data;
#endif
 
#define DEFAULT_BUFLEN 512
//IP e Porta para se Conectar ao Socket Perl Asterisk
#define DEFAULT_PORT 8888
#define IP “192.168.0.34”
//Intervalo para Iniciar a Ligação entre um movimento detectado
//Valor em mili-Segundos
#define intervalo 50000
using namespace std;
long int cont = 0;
int Me_Liga() {
    //———————-
    // Declarando e inicializando Variaveis.
    int iResult;
    WSADATA wsaData;
    SOCKET ConnectSocket;
    struct sockaddr_in clientService;
    int recvbuflen = DEFAULT_BUFLEN;
    char *sendbuf = “Movimento Detectado\n”;
    char recvbuf[DEFAULT_BUFLEN] = “”;
    //———————-
    // Inicializando o  Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
        printf(“WSAStartup Falhou com erro: %d\n”, iResult);
        return 1;
    }
    //———————-
    // Criando o Socket para se conectar ao Servidor
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        printf(“socket Falhou com erro: %ld\n”, WSAGetLastError());
        WSACleanup();
        return 1;
    }
    //———————-
    // IP e porta do Servidor Perl Asterisk para se conectar.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( IP );
    clientService.sin_port = htons( DEFAULT_PORT );
    //———————-
    // Conecta ao server em perl com o Asterisk.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService,
sizeof(clientService) );
    if (iResult == SOCKET_ERROR) {
        printf( “Conexao Falhou com erro: %d\n”, WSAGetLastError() );
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
  }
    //———————-
    // Enviando mensagem para Servidor
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        printf(“send() Falhou com erro: %d\n”, WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }
    printf(“Bytes envido: %d\n”, iResult);
    // Mata a Conexao com o Socket
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        printf(“shutdown falhou com  erro: %d\n”, WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }
    // Resposta do socket
    do {
        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            printf(“Bytes recebido: %d\n”, iResult);
        else if ( iResult == 0 )
            printf(“Conexao Encerrada\n”);
        else
            printf(“recebimento falhou com erro: %d\n”, WSAGetLastError());
    } while( iResult > 0 );

    // limpando
    closesocket(ConnectSocket);
    WSACleanup();
 
}

static void Thread1 (LPVOID lpParam){
   
   
  
            cont=cont+1;
            Sleep(intervalo);
   
    printf(“%d Contador \n”, cont);
  
  if(cont >= 1){
    cont=0;
    Me_Liga();
   
}
}

int main()
{
 //Cria uma janela
 cvNamedWindow(“Eng_Eder_souza”, CV_WINDOW_AUTOSIZE);
 
 //Cria objeto para captura.
 CvCapture* inputMovie;
 
 //Informa o modo de captura.
     inputMovie = cvCaptureFromCAM(0);

 
 //tamanho da imagem
 CvSize imgSize;
 imgSize.width = 320;
 imgSize.height = 240;
 
 //Imagens para usar no programa
 IplImage* greyImage = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);
 IplImage* colourImage;
 IplImage* movingAverage = cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
 IplImage* difference;
 IplImage* temp;
 IplImage* motionHistory = cvCreateImage( imgSize, IPL_DEPTH_8U, 3);
 
 //Retangulo nos objetos
 CvRect bndRect = cvRect(0,0,0,0);
 
 //Pontos para o retangulo
 CvPoint pt1, pt2;
 
 //Cria uma font para o objeto.
 CvFont font;
 
 
 
 int inicio = 0;
 
 //Buffer
 
 char Scores[60000];
 
          
 //centraliza X do retangulo
 int avgX = 0;
 
 //Indica a primeira vez do loop de um frame
 bool first = true;
 
 
 //Mantem proceços do Frame de pé
 for(;;)
 {
  //Pega o Frame da entrada de Video
  colourImage = cvQueryFrame(inputMovie);
 
  //Se nao existir mais framas cair fora do For
  if( !colourImage )
  {
   break;
  }
  
  //Primeira vez para iniciar Imagem
  if(first)
  {
   difference = cvCloneImage(colourImage);
   temp = cvCloneImage(colourImage);
   cvConvertScale(colourImage, movingAverage, 1.0, 0.0);
   
   first = false;
  }
  //else, faz a detecção de movimento
  else
  {
   cvRunningAvg(colourImage, movingAverage, 0.020, NULL);
  }
 
  //Converte a scala do video
  cvConvertScale(movingAverage, temp, 1.0, 0.0);
 
  //analiza o frame corrente
  cvAbsDiff(colourImage,temp,difference);
  
  //converte a imagem para grayscale.
  cvCvtColor(difference, greyImage, CV_RGB2GRAY);
  
  //Converte a imagem para black and white.
  cvThreshold(greyImage, greyImage, 70, 255, CV_THRESH_BINARY);
  
  cvDilate(greyImage, greyImage, 0, 18);
  cvErode(greyImage, greyImage, 0, 10);
 
  //acha o contador de imagens em video
  CvMemStorage* storage = cvCreateMemStorage(0);
        CvSeq* contour = 0;
  cvFindContours( greyImage, storage, &contour, sizeof(CvContour),
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
 
  //processa cada movimento no frame corrente
        for( ; contour != 0; contour = contour->h_next )
        {
   //pega quadrado nos objetos em movimento
   bndRect = cvBoundingRect(contour, 0);
 
   pt1.x = bndRect.x;
   pt1.y = bndRect.y;
   pt2.x = bndRect.x + bndRect.width;
   pt2.y = bndRect.y + bndRect.height;
         sprintf(Scores, “Com Movimento”);
   
   
   if(inicio == 0){
            Me_Liga();
            inicio = 1;
            }
            else{
                
               
                 if(cont == 0){
                  //Inicia a Thread para o Intervalo de tempo para Ligar
                 _beginthread( Thread1, 0, NULL );}
                 }
   
            }
         
   
 
  //desenha um retangulo nos objetos em movimento.
  cvRectangle(colourImage, pt1, pt2, CV_RGB(255,0,0), 1);
 
        cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.8, 0.8, 0, 2);
  cvPutText(colourImage, Scores, cvPoint(60, 200), &font, cvScalar(0, 0, 300));
  
  //Mostra o Frame.
  cvShowImage(“Eng_Eder_souza”, colourImage);
  
  
  cvWaitKey(10);
  sprintf(Scores, “Sem Movimento”);
        printf(“Apenas um Frame\n”);
  //Escreve o Frame no video de saida
 
 }
 
 // Termina com a imagem o video e a janela
 cvReleaseImage(&temp);
 cvReleaseImage(&difference);
 cvReleaseImage(&greyImage);
 cvReleaseImage(&movingAverage);
 cvDestroyWindow(“Eng_Eder_souza”);
 
 cvReleaseCapture(&inputMovie);
 
 return(0);
}
 
 
///#####FIM#####
 
Agora Segue script em Perl que recebe o socket e dispara a Ligação via Asterisk
este deve estar no servidor Asterisk executando no servidor Asterisk.
 
exemplo “perl serverasteriskEder.pl 8888″
 
#Eng. Eder de Souza
#    email: ederwan…@gmail.com, ederwan…@yahoo.com.br
#    Data: 22-09-2008
use IO::Socket::INET;
use strict;

my $numero;
my $arquivo;
my $r;
my $port = shift
    or die”Falta o numero da porta\n”;
my $socket = IO::Socket::INET->new(‘LocalPort’ => $port,
                                   ‘Proto’ => ‘tcp’,
                                   ‘Listen’ => SOMAXCONN)
    or die “Can’t create socket ($!)\n”;
print “Server listening\n”;
while (my $client = $socket->accept) {
    my $name = gethostbyaddr($client->peeraddr, AF_INET);
    my $port = $client->peerport;
    while (<$client>) {
        print “[$name $port] $_”;
        print $client “$.: $_”;
$r = $_;
if( $r =~ /Movimento/) {
print $r,”\n”;
        system(“echo ‘$r’ > /tmp/test.txt”);
        open ($arquivo, ‘</var/lib/asterisk/agi-bin/telefones.txt’);
        while (<$arquivo>) {
           $numero = $_;
           my $discar = “/var/spool/asterisk/”.$numero.”.call”;
           my $arqdestino = “/var/spool/asterisk/outgoing/” ;
           open(EXTEN,”>$discar”);
           print EXTEN “Channel: Sip/$numero\n”;
           print EXTEN “MaxRetries: 5\n”;
           print EXTEN “RetryTime: 60 \n”;
           print EXTEN “WaitTime: 60 \n”;
           print EXTEN “Context: Saida\n”;
           print EXTEN “Extension: 3300\n”;
           print EXTEN “Priority: 1\n”;
           close(EXTEN);
           system(“mv /var/spool/asterisk/*.call $arqdestino”);
       }
       close $arquivo;

        }
 

}
    close $client
        or die “cliente encerrou conexao ($!)\n”;
}
die “socket com problema ($!)\n”;

 
###FIM###
 
 
[]’s
 
Eng Eder de Souza