2 Digitalização da Voz - Projetos

Propaganda
UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
CURSO DE BACHARELADO EM SISTEMAS DE INFORMAÇÃO
Rede Peer-to-Peer de gateways VoIP
utilizando o padrão SIP.
EVANDRO DE ESPÍNDOLA
Trabalho de conclusão de curso
submetido à Universidade Federal de
Santa Catarina como parte dos
requisitos para obtenção do grau de
Bacharel em Sistemas de Informação
Florianópolis - SC
2005/2
ii
EVANDRO DE ESPÍNDOLA
Rede peer-to-Peer de gateways VoIP
utilizando o padrão SIP.
Trabalho de conclusão de curso submetido à Universidade Federal de Santa Catarina
como parte dos requisitos para obtenção do grau de Bacharel em Sistemas de
Informação.
Orientador:
_________________________________
Prof. Frank Siqueira, Dr.
Departamento de Informática e Estatística
Universidade Federal de Santa Catarina
Banca examinadora:
_________________________________
Prof. João Bosco da Mota Alves, Dr.
Departamento de Informática e Estatística
Universidade Federal de Santa Catarina
_________________________________
Prof. Leandro José Komosinski, Dr.
Departamento de Informática e Estatística
Universidade Federal de Santa Catarina
iii
Resumo
O presente trabalho tem como objetivo demonstrar a viabilidade da criação de
uma rede de gateways VoIP que serão conectados via rede Peer-to-Peer. Este
trabalho descreve as tecnologias utilizadas para o uso da Voz sobre IP, incluindo os
principais protocolos e uma descrição do software utilizado como gateway. Para que
fosse possível alterar este software de modo a encontrar os gateways mais adequados
para rotear uma ligação, foi necessário o estudo da plataforma JXTA, que permitiu a
criação de um protótipo de rede peer-to-peer de gateways VoIP.
O protótipo implementado demonstra a viabilidade da criação de uma rede peerto-peer de gateways VoIP, bastando para isto integrar o protótipo implementado com o
software dos gateways.
Palavras Chaves: Voz sobre IP, SIP, RTP, Asterisk, Gateways VoIP, redes
peer-to-peer
iv
Glossário
v
Sumário
1
2
Introdução ............................................................................................................... 9
Digitalização da Voz .............................................................................................. 11
2.1
Amostragem ................................................................................................... 11
2.2
Quantização ................................................................................................... 12
2.3
Codificação .................................................................................................... 13
2.3.1
Codecs .................................................................................................... 14
2.4
A Taxa de Bits ................................................................................................ 15
2.5
Problemas na Representação Digital ............................................................. 15
2.5.1
Distorção ................................................................................................. 15
2.6
Requisitos Para Transmissão de Voz ............................................................ 16
2.6.1
Largura de Banda ................................................................................... 16
2.6.2
Vazão (Throughput) ................................................................................ 17
2.6.3
Taxa de Erro ........................................................................................... 17
2.6.4
Atraso Fim-a-Fim .................................................................................... 17
2.6.5
Variação de atraso (Jitter) ....................................................................... 17
2.6.6
Variação de vazão com o tempo............................................................. 18
2.6.7
Dependência temporal ............................................................................ 18
2.6.8
Tolerância a Perda de Pacotes ............................................................... 18
3 Session Initiation Protocol (SIP) RFC-3261 .......................................................... 20
3.1
Estrutura do protocolo .................................................................................... 20
3.2
MENSAGENS ................................................................................................ 22
3.2.1
REQUISIÇÕES ....................................................................................... 22
3.2.2
RESPOSTAS .......................................................................................... 22
3.2.3
Campos do Cabeçalho ........................................................................... 23
3.2.4
Corpo ...................................................................................................... 23
3.2.5
Estabelecimento de uma sessão SIP ..................................................... 23
4 Real-Time-Transport Protocol (RTP) .................................................................... 26
4.1
Características Principais ............................................................................... 26
4.2
Comportamento do RTP ................................................................................ 27
4.2.1
Comportamento do emissor RTP............................................................ 27
4.2.2
Comportamento do Receptor RTP.......................................................... 28
4.3
Sessões RTP ................................................................................................. 29
4.4
O Pacote RTP para transferência de dados .................................................. 29
4.4.1
Elementos do cabeçalho ......................................................................... 30
4.5
Protocolo de controle RTP (RTCP) ................................................................ 32
4.5.1
Formato básico ....................................................................................... 33
4.5.2
Relatório do Receptor (RTCP RR) .......................................................... 35
4.5.3
Relatório do Emissor : RTCP SR ............................................................ 37
4.5.4
Descrição da fonte (Source Description – SDES): .................................. 38
4.5.5
Controle de membros da sessão (RTCP BYE) ....................................... 39
4.5.6
Pacotes Definidos Pela Aplicação (RTCP APP) ..................................... 40
5 ASTERISK ............................................................................................................ 41
5.1
Tecnologias suportadas ................................................................................. 42
5.1.1
Hardware Zaptel ..................................................................................... 42
5.1.2
Hardware Não Zaptel .............................................................................. 43
5.1.3
Pacotes de voz ....................................................................................... 43
5.2
Visão geral da arquitetura .............................................................................. 43
5.2.1
Canais ..................................................................................................... 44
vi
5.2.2
CODECS Suportados ............................................................................. 45
5.2.3
Plano de discagem ................................................................................. 45
5.2.4
Processo de instalação e configuração .................................................. 46
6 JXTA ..................................................................................................................... 48
6.1
CAMADAS ..................................................................................................... 49
6.2
Componentes principais do JXTA .................................................................. 50
6.2.1
Peer ........................................................................................................ 50
6.2.2
Grupo de Peers....................................................................................... 50
6.2.3
Serviços de Rede.................................................................................... 51
6.2.4
Dutos(pipes)............................................................................................ 51
6.2.5
Mensagens ............................................................................................. 52
6.2.6
Anúncios (Advertisements) ..................................................................... 52
6.2.7
Identificadores (IDs) ................................................................................ 53
6.3
Protocolos JXTA ............................................................................................ 53
7 A REDE DE GATEWAYS PEER-TO-PEER .......................................................... 54
7.1
Descrição da aplicação .................................................................................. 54
7.2
Tecnologias utilizadas .................................................................................... 54
7.3
Escopo da aplicação ...................................................................................... 55
7.4
Desenvolvimento da aplicação ...................................................................... 55
7.4.1
Implementação da rede .......................................................................... 56
7.4.2
Interface Gráfica ..................................................................................... 58
8 CONCLUSÃO ....................................................................................................... 62
9 Bibliografia ............................................................................................................ 63
10
Anexos............................................................................................................... 65
vii
Lista de Figuras
Figura 2.1– Processo de amostragem ......................................................................... 12
Figura 2.2 – Processo de quantização. ........................................................................ 13
Figura 2.3 – Sinal codificado ........................................................................................ 13
Figura 3.1- Estrutura de camadas SIP ........................................................................ 21
Figura 3.2 - Estabelecimento de uma ligação VoIP usando SIP .................................. 24
Figura 3.3 - Mensagem INVITE enviada de Alice para Bob ......................................... 25
Figura 3.4 - Resposta de atendimento ......................................................................... 25
Figura 4.1 – Diagrama de blocos para um emissor RTP - Fonte: PERKINS, 2003 .... 27
Figura 4.2 – Diagrama de blocos para um receptor RTP - Fonte: PERKINS, 2003 ..... 28
Figura 4.3 - Pacote de dados RTP ............................................................................... 30
Figura 4.4 - Formato básico do pacote RTCP .............................................................. 34
Figura 4.5 - Exemplo de um pacote RTCP composto ................................................. 35
Figura 4.6 - Formato do pacote Relatório do Receptor RTCP...................................... 35
Figura 4.7 - Formato do pacote de relatório do emissor RTCP ................................... 37
Figura 4.8 - Formato do pacote de descrição da fonte RTCP ...................................... 39
Figura 4.9- Formato do pacote de Controle de membros da sessão RTCP ................. 40
Figura 5.1 – Arquitetura básica do Asterisk .................................................................. 44
Figura 6.1 - Rede Virtual .............................................................................................. 48
Figura 6.2 - Camadas da plataforma JXTA .................................................................. 49
Figura 7.1 - Diagrama principal .................................................................................... 56
Figura 7.2 - Classes do pacote redepeertopeer ........................................................... 57
Figura 7.3 – Tela inicial do programa ........................................................................... 59
Figura 7.4 – Valor e resultados da pesquisa ................................................................ 60
Figura 7.5 - Mensagens recebidas ............................................................................... 61
viii
Lista de Tabelas
Tabela 2-1 – Codecs mais populares ........................................................................... 15
Tabela 5-1 – Funções suportadas pelo Asterisk .......................................................... 41
Tabela 5-2 - Tabela de Hardwares zaptel mais comuns .............................................. 42
Tabela 5-3 Lista de hardwares não Zaptel ................................................................... 43
Tabela 5-4 - Protocolos suportados ............................................................................. 43
9
1
Introdução
O crescimento da Internet, que nos últimos anos se popularizou como um meio
de comunicação de alcance global e de baixo custo, aliado a um aumento constante
na velocidade dos enlaces utilizados, criou um ambiente que viabiliza a criação de
uma tecnologia para aplicações de transmissão de áudio digital em tempo real. Esta
tecnologia chama-se Voz sobre IP ou VoIP [MONTEIRO, 2000].
Soluções baseadas em Internet Protocol (IP) têm sido propostas para substituir
com inúmeras vantagens os modelos de telefonia convencional. Com a utilização de
redes de pacotes para transportar voz elimina-se a necessidade da presença de um
circuito dedicado. Assim, a voz é empacotada e transmitida por meio de redes de
computadores juntamente com os dados. O IP é o protocolo usado nesse processo.
Para que seja possível a conexão de soluções VoIP com as centrais públicas de
comutação (PSTN) é necessário utilizar gateways, esses gateways podem ser
modems do tipo voicemodem ou até mesmo placas especiais que suportam 30 linhas.
A proposta deste trabalho é implementar uma rede Peer-to-Peer (P2P) de
gateways VoIP (voz sobre IP) que estabeleçam a ligação entre a rede Internet e a rede
pública de telefonia em vários pontos geograficamente distribuídos. Os gateways
devem ser implementados em software, utilizando um computador e um modem
convencional. O computador deve estar conectado à Internet via ADSL ou rede local.
Um software aplicativo de telefonia, através de uma conexão com a rede P2P, será
responsável por encontrar o gateway mais adequado para completar a ligação com a
rede pública de telefonia. A comunicação de voz sobre IP será efetuada utilizando o
padrão SIP, e a codificação utilizará o padrão de compressão G.711, que é
equivalente à telefonia convencional em termos de qualidade e taxa de bits gerada.
As vantagens deste tipo de rede podem ser bem variadas, como a redução do
custo de ligações interurbanas e internacionais, outra vantagem é a utilização de
equipamentos de baixo custo com software livre. Como se trata de uma rede peer-topeer não há a necessidade do uso de tecnologias do tipo cliente servidor, não
havendo um servidor central. Este tipo de rede apresenta como principal característica
a não existência de um servidor central, que normalmente é um computador potente e
consideravelmente caro.
Este trabalho está organizado da seguinte maneira: no capítulo 2 será descrito o
processo de amostragem e codificação da voz e os problemas provenientes deste
10
processo, também descreveremos os requisitos mínimos para transmissão da voz. No
capítulo 3 será descrito o protocolo SIP, veremos suas características principais, como
é estruturado, características de conexão, e um breve exemplo de como é
estabelecido uma conexão simples. No capítulo 4 será descrito o protocolo RTP, uma
visão geral sobre as principais características, como ele se comporta no
estabelecimento de uma sessão, uma visão mais aprofundada do pacote RTP para
transferência dos dados, neste capítulo também será descrito o protocolo de controle
RTP o RTCP e suas principais características. No capítulo 5 será descrito o software
Asterisk, pra que serve, como funciona será mostrado também uma visão geral de sua
arquitetura. No capitulo 6 será descrito a plataforma JXTA, suas camadas e seus
componentes. No capítulo 7 tratará sobre a parte prática, contendo informações de
como deverão ser instalados configurados os gateways e também a descrição de
como a rede peer-to-peer foi implementada.
11
2 Digitalização da Voz
A voz humana é uma onda sonora que pode ser transmitida por diversos meios
de transmissão. A faixa de freqüência que uma pessoa normalmente ouve é de 20 a
20.000 Hertz (Hz). No entanto, as principais freqüências da voz humana estão em uma
faixa mais reduzida, situada entre 300 e 3.400 Hz.
Segundo (MONTEIRO 2003) A codificação da voz tem como objetivo, produzir
um conjunto de códigos de voz a uma taxa mínima para a transmissão, de modo que o
equipamento receptor possa reconstruir o sinal de voz original e também que a
transmissão seja otimizada.
2.1 Amostragem
O processo de amostragem consiste basicamente em obter amostras de áudio
em intervalos regulares; estes intervalos, segundo o teorema de Nyquist, devem ter no
mínimo o dobro da maior freqüência que será amostrada. A freqüência de amostragem
adotada pela telefonia convencional é de 8 KHz. Para que seja obedecido o teorema
de Nyquist, as centrais telefônicas são equipadas com filtros que limitam a freqüência
do canal de voz em 3.4KHz. O circuito que permite amostrar o sinal é uma simples
chave que se fecha por um brevíssimo instante, na cadência da freqüência de
amostragem. Como a chave se fecha por um tempo extremamente curto, teremos na
sua saída um sinal em forma de pulsos estreitos, com amplitude igual ao valor
instantâneo do sinal, chamados pulsos PAM (pulsos modulados em amplitude).
12
Figura 2.1– Processo de amostragem
Fonte: http://paginas.terra.com.br/lazer/py4zbz/teoria/digitaliz.htm
2.2 Quantização
Na quantização, os valores da amostra são convertidos em valores discretos.
Neste processo, o domínio do sinal é dividido em um número fixo de intervalos. Para
cada amostra dentro de um intervalo é atribuído o valor do intervalo. Esse processo
gera um ruído denominado ruído de quantização, que é determinado pela diferença do
sinal de entrada pelo sinal de saída. A telefonia convencional utiliza 256 intervalos de
quantização (8 bits), e adota o padrão de quantização e codificação não linear, ou
seja, os valores de menor amplitude tem maior representação, o que só é possível
usando circuitos especiais. Na informática, devido a restrições de hardware, a
quantização é linear, ou seja os passos de quantização são iguais.
13
Figura 2.2 – Processo de quantização.
Fonte: http://paginas.terra.com.br/lazer/py4zbz/teoria/quantiz.htm
2.3 Codificação
No processo de codificação, cada amostra quantizada recebe um valor binário
referente ao valor do intervalo de quantização. Dependendo da codificação usada,
cada intervalo é representado por 8 bits, para algumas aplicações é importante que
este valor por ser aumentado, podendo chegar a até 16 bits, o que permite representar
65.536 intervalos de quantização.
Figura 2.3 – Sinal codificado
Fonte http://paginas.terra.com.br/lazer/py4zbz/teoria/quantiz.htm
14
2.3.1 Codecs
 G.711: Segundo FERNANDES(2003), o padrão de códificação G.711 teve sua
aprovação em 1972 (não havendo registro mais preciso) seu consumo de banda é de
64Kbps e utiliza a codificação PCM (Modulação por Código de Pulso). Fernandes
afirma também que a norma não define um escopo específico para a utilização deste
protocolo, mas que ele foi concebido para ser tratado de maneira mais eficiente pelos
sistemas digitais de comunicação. Com relação ao atraso, Fernandes afirma que o
atraso é de 0,125 ms, pois, são realizadas 8000 amostras por segundo sendo
quantizado em 256 níveis, utilizando 8 níveis para a representação
 G.721 : Segundo MONTEIRO(2003) o padrão G.721 melhorar a relação
sinal/ruído e diminui a banda devido ao seu funcionamento que é da seguinte forma: o
fluxo de áudio é codificado usando o G.711 e sobre este fluxo são aplicados cálculos
estatísticos onde é gerado uma estimativa baseada em duas amostras. A
recomendação G.727 do ITU especifica um algoritmo de modulação diferencial
adaptativo (ADPCM) onde são utilizados 5, 4, 3 e 2 bits por amostra, gerando desta
forma taxas de 40, 32, 24 e 16 Kbps respectivamente.
 G.728: Segundo FERNANDES(2003) a data de aprovação desta especificação
foi em 1º de setembro de 1992 e seu consumo de banda é de 16kbps. O tipo de
codificação é a LD-CELP (Low- Delay Code Excited Linear Prediction). Fernandes
afirma que o atraso mínimo desta recomendação é de 0,625 ms. A codificação é feita
da seguinte forma, um bloco formado por 5 amostras seqüenciais codificados usando
o G.711, para cada bloco é feito a comparação com todos os 1024 vetores
armazenados no dicionário de vetores quantizados, a comparação mais próxima dada
pelo módulo de minimização de erro, indicará o índice do dicionário que deverá ser
transmitido pelo codificador.
 G.729: MONTEIRO(2003) afirma que o padrão G.729 é também conhecido
como: Conjugate-Structure Agebraic Code Excited Linear Prediction – CS-ACEL. É um
algoritmo de codificação que gera uma taxa de 8kbps e com boa qualidade de voz. A
concepção desta especificação foi para ambientes sem fio, mas, podendo também, ser
usado em comunicação de multimídia e em redes de dados, o atraso deste codec é de
15ms. O G.729 funciona da seguinte forma: A cada espaço de tempo de 10ms do sinal
de voz, são analisadas 80 amostras de 8 bits (PCM) para geração de 10 códigos de 8
bits.
15
Tabela 2-1 – Codecs mais populares
Standard
Description
Bandwidth(Kbps)
MOS
Coding Delay
G.711
PCM
64
4.3
1.0μs
G.721
ADPCM
32,16,24,40
4.0
1.25μs
G.728
LD-CELP
16
4,0
2.5μs
G.729
CS-ACELP
8
4.0
15.0μs
Fonte: MONTEIRO, 2003
2.4 A Taxa de Bits
A taxa de Bits gerada é determinada pelo produto entre a taxa de amostragem e
o número de bits usados no processo de quantificação. Se a freqüência de
amostragem for de 8 kHz e a quantidade de bits da quantização for de 8 bits por
amostra, teremos então uma taxa de bits de 64Kbps.
2.5 Problemas na Representação Digital
Mesmo tendo inúmeras vantagens, a digitalização, especificamente de áudio,
apresenta inúmeras deficiências. Estas deficiências são inerentes ao processo de
digitalização, não sendo possível eliminá-las totalmente, mas apenas reduzi-los
utilizando técnicas que procurem restaurar fielmente o áudio analógico original (ou
seja, anterior ao processo de digitalização).
2.5.1 Distorção
O maior problema que ocorre na digitalização de sinais analógicos é que, não há
como ter um sinal de saída de um decodificador (equipamento que faz o processo
inverso ao de codificação) igual ao sinal de entrada. Este tipo de distorção é conhecida
como distorção de codificação (amostragem, quantificação e codificação dos valores).
Dependendo do tipo de distorção, o sinal pode ser recuperado e entendido
perfeitamente. O padrão G.711 especifica os níveis máximos de ruído que podem ser
inseridos na codificação analógica/digital.
16
Uma forma de diminuir o nível de ruído é aumentar a taxa de amostragem e o
número de bits usado para codificação. Tanto o aumento da taxa de amostragem
quanto o aumento dos bits de codificação geram automaticamente uma taxa de bits
por segundo maior. As limitações para que isto seja possível são a necessidade de
grandes espaços para armazenamento e de maior largura de banda para transmissão
do sinal.
Como o usuário final é normalmente um humano, a qualidade do dado convertido
de digital para o analógico não precisa ser extremamente fiel ao dado analógico da
entrada, tendo em vista que normalmente o cérebro humano é capaz de “ignorar”
pequenas distorções. No caso do som há freqüências que o ouvido não diferencia e
outras que ele não distingue. A especificação do padrão de digitalização G.711
especifica
os
níveis
máximos
de
ruídos
aceitáveis
para
uma
codificação
analógico/digital e depois para uma conversão digital/analógico.
2.6 Requisitos Para Transmissão de Voz
A transmissão de voz é muito sensível a problemas de rede. Na rede telefônica
estes problemas são minimizados, pois toda a rede de telefonia foi projetada para o
tráfego de voz; já a internet não apresenta a mesma qualidade na transmissão, pois
não garante atraso mínimo e também não garante que todos os dados transmitidos
chegarão ao seu destino. Neste capítulo mostraremos alguns requisitos para a
transmissão de voz pela internet.
2.6.1 Largura de Banda
O número de dígitos binários trocados entre dois sistemas comunicantes que a
rede é capaz de transportar é denominada de taxa de bits. A taxa de bits pode ser
expressa em bps (bits por segundo) ou em múltiplos desta unidade (Kbps - Kilo bits
por segundo, Mbps - Mega bits por segundo, etc.).
O codec convencionalmente utilizado na telefonia convencional gera uma taxa de
64 Kbps.
17
2.6.2 Vazão (Throughput)
A vazão de uma rede é a taxa de bits efetiva, ou seja, a taxa de bits total da
comunicação menos a sobrecarga (overhead) causada pela tecnologia empregada na
conexão devido ao envio de informações de controle (cabeçalhos, confirmações,
códigos de detecção de erro, etc.).
A vazão pode apresentar variações no tempo, seja devido a falhas em algum nó
da rede, seja devido a congestionamentos.
2.6.3 Taxa de Erro
A taxa de erro é um parâmetro importante para determinarmos a qualidade de
uma rede. São utilizadas duas métricas para a determinação da taxa de erro: uma é a
taxa de erro de bits (BER- Bit error rate) que é a razão entre bits errados e o total de
bits transmitidos; a outra métrica é a taxa de erro de pacote (PER) que é definido pela
razão entre o número de pacotes com erro e o número de pacotes transmitidos.
2.6.4 Atraso Fim-a-Fim
Um dos principais parâmetros de qualidade da rede é o atraso fim-a-fim, que
consiste no tempo necessário para transmitir um bloco de dados de um emissor para
um receptor. Este atraso pode ser composto pelos seguintes componentes:
- Atraso na interface: É o tempo que demora do pacote estar pronto para ser
transmitido até a rede estar pronta para esta transmissão. Este item é mais relevante
em redes orientadas a conexão, como a X.25 ou token-ring.
- Atraso de trânsito: Tempo necessário para enviar um bit de um local a outro
através de um enlace; este atraso só é relevante quando é utilizado um enlace via
satélite, pois nos outros meios este atraso pode ser desprezado, já que a velocidade
de propagação do sinal é igual à velocidade da luz.
- Atraso de transmissão: Tempo necessário para transmitir um bloco de dados
fim-a-fim. É dependente da taxa de bits da rede e do processamento dos nós
intermediários.
2.6.5 Variação de atraso (Jitter)
A variação de atraso entre a chegada de um pacote e outro é normalmente
chamado de jitter, segundo Fernandes: “A existência de variações entre os intervalos
18
de tempo necessários para que pacotes consecutivamente transmitidos, percorram a
distância entre pontos origem e destinos de um sistema de comunicação”
(FERNANDES, 2003).
A característica da rede IP na transmissão não garante que os pacotes sejam
entregues com a mesma diferença de tempo. Para que esta característica não afete a
qualidade da comunicação de voz é necessário o uso do buffer de jitter, que será
descrito na seção 4.5.2.
2.6.6 Variação de vazão com o tempo
A taxa de bits gerada por um codec VoIP pode ser constante (por exemplo,
codecs que não utilizam supressão de silêncio) ou variável (por exemplo, codecs que
utilizam supressão de silêncio).
O codec G.711 gera uma taxa de bits constante, sendo assim a rede deve
possuir uma taxa constante de bits, caso contrário há a necessidade de buffers para
corrigir essas variações.
2.6.7 Dependência temporal
Quando tratamos de comunicação entre pessoas há a necessidade de que o
atraso
não
prejudique
a
interatividade.
Segundo
FERNANDES(2003)
“A
recomendação G.114 discorre sobre especificações do tempo de transmissão,
incluindo o processamento em equipamentos e o tempo de propagação na rede.”
FERNANDES(2003) afirma que os limites de atraso aceitáveis para uma
transmissão fim-a-fim são:
- Ideal: de 0 até 150ms;
- Aceitável para usuários mais tolerantes: de 150 a até 400ms.
Para atrasos de mais de 400ms a comunicação se torna de difícil entendimento.
2.6.8 Tolerância a Perda de Pacotes
Veremos na sessão 4.1 que, as aplicações VoIP não utilizam retransmissão de pacote
perdidos. A perda de um pacote isolado não gera grandes problemas para esse tipo
de comunicação, já que o ruído gerado não passará de um pequeno “estalo” ou um
pequeno silêncio (20ms para o G.711), o que para o ouvido humano é quase
19
imperceptível. Já a perda de pacotes em rajadas (em seqüência) pode prejudicar
significativamente a qualidade do áudio, podendo chegar a inviabilizar a comunicação.
20
3 Session Initiation Protocol (SIP) RFC-3261
O SIP é um protocolo da camada de aplicação que serve para estabelecer,
modificar e finalizar sessões multimídia (conferências) como se fossem ligações
telefônicas. Novas mídias podem ser inseridas, e/ou removidas, de uma sessão já
existente. O SIP suporta de forma transparente o mapeamento de nomes e o
redirecionamento de serviços, assim como o http.
O protocolo SIP pode ser descrito em cinco facetas para o início e o término de
uma sessão multimídia. Estas facetas são:
 Localização do usuário: É a determinação do sistema da extremidade que será
utilizado na comunicação.
 Disponibilidade do usuário: É a definição da possibilidade do usuário chamado
participar da comunicação.
 Capacidades do usuário: Determina qual mídia e quais parâmetros serão
usados.
 Estabelecimento da sessão: Estabelece a os parâmetros da sessão entre o
chamado e o chamador.
 Gerenciamento da sessão: Inclui transferências e términos de sessões,
modificações de parâmetros e invocações de serviços.
Como o SIP foi desenvolvido pelo IETF (HTTP, SMTP, etc.) ele apresenta
algumas características semelhantes a estes protocolos como:
 ser baseado no modelo cliente-servidor;
 utilizar formato texto para a troca de mensagens
 fazer uso de endereços “similares” a endereços SMTP, uma parte formada pelo
telefone ou usuário e a outra parte formada pelo domínio.
No item 3.2.5 temos um exemplo de uma sessão SIP sendo estabelecida.
3.1 Estrutura do protocolo
O SIP está estruturado em camadas como mostrado na Figura 3.1, que
apresentam comportamentos diferenciados e possuem um baixo acoplamento. Temos
na seqüência uma breve descrição de cada camada e de sua responsabilidade.
21
Figura 3.1- Estrutura de camadas SIP
Fonte: O’Doerth, 2003

Camada inferior: Camada responsável pela codificação e sintaxe do
protocolo.

Segunda Camada: Camada de transporte. Define como o cliente envia
requisições e recebe as respostas, e como um servidor recebe as requisições e envia
as respostas. Todos os elementos SIP possuem camada de transporte.

Terceira camada: Camada de transação. Uma transação é uma requisição
enviada por um cliente de transação (usando a camada de transporte) para um
servidor de transação. Todas as respostas referentes a uma requisição são enviadas
para o cliente de transação. Esta camada manipula as retransmissões da camada de
aplicação, faz o casamento das respostas com as requisições e trata os time-outs da
camada de aplicação. Qualquer tarefa que um Agente usuário cliente (User Agent
Client - UAC) realiza ocorre usando uma série de transações. A camada de transação
pode ser encontrada nos Agentes usuários (User Agents – UA) como no proxy com
estado (stateful). Já os proxies sem estado (Stateless) não possuem esta camada. Ela
contém componentes referentes ao cliente e ao servidor e é representada por uma
máquina de estados finitos.

A camada acima da camada de transação é chamada de Usuário de
transação (Transaction User - TU). Toda entidade SIP, com exceção do proxy sem
22
estado, é um TU. O usuário que criou a transação pode cancelá-la através do
comando CANCEL.
3.2 MENSAGENS
3.2.1 REQUISIÇÕES
A RFC3261 define seis métodos para o registro, estabelecimento, manutenção e
término da sessão. Os métodos são: Register que registra informações de contato,
INVITE, ACK e CANCEL que definem o estabelecimento de sessões, BYE que serve
para finalizar uma sessão e por ultimo o OPTIONS, para verificar qual a capacidade
dos servidores.
3.2.2 RESPOSTAS
As respostas das requisições são caracterizadas por terem uma linha de status
na primeira linha, que é formada pela versão do SIP, pelo código de STATUS (que é
interpretado pelo receptor através de um autômato) e por uma frase correspondente
ao valor do código (esta frase serve para apresentação ao usuário). O valor do código
é composto por um inteiro de três algarismos, onde o primeiro algarismo define a
classe de resposta.
As classes ou categorias de resposta estão divididas em seis grupos, como
vemos a seguir:

Categoria -1xx – Provisional: requisição recebida, continuando a processar a
requisição.

Categoria - 2xx – Sucess: Ação foi recebida com sucesso.

Categoria – 3xx – Redirection: É necessário o envio de mais ações para
completar a requisição.

Categoria – 4xx – Client Error: A requisição possui erro de sintaxe ou o
servidor não pode atendê-la.
23

Categoria – 5xx – Server Error: O servidor não pode atender uma requisição
aparentemente válida.

Categoria – 6xx – Global Error: A requisição não pôde se atendida em
nenhum servidor.
3.2.3 Campos do Cabeçalho
Os campos do cabeçalho SIP são semelhantes ao do HTTP, tanto na semântica
quanto na sintaxe. Conforme a definição [H 4.2], que especifica a possibilidade de
haver múltiplos valores para um mesmo campo, apenas separados por vírgula.
Seguindo a forma genérica especificada na seção 2.2 da RFC 2822, o campo do
cabeçalho é composto pelo nome seguido do ”:” e finalizado com o valor do campo (se
forem múltiplos valores eles devem ser separados por vírgula).
Não é necessário que os campos estejam em ordem, mas a RFC 3261 sugere
fortemente que os campos que são utilizados para o processamento dos proxies
estejam no início (para evitar atrasos na interpretação do cabeçalho). Também é
definido na RFC que os campos com valores múltiplos podem ser representados de
três formas diferentes: a primeira, como já foi comentado anteriormente, é expressar
os valores separados por vírgula; a segunda é repetir o modelo “<Campo : Valor do
campo>”; e a terceira seria uma combinação dos dois anteriores.
3.2.4 Corpo
A interpretação do corpo da mensagem irá depender da requisição de cada
método. Para as mensagens de resposta, a interpretação do corpo da mensagem irá
depender do método de requisição e do código do Status da resposta.
O tipo de corpo da mensagem deve ser fornecido pelo campo “CONTENT-TYPE”
especificado no cabeçalho, a codificação de caracteres deve ser “UTF-8” caso não
haja um parâmetro especificando outro padrão de codificação.
3.2.5 Estabelecimento de uma sessão SIP
24
Nesta sessão descreveremos um exemplo típico no estabelecimento de uma
sessão SIP. Consideraremos dois usuários, Alice, registrada no servidor atlanta.com e
o usuário Bob, registrado no servidor biloxi.com. A Figura 3.2 mostra o
estabelecimento e o encerramento com sucesso de uma ligação utilizando o protocolo
SIP.
Figura 3.2 - Estabelecimento de uma ligação VoIP usando SIP
Fonte: Rosenberg, 2002
A primeira parte da ligação como mostrado na Figura 3.2 representa o envio por
parte da Alice de uma mensagem do tipo INVITE (Figura 3.3) para seu proxy SIP,
contendo a informação do destino, o proxy verificando que o usuário é de outro proxy
repassa o pedido de INVITE para o proxy onde Bob está registrado e envia uma
resposta para Alice informando que está tentando estabelecer a ligação. O proxy onde
Bob está localizado recebe e encaminha o INVITE para Bob (F4) respondendo para o
proxy onde Alice está registrada que ele está tentando se conectar.
Após o recebimento da mensagem INVITE, o telefone SIP de Bob irá responder
para o proxy onde está registrado que está “chamando” (ringing); esta mensagem será
encaminhada para o proxy atlanta.com e em seguida será encaminhada para o
25
Telefone SIP de Alice. Se Bob decide atender a ligação, o telefone SIP dele irá enviar
uma resposta do tipo 200 – OK (Figura 3.4) que será encaminhada até o telefone SIP
de Alice; este, ao receber a resposta, enviará um ACK (a partir deste momento nesta
sessão a comunicação entre Alice e Bob será direta, sem interferência dos proxies)
informando que recebeu a confirmação (F12). Neste momento é estabelecida a
sessão de mídia, normalmente com o uso do protocolo RTP que será mostrado na
sessão 4.
Figura 3.3 - Mensagem INVITE enviada de Alice para Bob
Fonte: Rosenberg, 2002
Figura 3.4 - Resposta de atendimento
Fonte: Rosenberg, 2002
Ao término da sessão, Bob decide finalizar a ligação e seu Telefone SIP
enviará para Alice uma mensagem BYE, e o telefone SIP de Alice irá apresentar uma
resposta do tipo 200.
26
4 Real-Time-Transport Protocol (RTP)
Atualmente o RTP é um dos protocolos de transporte mais usados para o
transporte de mídia em tempo real, por exemplo: para a transmissão VoIP as duas
principais especificações (SIP e H.323) fazem uso do RTP. Este protocolo provê
serviços úteis ao transporte de mídia em tempo real, como áudio e vídeo, sobre redes
IP. Estes serviços incluem detecção de erro, timing recovery, identificação do Payload
e da fonte, retorno de qualidade de recepção, sincronismo de mídia e gerenciamento
de membro de um grupo multicast.
O RTP foi desenvolvido pelo Internet Engineering Task Force(IETF) e com o
intuito de ser utilizado em conferências multicast usando o modelo de sessão leve.
Desde o início ele foi vantajoso para uma grande gama de aplicações distintas. Sua
primeira versão foi finalizada em Janeiro de 1996 (RFC 1889) e o International
Telecommunications Union (ITU) o adotou, como parte das recomendações do H. 323.
Atualmente a sua versão é definida pela RFC 3550. O RTP necessita de
personalização para funcionar com alguns tipos de aplicação, a RFC 3551 define um
dos perfis mais importantes pra VoIP, nesses perfis também constam as
especificações do formato de Payload e de extensões.
4.1 Características Principais
Normalmente as aplicações rodam o RTP no topo da pilha UDP, o que contribui
com as funcionalidades do protocolo de transporte. Os algoritmos RTP não são
usualmente implementados como camadas separadas, eles fazem parte do código da
aplicação.
O RTP não oferece nenhum mecanismo que garanta a transmissão em tempo
real, não há garantia de confiabilidade e QoS.
As especificações do RTP definam dois protocolos:
- O protocolo RTP (Real time Transport Protocol) que serve para
transporte da mídia.
- O protocolo RTCP (Real-Time Control Protocol), que tem como objetivo
o monitoramento da qualidade de serviço e distribuir informações acerca dos
participantes das sessões. O RTCP não controla completamente a sessão na
27
comunicação de uma aplicação. Para este tipo de controle pode existir um protocolo
de sessão com implementação separada.
4.2 Comportamento do RTP
O protocolo RTO é o elemento principal na geração de fluxos de áudio e vídeo.
Este protocolo oferece uma camada de transporte de mídia independente do protocolo
de sinalização e de aplicação. Veremos a seguir as responsabilidades das partes
envolvidas na comunicação.
4.2.1
Comportamento do emissor RTP
O emissor tem a responsabilidade de capturar e converter a informação de áudio
e/ou vídeo para a transmissão, assim como gerar os pacotes RTP.
Ele pode participar na correção de erros e controle de congestionamento com a
adequação do fluxo de mídia transmitido em uma resposta a um relatório enviado pelo
receptor. A Figura 4.1 mostra o diagrama de blocos para uma comunicação do tipo
VoIP.
Figura 4.1 – Diagrama de blocos para um emissor RTP - Fonte: PERKINS, 2003
O fluxo de áudio é capturado e enviado para o codec, que irá compactar e gerar
quadros, esses quadros, dependendo do tamanho, podem ser fragmentados em dois
ou mais pacotes RTP(isso pode ocorrer com quadros de vídeo) ou vários quadros
podem ser colocados juntos em um único pacote RTP (normalmente ocorre com fluxo
de áudio). Um codificador de canal pode ser utilizado para diminuir problemas com
perda de pacotes.
28
Cabe a quem está enviando o fluxo de mídia enviar periodicamente relatórios de
status, onde devem constar informações para sincronização labial, informações sobre
o codec utilizado e informações sobre os pacotes enviados.
4.2.2 Comportamento do Receptor RTP
A responsabilidade de um receptor RTP é coletar os pacotes RTP da rede,
corrigir eventuais perdas, reordenar os pacotes, decodificar as mídias e mostrar o
resultado final ao usuário. A Figura 4.2 mostra um possível diagrama de blocos da
recepção de um fluxo de mídia, mais especificamente de áudio.
Figura 4.2 – Diagrama de blocos para um receptor RTP - Fonte: PERKINS, 2003
O primeiro passo é coletar os pacotes RTP da rede, validando-os e inserindo-os
em uma fila de entrada, se for o caso, aplicar uma rotina de decodificação de canal,
para a correção de perdas. Após isso os pacotes serão enfileirados em um buffer de
apresentação (também conhecido como buffer de jitter). Nesta fila os pacotes são
ordenados através da sua marca temporal, corrigindo assim qualquer falta de
sincronismo da rede. Dependendo da mídia transportada os pacotes são armazenados
na fila de exibição até que os quadros tenham sido completamente recebidos. Uma
das funções do buffer de apresentação é a de diminuir eventuais atrasos na rede. Em
seguida os quadros são decodificados e se for necessário, e o codec permitir, corrigir
eventuais erros.
O próximo passo é efetuar uma compensação entre o relógio da mídia ao tempo
de apresentação. Essa compensação é necessária para que não haja falhas na
29
apresentação. Finalmente a mídia poderá ser apresentada para o usuário, se houver
mais de um fluxo de áudio será necessário mixar todas as fontes em um único fluxo.
Como podemos notar, a operação de recepção é mais complexa que a de
emissão, boa parte desta complexidade é necessária para corrigir problemas com
perdas e atrasos dos pacotes na rede.
4.3 Sessões RTP
Um grupo de participantes se comunicando constituem uma sessão RTP. As
sessões são concebidas para transportar um único tipo de mídia. Elas podem ser
unicast, no caso do VoIP, ou
multicast, que é o caso da videoconferência. Um
participante pode ser ativo em várias sessões RTP, por exemplo, uma sessão para
troca de dados de áudio e uma sessão para toca de dados de vídeo.
4.4 O Pacote RTP para transferência de dados
O pacote RTP pode ser dividido em quatro partes principais que podem ser
identificadas como:

O cabeçalho RTP principal

Cabeçalho de extensão (opcional)

Um cabeçalho do Payload (opcional)

Payload propriamente dito.
30
Figura 4.3 - Pacote de dados RTP
Fonte: PERKINS, 2003
4.4.1 Elementos do cabeçalho
Version (V, 2 bits) – Este campo identifica a versão do padrão RTP usada. A
versão atual é a versão 2.
Padding (P 1 bit) – Este campo indica se há bytes adicionais ao final do payload.
Se há um padding o bit P deve ser setado em 1 e o ultimo byte do payload indica o
número de bytes do padding.
Extension (X, 1bit) – Campo que indica se há extensão do cabeçalho.
Marker (M, 1 bit)Este campo tem sua função definida pelo tipo de mídia
transportada. No caso da voz, este campo serve para identificar o primeiro pacote de
uma rajada de voz após um período de silêncio (quando a supressão de silêncio está
sendo usada).
CSRC count(CC, 4bits) e CSRC list(CSRC identifier, cada fonte tem 32 bits) – O
campo CC possui 4 bits e indica o tamanho da lista (campo CSRC) de fontes que
contribuíram para formar o pacote RTP. Um exemplo de uso do campo CC e CSRC é
o de uma áudio conferência.
31
Payload Type (PT, 7bits) – Este campo identifica o tipo de mídia transportada, A
interpretação do valor deste campo irá depender do perfil utilizado, segundo
WILLRICH(2004) o perfil mais comum para a transferência de áudio é o especificado
na [RFC 3551] que são os mostrados na Tabela 4-1Error! Reference source not
found..
Tabela 4-1 Valores do campo PT
Fonte: WILLRICH (2004)
Número de Seqüência (Sequence number, 16bits) – Contém o contador do
número de seqüência dos pacotes RTP que é incrementado em um a cada envio de
pacote. Além de identificar o pacote permite ao receptor a identificação de pacotes
perdidos. Este campo não é usado para reordenar pacotes dispersos por atrasos na
rede. PERKINS(2003) afirma que, “Uma típica aplicação de voz-sobre-IP enviando
pacotes de áudio a cada 20 milisegundos irá zerar a seqüência em aproximadamente
20 minutos. Isso ocorre devido ao pequeno tamanho do campo PT que é de 16 bits.
32
Marca Temporal (TimeStamp,32 bits) – A marca temporal do pacote RTP denota
o instante em que foi amostrado o primeiro octeto do dado contido no pacote. Seu
valor é zerado quando é atingido o valor máximo. WILLRICH(2004) afirma que o valor
inicial da marca temporal é escolhido de forma aleatória, não iniciando com zero, para
prevenir ataques ao texto-plano conhecido de um fluxo RTP criptografado.
SSRC (32 bits) – Este campo identifica os participantes dentro de uma sessão
RTP.
Este identificador é mapeado por um nome canônico, CNAME, através do
protocolo RTCP.
Payload - O Payload vem logo após qualquer cabeçalho e pode conter um ou
mais quadros de áudio ou partes ou quadros inteiros de vídeo. Segundo
WILLRICH(2004) o tamanho e o formato do payload varia de acordo com o formato de
mídia negociados durante a configuração da sessão.
4.5 Protocolo de controle RTP (RTCP)
O protocolo de controle RTP conhecido como RTCP fornece suporte para
conferencia com grupos de tamanhos variados, segundo FERNANDES(2003) o
protocolo RTCP “é baseado na transmissão periódica de pacotes de controle por todos
os participantes de uma sessão, afim de monitorizar a qualidade de serviço e
transportar informações destes participantes” (FERNANDES, 2003). WILLRICH (2004)
afirma que o RTP permite:
- Monitoramento da qualidade de serviço e controle de congestionamento:
periodicamente os participantes das sessões enviam relatórios para todos os
emissores, estes relatórios contém, o número de seqüência do ultimo dado recebido, o
número de pacotes perdidos e uma medida da variação temporal entre transmissão e
recepção.
- Sincronização intermídia: aplicações que enviam dados recentemente emitem
um relatório que contém informações sobre a mídia transmitida. Esta informação pode
33
ser utilizada para a sincronização intermídia, também conhecida como sincronização
labial
- Identificação da fonte: Como não há identificação da fonte no pacotes de dados
RTP, essas e opcionalmente outras informações são transmitidas via RTCP.
Segundo PERKINS(2003) uma implementação RTCP possui 3 partes, que são:
- Formato de pacotes: Existem 5 tipos de formato de pacotes: Relatório de
recepção (Receiver Report – RR), Relatório de Envio (Sender Report – SR), descrição
da fonte (Source Description - SDES), gerenciamento de membros (Membership
managment - BYE) e Aplication definetd (APP).
- Regra de temporização: Definem a periodicidade com que serão enviados os
pacotes RTCP. O intervalo de tempo entre pacotes RTCP é conhecido como intervalo
de relatório (reporting Interval). Todas as atividades RTCP ocorrem em múltiplos
desse intervalo de tempo. Nesses intervalos são calculadas as estatísticas da
qualidade de recepção, e o tempo entre atualizações de descrição da fonte e
informações sobre sincronização labial. O intervalo varia de acordo com o tamanho da
sessão e também com o formato da mídia.
- Base de dados de participantes. Base de dados construída com as informações
coletadas dos pacotes RTCP recebidos. Esta base é usada no preenchimento dos
pacotes de relatórios de recepção enviados periodicamente, a base também pode ser
usada para sincronização labial e para manter informações de descrição de fonte.
4.5.1 Formato básico
Os cinco formatos de mensagens RTCP possuem uma estrutura básica e comum
no formato do pacote RTCP, como apresentado na Figura 4.4.
34
Figura 4.4 - Formato básico do pacote RTCP
Fonte: PERKINS, 2003
A Figura 4.4 mostra o formato comum de um pacote RTCP. O cabeçalho que os
cinco formatos possuem em comum é composto por 4 bytes que estão compreendidos
em cinco campos, que são:
- Número de versão (Version Number, V). Este campo tem sempre o valor 2, o
que representa a versão atual do RTCP.
- Padding (P) . Bit que indica a presença de padding ou não. Havendo um
padding o tamanho do mesmo é especificado no seu ultimo Byte.
- Iten Count (IC). Alguns pacotes possuem uma lista de itens. Este campo serve
para indicar o número de itens do pacote e esse número de itens pode chegar a no
máximo 31.
- Tipo do Pacote (Packet Type – PT). Identifica o tipo de pacote.
- Length. Indica o tamanho do conteúdo do pacote (em múltiplos de 32 bits).
Normalmente os pacotes RTCP não são transmitidos individualmente, mas sim
agrupados para formar um pacote composto. Este pacote composto é encapsulado
pela camada de transporte (normalmente UDP). Se há criptografia no pacote
composto o grupo de pacotes RTCP é prefixado por um valor aleatório de 32 bits.
Conforme demonstrado na Figura 4.5
35
Figura 4.5 - Exemplo de um pacote RTCP composto
Fonte: PERKINS, 2003
4.5.2 Relatório do Receptor (RTCP RR)
O uso do RTCP tem como um dos principais objetivos a transmissão de
relatórios sobre a qualidade de Recepção. Estes relatórios são enviados por todos os
participantes das sessões que recebem dados. A Figura 4.6 mostra o formato do
pacote de um relatório de recepção.
Figura 4.6 - Formato do pacote Relatório do Receptor RTCP
36
Fonte: PERKINS, 2003
Como demonstrado na Figura 4.6 o valor do campo “tipo de pacote” é 201.
- O campo Repórter SSRC identifica o participante que enviou o relatório.
- O campo Reportee SSRC é a identificação da fonte de dados que está sendo
reportada.
- Fração de perdas, campo que indica o número de pacotes perdidos pelo
número de pacotes esperados.
- Número Acumulativo de pacotes perdidos. Este campo é um inteiro não
sinalizado de 24 bits e indica o número de pacotes esperados menos o número de
pacotes realmente recebidos. O número de pacotes recebidos é definido como sendo
o ultimo número de seqüência estendido menos o número inicial da seqüência.
- Maior número de seqüência estendido. Contem o número de seqüência
estendido gerado pelo ultimo pacote RTP recebido.
- Variância entre chegadas, também denominado Jitter. O Jitter entre chegadas é
uma estimativa da variância estatística do tempo de transito dos pacotes de dados
enviados pela fonte na sincronização reportada na rede. Este campo é informado em
unidades de tempo e o tamanho do campo é de 32 bits. Como normalmente os
relógios do emissor e do receptor não são sincronizados a aferição do tempo de
transito absoluto se torna muito difícil. Para contornar este problema é feito o calculo
do tempo de transito relativo. Este calculo é feito como sendo a diferença entre a
marca de relógio temporal do pacote RTP e o clock RTP do receptor no tempo da
chegada. O jitter entre chegadas J é definido como a diferença D correspondente ao
espaço de tempo entre a chegada de um par de pacotes, comparado com os tempos
estampados neste par de pacotes no momento do envio. Logo seja o timeStamp RTP
do pacote i e Ri o tempo de chegada de unidades de timestamp RTP do pacote i,
então dois pacotes i e j, D podem ser expresso como:
O jitter entre chegadas é calculado continuamente por uma equação filtrada desta
diferença. Toda vez que um relatório de recepção RR for montado, o valor corrente
deste J é amostrado. A RFC 1889 prescreve este calculo de jitter.
O jitter entre chegadas é calculado quando cada pacote é recebido, sendo
calculado como uma média em movimento, de acordo com a seguinte fórmula:
37
toda vez em que um relatório de recebimento é gerado o Ji é calculado e inserido
no campo interarrival jitter.
- Marca temporal do último relatório emissor (LSR). É a ultima marca temporal
inclusa no último pacote SR recebido da fonte reportada.
- Atraso desde o último relatório emissor (Delay since last sender report received
– DLSR). Tempo decorrido entre o recebimento do último relatório da fonte (SR) até o
envio do relatório de recepção. Unidade expressa em 1/65536 segundos.
4.5.3 Relatório do Emissor : RTCP SR
Os pacotes denominados Relatórios do emissor são enviados pelos participantes
que enviaram informações recentemente para uma sessão RTP. Este tipo de relatório
fornece informações a respeito do que está sendo enviada e serve principalmente para
sincronização entre mídias. Como, por exemplo, áudio e vídeo.
O número de identificação de um pacote do tipo SR é 200 e seu formato é como
demonstrado na Figura 4.7.
Figura 4.7 - Formato do pacote de relatório do emissor RTCP
Fonte: PERKINS, 2003
38
Como podemos verificar na Figura 4.7 Payload tem o tamanho de 24 bytes e
pode ser seguido por zero ou mais blocos contendo relatórios de recebimento, cujo
número de blocos são indicados no campo RC. Normalmente os blocos do relatório de
recebimento estão presentes quando o emissor também é um receptor.
- Marca temporal NTP. Valor não sinalizado de 64 bits e representa a hora no
formato NTP, que é a contagem em segundos desde 1 de janeiro de 1900(para os 32
bits superiores) e frações de segundo (para isso são usados os 32 bits inferiores) , do
momento do envio do relatório.
Marca temporal RTP. Corresponde ao mesmo momento da marca temporal
NTP, mas é expresso na unidade do clock da mídia RTP. Normalmente este valor não
será o mesmo da marca temporal do pacote de dados mais recente, já que esta
provavelmente foi amostrado há mais tempo.
Segundo WILLRICH(2004) “as marcas temporais são usadas para obter uma
correspondência entre o relógio de mídia e uma referência externa conhecida(o relógio
no formato NTP)”.
Contador de pacotes e de octetos do emissor
Contagem de pacotes enviados é a contagem de todos os pacotes de dados
enviados desde o início da sessão, já o contador de octetos é a contagem de bytes
contidos no payload dos pacotes de dados enviados(desconsiderando qualquer
cabeçalho). Com esses dois dados é possível para a aplicação poder calcular a taxa
média de dados de payload e a média dos pacotes enviados. WILLRICH(2004) afirma
que o valor da razão entre os dois será o tamanho médio do payload.
4.5.4 Descrição da fonte (Source Description – SDES):
Os pacotes do tipo SDES permitem a identificação dos participantes, esta identificação
pode conter detalhes como, localização, e-mail, telefone. WILLRICH(2004) afirma que
a descrição da fonte normalmente é informada pelo usuário e é normal que seja
apresentada em uma interface gráfica da aplicação.
A Figura 4.8 ilustra um pacote SDES. Poderemos verificar que o campo PT
possui o valor 202. PERKINS afirma que os pacotes SDES podem conter zero ou mais
39
listas de itens SDES e que essa quantidade exata é informada no campo do cabeçalho
SC.
Figura 4.8 - Formato do pacote de descrição da fonte RTCP
Fonte: PERKINS, 2003
PERKINS afirma que é possível uma aplicação gerar pacotes com o campo SC
igual a zero, mas normalmente este campo possui o valor 1. WILLRICH(2004)
afirma que mixes e tradutores podem gerar uma lista maior de itens SDES. Cada
lista de itens SDES são iniciadas SSRC da fonte sendo descrita. Seguida por
uma ou mais entradas. Cada entrada inicia com o campo tipo e tamanho,
seguido pelo texto do item no formato UTF-8.
4.5.5 Controle de membros da sessão (RTCP BYE)
Os pacotes do tipo RTCP BYE permitem a identificação de que o participante
emissor irá deixar a sessão ou quando é necessário alterar o seu SSRC devido a
alguma colisão. O valor do campo PT para esse tipo de pacote é 203, como
demonstrado na Figura 4.9. Segundo PERKINS(2003) o campo RC indica o número
de identificadores SSRC no pacote. WILLRICH(2004) afirma que “Na recepção de um
pacote BYE, uma implementação deveria assumir que os participantes contidos na
lista de fontes deixaram a sessão e ignorar qualquer pacote RTP ou RTCP vindo
destas fontes (possivelmente atrasados pela rede).”
40
Figura 4.9- Formato do pacote de Controle de membros da sessão RTCP
Fonte: PERKINS, 2003
Um pacote do tipo RTCP BYE pode conter as razões sobre o abandono da
sessão, esta informação pode ser mostrada na interface para o usuário.
4.5.6 Pacotes Definidos Pela Aplicação (RTCP APP)
Os pacotes do tipo RTCP APP permitem extensões definidas pela aplicação. O
valor do campo PT para este tipo de pacote é 204. Os pacotes definidos pela
aplicação são usados para exceções não padrões do RTCP e para testes de novas
funcionalidades.
41
5 ASTERISK
SPENCER(2003) diz que: “O Asterisk é um software TDM híbrido de código aberto,
uma plataforma IVR com funcionalidades ACD e uma plataforma de pacotes de voz
PBX”. SPENCER(2003) afirma também que possivelmente o Asterisk seja a melhor
ferramenta para integração de telecomunicações, devido a sua flexibilidade e
extensibilidade. O nome Asterisk provém do símbolo “*” que no UNIX é um caractere
coringa que representa qualquer nome de arquivo. O Asterisk PBX foi concebido para
integrar qualquer peça de telefonia, podendo ser disponibilizado em hardware ou
software.
Normalmente os produtos utilizados em telefonia são concebidos para atender um
objetivo específico, mas muitas aplicações em telefonia compartilham um grande
acordo tecnológico e o Asterisk toma vantagem desta característica criando um único
ambiente que tem a possibilidade de ser moldado para agregar aplicações em
particular ou várias aplicações, variando de acordo com a escolha do usuário. A
Tabela 5-1Error! Reference source not found. mostra as aplicações onde é possível
o uso do asterisk, podendo ele atender uma aplicação em específico ou todas as
aplicações simultaneamente sem que seja necessário nenhuma alteração entre as
interfaces.
Tabela 5-1 – Funções suportadas pelo Asterisk
Gateway VoIP Heterogêneo (MGCP, SIP, IAX, H.323)
PABX
Servidor IVR
Softswitch
Servidor de Audioconferência
Tradução de Número
Aplicação de Cartão Telefônico
Discador Preditivo
Fila de Chamadas com Agentes Remotos
Estágio Remoto offices para PABS existentes
Fonte: Spencer, 2003.
A forma mais indicada para a obtenção da versão mais atual do Asterisk é
através do repositório anônimo localizado em cvs.digium.com. A distribuição do
asterisk está sob os termos do GNU ou GPL; esta licença permite a distribuição do
42
código e dos binários do Asterisk com ou sem modificações, sem qualquer restrição de
uso ou de redistribuição do código. Esta licença não se estende ao hardware ou a
softwares utilizados pelo asterisk.
5.1 Tecnologias suportadas
Segundo SPENCER(2003), o Asterisk foi desenvolvido para que seja possível a
agregação de novas tecnologias e interfaces. A meta para isso é suportar todo o tipo
de tecnologia telefônica possível. Uma lista atualizada de hardware e protocolos
suportados
pelo
Asterisk
pode
ser
encontrada
no
site
da
digium
(.http://www.digium.com). Normalmente as interfaces são divididas em três categorias,
sendo elas:

Hardware Zaptel

Hardware não Zaptel

Pacotes de voz
5.1.1 Hardware Zaptel
Estas interfaces de hardware provêem integração com a telefonia convencional,
sendo ela digital ou analógica (incluindo conexões com a rede pública de comutação).
Adicionalmente, as interfaces que suportam Pseudo TDM da Zaptel podem ser
conectadas entre si, diminuindo a latência a um nível bem baixo.
As interfaces de rede do zaptel incluem conexões com: PSTN, POTS, T1, E1,
PRI, PRA, E&M, Wink e funcionalidades para Grupos D. As interfaces zaptel constam
na Tabela 5-2.
Tabela 5-2 - Tabela de Hardwares zaptel mais comuns
Hardware
TE410P
TE450P
TDM400P
T100P
E100P
X100P
Descrição
4xE1/T1-3,3V PCI
4xE1/T1 5V PCI
4FXS/FXO
1 T1
1 E1
1 FXO
Fonte: GONÇALVES, 2005
43
5.1.2 Hardware Não Zaptel
As interfaces de hardware não zaptel provêem conexão aos serviços telefônicos
convencionais e também a serviços telefônicos legados, mas neste caso não há
suporte de chaveamento Pseudo TDM. Dentre as Interfaces de hardwares não zaptel
estão inclusas:
Tabela 5-3 Lista de hardwares não Zaptel
ISDN4Linux . Basic Rate ISDN interface for Linux
OSS/Alsa . Sound card interfaces
Linux Telephony Interface (LTI) . Quicknet Internet
Phonejack/Linejack
Dialogic hardware1 . Full-duplex Intel/Dialogic hardware
Fonte: Spencer, 2003
5.1.3 Pacotes de voz
Estes são os protocolos padrão para a comunicação através de redes de pacotes
(IP e Frame Relay) e são as únicas interfaces que não necessitam de um hardware
especializado para funcionar. A Tabela 5-3 informa quais são os protocolos
suportados.
Tabela 5-4 - Protocolos suportados
Session Initiation Protocol (SIP)
Inter-Asterisk eXchange (IAX) versions 1 and 2
Media Gateway Control Protocol (MGCP)
ITU H.3232
Voice over Frame Relay (VOFR)
Fonte: Spencer, 2003
5.2 Visão geral da arquitetura
44
Figura 5.1 – Arquitetura básica do Asterisk
Fonte:GONÇALVES, 2005
A Figura 5.1 demonstra como é a arquitetura básica do Asterisk, explicaremos a
seguir os conceitos mais importantes relacionados a figura acima.
5.2.1 Canais
Segundo GONÇALVES (2005), um canal se equipara a uma linha telefônica na
forma de um circuito de voz digital, ou analógico. Normalmente consiste de um sinal
analógico em um sistemas POTS (Plain Old Telephony System) ou de alguma
combinação de CODEC e protocolo de sinalização (G.711 com SIP, GSM com IAX).
Os canais suportados pelo asterisk são:
 Agent: Um canal de agente DAC
 Console: Cliente do Shell do Linux, driver para placas de som (OSS ou ALSA)
 H323: Protocolo VoIP
 IAX e IAX2: Inter Asterisk Exchange Protocol, protocolo nativo do Asterisk.
 MGCP: Media Gateway Control Protocol, outro protocolo de VoIP
45
 Modem: Utilizados em linhas ISDN
 NBS: Utilizado para broadcast de som.
 Phone. Canal de telefonia do Linux.
 SIP
 Skinny: Um driver para o protocolo de telefones IP da CISCO.
 VOFR: Voz sobre Frame Relay
 VPB: Linhas telefônicas para placas Voicetronix
 ZAP: Driver para conectar telefones e placas da Digium
5.2.2 CODECS Suportados
Como vimos na seção 2.3.1 os codecs tem por objetivo utilizar da melhor forma
possível as características da rede. O Asterisk suporta os seguintes codecs:
 G.711 uLAw (Norte americano) e aLaw(Brasil e Europa)
 G.723.1 – Precisa de licenciamento e sua taxa de transmissão varia de
5.3 até 6 Kbps
 G.726 - 32Kbps
 G.729 – Precisa de licença, a não ser que seja para fins educacionais.
Sua taxa de transmissão é de 8 Kbps
 GSM – possui taxa de transmissão de 12 a 13 Kbps
 iLBC – taxa de transmissão de 15 Kbps
 LPC10 – este codec possui taxa de transmissão de 2,5Kbps
 Speex – Sua taxa varia entre 2,15 a 44,2 Kbps
5.2.3 Plano de discagem
Segundo GONÇALVES (2005) o plano de discagem é uma das peças mais
importantes do asterisk, pois ele define como serão tratados as ligações efetuadas e
recebidas. “É no extensions.conf que você controla todas as conexões através do seu
PABX” (GONÇALVES, 2005). O arquivo extensions.conf pode ser separado em
contextos e estensões, Golçalves afirma que os contextos são um agrupamento de
extenções, que tem por objetivo principal, organizar e dar segurança ao plano de
discagem.
GONÇALVES (2005) também afirma que o contexto está ligado
diretamente aos canais. Quando há uma ligação por um canal ela é processada por
46
esse canal. SPENCER(2003) afirma que após uma modificação no arquivo
extensions.conf é necessário recarregar n mínimo o plano de discagem novamente,
isso se da de forma manual, através do comando “extensions reload”, digitado na
interface com o Cliente (CLI).
5.2.4 Processo de instalação e configuração
O Asterisk foi instalado em uma distribuição do Debian 3.1 testing usando a
versão do kernel 2.6.13. Já a versão instalada do Asterisk foi a 1.0.9, que é a
distribuição estável no momento. Para que o modem seja reconhecido como um
hardware do tipo FXO foi preciso instalar os drivers da Zaptel (disponíveis no site ou
via CVS). Após a descompactação é necessário compilar e instalar o driver através
dos comandos:
make clean
make linux26
make install
Após a instalação dos módulos é necessário que eles sejam carregados. Para
isso utilizamos os comandos:
modprobe zaptel.
modprobe wcfxo
Após a instalação dos módulos é necessário configurar corretamente os drivers.
A configuração é feita através do arquivo zaptel.conf (Anexo I) localizado no diretório
/etc.
Terminado o processo de configuração do módulo de telefonia o Asterisk já pode
ser instalado. Como informado no capítulo 5 ele pode ser obtido através do site
http://www.asterisk.org ou via CVS.
Após o download e descompactação dos arquivos, os comandos para efetuar a
instalação do asterisk foram os seguintes:
make clean
make
make install
make samples
47
O comando make samples gera os arquivos de configuração já bastante
completos, os arquivos que necessitaram de algum tipo de modificação constam em
anexo, foram os arquivos: zapata.conf (Anexo II), o sip.conf (Anexo III) e o
extensions.conf (Anexo IV). Os demais aquivos permaneceram inalterados.
48
6 JXTA
JXTA é uma plataforma aberta para o desenvolvimento de redes peer-to-peer. Ele
é composto por blocos e serviços de fácil desenvolvimento. O JXTA provê um conjunto
de protocolos abertos e uma implementação baseada em código aberto para o
desenvolvimento de aplicações que fazem uso de redes peer-to-peer. A plataforma
JXTA possibilita a criação de uma rede virtual sobre uma rede já existente, ocultando
características complexas, com NAT e firewall. Ao contrário das aplicações clienteservidor tradicionais para troca de mensagens a rede virtual JXTA permite que
qualquer ponto interagir outro ponto da rede ou recurso diretamente, sem ser afetado
por
Firewalls
ou
tecnologias
de
rede.
A Figura 6.1 mostra um exemplo de como pode funcionar uma rede virtual.
Figura 6.1 - Rede Virtual
Fonte: Sun Microsystems
Criado pela Sun, o JXTA foi desenvolvido para ser independente da linguagem de
programação e também do protocolo de transporte. As linguagens de programação em
que os protocolos podem ser implementados são: JAVA, C/C++, Perl e várias outras
linguagens.
49
6.1 CAMADAS
A arquitetura do JXTA é dividida em camadas, como mostrada na Figura 6.2.
Figura 6.2 - Camadas da plataforma JXTA
Fonte: JXTA v2.3.x: Java Program Guide (2005)
Como demonstrado na Figura 6.2, a plataforma JXTA é dividida em três camadas,
sendo elas: Camada da Plataforma ou Núcleo, Camada de serviços, e camada de
Aplicação.

Camada da plataforma (núcleo): A camada da plataforma, também
conhecida como Núcleo JXTA, encapsula as primitivas mínimas, essenciais e
comuns para as redes Peer-to-peer. Isso inclui blocos chaves para aplicações
P2P como, por exemplo, descoberta, transporte, criação de peers, criação de
grupos e as primitivas de segurança necessárias.

Camada de serviços: esta camada inclui serviços de redes que não são
estritamente necessárias para o funcionamento das redes P2P, mas que podem
ser inclusos em um ambiente P2P. Dentre estes serviços estão compreendidos
os serviços de indexação, de diretórios, compartilhamento de arquivos, protocolos
de tradução, autenticação e serviços de PKI (Infra-estrutura de Chaves Públicas).

Camada de Aplicação: estão inclusos nesta camada as implementações
das aplicações integradas, mensagens instantâneas P2P, compartilhamento de
documentos e recursos, etc.
50
Normalmente o limiar entre serviço e aplicação não é muito rígido, pois o que
pode ser visto como aplicação por um pode ser visto como serviço pra outros. O
sistema inteiro foi desenvolvido para ser modular, permitindo que o desenvolvedor
escolha quais tipos de serviços serão utilizados.
6.2 Componentes principais do JXTA
6.2.1 Peer
Um peer é qualquer dispositivo conectado a rede e que implementa um ou mais
protocolos da plataforma JXTA, podendo ser um computador, um sensor, um PDA.
Cada peer opera de forma assíncrona e de forma independente de qualquer outro
peer. Um peer recebe um ID único que o identifica.
6.2.2 Grupo de Peers
Um grupo de peers é uma coleção de peers que agregam uma série de
serviços comuns. Normalmente os peers se auto organizam em grupos, que são
identificados através de um identificador único (ID). Qualquer grupo pode estabelecer
uma política de ingresso no grupo, aumentando assim a segurança e proteção.
Os peers podem participar de mais de um grupo ao mesmo tempo. E por
padrão o primeiro grupo que é instanciado é o “Net Peer Group” e posteriormente os
peers podem escolher entrar em algum grupo adicional. Os protocolos JXTA
descrevem como peers poderão divulgar, descobrir, entrar e monitorar esses grupos
de peers. Há uma série de motivos para a criação e utilização de grupos, os principais
motivos são:

Criar um ambiente seguro – As políticas de segurança do grupo podem variar
de acordo com a necessidade. Esta política pode ser simples, como enviar o
nome de usuário e senha através de um arquivo de texto plano, ou complexa
com o uso da estrutura de chaves públicas.

Criar um ambiente de interesses mútuos – O exemplo mais comum de
interesses mútuos é o auto-agrupamento para compartilhamento de
documentos e recursos de processamento.

Criar um ambiente para monitoramento – Os grupos de peers permitem que
exista o monitoramento do estado de um conjunto de peers para algum
propósito específico.
51
Os grupos podem possuir hierarquia de pais e filhos. No caso de alguma
pesquisa no grupo filho essa pesquisa é repassada para o grupo pai.
Normalmente os grupos de peers oferecem uma série de serviços. O JXTA
define uma série de serviços oferecidos pelos grupos, mas serviços adicionais podem
ser implementados pelo desenvolvedor. Para que possa haver interação entre os
peers através dos serviços do grupo é necessário que os peers façam parte deste
grupo.
6.2.3 Serviços de Rede
Os peers cooperam entre si e comunicam-se para publicação, descoberta e
invocação dos serviços de rede. Normalmente os peers podem publicar múltiplos
serviços de rede. Os serviços de rede são descobertos através do Peer discovery
Protocol (PDP).
Os protocolos da plataforma JXTA conhecem dois níveis de serviços, os Serviços
de peers e os Serviços dos grupos de peers.
6.2.4 Dutos(pipes)
Os dutos são usados para o envio e recebimento de mensagens de um peer para
outro. A comunicação entre os dutos é assíncrona e unidirecional e sem
confiabilidade. O mecanismo de dutos pode ser utilizado para a comunicação ou
transferência de dados e eles suportam a transferência de qualquer tipo de objeto.
Incluindo código binário, cadeia de dados e objetos baseados na tecnologia JAVA.
Os dutos das extremidades são referenciados como sendo dutos de entrada
(input pipes) e dutos de saída (outputs pipes) é como são referenciados os dutos
usados para o envio.
Os dutos são uma comunicação virtual entre os peers, não tendo a necessidade
de uma conexão física entre os dois equipamentos das pontas. Em alguns casos
peers intermediários podem ser utilizados para prover a conexão.
Os dutos fornecem dois modos de comunicação, um é ponto a ponto e o outro
por propagação.
52
6.2.5 Mensagens
As mensagens são objetos enviados através dos peers. Elas são a base para
troca de dados entre os peers. Os serviço dos dutos (Pipe services) são utilizados
normalmente para criar, enviar e receber as mensagens, outra forma pra troca de
mensagens. Pode ser pelos serviços dos terminais (endpoint services).
Uma mensagem é ordenada seqüencialmente pelo nome e conteúdo descrito,
chamado de elemento da mensagem. As mensagens são basicamente um conjunto de
pares nome/conteúdos.
Existem dois tipos de representação para as mensagens: em formato XML ou
binários. A plataforma JXTA J2SF faz o uso do formato binário para o envio do
payload das mensagens. Os serviços podem enviar as mensagens no formato mais
apropriado para a situação.
6.2.6 Anúncios (Advertisements)
Todos os recursos de rede JXTA são representados através de um
anúncio(advertisement). Os anúncios são uma linguagem meta-dados neutra e são
representadas como sendo documentos XML. Os protocolos JXTA fazem uso desses
anúncios para efetuar a publicação da existência dos recursos de um peer. Os
recursos são descobertos pelos peers através da procura de seu anúncio
correspondente. O resultado da busca pode ser armazenado localmente para possível
próxima utilização.
Cada anúncio é publicado com um tempo de vida especificando a disponibilidade
do serviço associado ao anúncio. Os recursos com tempo de vida terminados podem
ser removidos sem qualquer controle centralizado. Um anúncio pode ser republicado
para que este tenha seu tempo de vida prolongado.
Os protocolos JXTA definem vários tipos de anúncios. Os mais conhecidos são:

Anúncios de peers (Peers Advertisement) Contem informações referentes aos
recursos disponíveis nos peers. O uso principal deste tipo de anuncio é manter
informações a respeito do peer, como nome, ID, etc.

Anúncios de Grupos de peers (Peers Group Advertisement) Descreve os
recursos específicos daquele grupo. Como Nome, ID, descrição, etc.

Anúncio de encontro (Rendezvous Advertisement) Descreve como um peer irá
encontrar outro peer num grupo.
53
6.2.7 Identificadores (IDs)
Todos os componentes, recursos necessitam ser exclusivamente identificados.
Os identificadores (ID) JXTA são usados como uma das únicas formas de conhecer as
entidade e servidores, como um nome canônico de referência desta unidade.
Atualmente há seis tipo sde identificadores, que são: peers, grupos de peers, dutos,
conteúdos, classes de módulos e especificações de módulos.
6.3 Protocolos JXTA
A especificação da plataforma JXTA define uma série de formatos para as
mensagens XML, ou protocolos, para a comunicação entre os peers. Estes protocolos
são utilizados pelos peers para, descobrir um ao outro, trocar mensagens, descobrir
serviços de rede e descobrir a rota das mensagens trocadas entre eles.
Os principais protocolos são:

Peer Discovery Protocol (PDP) – Usado pelos peers para anunciar os recursos
próprios e também para descobrir recursos de outros peers.

Peer Information Plrotocol (PIP) – Usado pelos peers para obter informações a
respeito de outros peers (status, tempo ativo, tráfego recente)

Peer Resolver Protocol (PRP) – Este protocolo permite que os peers enviem
uma consulta genérica para um ou mais peers e receba uma ou mais respostas
para esta consulta. Ao contrário do PIP e do PDP, que utilizam informações
específicas e pré-definidas para consultas, o PRP permite que o serviço do peer
defina arbitrariamente a informação que ele necessite procurar.

Pipe Binding Protocol (BPB) – usado pelos peers para estabelecer um canal de
comunicação, ou um duto entre um ou mais peers.

Endpoint Routing Protocol (ERP) – usado pelos peers para encontrar rotas para
as portas de destino dos outros peers.

Rendezvous Protocol (RVP) – Mecanismo que permite aos peers se associar
ou permitir que outros se associem a um serviço de propagação. O RVP é
utilizado pelo PRP e pelo PBP pra a propagação de mensagens.
54
7 A REDE DE GATEWAYS PEER-TO-PEER
7.1 Descrição da aplicação
Atualmente a maioria das soluções de Gateway VoIP envolve um custo elevado
e um trabalho complexo para configuração dos gateways. Uma das intenções deste
trabalho foi encontrar uma solução que fosse acessível para a maioria das pessoas,
tanto
economicamente
quanto
em
relação
à
complexidade
envolvida
para
configuração.
Este trabalho se propõe a criar uma rede de gateways de baixo custo
conectados através de uma rede peer-to-peer que permita o roteamento da chamada
entre os gateways que fazem parte da rede.
7.2 Tecnologias utilizadas
A primeira parte deste trabalho foi encontrar uma forma de criar um gateway
VoIP/PSTN. Após uma extensiva pesquisa sobre a viabilidade de se criar uma
ferramenta que funcionasse de acordo com o esperado, foi resolvido adotarmos uma
ferramenta disponível atualmente no mercado. A escolha do ASTERISK se deu pelo
fato de ser de código aberto, e já fornecer suporte para modems do tipo voicemodem,
como canal de conexão com o sistema de telefonia convencional.
A segunda parte do trabalho consiste no desenvolvimento de uma rede peer-topeer para a conexão e comunicação entre os gateways. Esta aplicação deverá
funcionar em conjunto com a ferramenta ASTERISK. A linguagem de programação
utilizada para a criação da aplicação foi a linguagem JAVA da Sun Microsystems.
devido a um maior domínio desta linguagem. A API utilizada para a construção da
rede de gateways foi a JXTA também desenvolvida pela Sun.
Para demonstrarmos a conexão com a rede peer-to-peer, utilizaremos uma
aplicação simples que fará a conexão, a entrada no grupo, a descoberta dos peers na
rede e também o envio e recebimento de mensagens (requisitos mínimos para
funcionamento da rede de gateways).
55
7.3 Escopo da aplicação
Na atual fase do trabalho, a aplicação ficará restrita à construção de um
programa para troca de mensagens entre os nós da rede P2P, ficando a integração
com o asterisk para uma etapa posterior.
A aplicação deve ter as seguintes funcionalidades:
- Permitir a conexão com a rede peer-to-peer
- Permitir o ingresso no grupo “VoIPGateways”, criado especificamente para
este esta aplicação
- Permitir busca por peers na rede P2P.
- Permitir o envio de mensagens para peers conhecidos; como não é intenção
da aplicação o envio de mensagens do tipo multicast, as mensagens devem ser
enviadas para um peer de cada vez.
- Permitir o recebimento de mensagens de peers conhecidos e desconhecidos.
7.4 Desenvolvimento da aplicação
A aplicação está estruturada em três pacotes principais: o Gerente, que é
responsável por criar as duas outras classes, a casse ResponsavelRede, localizada no
pacote
redepeertopeer
e
a
classe
InterfaceGrafica
localizada
no
pacote
interfacegrafica. O objetivo de a aplicação ser desenvolvida em pacotes é justamente
separar a implementação dos serviços de rede, dos serviços referentes à interface e
do gerenciamento da aplicação.
56
Figura 7.1 - Diagrama principal
Como é mostrado na Figura 7.1, a Classe Gerente (Anexo V) é responsável
pela criação e integração entre a interface e a rede. A classe interface possui os
métodos específicos da interface gráfica e alguns métodos de validação, para garantir
que não haja inconsistências nos dados fornecidos a classe ResponsavelRede.
7.4.1 Implementação da rede
O pacote redepeertopeer possui as classes mostradas na Figura 7.2 e o código fonte
da aplicação se encontra no Anexo VI.
57
Figura 7.2 - Classes do pacote redepeertopeer
O pacote redepeertopeer é composto por seis classes que juntas dão as
funcionalidades utilizadas na rede peer-to-peer, que são a conexão na rede, a entrada
no grupo, a localização de peers e a troca de mensagens utilizando dutos (pipes). As
classes são as seguintes:

ResponsavelRede: Classe que efetua a criação dos objetos responsáveis pela
rede e pela delegação de tarefas. Esta classe serve como interface com os
métodos da rede. Os principais métodos são:
o ResponsavelRede: Método que inicializa os parâmetros da rede.
o Conecta: Método cujos objetivos são conectar ao grupo (rendezvous),
entrar no grupo “VoIPGateways” e definir como monitor das mensagens
recebidas a classe RecebedorDeMSG utilizando a classe CriadorDeAdv
para gerar um documento válido e com um ID fixo.
o Desconecta: Este método serve para parar o “Rendezvous”.
o getMensagensRecebidas: este método tem como retorno um array de
String onde os índices de valor par são o identificador da fonte que está
enviando e o valor impar subseqüente consiste na mensagem recebida.
58
o descubraPeers: Método responsável pela localização dos peers através
de um conjunto de caracteres passados pela interface do usuário. Este
valor representa na rede peer-to-peer o código de país e código de área
do gateway que efetuará a conexão com a rede pública de telefonia.
o envia_MsgPeer: Método com a função de enviar uma mensagem
específica para um peer específico.

CriadorDeAdv: Classe responsável por criar os PipesAdversments que são
documentos que contém informações que possibilitam a troca de mensagens
entre dois peers; o documento está em XML, como demonstra este exemplo de
documento a seguir:
<!DOCTYPE jxta:PipeAdvertisement>
<jxta:PipeAdvertisement xmlns:jxta="http://jxta.org">
<Id>
urn:jxta:uuid-3230313534384736B531B035373938372D31333235324032B436B604
</Id>
<Type>
JxtaUnicast
</Type>
<Name>
Inominavel...
</Name>
</jxta:PipeAdvertisement>

EnviadorDeMsg: Classe responsável pelo envio das mensagens repassadas
pela classe ResponsavelRede, que possui dois métodos principais: enviaMsg,
que cria a mensagem propriamente dita, incluindo na mensagem o destinatário
e gerando um evento para o método outputPipeEvent, que é a forma de enviar
a mensagem gerada pelo método enviaMensagem.

IngressadorGrupo: Esta classe é responsável por enviar a pesquisa pelo grupo
VoIPGateways e caso não localize um gateway para estabelecer a ligação, cria
um grupo com este nome, e com um ID específico. Se o grupo existir ele será
obtido pela classe EscutadorGrupo.

RecebedorDeMsg: Classe responsável pelo recebimento e armazenamento
temporário das mensagens.
7.4.2 Interface Gráfica
59
A interface gráfica foi desenvolvida de forma simples e rápida; para isso
utilizamos a ferramenta de desenvolvimento NetBeans. Foi priorizada a elaboração de
uma interface simples e amigável que servisse ao propósito da aplicação,
possibilitando a demonstração da funcionalidade do pacote redepeertopeer.
A maioria dos componentes utilizados na interface faz parte da biblioteca Swing,
que faz parte da biblioteca padrão do JAVA. A Figura 7.3 mostra como é a interface
com o usuário.
Figura 7.3 – Tela inicial do programa
As opções de conectar, desconectar e sair pode ser encontradas nos botões
mostrados na Figura 7.3 ou no menu “Arquivo”.
O Botão Envia MSG abrirá a janela para a digitação da mensagem somente se
a aplicação estiver conectada e a pesquisa retornar no mínimo um peer e ele estiver
selecionado.
O botão Limpar Resultados limpa a lista de peers localizados.
Ver Detalhes apresenta uma janela com os dados do peer selecionado.
60
O botão Pesquisar serve para localizar peers cujo valores iniciam com 2
caracteres numéricos que serão usados para a localização dos peers, estes valores
representam o código de país seguido pelo código de área, ao final da procura o
resultado mostrado para o usuário como mostrado na Figura 7.4.
Figura 7.4 – Valor e resultados da pesquisa
As mensagens recebidas e armazenadas pelo pacote redepeertopeer são
mostradas na parte inferior da janela, como mostrado na Figura 7.5. Para que a
verificação de mensagens ocorra sem a necessidade de o usuário executar um
comando, as mensagens são carregadas de forma automática na interface, através de
uma thread.
61
Figura 7.5 - Mensagens recebidas
O código fonte da interface gráfica se encontra no anexo Anexo VII
62
8 CONCLUSÃO
A telefonia IP hoje em dia está muito presa ao valor dos equipamentos que
possibilitam a conexão entre o VoIP e a telefonia convencional. Neste trabalho
verificamos a existência de uma ferramenta que possibilite a conexão do VoIP com a
telefonia convencional de uma forma consideravelmente barata, tendo como único
custo necessário a aquisição de um modem específico.
A plataforma JXTA se mostrou essencial para a criação da rede peer-to-peer
para a conexão dos peers. O fato de a tecnologia ser aberta e devido sua
independência de plataforma e protocolo de comunicação esta provavelmente será
uma das áreas que terá um crescimento considerável em pouco tempo.
Na construção de nossa aplicação conseguimos demonstrar a possibilidade de
conectamos via rede peer-to-peer várias máquinas geograficamente separadas.
Mesmo sem conhecer os membros que estão conectados a rede peer-to-peer a
plataforma JXTA possibilita a localização dos peers, que, até então, eram
desconhecidos, e possibilite a troca de informações através dos componentes
fornecidos pelo JXTA,
As dificuldades encontradas no decorrer do desenvolvimento do trabalho em sua
maioria referentes à tentativa de integrarmos a ferramenta de rede com o gateway
VoIP. Coisa que não foi possível devido a limitação de tempo e conhecimento da
linguagem em que o Gateways foi desenvolvido. Outra dificuldade encontrada no
desenvolvimento do trabalho foi referente a Plataforma JXTA que tem sua bibliografia
consideravelmente restrita e em determinados momentos de difícil entendimento.
As sugestões para trabalhos futuros é a mudança de plataforma da aplicação para
a linguagem C++ pra Linux e fazer a conexão com o Gateway VoIP.
63
9 Bibliografia
FERNANDES, N. L. L. RELAÇÃO ENTRE A QUALIDADE DAS RESPOSTAS DAS
RECOMENDAÇÕES G.723.1 E G.729, E O COMPORTAMENTO DA REDE IP DE
SUPORTE. 2003. 170f. Dissertação (Mestrado em Ciências em Engenharia De
Sistemas e Computação). – Faculdade de Engenharia de Sistemas e Computação,
Universidade Federal do Rio de Janeiro, Rio de Janeiro 2003.
MONTEIRO, T. L. SOLUÇÃO DE TELEFONIA IP EM UMA REDE PRIVATIVA DE
SOLUÇÕES MISTAS. 2003. 160f Dissertação (Mestrado em Ciências da
Computação). – Faculdade de Ciências da Computação, Universidade Federal de
Santa Catarina, Florianópolis 2003.
MONTEIRO, R. F. Implementação de Transporte Robusto de Voz em Redes
Baseadas em Protocolos IP. 2000. 85 f. Dissertação de Mestrado (Engenharia
Elétrica) - Universidade Federal de Minas Gerais, Belo Horizonte. 2000
ZURMELY, R. Digitalização - Digitalização De Um Sinal Analógico – Disponível em
http://paginas.terra.com.br/lazer/py4zbz/teoria/digitaliz.htm acessado em 15 de
novembro de 2005.
ZURMELY, R. Digitalização - Quantização E Codificação – Disponível em
http://paginas.terra.com.br/lazer/py4zbz/teoria/quantiz.htm acessado em 15 de
novembro de 2005.
ROSENBERG, et. al. RFC 3261 - SIP: Session Initiation Protoco. EUA, 2002. 260 p.
O’DOHERTY, P. JAIN SIP Tutorial: Serving the Developer Community. Sun
Microsystem. EUA 2003. 49 p.
PERKINS, C. RTP: Audio and Video for the Internet. EUA, 2003. 472 p.
SPENCER, M Asterisk Handbook - Draft. EUA: Digium, 2003. 71 p.
GONÇALVES, F, E de A. ASTERISK pbx: Guia de configuração. Florianópolis:
V.Office Networks, 2005. 251 p
64
JXTA v2.3.x: Java™ Programmer’s Guide. Sun Microsystems, 2005. 147 p.
Project JXTA Technology: Creating Connected Communities. Sun Microsystems,
2002
WILLRICH, R. Sistemas Multimídia Florianópolis: UFSC, 2004. 151 p.
65
10 Anexos
Anexo I. – Arquivo zaptel.conf.
#=========================================
#Zaptel.conf
#arquivo de configuração Para a Placa genériaca XP100 da Digium
#
loadzone = us
defaultzone = us
fxsks = 1
#==================================
Anexo II. Arquivo de Configuração zapata.conf
;========================================
; Zapata telephony interface
;
; Arquivo de Configuracao zapata.conf
[trunkgroups]
[channels]
context=default
switchtype=national
signalling=fxo_ls
rxwink=300
usecallerid=yes
hidecallerid=no
callwaiting=yes
usecallingpres=yes
callwaitingcallerid=yes
threewaycalling=yes
transfer=yes
cancallforward=yes
callreturn=yes
echocancel=yes
echocancelwhenbridged=yes
rxgain=0.0
txgain=0.0
group=1
callgroup=1
pickupgroup=1
immediate=no
;================================================
;fim arquivo zapata.conf
;===================================================
Anexo III. Arquivo de configuração sip.conf
;====================================
; Aquivo sip.conf
66
;=====================================
[general]
context=default
port=5060
bindaddr=0.0.0.0
srvlookup=yes
disallow=all
allow=ulaw
[1001]
type=friend
username=redips
secret=minha_senha
host=dynamic
mailbox=1001
[2002]
type=friend
username=dips
secret=outra_senha
host=dynamic
mailbox=2002
;========================================
; Fim arquivo SIP.conf
;========================================
Anexo IV. Arquvo de Configuração Extension.conf
;=========================================
; Arquivo extensions.conf
;=========================================
[general]
[globals]
CONSOLE=Zap/1
[default]
;--------------------------------; Ligacoes entrantes sao encaminhadas para o usuario sip dips
exten => s,1,Dial(SIP/1001,10,tT)
exten => s,2,Hangup
; ---------------------------------------------;
;------------------------------------------; Ligacao internas com 4 digitos sao encaminhadas para o usuario sip
correspondente
;
exten => _XXXX,1,Dial(SIP/${EXTEN},20)
exten => _XXXX,2,Hangup
;-------------------------------------------------;----------------------------------------------------;---------------------------------------------------;ligacoes internas com 8 digitos sao realizadas como ligacoes locais.
67
exten => _XXXXXXXX,1,Dial(${CONSOLE}/${EXTEN},20)
exten => _XXXXXXXX,2,Hangup
;========================================
;Fim Arquivo extensions.conf
;=============================================
68
Anexo V.
-
Código Fonte Gerente.java
package gerenciamento;
import interfacegrafica.InterfaceGrafica;
import redepeertopeer.ResponsavelRede;
/**
*
* @author REDIPS
*/
public class Gerente {
private ResponsavelRede umCaraDaRede;
private InterfaceGrafica umaI;
/** Creates a new instance of Gerente */
public Gerente() {
umCaraDaRede = new ResponsavelRede();
umaI = new InterfaceGrafica();
umaI.conhecaResponsavelRede(umCaraDaRede);
}
public void vai(){
umaI.show();
umaI.run();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Gerente umGerente = new Gerente();
umGerente.vai();
// TODO code application logic here
}
}
69
Anexo VI. Código Fonte das classes pertencentes ao pacote redepeertopeer
-
CriadorDeAdv.java
package redepeertopeer;
import
import
import
import
import
import
net.jxta.id.IDFactory;
net.jxta.peer.PeerID;
net.jxta.peergroup.PeerGroup;
net.jxta.peergroup.PeerGroupID;
net.jxta.protocol.PipeAdvertisement;
net.jxta.util.PipeUtilities;
/**
*
* @author REDIPS
*/
public class CriadorDeAdv {
private PeerGroupID pGID;
/**
* Creates a new instance of CriadorDeAdv
*/
public CriadorDeAdv() {
}
public synchronized PipeAdvertisement getPipeadv(){
PipeAdvertisement pipeAdv = null;
try{
pipeAdv = PipeUtilities.createPipeAdvertisement();
pipeAdv.setPipeID(IDFactory.newPipeID(this.pGID,
(this.pGID.hashCode()+"").getBytes()));
pipeAdv.setName("Inominavel...");
System.out.println(pipeAdv.toString());
}catch(Exception e){System.out.println("Deu erro no
Adv#"+e.getLocalizedMessage());}
return pipeAdv;
}
public synchronized PipeAdvertisement getPipeadv(PeerGroupID pGID){
PipeAdvertisement pipeAdv = null;
try{
pipeAdv = PipeUtilities.createPipeAdvertisement();
pipeAdv.setPipeID(IDFactory.newPipeID(pGID,
(this.pGID.hashCode()+"").getBytes()));// Usando o
ID do grupo como seed ainda sem uso....
pipeAdv.setName("Inominavel...");
System.out.println(pipeAdv.toString());
}catch(Exception e){System.out.println("Deu erro no
Adv#"+e.getLocalizedMessage());}
return pipeAdv;
}
public synchronized PipeAdvertisement getPipeadv(PeerGroupID pGID,
PeerID idPeer){
PipeAdvertisement pipeAdv = null;
70
try{
pipeAdv = PipeUtilities.createPipeAdvertisement();
pipeAdv.setPipeID(IDFactory.newPipeID(pGID,
idPeer.toString().getBytes()));
pipeAdv.setName("Inominavel...");
System.out.println("Peer Local......"+pipeAdv.toString());
}catch(Exception e){System.out.println("Deu erro no
Adv#"+e.getLocalizedMessage());}
return pipeAdv;
}
public synchronized PipeAdvertisement getPipeadv(PeerID idPeer){
PipeAdvertisement pipeAdv = null;
try{
pipeAdv = PipeUtilities.createPipeAdvertisement();
pipeAdv.setPipeID(IDFactory.newPipeID(this.pGID,
(idPeer.hashCode()+"").getBytes()));// Usando o ID
do grupo como seed ainda sem uso....toString().getBytes())); // Usando o ID
do destino como seed variaremos o id pra conectar....
pipeAdv.setName("Inominavel...");
System.out.println("Peer Local......"+pipeAdv.toString());
}catch(Exception e){System.out.println("Deu erro no
Adv#"+e.getLocalizedMessage());}
return pipeAdv;
}
/**
* Setter for property pGID.
* @param pGID New value of property pGID.
*/
public void setPGID(PeerGroupID pGID) {
this.pGID = pGID; // Define o pGID como sendo o ID do Grupo...
necessário para a criação de um pipe...
}
}
71
Classe EnviadorDeMensagens.java
/*
* EnviadorDeMensagens.java
*
* Created on 1 de Novembro de 2005, 03:22
*
* To change this template, choose Tools | Options and locate the
template under
* the Source Creation and Management node. Right-click the template
and choose
* Open. You can then make changes to the template in the Source
Editor.
*/
package redepeertopeer;
import
import
import
import
import
java.io.IOException;
net.jxta.discovery.DiscoveryService;
net.jxta.endpoint.Message;
net.jxta.endpoint.StringMessageElement;
net.jxta.pipe.*;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
java.io.IOException;
java.io.StringWriter;
java.util.ArrayList;
net.jxta.discovery.DiscoveryService;
net.jxta.exception.PeerGroupException;
net.jxta.peergroup.PeerGroup;
net.jxta.peergroup.PeerGroupFactory;
net.jxta.rendezvous.RendezVousService;
net.jxta.discovery.DiscoveryEvent;
net.jxta.discovery.DiscoveryListener;
net.jxta.protocol.DiscoveryResponseMsg;
net.jxta.protocol.PeerGroupAdvertisement;
java.util.Enumeration;
java.util.Vector;
net.jxta.credential.AuthenticationCredential;
net.jxta.credential.Credential;
net.jxta.document.*;
net.jxta.endpoint.Message;
net.jxta.endpoint.MessageElement;
net.jxta.endpoint.StringMessageElement;
net.jxta.id.IDFactory;
net.jxta.membership.Authenticator;
net.jxta.membership.MembershipService;
net.jxta.peer.PeerID;
net.jxta.peergroup.PeerGroupID;
net.jxta.protocol.PeerAdvertisement;
net.jxta.protocol.PipeAdvertisement;
net.jxta.util.PipeUtilities;
/**
*
* @author REDIPS
*/
public class EnviadorDeMensagens implements OutputPipeListener{
static PeerGroup netPeerGroup
= null;
72
static PeerGroup teste = null;
private RendezVousService rdv;
boolean descobriu = false;
private ArrayList listaPeers;
private Message msg;
private InputPipe pipeIn = null;
private IngressadorGrupo ingressadorGrupo;
/** Creates a new instance of EnviadorDeMensagens */
private DiscoveryService descobridor;
public EnviadorDeMensagens() {
this.msg = new Message();
}
public synchronized void enviaMsg(String mensagem,
PipeAdvertisement pipeADV) {
System.out.println("inicio metodo envia msn do enviador");
this.msg.clear();
enviou = false;
try {
descobridor.getRemoteAdvertisements(null,
DiscoveryService.ADV, null, null, 1, null);
if (msg!=null){
this.msg.addMessageElement(new
StringMessageElement(null, mensagem, null));
}
pipe.createOutputPipe(pipeADV, this);
System.out.println("Chegou até aqui....");
} catch (IOException e) {
System.out.println("OutputPipe creation failure");
e.printStackTrace();
System.exit(-1);
}
System.out.println("Chegou até aqui....(Fim método
enviaMSG"+pipeADV);
}
public synchronized void enviaMsg(String mensagem, String sender,
PipeAdvertisement pipeADV) {
this.msg.clear();
enviou = false;
System.out.println("inicio metodo envia msn do enviador");
try {
descobridor.getRemoteAdvertisements(null,
DiscoveryService.ADV, null, null, 1, null);
if (msg!=null){
this.msg.addMessageElement("Sender", new
StringMessageElement("Sender", sender, null));
this.msg.addMessageElement(new
StringMessageElement(null, mensagem, null));
}
pipe.createOutputPipe(pipeADV, this);
System.out.println("Chegou até aqui....");
} catch (IOException e) {
System.out.println("OutputPipe creation failure");
73
e.printStackTrace();
System.exit(-1);
}
System.out.println("Chegou até aqui....(Fim método enviaMSG");
}
public synchronized void outputPipeEvent(OutputPipeEvent event) {
System.out.println(" Ativou o outputEvent...");
OutputPipe op = event.getOutputPipe();
Message msg = null;
try {
op.send(this.msg);
} catch (IOException e) {
System.out.println("failed to send message");
e.printStackTrace();
System.exit(-1);
}
op.close();
System.out.println("message sent");
this.enviou = true;
}
/**
* Setter for property descobridor.
* @param descobridor New value of property descobridor.
*/
public void setDescobridor(DiscoveryService descobridor) {
this.descobridor = descobridor;
}
/**
* Holds value of property enviou.
*/
private boolean enviou;
/**
* Getter for property enviou.
* @return Value of property enviou.
*/
public boolean isEnviou() {
return this.enviou;
}
/**
* Holds value of property pipe.
*/
private PipeService pipe;
public void setPipe(PipeService pipe) {
this.pipe = pipe;
}
}
74
Classe EscutadorGrupo.java
/*
* EscutadorGrupo.java
*
* Created on 30 de Outubro de 2005, 16:07
*
* To change this template, choose Tools | Options and locate the
template under
* the Source Creation and Management node. Right-click the template
and choose
* Open. You can then make changes to the template in the Source
Editor.
*/
package redepeertopeer;
import
import
import
import
import
import
import
import
java.util.Enumeration;
net.jxta.discovery.DiscoveryEvent;
net.jxta.discovery.DiscoveryListener;
net.jxta.discovery.DiscoveryService;
net.jxta.peergroup.PeerGroup;
net.jxta.protocol.DiscoveryResponseMsg;
net.jxta.protocol.PeerAdvertisement;
net.jxta.protocol.PeerGroupAdvertisement;
/**
*
* @author REDIPS
*/
public class EscutadorGrupo implements DiscoveryListener
private boolean encontrou;
private PeerGroupAdvertisement grupoAdv;
{
/** Creates a new instance of EscutadorGrupo */
public EscutadorGrupo() {
encontrou = false;
grupoAdv = null;
}
public synchronized void discoveryEvent(DiscoveryEvent ev) {
this.setEncontrouFalso();
if(!encontrou) {
DiscoveryResponseMsg res = ev.getResponse();
//
//
int tipoEvento = res.getDiscoveryType();
PeerGroup pg;
System.out.println(" Got a Discovery Response [" +
res.getResponseCount()+ " elements]");
PeerGroupAdvertisement adv = null;
Enumeration en = res.getAdvertisements();
if (en != null ) {
encontrou = true;
while (en.hasMoreElements()) {
adv = (PeerGroupAdvertisement) en.nextElement();
System.out.println(" Peer Group Name = " +
adv.getName());
System.out.println(" Peer Group description = " +
adv.getDescription());
75
System.out.println(" Peer Group ID = " +
adv.getID());
encontrou = true;
this.grupoAdv = adv;
}
}
}
}
/**
* Getter for property encontrou.
* @return Value of property encontrou.
*/
public boolean isEncontrou() {
return this.encontrou;
}
/**
* Holds value of property grupoAdv.
*/
/**
* Getter for property grupo.
* @return Value of property grupo.
*/
public PeerGroupAdvertisement getGrupoAdv()
{
return this.grupoAdv;
}
/**
* Setter for property encontrou.
* @param encontrou New value of property encontrou.
*/
public void setEncontrouFalso() {
this.encontrou = false;
}
}
76
Classe IngressadorGrupo.java
package redepeertopeer;
import java.io.StringWriter;
import java.util.ArrayList;
import net.jxta.credential.AuthenticationCredential;
import net.jxta.credential.Credential;
import net.jxta.discovery.DiscoveryListener;
import net.jxta.peergroup.PeerGroup;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredTextDocument;
import net.jxta.endpoint.Message;
import net.jxta.id.IDFactory;
import net.jxta.membership.Authenticator;
import net.jxta.membership.MembershipService;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.ModuleImplAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.rendezvous.RendezVousService;
public class IngressadorGrupo{
EscutadorGrupo ouvidor;
//
static PeerGroup netPeerGroup = null;
private DiscoveryService discovery;
private RendezVousService rdv;
static PeerGroup teste = null;
boolean descobriu = false;
private ArrayList listaPeers;
private PipeAdvertisement pipeAdv, pipeAdvEntrada;
private PipeService pipe;
private Message msg;
private InputPipe pipeIn = null;
public IngressadorGrupo() {
ouvidor = new EscutadorGrupo();
}
private void mandarequisicao() {
ouvidor.setEncontrouFalso();
this.discovery.addDiscoveryListener((DiscoveryListener)ouvidor);
int cont = 0;
try {
// Add ourselves as a DiscoveryListener for
DiscoveryResponse events
while ((!(ouvidor.isEncontrou())&&(cont<5))) {
System.out.println("Sending a Discovery Message");
discovery.getRemoteAdvertisements(null,
DiscoveryService.GROUP,
77
"Name", "VoIPGateways", 1);
cont++;
try {
Thread.sleep( 5* 1000);
} catch(Exception e) {}
}
} catch(Exception e) {
e.printStackTrace();
}
//
System.exit(0);
}
public synchronized PeerGroup crieGrupo(PeerGroup nPG,
DiscoveryService discovery ) {
PeerGroup retorno;
this.discovery = discovery;
PeerGroupAdvertisement adv; // advertisement for the new Peer
group
System.out.println("Creating a new group advertisement");
this.mandarequisicao();
try {
if(!(ouvidor.isEncontrou())){
System.out.println("Não encontrou? Encontrou!!!!!");
// create a new all purpose peergroup.
ModuleImplAdvertisement implAdv =
nPG.getAllPurposePeerGroupImplAdvertisement();
//
nPG.
retorno =
nPG.newGroup(IDFactory.newPeerGroupID("201548765105798765207289654213232985
463136546".getBytes()) ,
// Assign new group ID
implAdv,
// The implem. adv
"VoIPGateways",
// The name
"grupo de gateways Voip"); // Helpful descr.
// print the name of the group and the Peer group ID
adv = retorno.getPeerGroupAdvertisement();
PeerGroupID GID = adv.getPeerGroupID();
System.out.println(" Group = " +adv.getName() +
"\n Group ID = " + GID.toString());
} else{
System.out.println("
Encontrou!!!!!");
// create a new all purpose peergroup.
retorno = nPG.newGroup(ouvidor.getGrupoAdv());
// print the name of the group and the Peer group ID
adv = nPG.getPeerGroupAdvertisement();
PeerGroupID GID = adv.getPeerGroupID();
System.out.println(" Group = " +adv.getName() +
"\n Group ID = " + GID.toString());
78
}
// publish this advertisement
// (send out to other peers and rendezvous Peer)
discovery.remotePublish(adv);
nPG.globalRegistry.registerInstance(adv.getPeerGroupID(),retorno);
System.out.println("Group published successfully.\n");
System.out.println("ID PEER depois de pegar no
grupo...."+nPG.getPeerAdvertisement().getID().toString());
} catch (Exception e) {
System.out.println("Error publishing group advertisement");
e.printStackTrace();
return (null);
}
return(retorno);
}
private void startJxta() {
try {
//
netPeerGroup = PeerGroupFactory.newNetPeerGroup();
//
} catch ( PeerGroupException e) {
/*/
// could not instantiate the group, print the stack and
exit
System.out.println("fatal error : group creation failure");
e.printStackTrace();
System.exit(1);
}
*/
peer group
// Extract the discovery and rendezvous services from our
//
//
discovery = netPeerGroup.getDiscoveryService();
rdv = netPeerGroup.getRendezVousService();
// Wait until we connect to a rendezvous peer
System.out.print("Waiting to connect to rendezvous...");
while (! rdv.isConnectedToRendezVous()) {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
// nothing, keep going
}
}
System.out.println("connected!");
//
crieGrupo(netPeerGroup).toString();
}
public void entraNoGrupo(PeerGroup grp) {
System.out.println("Joining peer group...");
StructuredDocument creds = null;
try {
// Generate the credentials for the Peer Group
AuthenticationCredential authCred =
new AuthenticationCredential( grp, null, creds );
79
// Get the MembershipService from the Peer group
MembershipService membership = grp.getMembershipService();
// Get the Authenticator from the Authentication creds
Authenticator auth = membership.apply( authCred );
// Check if everything is okay to join the group
if (auth.isReadyForJoin()){
Credential myCred = membership.join(auth);
// display the credential as a plain text document.
StructuredTextDocument doc = (StructuredTextDocument)
myCred.getDocument(new MimeMediaType("text/plain"));
StringWriter out = new StringWriter();
doc.sendToWriter(out);
System.out.println(out.toString());
out.close();
} else
System.out.println("Failure: unable to join group");
} catch (Exception e){
System.out.println("Failure in authentication.");
e.printStackTrace();
}
}
public static void main(String[] args) {
IngressadorGrupo
n.startJxta();
n = new IngressadorGrupo();
// TODO code application logic here
}
}
80
Classe Peer.java
/*
* Peer.java
*
* Created on 28 de Outubro de 2005, 11:06
*
* To change this template, choose Tools | Options and locate the
template under
* the Source Creation and Management node. Right-click the template
and choose
* Open. You can then make changes to the template in the Source
Editor.
*/
package redepeertopeer;
import net.jxta.peer.PeerID;
/**
*
* @author REDIPS
*/
public class Peer {
private String nome;
private PeerID id;
/**
* Creates a new instance of Peer
*/
public Peer() {
}
public Peer(String nome, PeerID id){
this.nome = nome;
this.id = id;
}
/**
* Getter for property nome.
* @return Value of property nome.
*/
public String getNome() {
return this.nome;
}
/**
* Setter for property nome.
* @param nome New value of property nome.
*
* @throws PropertyVetoException if some vetoable listeners reject
the new value
*/
public void setNome(String nome) throws
java.beans.PropertyVetoException {
this.nome = nome;
}
/**
* Holds value of property id.
81
*/
/**
* Getter for property id.
* @return Value of property id.
*/
public PeerID getId() {
return this.id;
}
/**
* Setter for property id.
* @param id New value of property id.
*/
public void setId(PeerID id) {
this.id = id;
}
}
82
Classe ResponsavelRede.java
/**
*
* @author REDIPS
*/
public class ResponsavelRede implements DiscoveryListener,
PipeMsgListener {
private CriadorDeAdv criadorDeAdv;
static PeerGroup netPeerGroup = null;
static PeerGroup grupoVoIP;
private DiscoveryService discovery;
private RendezVousService rdv;
boolean descobriu = false;
private ArrayList listaPeers;
private PipeAdvertisement pipeAdv, pipeAdvEntrada;
private PipeService pipe;
private Message msg;
private InputPipe pipeIn = null;
private IngressadorGrupo ingressadorGrupo;
private EnviadorDeMensagens enviadorDeMSG;
private ArrayList msgRecebidas;
public ResponsavelRede() {
ingressadorGrupo = new IngressadorGrupo();
criadorDeAdv = new CriadorDeAdv();
enviadorDeMSG = new EnviadorDeMensagens();
msgRecebidas = new ArrayList();
listaPeers = new ArrayList();
this.inicializaJXTA();
}
public void descubraPeers(String nomePeer){
descobriu = false;
listaPeers.clear();
discovery.addDiscoveryListener(this);
//
while(!descobriu){
try{
System.out.println("Sending a Discovery Message");
discovery.getRemoteAdvertisements(null,
DiscoveryService.PEER,
"Name", nomePeer+"*", 5);
Thread.sleep(15*1000); //Dorme 10 seg para aguardar a
resposta de pelo menos 1 Peer...
} catch(Exception e){ //Erro no tempo....
}
//
}
}
public synchronized boolean envia_MsgPeer(int carinha,String
mensagem){
boolean resposta = false;
Peer aux = (Peer)listaPeers.get(carinha);
System.out.println("mmmmmmmmmmmmmmmmmmmmmmmmmmmMétodo
enviaMSG");
83
PipeAdvertisement pipeADV =
this.criadorDeAdv.getPipeadv(aux.getId());
this.enviadorDeMSG.enviaMsg(mensagem,netPeerGroup.getPeerName(), pipeADV);
try{
Thread.sleep(10*1000);
}catch(Exception e){}
resposta = this.enviadorDeMSG.isEnviou();
return resposta;
}
public synchronized String[] getListaNomes(){
String [] resposta = new String[listaPeers.size()];
Peer auxiliar;
for (int i=0; i< listaPeers.size(); i++){
auxiliar = (Peer)listaPeers.get(i);
resposta[i] = auxiliar.getNome();
}
return resposta;
}
private void inicializaJXTA() {
try {
netPeerGroup = PeerGroupFactory.newNetPeerGroup();
discovery = netPeerGroup.getDiscoveryService();
rdv = netPeerGroup.getRendezVousService();
pipe = netPeerGroup.getPipeService();
enviadorDeMSG.setDescobridor(discovery);
enviadorDeMSG.setPipe(pipe);
} catch ( PeerGroupException e) {
System.out.println("Erro na criação do Grupo...");
e.printStackTrace();
System.exit(1);
}
}
public boolean conecta(){
System.out.print("Aguardando conexão com rendezvous...");
while (! rdv.isConnectedToRendezVous()) {
try {
wait();
//
Thread.sleep(1000);
} catch (Exception ex) {
}
}
grupoVoIP =
ingressadorGrupo.crieGrupo(netPeerGroup,
discovery);
ingressadorGrupo.entraNoGrupo(grupoVoIP);
criadorDeAdv.setPGID(grupoVoIP.getPeerGroupID());
PipeAdvertisement adv =
criadorDeAdv.getPipeadv(netPeerGroup.getPeerID());
System.out.println("adv"+adv.toString());
try{
84
pipeIn = pipe.createInputPipe(adv, this);
System.out.println("Creating input pipe");
} catch (Exception e) {
System.out.println("IXXI DEU ERRO no pipe
in..."+e.getMessage());
return false;
}
if (pipeIn == null) {
System.out.println(" cannot open InputPipe");
System.exit(-1);
}
//
System.out.println("Waiting for msgs on input pipe");
System.out.println("Xablim!!!!! Está conectado...");
return true;
}
public boolean desconecta(){
rdv.stopRendezVous();
return true;
}
public void pipeMsgEvent(PipeMsgEvent event) {
Message msg=null;
try {
// grab the message from the event
msg = event.getMessage();
if (msg == null) {
return;
}
} catch (Exception e) {
e.printStackTrace();
return;
}
Message.ElementIterator en = msg.getMessageElements();
MessageElement msgElement;
if (!en.hasNext()) {
return;
}
while (en.hasNext()){
msgElement = (MessageElement)en.next();
System.out.println("mensagem...."+msgElement.toString());
this.adicionaMensagem(msgElement.toString());
}
}
public synchronized void discoveryEvent(DiscoveryEvent ev) {
DiscoveryResponseMsg res = ev.getResponse();
int tipoEvento = res.getDiscoveryType();
switch (tipoEvento){
case DiscoveryService.PEER:{
System.out.println("Got a Discovery Response [" +
85
res.getResponseCount() + " elements] from peer:
");
PeerAdvertisement adv = null;
Enumeration en = res.getAdvertisements();
if (en != null ) {
descobriu = true;
Peer p;
while (en.hasMoreElements()) {
adv = (PeerAdvertisement) en.nextElement();
p = new Peer(adv.getName(), adv.getPeerID());
if(!this.verificaSeExiste(listaPeers, p))
listaPeers.add(p);
System.out.println("peer
Descoberto..."+adv.getName());
descobriu = true;
}
}
break;}
}
}
private synchronized boolean verificaSeExiste(ArrayList lista, Peer
p){
Peer aux;
boolean auxiliar;
for (int i=0; i < lista.size();i++){
auxiliar =
((Peer)lista.get(i)).getNome().equals(p.getNome());
if (auxiliar)
return true;
}
return false;
}
public boolean possuiMSG(){
if(msgRecebidas.size()==0)
return false;
else return true;
}
private void zeraMsgRecebidas() {
msgRecebidas.clear();
}
public String[] getMensagensRecebidas(){
String[] resposta = new String[msgRecebidas.size()];
for(int i =0; i<msgRecebidas.size();i++){
resposta[i] = (String) msgRecebidas.get(i);
}
for(int i =0; i<msgRecebidas.size();i++){
System.out.println("MSG RECEBDAS
"+ (String)
msgRecebidas.get(i));
}
86
this.zeraMsgRecebidas();
return resposta;
}
public void adicionaMensagem(String msgRecebida) {
this.msgRecebidas.add(msgRecebida);
}
}
87
Anexo VII. Interface gráfica
Classe InterfaceGrafica.java
/*
* InterfaceGrafica.java
*
* Created on 26 de Outubro de 2005, 20:41
*/
package interfacegrafica;
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import redepeertopeer.ResponsavelRede;
import redepeertopeer.Peer;
/**
*
* @author REDIPS
*/
public class InterfaceGrafica extends javax.swing.JFrame{
/**
* Creates new form InterfaceGrafica
*/
public InterfaceGrafica() {
initComponents();
painel = new JOptionPane();
conectado = false;
listaPencontrados = new DefaultListModel();
listaIDMSGRecebidas = new DefaultListModel();
listaMSGRecebidas = new DefaultListModel();
this.jLteste.setModel(listaPencontrados);
this.jList2.setModel(listaIDMSGRecebidas);
this.jList1.setModel(listaMSGRecebidas);
//this.run();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
public void conhecaResponsavelRede(ResponsavelRede umCaraDaRede){
this.umcaraDaRede = umCaraDaRede;
System.out.println("conheceu");
}
private void mandaProcurar(){
if (!(this.jTFPesquisar.getText().length() !=2)){ // Alterar pra 4 na
hora do vamso ver!
this.listaPencontrados.removeAllElements();
if(this.isConectado()){
String[] lista;
int aux;
88
this.jLStatus.setForeground(this.AZUL);
this.jLStatus.setText("
pesquisando....");
Peer auxiliar;
this.umcaraDaRede.descubraPeers(this.jTFPesquisar.getText());
/*
try{
Thread.sleep(5 * 1000);// Descanço pra ver se pega o número de
peers
}catch(Exception e){}*/
lista = this.umcaraDaRede.getListaNomes();
for(int i = 0; i < lista.length; i++){
listaPencontrados.addElement(lista[i]);
}
this.jLStatus.setText( "Pesquisa Concluída....encontrados "+
lista.length+" elementos.");
this.jLStatus.setForeground(this.PRETO);
} else
painel.showMessageDialog(this,"Voce não está conectado!!!",
"ATENCAO!!!",painel.ERROR_MESSAGE);
} else
painel.showMessageDialog(this,"Digite apenas 4 caracteres",
"ATENCAO!!!",painel.ERROR_MESSAGE);
}
public void run(){
System.out.println("Vamos ver se esse método é executado, pelo menos
uma vez.....");
while(true){
try{
Thread.sleep(30*1000);
}catch(Exception e){}
if (this.umcaraDaRede.possuiMSG()){
String[] listaMensagens;
listaMensagens = this.umcaraDaRede.getMensagensRecebidas();
for( int i = 0; i < listaMensagens.length; i = i + 2){
this.listaIDMSGRecebidas.addElement(listaMensagens[i]);
this.listaMSGRecebidas.addElement(listaMensagens[i+1]);
}
}
}
}
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">
private void initComponents() {
jPanel2 = new javax.swing.JPanel();
jTFPesquisar = new javax.swing.JTextField();
jBTProcura = new javax.swing.JButton();
jPanel5 = new javax.swing.JPanel();
jLStatus = new javax.swing.JLabel();
jPanel8 = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList();
jPanel9 = new javax.swing.JPanel();
jScrollPane3 = new javax.swing.JScrollPane();
jList2 = new javax.swing.JList();
jPanel10 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
jLMsgRec = new javax.swing.JLabel();
89
jLabel1 = new javax.swing.JLabel();
jPanel3 = new javax.swing.JPanel();
jLbPeersLocalizados = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
jLteste = new javax.swing.JList();
jPanel7 = new javax.swing.JPanel();
jPanel4 = new javax.swing.JPanel();
jBTenviaMSG = new javax.swing.JButton();
jBLimpaResultado = new javax.swing.JButton();
jPanel6 = new javax.swing.JPanel();
JBTVerDetalhes = new javax.swing.JButton();
jPanel1 = new javax.swing.JPanel();
jBTConecta = new javax.swing.JButton();
jBTDesconecta = new javax.swing.JButton();
jBTSaiFora = new javax.swing.JButton();
jMenuBar2 = new javax.swing.JMenuBar();
jMArquivo = new javax.swing.JMenu();
jMIConecta = new javax.swing.JMenuItem();
jMIDesconecta = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JSeparator();
jMISair = new javax.swing.JMenuItem();
jMAjuda = new javax.swing.JMenu();
jMIAjuda = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Gatewaysss VOIP");
jPanel2.setLayout(new java.awt.BorderLayout());
jPanel2.setBorder(new javax.swing.border.LineBorder(new
java.awt.Color(0, 0, 0)));
jTFPesquisar.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
jTFPesquisarKeyPressed(evt);
}
});
jPanel2.add(jTFPesquisar, java.awt.BorderLayout.CENTER);
jBTProcura.setMnemonic('P');
jBTProcura.setText("Pesquisar");
jBTProcura.setToolTipText("Localise o gateway");
jBTProcura.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBTProcuraActionPerformed(evt);
}
});
jPanel2.add(jBTProcura, java.awt.BorderLayout.EAST);
jPanel5.setLayout(new java.awt.BorderLayout());
jPanel5.setBorder(new javax.swing.border.LineBorder(new
java.awt.Color(0, 0, 0)));
jLStatus.setText("Desconectado");
jPanel5.add(jLStatus, java.awt.BorderLayout.SOUTH);
jScrollPane2.setViewportView(jList1);
jPanel8.add(jScrollPane2);
jPanel5.add(jPanel8, java.awt.BorderLayout.EAST);
90
jScrollPane3.setViewportView(jList2);
jPanel9.add(jScrollPane3);
jPanel5.add(jPanel9, java.awt.BorderLayout.WEST);
jPanel10.setLayout(new java.awt.GridLayout(1, 2));
jLabel2.setText("
jPanel10.add(jLabel2);
Remetente");
jLMsgRec.setText("Mensagem Recebida");
jPanel10.add(jLMsgRec);
jLMsgRec.getAccessibleContext().setAccessibleName("Mensagem
Recebida");
jPanel5.add(jPanel10, java.awt.BorderLayout.NORTH);
jPanel2.add(jPanel5, java.awt.BorderLayout.SOUTH);
jLabel1.setText("
Localiza\u00e7\u00e3o de Gateways");
jLabel1.setBorder(new javax.swing.border.LineBorder(new
java.awt.Color(0, 0, 0)));
jPanel2.add(jLabel1, java.awt.BorderLayout.NORTH);
getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);
jPanel3.setLayout(new java.awt.BorderLayout());
jPanel3.setBorder(new javax.swing.border.LineBorder(new
java.awt.Color(0, 0, 0)));
jLbPeersLocalizados.setText("
Peers encontrados");
jPanel3.add(jLbPeersLocalizados, java.awt.BorderLayout.NORTH);
jLteste.setBorder(new javax.swing.border.LineBorder(new
java.awt.Color(0, 0, 0)));
jLteste.setValueIsAdjusting(true);
jScrollPane1.setViewportView(jLteste);
jPanel3.add(jScrollPane1, java.awt.BorderLayout.CENTER);
getContentPane().add(jPanel3, java.awt.BorderLayout.CENTER);
jPanel7.setLayout(new java.awt.GridLayout(2, 0, 0, 5));
jPanel4.setLayout(new java.awt.GridLayout(2, 0, 0, 2));
jPanel4.setAutoscrolls(true);
jBTenviaMSG.setMnemonic('n');
jBTenviaMSG.setText("Envia MSG");
jBTenviaMSG.setHorizontalAlignment(javax.swing.SwingConstants.LEADING);
jBTenviaMSG.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
jBTenviaMSG.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBTenviaMSGActionPerformed(evt);
}
});
91
jPanel4.add(jBTenviaMSG);
jBLimpaResultado.setText("Limpa Resultados");
jBLimpaResultado.addActionListener(new
java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBLimpaResultadoActionPerformed(evt);
}
});
jPanel4.add(jBLimpaResultado);
jPanel7.add(jPanel4);
jPanel6.setLayout(new java.awt.GridLayout(1, 0));
JBTVerDetalhes.setMnemonic('C');
JBTVerDetalhes.setText("Ver Detalhes");
JBTVerDetalhes.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt) {
JBTVerDetalhesActionPerformed(evt);
}
});
jPanel6.add(JBTVerDetalhes);
jPanel7.add(jPanel6);
getContentPane().add(jPanel7, java.awt.BorderLayout.EAST);
jPanel1.setLayout(new java.awt.GridLayout(1, 3));
jBTConecta.setMnemonic('C');
jBTConecta.setText("Conectar");
jBTConecta.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBTConectaActionPerformed(evt);
}
});
jPanel1.add(jBTConecta);
jBTDesconecta.setMnemonic('D');
jBTDesconecta.setText("Desconectar");
jBTDesconecta.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBTDesconectaActionPerformed(evt);
}
});
jPanel1.add(jBTDesconecta);
jBTSaiFora.setMnemonic('S');
jBTSaiFora.setText("Sartar Fora!!!");
jBTSaiFora.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jBTSaiForaActionPerformed(evt);
}
});
92
jPanel1.add(jBTSaiFora);
getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);
jMArquivo.setText("Arquivo");
jMIConecta.setMnemonic('C');
jMIConecta.setText("Conectar");
jMIConecta.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMIConectaActionPerformed(evt);
}
});
jMArquivo.add(jMIConecta);
jMIDesconecta.setMnemonic('D');
jMIDesconecta.setText("Desconecta");
jMIDesconecta.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMIDesconectaActionPerformed(evt);
}
});
jMArquivo.add(jMIDesconecta);
jMArquivo.add(jSeparator1);
jMISair.setMnemonic('S');
jMISair.setText("Sair");
jMISair.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMISairActionPerformed(evt);
}
});
jMArquivo.add(jMISair);
jMenuBar2.add(jMArquivo);
jMAjuda.setText("Ajuda");
jMIAjuda.setMnemonic('S');
jMIAjuda.setText("Sobre");
jMAjuda.add(jMIAjuda);
jMenuBar2.add(jMAjuda);
setJMenuBar(jMenuBar2);
pack();
}
// </editor-fold>
private void JBTVerDetalhesActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
}
private void jTFPesquisarKeyPressed(java.awt.event.KeyEvent evt) {
if(evt.getKeyCode()==evt.VK_ENTER){
93
this.mandaProcurar();
}
}
private void jBTenviaMSGActionPerformed(java.awt.event.ActionEvent evt) {
String mensagem = painel.showInputDialog(this,"Digite uma
mensagem....");
System.out.println(" Valor de s = "+mensagem);
System.out.println(" valor" +this.jLteste.getSelectedIndex());
if (umcaraDaRede.envia_MsgPeer(this.jLteste.getSelectedIndex(),
mensagem)){
this.jLStatus.setForeground(this.VERDE);
this.jLStatus.setText("Mensagem enviada com sucesso....");
}else{
this.jLStatus.setForeground(this.VERMELHO);
this.jLStatus.setText("ERRO NO ENVIO....");
}
// TODO add your handling code here:)
}
private void jBLimpaResultadoActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
this.listaPencontrados.clear();
}
private void jBTSaiForaActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
jMISairActionPerformed(evt);
}
private void jMISairActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
System.exit(0);
}
private void jMIDesconectaActionPerformed(java.awt.event.ActionEvent evt)
{
// TODO add your handling code here:
jBTDesconectaActionPerformed(evt);
}
private void jMIConectaActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
jBTConectaActionPerformed(evt);
}
private void jBTDesconectaActionPerformed(java.awt.event.ActionEvent evt)
{
94
this.jLStatus.setText("Desconectando");
if(this.umcaraDaRede.desconecta()){
painel.showMessageDialog(this,"Desconectado com
Sucesso","Desconectado",painel.INFORMATION_MESSAGE);
this.setConectado(false);
}
this.jLStatus.setText("
Desconectado....");
this.jLStatus.setForeground(this.VERMELHO);
// TODO add your handling code here:
}
private void jBTConectaActionPerformed(java.awt.event.ActionEvent evt) {
this.jLStatus.setForeground(this.VERDE);
this.jLStatus.setText("Conectando..........");
if(this.umcaraDaRede.conecta()){
//
painel.showMessageDialog(this,"Conectado","Conectado",painel.INFORMATION_MESS
AGE);
this.setConectado(true);
}
this.jLStatus.setText("
Conectado");
this.jLStatus.setForeground(this.PRETO);
// TODO add your handling code here:
}
private void jBTProcuraActionPerformed(java.awt.event.ActionEvent evt) {
this.mandaProcurar();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new InterfaceGrafica().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton JBTVerDetalhes;
private javax.swing.JButton jBLimpaResultado;
private javax.swing.JButton jBTConecta;
private javax.swing.JButton jBTDesconecta;
private javax.swing.JButton jBTProcura;
private javax.swing.JButton jBTSaiFora;
private javax.swing.JButton jBTenviaMSG;
private javax.swing.JLabel jLMsgRec;
private javax.swing.JLabel jLStatus;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLbPeersLocalizados;
private javax.swing.JList jList1;
private javax.swing.JList jList2;
private javax.swing.JList jLteste;
private javax.swing.JMenu jMAjuda;
private javax.swing.JMenu jMArquivo;
95
private javax.swing.JMenuItem jMIAjuda;
private javax.swing.JMenuItem jMIConecta;
private javax.swing.JMenuItem jMIDesconecta;
private javax.swing.JMenuItem jMISair;
private javax.swing.JMenuBar jMenuBar2;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel10;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JPanel jPanel4;
private javax.swing.JPanel jPanel5;
private javax.swing.JPanel jPanel6;
private javax.swing.JPanel jPanel7;
private javax.swing.JPanel jPanel8;
private javax.swing.JPanel jPanel9;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JTextField jTFPesquisar;
// End of variables declaration
private ResponsavelRede umcaraDaRede;
private JOptionPane painel;
private DefaultListModel listaPencontrados;
private DefaultListModel listaIDMSGRecebidas;
private DefaultListModel listaMSGRecebidas;
private final Color PRETO = new Color(0.0f,0.0f,0.0f);
private final Color VERDE = new Color(0.0f,1.0f,0.0f);
private final Color VERMELHO = new Color(1.0f,0.0f,0.0f);
private final Color AZUL = new Color(0.0f,0.0f,1.0f);
private boolean conectado;
public boolean isConectado() {
return this.conectado;
}
public void setConectado(boolean conectado) {
this.conectado = conectado;
}
}
Download