Você está na página 1de 155

UNIVERSIDADE POTIGUAR

ENGENHARIA DE COMPUTAÇÃO

ESTUDO DO PADRÃO BLUETOOTH PARA COMUNICAÇÃO


ENTRE DISPOSITIVOS PORTÁTEIS E COMPUTADORES
PESSOAIS.

GEORGE GILSON SOUSA DE OLIVEIRA


RENATO MONTEIRO BATISTA

NATAL
NOVEMBRO DE 2005.
UNIVERSIDADE POTIGUAR
ENGENHARIA DE COMPUTAÇÃO

ESTUDO DO PADRÃO BLUETOOTH PARA COMUNICAÇÃO


ENTRE DISPOSITIVOS PORTÁTEIS E COMPUTADORES
PESSOAIS.

Exame de Qualificação submetido à direção do curso de


Engenharia de Computação da Universidade Potiguar
como parte dos requisitos necessários para a obtenção
da graduação em Engenharia de Computação.

GEORGE GILSON SOUSA DE OLIVEIRA


RENATO MONTEIRO BATISTA
Orientador: Prof. Dr. ALLAN MEDEIROS MARTINS

NATAL
NOVEMBRO DE 2005.

ii
ÍNDICE

LISTA DE SIMBOLOS, ABREVIATURAS E SIGLAS .................................................................... VIII


RESUMO...................................................................................................................................................... X
ABSTRACT ............................................................................................................................................... XI
CAPÍTULO 1 – INTRODUÇÃO ............................................................................................................. 1
CAPÍTULO 2 – FUNDAMENTAÇÃO TEÓRICA ............................................................................... 4
2.1 COMUNICAÇÕES SEM FIO .............................................................................................................. 4
2.1.1 Modo de funcionamento .................................................................................................................... 5
2.1.2 Tecnologias de modulação existentes ................................................................................................ 6
2.1.3 Padrões organizacionais existentes .................................................................................................. 10
2.2 TECNOLOGIA BLUETOOTH .......................................................................................................... 11
2.2.1 Faixa de freqüência e organização dos canais.................................................................................. 12
2.2.2 Modo de funcionamento .................................................................................................................. 12
2.2.3 Modos de operação .......................................................................................................................... 14
2.2.4 Gerenciador de Link e Controlador de Link .................................................................................... 16
2.2.5 Estabelecendo a conexão.................................................................................................................. 16
2.3 JAVA................................................................................................................................................... 17
2.3.1 A linguagem JAVA ........................................................................................................................... 17
2.3.2 Divisão da família JAVA .................................................................................................................. 18
2.3.3 J2ME ................................................................................................................................................ 19
2.3.4 VM – Máquinas Virtuais .................................................................................................................. 19
2.3.5 Configurations .................................................................................................................................. 21
2.3.6 Profiles ............................................................................................................................................. 22
CAPÍTULO 3 – TECNOLOGIAS DE SOFTWARE ........................................................................... 28
3.1 API BLUETOOTH ............................................................................................................................. 28
3.1.1 Javax.Bluetooth Interfaces ............................................................................................................... 28
3.1.2 Classes .............................................................................................................................................. 37
3.1.3 Exceções ........................................................................................................................................... 40
3.2 MIDLETS: ............................................................................................................................................ 41
3.2.1 Ambiente de tempo de execução...................................................................................................... 41
3.2.2 Arquivo JAR - Java Archive............................................................................................................ 41
3.2.3 Arquivo JAD - Java Aplication Descriptor ..................................................................................... 43
3.2.4 Pacotes Java ..................................................................................................................................... 44

iii
3.2.5 Ambiente de desenvolvimento. ........................................................................................................ 44
3.3 PAREANDO DISPOSITIVOS BLUETOOTH ............................................................................................... 54
3.4 INSTALANDO APLICATIVOS NO CELULAR ............................................................................................ 67
3.4.1 API MIDIP - Fundamentos .............................................................................................................. 71
CAPÍTULO 4 – IMPLEMENTAÇÃO .................................................................................................. 77
4.1 CHATOOTH .......................................................................................................................................... 77
4.2 PC-PC .................................................................................................................................................. 79
4.2.1 Recursos ........................................................................................................................................... 80
4.2.2 A conexão......................................................................................................................................... 80
4.2.3 O Chat .............................................................................................................................................. 81
4.3 PC-CELULAR ....................................................................................................................................... 83
4.3.1 Definições Iniciais ............................................................................................................................ 83
4.3.2 Funcionamento ................................................................................................................................. 84
CAPÍTULO 5 – CONCLUSÃO ............................................................................................................. 90
ANEXO 1 ..................................................................................................................................................... 92
ANEXO 2 ..................................................................................................................................................... 93
ANEXO 3 ..................................................................................................................................................... 95
ANEXO 4 ................................................................................................................................................... 100
ANEXO 5 ................................................................................................................................................... 102
ANEXO 6 ................................................................................................................................................... 103
ANEXO 7 ................................................................................................................................................... 104
ANEXO 8 ................................................................................................................................................... 105
ANEXO 9 ................................................................................................................................................... 108
ANEXO 10 ................................................................................................................................................. 110
ANEXO 11 ................................................................................................................................................. 112
ANEXO 12 ................................................................................................................................................. 117
ANEXO 13 ................................................................................................................................................. 118
ANEXO 14 ................................................................................................................................................. 120
ANEXO 15 ................................................................................................................................................. 121
ANEXO 16 ................................................................................................................................................. 122
ANEXO 17 ................................................................................................................................................. 125
ANEXO 17 ................................................................................................................................................. 125
ANEXO 18 ................................................................................................................................................. 126
ANEXO 19 ................................................................................................................................................. 128
ANEXO 19 ................................................................................................................................................. 128
ANEXO 20 ................................................................................................................................................. 129
iv
ANEXO 21 ................................................................................................................................................. 135
ANEXO 22 ................................................................................................................................................. 137
ANEXO 23 ................................................................................................................................................. 138
ANEXO 24 ................................................................................................................................................. 140
ANEXO 25 ................................................................................................................................................. 142

v
LISTA DE FIGURAS

Figura 2.1 - Ilustração do conceito de célula. .................................................................................. 6


Figura 2.2 - Transmissão FHSS [2]. ................................................................................................. 8
Figura 2.3 - Coexistência de dispositivo em mais de uma piconet. ............................................... 13
Figura 2.4 - Protocolo de conexão. ................................................................................................ 16
Figura 2.5 - Família JAVA [14]. ..................................................................................................... 24
Figura 3.1 - Testando a instalação do ambiente de desenvolvimento. ........................................... 47
Figura 3.2 - Ferramentas do WTK. ................................................................................................ 51
Figura 3.3 - Tela principal do KToolBar........................................................................................ 52
Figura 3.4 - Tela de adição de novo projeto. .................................................................................. 52
Figura 3.5 - Configurações do arquivo JAD. ................................................................................. 53
Figura 3.6 - Definição do atributo MIDlet-<n>. ............................................................................ 53
Figura 3.7 - Campos opcionais do arquivo JAD. ........................................................................... 54
Figura 3.8 - Configuração do serviço Bluetooth. ........................................................................... 55
Figura 3.9 - Nokia 6230, tela principal com Bluetooth desativado. ............................................... 56
Figura 3.10 - Nokia 6230, tela principal com Bluetooth ativado. .................................................. 56
Figura 3.11 - Nokia 6230, configurações. ...................................................................................... 56
Figura 3.12 - Nokia 6230, menu configurações. ............................................................................ 57
Figura 3.13 - Nokia 6230, menu conectividade. ............................................................................ 57
Figura 3.14 - Nokia 6230, configurações Bluetooth. ..................................................................... 57
Figura 3.15 - Nokia 6230, menu Bluetooth, ativar serviço. ........................................................... 57
Figura 3.16 - Nokia 6230, menu Bluetooth. ................................................................................... 57
Figura 3.17 - Nokia 6230, configurações Bluetooth. ..................................................................... 57
Figura 3.18 - Ativando ícone Bluetooth na área de notificação. ................................................... 58
Figura 3.19 - Ativando localização no PC. .................................................................................... 59
Figura 3.20 - Lista de dispositivos Bluetooth durante o primeiro acesso. ..................................... 60
Figura 3.21 - Tela de adição de dispositivo. .................................................................................. 61
Figura 3.22 - Windows buscando por dispositivos próximos. ....................................................... 62
Figura 3.23 - Dispositivos localizados. .......................................................................................... 62
Figura 3.24 - Escolha da chave de acesso. ..................................................................................... 63
Figura 3.25 - Estabelecendo a conexão entre os dispositivos. ....................................................... 64
Figura 3.26 - Nokia 6230, tela de confirmação de pareamento de dispositivo. ............................. 64
vi
Figura 3.27 - Nokia 6230, tela de requisição de senha para pareamento. ..................................... 64
Figura 3.28 - Nokia 6230, confirmação de senha entre dispositivos sendo realizada................... 65
Figura 3.29 - Janela de pareamento de dispositivos bem sucedida. ............................................... 65
Figura 3.30 - Lista de dispositivos Bluetooth pareados. ................................................................ 66
Figura 3.31 - Nokia 6230, tela de confirmação de conexão. .......................................................... 67
Figura 3.32 - Nokia 6230, lista de dispositivos pareados............................................................... 67
Figura 3.33 - Nokia 6230, tela de opções de dispositivo pareado. ................................................. 67
Figura 3.34 - Tela do Nokia Connection Manager na primeira execução. .................................... 68
Figura 3.35 - Nokia Connection Manager, adicionando novo telefone. ........................................ 69
Figura 3.36 - Nokia Connection Manager, lista de telefones conhecidos. ..................................... 70
Figura 3.37 - Suíte de aplicativos que compoem o Nokia PC Suite. ............................................. 70
Figura 3.38 - Nokia Application Installer. ..................................................................................... 71
Figura 3.39 - Hierarquia da classe Display. ................................................................................... 74
Figura 4.1 - Projeto ChaTooth, fluxograma de funcionamento. .................................................... 79
Figura 4.2 - Aplicativo PC-PC, tela servidor. ................................................................................ 82
Figura 4.3 - Aplicativo PC-PC, tela cliente .................................................................................... 83
Figura 4.4 - Aplicativo PC-Celular, fluxograma de funcionamento servidor. ............................... 86
Figura 4.5 - Aplicativo PC-Celular, fluxograma de funcionamento cliente. ................................. 87

vii
LISTA DE SIMBOLOS, ABREVIATURAS E SIGLAS

AMS - Aplicatioin Manager Software.


ANATEL - Agência Nacional de Telecomunicações.
API - Application Programming Interface.
CCIR - International Radio Comunications Consulative Comitee.
CDC - Connected Device Configuration.
CDMA - Code Division Multiple Acess.
CLDC - Connected Limited Device Configuration.
CVM - C Virtual machine.
DS - Direct Sequence.
DSSS - Direct Sequence Spread Spectrum.
FH - Frequency Hopping.
FHSS - Frequency Hopping Spread Spectrum.
IEEE - Institute of Electrical and Electronics Engineers.
IFRB - International Frequency Registration Board.
J2EE - Java to Enterprise Edition.
J2ME - Java to Micro Edition.
J2SE - Java to Standard Edition.
JVM - Java Virtual machine.
KVM - K Virtual machine.
LAN - Local Area Network.
LC - Link Controller.
LM - Link Manager.
LMP - Link Manager Protocol.
MIDP - Mobile Information Device Profile.
PDA - Personal Digital Assistante.
RF - Radio Freqüência.
RMS - Record Management System.
SDK - Software Development Kit.
SIG - Special Interest Group.
SST - Spread Spectrum Technology.
TDD - Time-Division Duplex.
viii
VM - Virtual machine.
WLAN - Wireless Local Area Network.
WPAN - Wireless Personal Area Network.
WTK - Wireless Tool Kit.

ix
RESUMO

Este trabalho apresenta um estudo do padrão Bluetooth para aplicação na comunicação


entre dispositivos móveis e computadores pessoais, utilizando a linguagem de programação Java
como plataforma para prover esta comunicação entre os dispositivos. O trabalho pode ser
dividido em quatro etapas, onde são apresentados conceitos, ferramentas e implementações com
focos mais direcionados em cada uma delas. De forma a embasar o leitor, são apresentadas na
primeira etapa duas tecnologias que são exploradas no decorrer do trabalho, o Bluetooth, suas
características e seus diferenciais enquanto tecnologia de comunicação sem fio; e o Java, a
linguagem de programação e seus ambientes de desenvolvimento para diferentes tipos de
dispositivo. Na etapa seguinte, há um detalhamento das tecnologias MIDP (o perfil da Java para
dispositivos portáteis), da biblioteca (API) Javax.Bluetooth que é necessária para interface desta
tecnologia com ambiente Java, também apresentando as ferramentas de desenvolvimento
utilizadas. Com o embasamento inicial e específico já aplicado, a terceira etapa deste trabalho
apresenta os projetos implementados através da linguagem Java e da tecnologia Bluetooth. Estes
projetos abrangem um Chat entre dispositivos móveis (celular-celular), um outro Chat entre
computadores pessoais, e um terceiro projeto de Chat que utiliza os resultados dos projetos
anteriores e estabelece a comunicação entre um dispositivo móvel e um computador pessoal.
Com estas implementações e estudo das tecnologias, a quarta e última etapa deste trabalho
apresenta as dificuldades e possibilidades deste universo de desenvolvimento.

x
ABSTRACT

This work presents softwares developed using Java language to provide communication
between mobile devices and personal computers through the Bluetooth standard. It was split in
four stages where concepts concepts, tools and implementations are showed. Two technologies
will be presented: in the first stage Bluetooth will be explored, its characteristics and differences
between Bluetooth and anothers wireless technologies. We also show the Java programming
language and its environments of development for different kinds of device. In the following
stage, we explore MIDP (the Java profile for portable devices), of the Application Program
Interface Javax.Bluetooth also presenting the used tools of development. With applied the initial
and specific basement already, the third stage of this work presents the projects implemented
through the Java language and of the Bluetooth technology. These projects enclose three
softwares: a Chat between mobile devices (cellular-cellular), a Chat between personal
computers, and anoter Chat that uses the results of the previous projects and establishes the
communication between a mobile device and a personal computer. With these implementations
and study of the technologies, the fourth and last stage of this work presents the difficulties and
possibilities of this universe of development.

xi
CAPÍTULO 1 – INTRODUÇÃO

Com o advento da tecnologia, é cada vez maior a quantidade de dispositivos eletrônicos


que faz parte do nosso dia a dia. A necessidade de transmitir dados entre os dispositivos que
utilizamos esbarra nos diferentes padrões de transmissão e interfaces existentes no mercado.
Dentre as diferentes interfaces existentes de comunicação entre dispositivos, as que
utilizam como meio físico os cabos ainda compõem a maioria. Vários dispositivos possuem um
cabo proprietário ou até mesmo seguem um padrão de determinada região, mas sempre existem
algumas implicações neste meio físico. A mobilidade é uma das características que é bastante
reduzida em conexões deste tipo. A portabilidade dos acessórios de comunicação dos dispositivos
não é alvo destes objetos e além disto, nem todos atendem a uma outra necessidade dos usuários,
a flexibilidade da área de atuação é limitada, impedindo a mobilidade mesmo dentro de uma área
pessoal. Uma solução para estas necessidades é a utilização de padrões de comunicação sem-fio,
ou wireless como também são chamados.
O Bluetooth foi desenvolvido com o intuito de eliminar o emaranhado de fios presente
atualmente nos aparelhos domésticos e surge como candidato natural a suceder definitivamente o
infravermelho, tipo de conexão sem fio mais comum e utilizado em controle remoto para
equipamentos eletrônicos. Por ser um padrão de abrangência mundial, o Bluetooth já é
encontrado nos equipamentos mais modernos e vem se consolidando como o padrão mais
utilizado principalmente entre os dispositivos de baixo poder de processamento, como telefones
celulares, assistentes pessoais digitais (PDA`s), fones de ouvido, mouses, teclados etc. Porém, o
padrão atualmente também é bastante aplicado em computadores pessoais, os desktops, para que
seja possível a interação entre eles e outros dispositivos que utilizem o Bluetooth. Apesar de já
está sendo disponibilizado até de forma integrada em vários dispositivos, o Bluetooth ainda é
sub-utilizado pela maioria dos usuários. Isto pode ser atribuído ao fato de a gama de aplicações e
aplicativos que utilizam o Bluetooth ainda ser bastante reduzida, e o material de consulta para
desenvolvimento de softwares para este padrão ainda não está tão difundido e trabalhado tanto
quanto os de outros meios de conexão.
Para apresentar as particularidades do padrão Bluetooth, o Capítulo 2 expõe algumas
tecnologias de comunicação sem-fio, comparando-as com as especificações do Bluetooth.

1
Conhecendo a forma de funcionamento do padrão Bluetooth para conexão de dispositivos, pode-
se aplicar este conhecimento para desenvolver aplicativos dos mais diversos que utilizem esta
tecnologia, diminuindo drasticamente a quantidade de cabos necessários para se manter um
conexão entre os dispositivos próximos e facilitando a comunicação entre dispositivos que
utilizam interfaces diferentes, mas que tenham em comum o suporte ao Bluetooth. Para que seja
possível implementar uma comunicação entre os dispositivos via rádio Bluetooth, é necessário
conhecer o ambiente de desenvolvimento que cada dispositivo suporta. Para desenvolvimento
deste trabalho será utilizada a linguagem de programação Java, devido a vasta gama de
dispositivos com suporte a esta linguagem. A linguagem Java, desenvolvida pela Sun
Microsystems com o objetivo de fornecer ao programador um ambiente de programação
independentemente de plataforma, também é apresentada no Capítulo 2. Sobre o Java, será
apresentando o conceito de máquina virtual, onde todo programa é desenvolvido baseado nos
recursos disponíveis nessa ‘máquina’, enquanto que para cada plataforma é implementada uma
comunicação entre essa máquina virtual e o sistema operacional. Dessa forma torna-se possível
que um programa desenvolvido para ambiente windows seja executado em ambiente linux e vice-
versa sem necessidade de mudanças no código fonte, isso porque o código é desenvolvido para a
máquina virtual e a Sun Microsystems disponibiliza uma máquina virtual adequada a cada um
dos dois sistemas.
Entendendo que “tamanho único” não se adapta a todas as necessidades, a Sun
Microsystems lançou em 1999 uma edição da sua plataforma chamada Java 2 Micro Edition
(J2ME). Essa edição tem enfoque em ambientes cujos recursos são limitados, ou seja, sistemas
embarcados e produtos de consumo tais como celulares, PDA`s, entre outros. A J2ME oferece
suporte a vários tipos de dispositivos, modularizados através de configurações, perfis e
bibliotecas específicas. Apesar de haver citação conceitual sobre estes assuntos no Capítulo 2, o
foco no perfil específico para celulares e dispositivos móveis (MIDP), assim como na biblioteca
específica para o padrão Bluetooth (API Javax.Bluetooth), é dado no Capítulo 3, onde as são
apresentadas as ferramentas e tecnologias utilizadas neste trabalho. Neste capítulo são
apresentados os softwares da Sun Microsystems e da Nokia que auxiliam o trabalho com
dispositivos celulares, ambientes de desenvolvimento, simuladores e compiladores da linguagem
Java.
Percebe-se que a união dessas duas tecnologias abre um enorme potencial de novas
2
aplicações, pois a maioria dos dispositivos móveis que disponibilizam interface de programação
ao usuário também oferecem suporte ao Java. O mercado de aplicações destas tecnologias vai
desde um simples Chat até as mais ousadas e promissoras idéias. Os projetos implementados são
apresentados no Capítulo 4, onde três projetos de Chat são desenvolvidos. Os três projetos têm
uma seqüência, onde primeiro a comunicação é estabelecida entre celulares, implementando no
ambiente J2ME. Em seguida é desenvolvido um Chat entre computadores pessoais, utilizando o
J2SE. Por fim, o terceiro projeto implementa os dois anteriores, realizando um Chat entre
computador pessoal e celular.
Apesar do grande potencial e do fato da indústria lançar cada vez mais produtos com
estes recursos, são poucas as criações nesta área. Acreditamos que esse fato se deva
principalmente a escassez de informações técnicas. Por isto, este trabalho se propõe a servir de
referência técnica no estudo básico das tecnologias Bluetooth e J2ME, de modo a fornecer
embasamento teórico para a criação de aplicações futuras. Estas e outras conclusões, assim como
as principais dificuldades enfrentadas neste trabalho, são expostas no Capítulo 5.

3
CAPÍTULO 2 – FUNDAMENTAÇÃO TEÓRICA

2.1 COMUNICAÇÕES SEM FIO

Normalmente quando se fala em transmissão de dados se remete ao uso da palavra


“cabeamento”. Entretanto, o termo mais correto seria “mídia” e não cabeamento, já que as
informações de uma rede não necessariamente trafegam de um lado para outro através de cabos
convencionais [1].
Os trabalhos com comunicação sem fio foram inicialmente desenvolvidos durante a 2ª
Guerra Mundial (década de 40). Com objetivos estritamente militares ela foi usada para
transmissão de informações seguras via ondas de rádio. O trabalho com sistemas comerciais só
começou depois da década de 70. Em meados dos anos 80 quando o FCC, órgão regulador de
telecomunicações dos EUA, autorizou o uso de três faixas de rádiofreqüência (RF) para
finalidades industriais, científicas e médicas (ISM - Industrial, Scientific and Medical) sem
necessidade de concessão. A partir daí houve novo interesse na tecnologia e começaram a surgir
os sistemas de comunicação que conhecemos como: bips, pagers, rádio transmissores (PX),
telefones sem fio, celulares, etc. [2].
As redes sem fio são utilizadas, normalmente, para acrescentar funcionalidades as redes
tradicionais e não para substituí-las. Com a utilização de redes sem fio o usuário pode ter acesso
aos recursos compartilhados sem necessidade de procurar um conector para fazer parte da rede
uma vez que a mídia em geral é o ar. Com isso há o ganho de mobilidade, bem como a redução
de custos no que diz respeito à instalação de infra-estrutura física (instalação de cabos).
De acordo com [3], as vantagens de utilização de redes sem fio são:
ü Redução nos custos de instalação de cabeamento;
ü Uma vez que não exista link físico usado, não há interferência eletromagnética;
ü Se Ganha com portabilidade e flexibilidade;
ü Em caso de re-alocação dos dispositivos não há custos adicionais de cabeamento.

4
2.1.1 Modo de funcionamento

Sinais eletromagnéticos carregam informações na atmosfera. Para que seja possível


transmitir e receber sinais no caso das mídias não guiadas se faz necessário o uso de uma antena.
A antena transmite o sinal eletromagnético para a atmosfera (usualmente o ar) e o receptor recebe
o sinal também através de outra antena. Os sinais eletromagnéticos são transmitidos utilizando
diferentes faixas de freqüências. Essas faixas de freqüência são regulamentadas pelo
International Radio Comunications Consulative Comitee (CCIR) e pelo International Frequency
Registration Board (IFRB) [3].
No Brasil, a Agência Nacional de Telecomunicações (ANATEL) é responsável pela
regulamentação e fiscalização das concessões do uso das faixas de freqüência.
Vários dados podem estar sendo transmitidos e recebidos ao mesmo tempo sem
interferirem uns nos outros, desde que suas freqüências de modulação sejam diferentes. O
receptor da mensagem deve estar sintonizado para a freqüência do transmissor de dados para
poder receber os dados a ele destinado, rejeitando todas as outras freqüências a partir desta
sintonização [2].
Em redes sem fio onde se utilizam estações base – também conhecidas como access
points – não há necessidade de alinhamento dos dispositivos para a recepção do sinal de rádio. As
estações base transmitem o sinal de rádio que se propaga e, dependendo da intensidade, atravessa
paredes, divisórias e todos os obstáculos não metálicos. A abrangência do alcance do sinal de
uma estação base é denominada de célula, todo o tráfego de uma célula é gerenciado pelo access
point. Os usuários em movimento – também conhecido como roam – trocam de uma célula para
outra de modo a manter-se onde o sinal é mais forte e não perder a conexão.
Na Figura 2.1 ilustra-se o exemplo de funcionamento de uma célula, a área do retângulo
corresponde a área de abrangência da estação base. Note que o sinal pode atravessar paredes e
divisórias não metálicas, ao passo de que equipamentos que não estejam isolados por paredes e
divisórias podem não ser atendidos simplesmente pelo fato de encontrarem-se fora do alcance da
célula.

5
Figura 2.1 - Ilustração do conceito de célula.

2.1.2 Tecnologias de modulação existentes

Existem algumas tecnologias de modulação e bandas de freqüências que foram


propostas como link de comunicação para redes wireless. Algumas delas são:

2.1.2.1 Tecnologia de espectro espalhado (SST – Spread Spectrum Technology)


Essa tecnologia foi definida basicamente para fins militares e é imune a interferências.
Esta técnica oferece diversas vantagens, mas não garante um ambiente seguro. Esta técnica
recentemente passou a ser empregada em redes locais de computadores (LANs). O SST se
propaga por uma larga faixa de espectro de freqüência, é transmitido um sinal forte e de fácil
detecção, porém o receptor deve saber a freqüência exata do sinal para poder reconhecê-lo, caso
não esteja sintonizado adequadamente o sinal será escutado como uma interferência (ruído).
Existem duas técnicas principais usadas nas transmissões SST, são elas: Seqüência direta (DS –

6
Direct Sequence) e Salto de Freqüência (FH – Frequency Hopping). Os sistemas DS são
baseados na amplitude modulada (AM), enquanto que os FH são baseados na freqüência
modulada (FM) [3].
Conforme comentado, o método de transmissão por espectro espalhado utiliza uma faixa
de freqüência (várias freqüências de transmissão) em vez de utilizar uma única freqüência fixa.
Essa faixa de freqüência normalmente é dividida em canais.

2.1.2.2 FHSS – Frequency Hopping Spread Spectrum


No sistema FHSS, de tempos em tempos o canal usado é alterado automaticamente por
todos os dispositivos da rede, só que não de uma maneira seqüencial (canal 1, canal 2, canal 3,
etc), mas sim de uma maneira aleatória. Assim, para poderem transmitir e receber dados, os
dispositivos da rede necessitam saber a seqüência exata dos canais usados [1].
Apesar de o padrão parecer aleatório, na realidade segue uma seqüência periódica
conhecida pelo transmissor e receptor, cada unidade permanece em uma freqüência sucessiva
apenas por um tempo determinado antes de saltar para a próxima largura de banda de RF [2].
Outra vantagem desse sistema é que várias redes operando por ondas de rádio podem co-
existir usando a mesma faixa de freqüência na mesma região sem gerarem interferência de rádio
entre elas. O que não ocorre normalmente em regiões onde existem dois sistemas de transmissão
de rádio operando na mesma faixa de freqüência, já que um sistema irá interferir no outro.
Quando se utiliza a tecnologia FHSS, quando há interferência, os sistemas irão ter problemas de
estar usando o mesmo canal somente durante um pequeno intervalo de tempo, até que seja feita a
próxima troca de canal, e possivelmente o próximo canal usado pelos sistemas será diferente,
eliminando o conflito. Em uma área que tenha dois sistemas FHSS operando as chances de
conflito de canal são de 1:79 (1,26%) [1].
A tecnologia FHSS, por causa das freqüentes alternâncias de canal, é mais lenta que a
tecnologia DSSS e, por esse motivo, está cada vez mais sendo substituída por esta última. As
taxas de transmissão FHSS são de 1 ou 2 Mbps.

7
Figura 2.2 - Transmissão FHSS [2].

Na Figura 2.2 exemplificamos o funcionamento da alternância de canais que ocorre na


tecnologia FHSS. Note que a transmissão em determinado instante é feita em um canal,
alternando no instante seguinte, e alternando novamente várias vezes consecutivas podendo
voltar a um canal já utilizado anteriormente. Através da ilustração é possível entender que se faz
necessário o conhecimento prévio da alternância de canais para que o transmissor e o receptor
possam estabelecer a comunicação.

2.1.2.3 DSSS – Direct Sequence Spread Spectrum


A tecnologia DSSS funciona de forma similar à tecnologia FHSS, porém, em vez de a
troca de canais ser feita de forma aleatória, ela é feita de uma forma seqüencial. É importante
notar que as tecnologias FHSS e DSSS são incompatíveis entre si. Apesar de serem especificadas
pelo mesmo padrão (IEEE 802.11), uma antena FHSS não consegue comunicar-se com uma
antena DSSS e vice-versa [1].
Em sistemas DSSS, os sinais são dispersos ao longo de uma faixa de RF relativamente
extensa, aumentando o número de freqüências de transmissão simultânea. Esta técnica supera
ameaças de interferências de sinal ao transmitir os dados através de várias freqüências para que
os receptores façam a recomposição do sinal [2].
A técnica de compartilhamento da mesma faixa de freqüência por um número de
usuários também é conhecida como Code Division Multiple Acess (CDMA), que está se tornando
8
um padrão para as LANs wireless. Ela aloca para cada usuário um número de seqüência que é
único e reconhecido apenas pela antena receptora. O CDMA está se tornando o mais popular em
muitos países, particularmente os Estados Unidos [3].
AirPort é o nome comercial que a Apple dá ao sistema DSSS que vem embutido em seus
computadores Macintosh. Assim, AirPort e DSSS são sinônimos. Como usa um padrão de
mercado é possível montar uma rede sem fio contendo computadores Macintosh com antenas
AirPort e PCs contendo antenas DSSS [1].

2.1.2.4 Tecnologia de faixa de freqüência estreita (Narrowband)


Os sistemas de rádio de largura de faixa de freqüência estreita (Narrowband), são usados
pelos telefones sem fio. Eles transmitem e recebem informações usando uma freqüência de rádio
específica. A idéia é manter a freqüência de rádio o mais estreita possível para que seja capaz de
transmitir a informação. A interferência entre os canais de comunicação é evitada dando
diferentes freqüências para diferentes usuários, de modo que um não possa escutar o sinal do
outro, pois o filtro existente no seu receptor impede a entrada de qualquer outra freqüência que
não a definida para o seu receptor [2].

2.1.2.5 Microondas
Esta tecnologia oferece uma taxa de transmissão equivalente a do padrão Ethernet
(10Mbps), podendo atingir taxas superiores. A faixa de freqüência usada é em torno de 18 a 19
GHz (entre as ondas de rádio e o infravermelho) [3].

2.1.2.6 Infravermelho
A tecnologia infravermelho em vez de utilizar ondas de rádio, utiliza luz infravermelha
para fazer a transmissão de dados. Existem dois métodos para a transmissão de dados usando luz
infravermelha: a transmissão direta e a transmissão difusa. Na transmissão direta, os dispositivos
transmissores e receptores possuem um ângulo de abertura pequeno e, com isso, precisam estar
alinhados para que a transmissão possa ser efetuada. Já na transmissão difusa, os sinais

9
infravermelhos são enviados em todas as direções. Em termos práticos, a transmissão difusa
obtém uma taxa de transmissão menor e uma área de alcance menor que a direta.

2.1.3 Padrões organizacionais existentes

A definição de padrões é muito importante, pois permite que equipamentos de


fabricantes diferentes possam comunicar-se entre si desde que ambos obedeçam ao padrão
estabelecido.
Usualmente se segmenta as redes wireless em diferentes categorias, são elas:
ü Redes locais sem fio (WLANs);
ü Redes pessoais sem fio (WPANs);
Apesar de parecerem iguais por apresentarem algumas características em comum, tais
como prever a mobilidade. Essas segmentações possuem sutis diferenças principalmente no que
diz respeito a finalidade da rede. As WLANs se propõem a ser uma extensão ou alternativa as
redes locais cabeadas interconectando computadores, enquanto as WPANs se propõem a
interconectar dispositivos tais como: relógio, PDA, computador, etc.
Os padrões atualmente existentes são:
Para WLANs:
ü Protocolo IEEE 802.11

Para WPANs:
ü Protocolo IEEE 802.15
ü Bluetooth
ü HomeRF
ü IrDA

2.1.3.1 O protocolo IEEE 802.11


Em 1997 o IEEE aprovou o primeiro protocolo de mercado pare redes locais sem fio.
Com taxa de transmissão de 2Mbps, freqüência de 2.4GHz e podendo utilizar como tecnologia

10
para transmissão de dados FHSS, DSSS ou Infravermelho.
Verificando a extrema necessidade de velocidade, os fabricantes comecaram a
apresentar equipamentos com protocolos proprietários para aumentar a taxa de transferência para
10Mbps, o mesmo do Ethernet IEEE 802.3 [2].
Diante deste fato o IEEE definiu dois padrões para complementar a velocidade
requerida, são eles:
ü IEEE 802.11a – Trabalha na freqüência de 5GHz e suporta taxa de transferência
de 54Mbps;
ü IEEE 802.11b – Trabalha na freqüência de 2.4GHz e suporta taxa de
transferência de 11Mbps;
Na arquitetura 802.11 a unidade básica é a célula, que é composta de uma ou mais
estações de trabalho sem fio e um access point.

2.2 TECNOLOGIA BLUETOOTH

A tecnologia wireless Bluetooth é um sistema de comunicações de curto alcance que foi


desenvolvido com o objetivo de substituir os cabos que conectam dispositivos eletrônicos
portáteis e/ou fixos. Ela utiliza sinais de rádio-freqüência (RF) para estabelecer transferências de
voz e dados ponto-a-ponto dentro de um raio de 10m a 100m variando de acordo com a potência.
Existem três classes de dispositivos Bluetooth e que são baseadas no poder de alcance.
Na prática a maioria dos dispositivos com Bluetooth suporta apenas um ou dois tipos de classes.
Nessas classes quanto menor a sua potência menor a distância de alcance [4]. A Tabela 2.1
mostra as especificações dessas classes.

Tabela 2.1 - Classes de transmissão Bluetooth

Classe de Potência Máxima Potência Potência Mínima Alcance


potência Nominal
1 100mW (20dBm) N/A 1mW (0 dBm) 100 metros
2 2,5mW (4dBm) 1mW(0 dBm) 0,25mW (-6 dBm) 20 metros
3 1mW (0dBm) N/A N/A 10 metros

11
O sistema do núcleo de Bluetooth consiste em um transceptor RF. O sistema oferece os
serviços que permitem a conexão entre dispositivos e da troca de dados entre estes dispositivos.

2.2.1 Faixa de freqüência e organização dos canais

Como citado anteriormente o sistema Bluetooth opera na faixa de freqüência conhecida


como ISM, que vai de 2400 MHz a 2483,5 MHz. Os canais de RF são divididos em 79 canais
espaçados em 1 MHz e ordenados de 0 a 78. Para compatibilidade com as regulamentações de
cada país existe uma borda de banda que varia de 2MHz a 3,5MHz. Dessa forma temos que:
Freqüência = 2400 + borda + k MHz, k ≥0 e k ≤ 78

2.2.2 Modo de funcionamento

A camada física do Bluetooth trabalha na faixa de freqüência aberta — não requer


concessão de licença para uso e é livre para uso e qualquer finalidade — de 2,4GHz conhecida
como faixa ISM (para uso Industrial, Científico e Médico). O sistema emprega um transceptor de
FHSS cujo funcionamento foi detalhado anteriormente. A taxa de transmissão suporta 1 Mbps.
Ao contrário das transmissões infravermelhas, que utilizam ondas de luz e exigem que
os dispositivos a serem conectados estejam visíveis um ao outro, as ondas de rádio não têm
nenhuma exigência de linha de visão e podem, de fato, atravessar a maioria dos objetos sólidos
[5].
Durante a operação típica um canal físico de rádio é compartilhado por um grupo de
dispositivos que são sincronizados com clock e saltos de freqüência comuns. Um dispositivo
fornece a referência de sincronização e é conhecido como mestre. Todos os outros dispositivos
são conhecidos como escravos. Um grupo de dispositivos sincronizados desta forma é conhecido
como piconet. A piconet é o modo fundamental de comunicação na tecnologia wireless
Bluetooth.
Cada piconet pode conter até oito dispositivos diferentes e diversas piconets podem ser
conectadas em redes de dispersão (scatternets) maiores. Em uma scatternet, todas as

12
comunicações entre as piconets são filtradas pelos dispositivos mestres das piconets individuais.
Até 10 piconets contendo um total de 80 dispositivos Bluetooth diferentes podem ser incluídas
em uma única scatternet, além desse número a rede fica saturada. Como as piconets têm
identidades diferentes baseadas em canais de salto de freqüência diferentes, diversas piconets
podem compartilhar o mesmo espaço físico sem intervir entre si [2].
Apesar de um dispositivo Bluetooth poder participar de mais de uma piconet não é
possível que um dispositivo seja o mestre de mais de uma piconet ao mesmo tempo uma vez que
o clock sincronização da piconet é baseado no clock do dispositivo mestre. Em contrapartida um
dispositivo pode ser escravo em várias piconets independentes, a Figura 2.3 ilustra esse exemplo,
o dispositivo D faz parte das piconets 1 e 2. Um dispositivo que seja membro de duas ou mais
piconets não obrigatoriamente desempenhará funções de roteamento entre essas piconets. Apesar
de poder fazer parte de mais de uma piconet ao mesmo tempo um único dispositivo não pode ser
mestre de mais de uma piconet isso porque a alternância de freqüência é definida baseada no
clock do dispositivo e nesse caso seria a mesma para as duas piconets o que causaria interferência
nas transmissões.

Figura 2.3 - Coexistência de dispositivo em mais de uma piconet.

Os dispositivos situados em uma piconet usam um padrão específico para salto de


freqüência, que é determinado por um algoritmo que utiliza certos campos do endereço Bluetooth
e clock do dispositivo mestre. O padrão básico de salto de freqüência consiste na divisão da
banda ISM em 79 canais e realizar saltos pseudo-randômicos, mas o algoritmo pode ser adaptado
para excluir as faixas de freqüências que por ventura estejam sendo usadas por outros
dispositivos e causando interferências. A técnica do “salto adaptativo” melhora a compatibilidade

13
do Bluetooth com sistemas ISM estáticos que compartilham o mesmo ambiente [6].
Os sinais de dados utilizam a tecnologia baseada em comutação de pacote. Eles podem
ser transmitidos por rotas, freqüências e ordem diferentes da original. Uma vez que os pacotes de
uma mensagem sejam recebidos, eles serão reordenados na sua seqüência original. Já o sinal de
voz, por outro lado utiliza a tecnologia denomiada de comutação de circuito. Com ela, as
mensagens não são fatiadas em pacotes, em vez disso, um canal dedicado (ou circuito) é
estabelecido durante a transmissão. A taxa de transferência total de 1Mbps da tecnologia é o
máximo teórico, as taxas de transferências efetivas variam de acordo com o tipo de comunicação
[2].
De acordo com a especificação, cada freqüência é subdividida em unidades de tempo
conhecida como slots. Os dados são transmitidos entre dispositivos Bluetooth em pacotes que são
posicionados nesses slots. Quando as circunstâncias permitem, um número de consecutivos slots
pode ser alocado em um único pacote. A tecnologia Bluetooth oferece o efeito de transmissão
full-duplex através do uso do esquema de TDD (Time-Division Duplex). Nesse sistema cada slot
de tempo tem 625ms de duração, o TDD atribui slots de tempo subseqüentes para transmissão e
recepção. As unidades mestras transmitem em unidades pares, enquanto as escravas transmitem
nos slots ímpares.
Em nível físico, consideramos um circuito quando se estabelece uma conexão entre dois
dispositivos que transmitem pacotes em ambas as direções entre eles. Na arquitetura piconet
existem restrições no que diz respeito à formação desses circuitos. Existe um circuito entre cada
escravo e o mestre, porém não existem circuitos conectando diretamente dois escravos [6].

2.2.3 Modos de operação

O modo de operação típico de um dispositivo Bluetooth é estar conectado a outros


dispositivos Bluetooth e trocando informações com esses outros dispositivos. Existem dois
estados principais, o conectado (connection) e em espera (standby). Um dispositivo estará
conectado se possuir uma conexão com outro(s) dispositivo(s) e estiver envolvido com atividades
com esse(s) outro(s) dispositivo(s). Já se ele não possuir uma conexão estabelecida com outro(s)
dispositivo(s) ou se possuir uma conexão estabelecida mas não estiver envolvido em atividades
14
com esse(s) ultimo(s) diz-se que ele encontra-se no modo de espera. A criação desse estado de
espera foi concebida como uma maneira para economizar a energia dos dispositivos.
De acordo com [5], quando um dispositivo está em espera, ele monitora as mensagens
de outros dispositivos. Uma vez que o dispositivo saida do estado de espera e entre no estado de
conectado, ele pode ser colocado em um dos quatro modos possíveis de conexão.

2.2.3.1 Modo Ativo (Active)


O dispositivo está participando ativamente da piconet, transmitindo ou recebendo.
Unidades escravas ativas são automaticamente mantidas sincronizadas com a unidade mestra da
piconet.

2.2.3.2 Modo Monitor (Sniff)


O dispositivo monitora a piconet a uma taxa reduzida, diminuindo assim seu consumo
de energia.

2.2.3.3 Modo Parado (Hold)


O dispositivo mantém ativado apenas o timer interno, esse modo é usado quando
nenhum dado precisa ser transmitido ou quando a transferência de dados é pequena, sendo
bastante aplicado a sensores de temperatura.

2.2.3.4 Modo Estacionado (Park)


O dispositivo precisa permanecer conectado a uma piconet, mas não necessita participar
do tráfego de dados em progresso. Nesse modo ele suspende seu endereço MAC.

Todos os dispositivos Bluetooth que não estejam conectados a uma piconet iniciam no
estado de baixo consumo de energia. Quando uma unidade percebe outro dispositivo Bluetooth
na área, um procedimento de conexão é iniciado. Neste momento o primeiro dispositivo (que
encontrou o segundo) se torna mestre e formará uma piconet.

15
2.2.4 Gerenciador de Link e Controlador de Link

As conexões entre dispositivos Bluetooth são manipuladas por uma combinação de


hardware e software. O software é denominado Gerenciador de Link (Link Manager ou LM),
enquanto o hardware é denominado de Controlador de Link (Link Controller – LC).
O software LM atua numa camada superior executando as funções de autenticação,
configuração e outras atividades necessárias ao estabelecimento de uma conexão entre dois
dispositivos. O LM detecta outros dispositivos que executam o mesmo software LM e, em
seguida, se comunica com eles através do protocolo LMP (Link Manager Protocol). Já o LC é
responsável, basicamente, pela codificação e decodificação de pacotes bem como a comunicação
com a interface de RF.

2.2.5 Estabelecendo a conexão (pareamento)

O processo de estabelecimento de conexão obedece ao protocolo na Figura 2.4:

Dispositivo Dispositivo
realizando encontrado
busca
◄––––––––––––––––––––► Busca e localização de dispositivo
LMP, Requisição de:
ü Diferença (offset) de clock;
ü Versão do LMP;
◄––––––––––––––––––––►
ü Recursos suportados;
ü Nome;
ü Desconexão (opcional);
––––––––––––––––––––––► LMP, Requisição de conexão.
◄–––––––––––––––––––––– LMP, Resposta de conexão aceita ou conexão recusada.
◄––––––––––––––––––––► LMP, Procedimentos de autenticação e criptografia.
––––––––––––––––––––––► LMP, Mensagem de configuração completa.
◄–––––––––––––––––––––– LMP, Mensagem de configuração completa.

Figura 2.4 - Protocolo de conexão.

16
2.3 JAVA

Neste item será abordada a tecnologia Java para programação. Suas características de
portabilidade assim como sua plataforma com foco em dispositivos que possuem poucos
requisitos de hardware, a tornou a linguagem predominante nos dispositivos móveis, um dos
focos deste projeto.

2.3.1 A linguagem JAVA

O JAVA é uma linguagem de programação orientada a Objetos. Em JAVA, tudo é uma


classe, com propriedades e métodos. Apesar da sintaxe do JAVA ter sido desenvolvida sobre a
sintaxe da linguagem C++, muitas características do C++ foram deixadas de lado para
proporcionar uma linguagem mais robusta e com menor tempo de depuração.
Porém, a característica particular e mais marcante do JAVA é a sua portabilidade. O
JAVA não é só uma linguagem, sua estrutura foi projetada de forma a criar um código
independente da plataforma (SO/Máquina) sobre a qual está rodando, chamado de “bytecode”. O
JAVA possui JVM´s (Java Virtual Machines – ou Máquinas Virtuais Java) que interpretam e
executam o bytecode, fazendo a interface com o processador. Portanto, para desenvolver e
executar aplicativos Java é necessário um compilador JAVA, para traduzir o código-fonte para
bytecode, e uma JVM adequada à plataforma utilizada, que irá se encarregar de traduzir o
bytecode para a máquina real. Esta característica do JAVA é chamada pela Sun Microsystems de
“Write once, run anywhere” (escreva uma vez, rode em qualquer lugar), pois possibilita que uma
vez compilado, o programa possa ser executado em qualquer máquina com uma JVM instalada.
Uma outra característica do JAVA é a simplicidade do código no que se refere a funções.
Isto porque a Sun Microsystems, conforme as necessidades, disponibiliza várias bibliotecas de
funções para o JAVA, esta bibliotecas são chamadas API. As API’s (Application Programming
Interface ou Interface para Programação de Aplicativos) são voltadas para aplicações de uma
determinada área, otimizando assim o código para o programador, que simplesmente adicionará
as API’s que se fizerem necessárias à sua aplicação [8],[9].

17
2.3.2 Divisão da família JAVA

A computação evoluiu em grande escala. As aplicações do JAVA não estão restritas só


aos computadores pessoais ou de grande porte. A industria de eletrônicos portáteis também
aderiu aos sistemas computacionais, porém com baixa capacidade de processamento e
armazenamento quando comparados aos PC´s e mainframes.
A enorme variedade de aplicações para linguagem JAVA impulsionou a Sun
Microsystems a dividir o JAVA em 3 categorias. Buscando otimizar a grande quantidade de
aplicações em cada área de atuação, desenvolvendo melhores VM’s para cada necessidade e
assim reduzindo o tamanho das aplicações para um melhor desempenho em cada área [9].
A linguagem JAVA está dividida da seguinte forma:

ü J2EE – Java to Enterprise Edition


Java Edição Corporativa - Plataforma Java voltada para aplicações em servidores
corporativos e serviços em ambiente Internet. Também voltada para sistemas multicomponentes.

ü J2SE – Java to Standard Edition


Java Edição Padrão - Plataforma Java voltada para aplicações em computadores comuns
(PC’s). Serve também de plataforma para as demais versões.

ü J2ME – Java to Micro Edition


Java Edição Micro - Plataforma Java voltada para aplicações em dispositivos de
pequeno porte, com baixo poder de processamento, menor memória, periféricos proprietários
(display, E/S); tais como celulares, pagers, PDA’s, sistemas veiculares, etc.

As edições do JAVA se completam, e desta forma oferecem aplicativos em todas as


plataformas. Com algumas restrições de recursos, o J2ME, que será utilizada neste projeto,
possui VM’s específicas, como será abordado a seguir.

18
2.3.3 J2ME

A plataforma J2ME provê um ambiente robusto e flexível para aplicações que rodam em
dispositivos como celulares, pagers, PDA’s e uma outra grande gama de dispositivos de baixo
poder de processamento e armazenamento. Assim como as plataformas J2EE e J2SE, a J2ME
inclui máquinas virtuais e vários API’s padrões definidos pela Sun Microsystems e comunidades
Java (comunidades de peritos, fabricantes, vendedores e prestadores de serviço de dispositivos
que utilizam a J2ME).
A J2ME inclui dispositivos de interface flexíveis com o usuário (isto devido a grande
variedade de displays, que variam em cada modelo de aparelho), um modelo de segurança
robusto, uma grande variedade de protocolos de rede embutidos, além de suporte a aplicativos em
rede ou off-line, que podem ser carregados dinamicamente [10].
A arquitetura do J2ME inclui uma variedade de configurations, profiles, e API’s que o
programador pode escolher, combinando-os para construir um ambiente completo que se ajuste
ao dispositivo e às necessidades do aplicativo. Estas combinações visam aperfeiçoar o aplicativo
para a capacidade de memória, poder de processamento e particularidades dos periféricos de E/S
(entrada e saída) da uma determinada categoria de dispositivos. O resultado é uma plataforma
Java comum a todos os dispositivos e que tira proveito de cada um de forma aperfeiçoada [10].
Um exemplo da capacidade de otimização do J2ME para com as limitações físicas do
dispositivo é a dualidade de configurations, que podem se adequar às características do
dispositivo para o qual se está desenvolvendo o aplicativo, hoje existem duas configurations para
esta plataforma, a ‘CLDC’ e ‘CDC’, que diferem na quantidade de recursos suportados e
disponibilizados para o programador [9].

2.3.4 VM – Máquinas Virtuais

2.3.4.1 JVM

A Máquina Virtual Java usada nas versões Standard Edition e Enterprise Edition é

19
voltada apenas para o uso em computadores convencionais e servidores. Já no caso dos
dispositivos de pequeno porte, necessitam de uma Máquina Virtual adequada as suas arquiteturas
como Celulares, Telefones Inteligentes, Pagers, PDA’s, etc.
Porém, a VM para estes dispositivos de pequeno porte também leva em conta a mesma
dualidade das configurations, ou seja, a Sun Microsystems desenvolveu duas VM´s para atender
ao mercado do J2ME. Nesta plataforma, o Java dispõe de duas VM´s, a KVM e a CVM, uma
para desenvolvimento e aplicações em dispositivos com pouca memória e pouco poder de
processamento (dispositivos de baixo desempenho) e a outra para dispositivos com um pouco
mais de memória e melhor poder de processamento (dispositivos de alto desempenho). Os
dispositivos de baixo desempenho utilizam KVM (K Virtual machine, ou Máquina Virtual K) e
os dispositivos de alto desempenho utilizam a CVM (C Virtual machine, ou Máquina Virtual C)
[11].

2.3.4.2 KVM

O surgimento do J2ME trouxe consigo uma máquina virtual bastante otimizada. O KMV
é uma pequena VM com o mínimo de API´s incluídas. A letra K no nome da VM faz referencia a
palavra ‘kilo’, indicando que o tamanho da VM é dimensionado em kilobytes, e não em
megabytes. A KVM é otimizada para dispositivos de baixo desempenho, e o seu tamanho está
entre 40 e 80 KB [10].
A KVM pode rodar em sistemas com processadores de 16 e 32 bits e de 160 a 512 KB
de memória e não tem suporte a dados do tipo inteiro longo e ponto flutuante, isto porque o
design da KVM é baseado em considerações importantes, incluindo o pequeno tamanho para
conservar a maior quantidade possível de espaço na memória do dispositivo (tanto em termos de
armazenamento quanto de execução) para assegurar a portabilidade [11].
Devido a grande quantidade de dispositivos com características diferentes e que utilizam
o J2ME, a Sun Microsystems dividiu a plataforma em duas configurations, conforme já
mencionado, a CDC e CLDC, esta configurations são quem definem as características da VM a
ser utilizada, e através delas é que se escolhe quais API´s serão utilizadas. Sendo a KVM
desenvolvida para trabalhar com o CLDC.
20
A Máquina Virtual K teoricamente pode rodar vários Profiles, mas isso não significa
que vai rodar perfeitamente todos Profiles e API’s, pois podem não ter sido especificamente
desenvolvidas para a KVM. Esta VM não pode ser usada, por exemplo, para rodar a CDC.
Isto que dizer que não dá para fazer com que as aplicações desenvolvidas para CVM
sejam executadas na KVM sem as devidas modificações. Já o contrario é verdadeiro, isto é, uma
aplicação feita em KVM roda em CVM ou JVM [9].

2.3.4.3 CVM

A Máquina Virtual C foi desenvolvida para fornecer funcionalidade à categoria de alto


desempenho dos dispositivos de pequeno porte que a KVM não podia suportar. Esta VM tem
quase todas as funcionalidades de uma JVM (usada na J2SE e J2EE), com quase todos seus
recursos.
Muito dos recursos que não são suportados pela KVM, são suportados pela CVM, isto é
esperado por uma VM com muitos recursos e somente uma pequena porção de sua
funcionalidade foi sacrificada para sua otimização [11].

2.3.5 Configurations

As configurations formam a base da plataforma J2ME, definindo quais classes (conjunto


de objetos com características comuns - uma classe é como um modelo para a criação de objetos,
que tem as mesmas características da classe à qual pertence) e bibliotecas (conjunto de classes e
funções que ficam num arquivo com a função de estruturar e otimizar a programação) serão
carregadas para cada categoria de dispositivos [11],[12].
As configurations incluem também a VM além do pacote mínimo de bibliotecas de
classe, que provêem a funcionalidade da configuration. Atualmente, há duas configurations para
o J2ME: a CLDC (Connected Limited Device Configuration, ou Configuração de Dispositivo
Conectado Limitada) e a CDC (Connected Device Configuration, ou Configuração de
Dispositivo Conectado) [10].
A configuration no J2ME define os limites na plataforma para cada categoria de

21
dispositivos, determinando assim quais as características da VM (KVM ou CVM) adequada.

2.3.5.1 CLDC

Essa configuração foi desenvolvida para dispositivos com baixos recursos de memória
(entre 160 kB e 512 kB de memória), baixo poder de processamento (processadores de 16 ou 32
bits) e baixo consumo de energia (funcionam com bateria) como os telefones celulares, PDA’s,
pagers etc. Com vista nisso, toda a tecnologia Java foi otimizada para prover funcionalidade para
este grupo de dispositivos. A Máquina Virtual K como já foi citado beneficia muito esta
configuration pela característica de ser muito pequena, e não ter todos os recursos de uma JVM.
O maior destaque é que mesmo com poucas bibliotecas disponíveis conseguem permitir que as
configurations implementem a execução de diversas funcionalidades. Porém, mesmo assim, elas
devem ser usadas com muito cuidado, já que os dispositivos não dispõem de muita memória [12].

2.3.5.2 CDC

Esta Configuration foi desenvolvida para dispositivos com um razoável nível de


memória (acima de 2MB) e bom poder de processamento (processadores de 32 bits). Esta
configuration fornece muito mais recursos da J2ME, no que diz respeito à Linguagem Java e
Máquina Virtual C. O maior diferencial é a quantidade de API’s incluídas na CDC que é
significativamente maior do que na CLDC, isto significa que se podem ter muito mais
funcionalidades nas aplicações usando-se CDC [12].

2.3.6 Profiles

Para prover o ambiente completo de desenvolvimento e execução, além das


configurations, é necessária a utilização de profiles. Um profile (ou perfil) define a interface
entre o dispositivo e a aplicação. Para tanto, os profiles fornecem pacotes de bibliotecas

22
chamadas API´s [13].
As API’s têm foco em um determinado dispositivo, como celulares ou PDA´s, porém
não são desenvolvidas sobre as características de um dispositivo específico, na verdade os
fabricantes é que implementam, de acordo com o desejado, as execuções desenvolvidas nos
profiles. Porém, existe a opção de adicionar pacotes extras de API´s, que podem ser
desenvolvidas para uma determinada aplicação em um determinado dispositivo, como por
exemplo, conexões Bluetooth e alguns serviços web. Estes pacotes, mesmo depois de
desenvolvidos, geralmente não são incluídos como padrão nos profiles, pois uma preocupação
inicial das bibliotecas de API´s é a otimização. Na Tabela 4.1 temos uma demonstração de alguns
profiles e suas aplicações e configurations [9],[13].

Tabela 2.2 - Características de Profiles [9]

PROFILES CONFIGURATION VIRTUAL EXEMPLOS


MACHINE
MIDP CLDC KVM Telefones celulares e Pagers
PDAP CLDC KVM PDAs
FOUNDATION CDC CVM Base para o Personal Profile
PERSONAL CDC CVM Pockts pcs, Tablets
RMI CDC CVM Qualquer dispositivo com suporte
PERSONAL BASIS CDC CVM Qualquer dispositivo com suporte
MULTIMEDIA CDC/CLDC CVM Qualquer dispositivo com suporte
GAMING CDC/CLDC CVM / KVM Qualquer dispositivo com suporte
WTCA CDC/CLDC CVM / KVM Telefones Celulares

Para desenvolvimento de aplicativos, a camada que interessa ao programador é a de


profiles, que em conjunto com as API´s irá determinar características como modelo de ciclo-de-
vida da aplicação, a interface do usuário e acesso a propriedades específicas do dispositivo. Com
isso, uma aplicação desenvolvida sobre um profile deverá ser suportada em qualquer outro
dispositivo que utilize o mesmo profile [10],[12] e [13].
Em conjunto com os profiles, a configuration (incluindo a VM) forma o ambiente de
desenvolvimento, identificado principalmente pelas especificações do profile, e isto é quem
determina os dispositivos que a aplicação irá suportar.
Existem diversos tipos de profiles para a plataforma J2ME, eles podem ser classificados
23
quanto a configuration que o suporta, dividindo-os em profiles desenvolvidos para CDC ou
CLDC.
Dentre os profiles voltados para a configuration CDC podemos citar alguns mais
importantes, como o Foundation Profile, Personal Profile, Personal Basis, RMI Profile dentre
outros. Já quando falamos em CLDC, os profiles mais utilizados são o MIDP, KJava Profile,
PDAP. Além dos citados, existem também alguns profiles desenvolvidos e bastante utilizados
para ambos os tipos de configurations, são eles o Multimedia Profile, Gaming Profile e WTCA
Profile, que agregam funções aos demais profiles [9],[13].
A Figura 2.5 demonstra graficamente a arquitetura da família JAVA.

Figura 2.5 - Família JAVA [14].

2.3.6.1 MIDP

O MIDP (Mobile Information Device Profile, ou Perfil para Dispositivos Móveis de


Informação), é um profile, como dito anteriormente, baseado na configuration CLDC, portanto,
baseada na KVM. O MIDP é destinado à dispositivos de baixo poder de processamento, pouca

24
memória, limitada capacidade de entrada/saída de dados, enfim, dispositivos de baixo
desempenho. Sendo utilizado principalmente em aparelhos celulares, pequenos PDA´s e pagers
[9].
As aplicações desenvolvidas em MIDP são chamadas de MIDlets, e podem utilizar as
API´s do perfil e API´s opcionais que podem ser adicionadas se desejado. Porém, os MIDlets não
têm acesso todas as API´s de alguns dispositivos, como por exemplo a API do celular que, para
evitar que usuários mal intencionados desenvolvam programas para acessar esta API nativa dos
celulares e possam modificar os dados do dispositivo, é mantida em uma memória independente
da VM dos MIDlets [9],[10].
Outro ponto importante é que a carga de classes definidas pelo usuário não é permitida,
ou seja, o usuário não tem acesso a outras funções que não seja as da VM, o que aumenta a
segurança, porém restringe um pouco o desenvolvimento [9].
Os fabricantes de dispositivos podem fornecer API’s especificas para desenvolvimento
de aplicações, como é o caso dos jogos nos celulares. Cada fabricante disponibiliza sua própria
API para os jogos, podendo assim aproveitar melhor o desempenho do celular e seus recursos
proprietários. Esta prática compromete a portabilidade do Java, mas é desejável em algumas
situações, principalmente quando o fabricante cria um diferencial em seu produto [9].

2.3.6.1.1 Requisitos de Hardware


ü Tela:
Display de 96 x 54, com mínimo de 1-bit de cor e pixel shape 1:1;
Por estar voltado a dispositivos de pequeno porte, o MIDP trabalha com dispositivos de
tela pequena, monocromáticos ou com suporte a cores, e com pixels com relação
aproximadamente de um pra um, ou seja, quadrados. Porém, também suportam configurações de
telas maiores, abrangendo desde os recursos de celulares simples até PDA´s mais modernos.

ü Entrada:
Mínimo de um dispositivo de entrada tipo teclado, ou touch-screen;
Suporte a teclado numérico, bastante utilizado em celulares, a teclado alfa-numérico
utilizado em PDA´s e alguns celulares, e a telas sensíveis ao toque – conhecidas também como
25
touch-screen – comum em PDA´s. Outros dispositivos podem ser adicionados através de inclusão
de API´s específicas.

ü Memória:
128 kB de memória não-volátil para os componentes MIDP;
8 kB de memória não-volátil para os dados dos MIDlets criados
32 kB de memória volátil para runtime;
As mínimas condições de funcionamento do MIDP exigem uma pequena quantidade de
memória do dispositivo, que deverá oferecer disponibilidade de 128kB de memória não-volátil
para o armazenamento do MIDlet e dos componentes MIDP, uma disponibilidade adicional de
8kB de memória persistente para os dados do MIDlet que devem ser guardados durante e após a
execução da aplicação além de um mínimo de 32kB de memória volátil (tipo RAM) para rodar o
MIDlet. Esta memória de troca deverá ser observada pelo programador durante a construção de
seu projeto, para não comprometer o desempenho ou até mesmo as condições de execução do
aplicativo programado.
Este profile provê um mecanismo de gravação de dados (memória persistente) que
permite a gravação de dados e sua leitura posterior, chamado RMS (Record Management System,
ou Sistema de Gerência de Gravação). Este sistema provê a gravação de dados persistentes na
memória durante inúmeras solicitações do aplicativo, e deve manter a integridade destes dados,
mesmo em condições de falta de alimentação ou descarregamento de baterias do dispositivo
como, por exemplo, ocorre com a agenda de um aparelho celular durante a troca de baterias [9]
[10].

ü Rede:
Duas vias, com ou sem fios, com banda limitada.
O MIDP suporta conexões de rede de acordo com os recursos do dispositivo. As
conexões sem fio (wireless) são as mais utilizadas em dispositivos portáteis, porém há também
utilização de conexões através de cabos. Com o aumento da utilização da tecnologia Bluetooth,
esta tem se fortalecido como uma parceira forte do MIDP em conjunto com o CLDC, merecendo
até API´s específicas sobre este tecnologia wireless em dispositivos portáteis [13].

26
2.3.6.1.2 MIDP MIDlets suítes

Conforme apresentado anteriormente, um MIDlet é um aplicativo MIDP. Porém este


aplicativo pode ser formado por mais de uma classe, quando passa a ser chamado MIDlet Suíte.
Os MIDlets suites são formados por um empacotamento de classes em um único
arquivo, e são gerenciados pelo AMS (application manegement software), um software de
gerenciamento de aplicativos que provê o ambiente para instalação, inicialização, finalização e
desinstalação do MIDlet. Ele também é responsável por controlar os processos de instalação,
execução e remoção dos MIDlets Suítes, tratando quaisquer erros que ocorram e interagindo com
o usuário quando necessário [15].
Na formação do pacote Suite, alguns elementos estão presentes, além do empacotamento
de classes propriamente dito, há também o ambiente de execução, um descritor do aplicativo e
informações sobre o ciclo de vida do MIDlet suite.

2.3.6.1.3 Ciclo de vida dos MIDlets

Para iniciar o aplicativo (MIDlet), o AMS executa a um método chamado “startApp”,


definido no código. Este método põe o aplicativo no que chamamos de modo ativo. Caso o
dispositivo informe uma interrupção, o AMS executa o método “pauseApp”, pondo o aplicativo
em modo de pausa, que também pode ser provocado pelo próprio aplicativo, enviando uma
requisição ao AMS através do método “notifyPaused”. Para que o MIDlet seja reativado, o AMS
deverá executar o método “resumeApp” ou, caso a pausa tenha sido solicitada pela próprio
aplicativo, o método que deverá ser executado é o “resumeRequest” que solicitará o resumo da
aplicação ao AMS. Para finalizar o aplicativo também há duas opões, uma sendo enviada pelo
AMS, que deverá fazê-lo através do método “destroyApp”, e outra sendo solicitada pelo MIDlet,
que o faz através do método “notifyDestroyed”, que envia esta solicitação ao AMS, que por sua
vez trata de executar a finalização do MIDlet [9].

27
CAPÍTULO 3 – TECNOLOGIAS DE SOFTWARE

3.1 API BLUETOOTH

A API Java Bluetooth é composta de dois pacotes, o Javax.Bluetooth e o Javax.obex. O


primeiro é composto de interfaces e classes relacionadas à conexão entre dispositivos, enquanto
que o segundo pacote possui interfaces e classes relacionadas à sessão da conexão. A seguir
apresentamos as interfaces, classes e exceções do pacote principal desta API, o Bluetooth.

3.1.1 Javax.Bluetooth Interfaces


As interfaces que compõem este pacote são apresentadas com seus métodos, sintaxes,
parâmetros, retorno e tratamentos de erro onde cada um for aplicado.

3.1.1.1 DiscoveryListener
A interface DiscoveryListener permite que uma aplicação receba os eventos de
descoberta de dispositivo - device discovery - e descoberta de serviço - service discovery. Esta
interface fornece quatro métodos, dois de descoberta de dispositivos e dois de descoberta de
serviços.

3.1.1.1.1 Método deviceDiscovered


Esse método é chamado quando um dispositivo é encontrado durante um processo de
busca - inquiry. Um processo de busca procura por dispositivos que podem ser descobertos. O
mesmo dispositivo pode ser encontrado múltiplas vezes.

3.1.1.1.1.1 Sintaxe:
public void deviceDiscovered(RemoteDevice btDevice,
DeviceClass cod)

3.1.1.1.1.2 Parâmetros:

btDevice – Dispositivo que foi encontrado durante uma busca.

cod – Classe do serviço, classe majoritária do dispositivo e a classe minoritária do

dispositivo remoto.
28
3.1.1.1.2 Método servicesDiscovered
Este método é chamado quando serviços são encontrados durante uma busca por
serviços.

3.1.1.1.2.1 Sintaxe:
public void servicesDiscovered(int transID,
ServiceRecord[] servRecord)

3.1.1.1.2.2 Parâmetros:

transID – Identificador de transação da busca de serviços que está relacionado aos

resultados.
service – Lista de serviços encontrados durante a requisição de busca.

3.1.1.1.3 Método serviceSearchCompleted


Método chamado quando uma busca de serviços é concluída ou finalizada com erros. Os
valores de status no argumento respCode incluem:

Tabela 3.1- Códigos de resposta do método serviceSearchCompleted.

respCode Descrição
SERVICE_SEARCH_COMPLETED Busca por serviços foi concluída com
sucesso.
SERVICE_SEARCH_TERMINATED Busca por serviços foi interrompida
através da chamada
DiscoveryAgent.cancelServiceSearch().
SERVICE_SEARCH_ERROR Ocorreu um erro durante o
processamento da busca de serviços.
SERVICE_SEARCH_NO_RECORDS Não foi encontrado nenhum serviço
durante a busca.
SERVICE_SEARCH_DEVICE_NOT_REACHABLE O dispositivo especificado na busca não
foi encontrado ou o dispositivo local foi
incapaz de conectar ao dispositivo
remoto.

29
3.1.1.1.3.1 Sintaxe:
public void serviceSearchCompleted(int transID,
int respCode)

3.1.1.1.3.2 Parâmetros:

transID – Identificador de transação que identifica a requisição que iniciou a busca de

serviços.
respCode – O código de resposta que indica o status da transação.

3.1.1.1.4 Método inquiryCompleted


Este método é chamado quando uma busca por serviços é concluída. O parâmetro
discType será:

Tabela 3.2 - Tipos de requisição do método inquiryCompleted.

discType Ocorre quando:


INQUIRY_COMPLETED A busca foi concluída normalmente.
INQUIRY_TERMINATED A busca foi cancelada através da chamada Busca por
serviços foi interrompida através da chamada
DiscoveryAgent.cancelInquiry().
INQUIRY_ERROR Ocorreu um erro durante a busca o que resultou num
encerramento anormal.

3.1.1.1.4.1 Sintaxe:
public void inquiryCompleted(int discType)

3.1.1.1.4.2 Parâmetros:

discType – O tipo de requisição que foi concluída, podendo ser:


INQUIRY_COMPLETED, INQUIRY_TERMINATED, ou INQUIRY_ERROR

30
3.1.1.2 L2CAPConnection
A interface L2CAPConnection representa um canal L2CAP orientado a conexão. Esta
interface é usada como parte do Framework de conexão genérica do CLDC. Para criar uma
conexão de cliente, o protocolo a ser usado é o btl2cap. O destino é uma combinação de endereço
de dispositivo Bluetooth a ser conectado e o PSM do serviço. O valor PSM é usado pelo L2CAP
para determinar qual a camada de protocolo ou aplicação é destinatária das mensagens. O
parâmetro definido especificamente para o L2CAP é o ReceiveMTU (MTU – Maximum
Transmission Unit, Unidade de Transmissão Máxima de recebimento) e o TransmitMTU
(Unidade de Transmissão Máxima do transmissor). O ReceiveMTU e o TransmitMTU são
parâmetros opcionais. Um exemplo de uma string válida de conexão L2CAP é:
btl2cap://0050CD00321B:1003;ReceiveMTU=512;TransmitMTU=512
No exemplo acima, podemos identificar:
• Endereço do dispositivo Bluetooth: 0050CD00321B;
• PSM: 1003;
• ReceiveMTU: 512;
• TransmitMTU: 512.

3.1.1.2.1 Método getReceiveMTU


Retorna o valor do ReceiveMTU que a conexão suporta. Se a string de conexão não
especifica um ReceiveMTU, o valor retornado será igual ou menor do que o DEFAULT_MTU
(672 bytes). Se a string de conexão especificar uma MTU, o valor sera igual ou menor do que o
valor especificado na string de conexão.

3.1.1.2.1.1 Sintaxe:
public int getReceiveMTU()
throws Java.io.IOException

3.1.1.2.1.2 Retorno:

O número máximo de bytes que podem ser lidos em uma única chamada de receive().

3.1.1.2.1.3 Tratamento de erro:

Java.io.IOException – Se a conexão foi fechada.

31
3.1.1.2.2 Método getTransmitMTU
Retorna o MTU que o dispositivo remoto suporta. Este valor é obtido após a conexão ter
sido configurada. Se a aplicação houver especificado o TransmitMTU na string
Connector.open(), então o retorno sera igual ao valor especificado. Se a aplicação não

especificar nenhum TransmitMTU, então o valor sera menor ou igual ao valor de ReceiveMTU
que o dispositivo remoto informou na configuração do canal.

3.1.1.2.2.1 Sintaxe:
public int getTransmitMTU()
throws Java.io.IOException

3.1.1.2.2.2 Retorno:

O número máximo de bytes que podem ser enviados em uma única chamada do send(),
sem que nenhum dado seja perdido.

3.1.1.2.2.3 Tratamento de erro:

Java.io.IOException – Se a conexão foi fechada.

3.1.1.2.3 Método ready


Determina se este é um pacote que possa ser lido através de uma chamada
receive(). Se verdadeiro, uma chamada receive() não bloqueará o aplicativo.

3.1.1.2.3.1 Sintaxe:
public boolean ready()
throws Java.io.IOException

3.1.1.2.3.2 Retorno:

true se o dado poder se lido; false caso contrário.

3.1.1.2.3.3 Tratamento de erro:

Java.io.IOException – Se a conexão foi fechada.

32
3.1.1.2.4 Método receive
Lê um pacote de dados. A quantidade de dados recebidos em uma operação é
determinado pelo ReceiveMTU. Se o tamanho de inBuf for maior ou igual ao
ReceiveMTU, nenhum dado sera perdido. Diferentemente do read() da
Java.io.InputStream, se o tamanho do inBuf for menor que o ReceiveMTU, então os

dados no pacote L2CAP que caibam no inBuf serão armazenados, e os demais serão
descartados. Se o inBuf tiver comprimento 0, todos os dados no pacote recebido serão
perdidos, exceto se o pacote for de comprimento 0.

3.1.1.2.4.1 Sintaxe:
public int receive(byte[] inBuf)
throws Java.io.IOException

3.1.1.2.4.2 Parameters:

inBuf – vetor de bytes para armazenamento dos dados recebidos.

3.1.1.2.4.3 Retorno:

O número de bytes lidos; 0 se o pacote recebido tiver comprimento zero; 0 se o


inBuf tiver comprimento zero.

3.1.1.2.4.4 Tratamento de erro:

Java.io.IOException – Se um erro de I/O ocorreu ou se a conexão foi fechada;


InterruptedIOException – Se a requisição exceder o tempo limite;
NullPointerException – Se inBuf for nulo.

3.1.1.2.5 Método send


Encaminha o envio de dados para um dispositivo remoto. O TransmitMTU
determina a quantidade de dados que poderão ser enviados por vez. Se o tamanho de data

33
for maior que o TransmitMTU, somente os primeiros bytes do pacote serão enviados, e o
restante dos bytes de data que estiverem além do tamanho do TransmitMTU serão
descartados. Se data tiver comprimento 0, um pacote L2CAP vazio sera enviado.

3.1.1.2.5.1 Sintaxe:
public void send(byte[] data)
throws Java.io.IOException

3.1.1.2.5.2 Parametros:

data – Dados que serão enviados

3.1.1.2.5.3 Tratamento de erro:

Java.io.IOException – Se data não puder ser enviado corretamente ou se a


conexão for fechada;
NullPointerException – Se data for nulo.

3.1.1.3 L2CAPConnectionNotifier
A interface L2CAPConnectionNotifier provê um notificador de conexão L2CAP.
Para criar um conexão de servidor, o protocolo a ser utilizado é o btl2cap. O alvo é
"localhost:" e a UUID do serviço desejado. Os parametros são ReceiveMTU e TransmitMTU, os
mesmos usados para definir uma conexão de cliente. Abaixo segue um exemplo de uma string
válida para um conexão de servidor:
btl2cap://localhost:3B9FA89520078C303355AAA694238F07;ReceiveMTU=512;Tra
nsmitMTU=512
Chamando o método Connector.open() com a string acima retornará um objeto
Javax.Bluetooth.L2CAPConnectionNotifier. Um objeto L2CAPConnection é obtido do

L2CAPConnectionNotifier através da chamada do método acceptAndOpen().

3.1.1.3.1 Método acceptAndOpen


Aguarda por um cliente para conectar o serviço L2CAP. Após a conexão, retornará uma

34
L2CAPConnection que poderá ser usada para comunicação com este cliente.

Um registrador de serviço associado a esta conexão será adicionado ao SDDB,


associando-o com este objeto L2CAPConnectionNotifier se não existir nenhum outro no
SDDB. Este método porá o dispositivo local em modo conectável, podendo então responder as
tentativas de conexão de clientes.
Em seguida são realizadas as seguintes checagens para verificar se as mudanças feitas no
aplicativo pelo registrador de serviço após a criação com Connector.open() não criaram
nenhum registro de serviço inválido. Se alguma das checagens falhar, um
ServiceRegistrationException é emitido.

São obrigatórios os atributos de serviço ServiceClassIDList e ProtocolDescriptorList


para um registrador de serviço btl2cap, e deverão estar presentes no registrador de serviço;
L2CAP deverá estar no ProtocolDescriptorList.
O valor de PSM não deve ter sido alterado no registrador de serviço.
Este método não garante que o registrador de serviço criou um registro completamente
válido. É responsabilidade do aplicativo assegurar que o registro de serviço seguiu todas as regras
de sintática e semântica aplicáveis na criação correta do registro de serviço.

3.1.1.3.1.1 Sintaxe:
public L2CAPConnection acceptAndOpen()
throws Java.io.IOException

3.1.1.3.1.2 Retorno:

Uma conexão para comunicação com o cliente.

3.1.1.3.1.3 Tratamento de erro:

Java.io.IOException – Se o notificador for fechado antes de


acceptAndOpen() ser chamado;

ServiceRegistrationException – Se a estrutura de associação do registrador de


serviço for inválida ou o registrador de serviço não conseguir adicionar o SDDB.
BluetoothStateException – Se o dispositivo servidor não puder ser posto no

35
modo conectável devido ao usuáio ter configurado o dispositivo como não-conectável.

3.1.1.4 ServiceRecord
A interface ServiceRecord descreve as características de um serviço Bluetooth. O
ServiceRecord contem os atributos de configuração de um serviço, ondes estes atributos são um
par de configurações formados por ID e value. O atributo ID do Bluetooth é um inteiro de 16-bit,
e o atributo value é um DataElement.
A estrutura e o uso do ServiceRecords são definidos pela especificações de Bluetooth
Service Discovery Protocol (SDP). A maioria das especificações de perfis Bluetooth são descritas
na estrutura do ServiceRecord usado pelos serviços Bluetooth de cada perfil.
Um servidor SDP mantêm um Service Discovery Database (SDDB) de ServiceRecords
que descrevem os serviços no dispositivo local. Já os clientes SDP remotos podem usar o SDP
para questionar um servidor SDP sobre qualquer ServiceRecords de seu interesse. Um
ServiceRecord provê informações suficientes para permiitir a um cliente SDP conectar o serviço
Bluetooth no dispositivo do servidor SDP.
ServiceRecords são disponibilizados ao aplicativo cliente através de um argumento do
método servicesDiscovered da interface DiscoveryListener. O ServiceRecords é disponibilizado
para o aplicativo servidor através do método getRecord() no dispositivo local.
Podem haver vários atributos de serviços em um mesmo ServiceRecord, e o protocolo
SDP torna possível especificar o subconjunto de atributos de service que o cliente SDP receber
do ServiceRecord remoto. A interface ServiceRecord trata alguns atributos IDs de serviço como
IDs padrão, desta forma, esses serviços são automaticamente identificados durante uma busca de
serviços.
Existe um documento que define uma grande quantidade de números IDs padrões para
assinatura de atributos de serviços Bluetooth, este documento poderá ser obtido através do site na
internet: https://www.Bluetooth.org/foundry/assignnumb/document/service_discovery.

36
3.1.2 Classes
A seguir são apresentadas as classes que compõem o pacote Bluetooth da API de mesmo
nome. Alguns métodos citados não estão detalhados devido a sua simplicidade, mas estão
disponíveis em sua íntegra no CD Anexo deste projeto.

3.1.2.1 DataElement
A classe DataElement define os vários tipos de dados a que atributos e serviços do
Bluetooth podem pertencer. A Tabela 3.3 apresenta os tipos de dados e valores válidos para
armazenamento em um objeto DataElement.

Tabela 3.3 - Tipos de dados da classe DataElement.

Elemento Tipo Valores Válidos


NULL Null Nulo
U_INT_1 Long Intervalo: [0, 255]
U_INT_2 Long Intervalo: [0, 216-1]
U_INT_4 Long Intervalo: [0, 232-1]
U_INT_8 Byte[] Intervalo: [0, 264-1]
U_INT_16 Byte[] Intervalo: [0, 2128-1]
INT_1 Long Intervalo: [-128, 127]
INT_2 Long Intervalo: [-215, 215-1]
INT_4 Long Intervalo: [-231, 231-1]
INT_8 Long Intervalo: [-263, 263-1]
INT_16 Byte[] Intervalo: [-2127, 2127-1]
BOOL Boolean 0 ou 1 || true ou false
URL Java.lang.String
UUID Javax.Bluetooth.UUID
BOOL Booleano
STRING Java.lang.String
DATSEQ Java.util.Enumeration
DATALT Java.util.Enumeration

3.1.2.2 DeviceClass
A classe DeviceClass representa a classe do dispositivo - class of device (CoD) – que

37
registra as definições da especificação Bluetooth. Este registro é definido no documento de
números Bluetooth assinados - Bluetooth Assigned Numbers – e contem informações do tipo de
dispositivo e dos tipos de serviços disponíveis neste dispositivo.
O documento Bluetooth Assigned Numbers pode ser encontrado na internet
(https://www.Bluetooth.org/foundry/assignnumb/document/baseband), com as definições de
classes de dispositivos e serviços, dentre outras informações.

3.1.2.3 DiscoveryAgent
Uma classe DiscoveryAgent provê métodos para permitir a descoberta de dispositivos e
serviços. Um dispositivo local possui apenas um objeto DiscoveryAgent. Este objeto é retornado
a partir de uma chamada do getDiscoveryAgent() no objeto LocalDevice.

3.1.2.3.1 Device Discovery


Existem duas alternativas para encontrar dispositivos. Uma delas é o aplicativo utilizar o
startInquiry() para iniciar uma busca de dispositivos próximos do dispositivo local. Os

dispositivos encontrados serão retornados através do método deviceDiscovered() da interface


DiscoveryListener. A outra alternativa para encontrar dispositivos é através do método

retrieveDevices(). Este método irá retornar os dispositivos que já foram descobertos através

de uma busca anterior ou os dispositivos que já estejam classificados como pré-conhecidos.


(Dispositivos “pré-conhecidos” são dispositivos que estão definidos no centro de controle do
Bluetooth - Bluetooth Control Center - como dispositivos que freqüentemente são contatados.) O
método retrieveDevices() não realiza uma busca, mas provê uma forma mais rápida de gerar
uma lista de dispositivos que podem estar próximos.

3.1.2.3.2 Service Discovery


A classe DiscoveryAgent também encapsula uma funcionalidade de descoberta de
serviços, provida para o perfil de aplicativo. Esta funcionalidade provê uma interface para que o
aplicativo busque e retorne atributos de um determinado serviço. Existem duas formas de realizar
uma busca por serviços: Para buscar por um serviço em um determinado dispositivo, o método
searchServices() deverá ser utilizado; Porém, se a busca não for direcionada a um

38
determinado dispositivo, o método selectService() realiza a busca pelo serviço independente
do dispositivo em que este serviço possa estar, abrangendo todos os dispositivos remotos
disponíveis.

3.1.2.4 LocalDevice
A classe LocalDevice define as funções básicas do gerenciador Bluetooth - Bluetooth
Manager. O Bluetooth Manager provê o mais baixo nível de interface possível de acesso à pilha
do Bluetooth. Este acesso é provido e controlado pelo dispositivo local.
Esta classe produz um único objeto. Os detalhes dos métodos desta classe podem ser
consultados no CD anexo deste projeto.

3.1.2.5 RemoteDevice
A classe RemoteDevice representa um dispositivo Bluetooth remoto. Ela provê as
informações básicas sobre o dispositivo remoto, inclusive o endereço, nome de contato - friendly
name – e outras informações registradas no LocalDevice do dispositivo remoto representado.

3.1.2.6 UUID
A classe UUID define os identificadores únicos universais - universally unique
identifiers. Estes identificadores são números inteiros positivos de 128-bit, o que garante que
sejam únicos.
A especificação do SDP – Service Dicovery Protocol – Bluetooth define uma forma de
representar um UUID de 128-bit em formas menores de 16-bit e 32-bit, subdividindo em
intervalos. O primeiro intervalo de 232 valores é chamado de uuid32, e pode-se dele obter um
intervalo menor de 216 chamado uuid16. Toda a definição de campos utilizados e reservados é
determinada pela IEEE, ISO e Bluetooth.org, que controlam as alterações e padronizações para
identificação de fabricantes e serviços no UUID. Esta especificação pode ser obtida através do
site: (https://www.Bluetooth.org/foundry/assignnumb/document/assigned_numbers).

39
3.1.3 Exceções

3.1.3.1 BluetoothConnectionException
A exceção BluetoothConnectionException acontece quando uma conexão Bluetooth
(L2CAP, RFCOMM, or OBEX over RFCOMM) não pôde ser realizada com sucesso. Os campos
na classe desta exceção indicam a causa de sua ocorrência, repassando ao aplicativo a razão da
falha de uma determinada conexão que não pôde ser estabelecida.

3.1.3.2 BluetoothStateException
A exceção BluetoothStateException é acionada quando uma requisição feita pelo
sistema ao Bluetooth não pode ser atendida no estado atual do sistema, mas poderia ser
completada se o sistema estivesse em um outro estado. Isto acontece quando há
incompatibilidade de tarefas solicitadas com as tarefas que estão sendo executadas. Por exemplo,
alguns sistemas Bluetooth não permitem que o dispositivo entre em modo de busca se uma
conexão estiver estabelecida. Neste caso, se o método startInquiry() fosse chamado, esta
exceção seria acionada.

3.1.3.3 ServiceRegistrationException
A ServiceRegistrationException é uma exceção que informa uma falha na adição
de dados pelo ServiceRecord ao banco de dados local do ServiceDiscovery (SDDB) ou na
modificação de dados existentes no SDDB pelo ServiceRecord. Esta falha pode ser causada se o
SDDB não tiver onde alocar novos registros ou porque a modificação de dados pelo
ServiceRecord violou as regras de alteração de registro. Esta exceção também é acionada quando
não é possível obter um canal de servidor RFCOMM necessário para registrar um serviço btspp.
Para o desenvolvimento de um aplicativo Java, utilizando a plataforma J2ME, são
necessários softwares específicos, alguns distribuídos pela própria Sun Microsystems e outros que
podem ser encontrados na Internet em distribuições gratuitas. Neste capítulo são apresentados os
softwares que foram utilizados para desenvolver o primeiro aplicativo J2ME deste projeto,
direcionado para aparelhos celulares com suporte a tecnologia MIDP.

40
3.2 MIDlets:

Uma MIDlet é um aplicativo Java projetado para ser executado em um dispositivo


móvel. Mais especificamente, uma MIDlet tem como classes Java básicas a CLDC e o MIDP.
Um conjunto de MIDlets consiste em uma ou mais MIDlets empacotadas, usando um arquivo
JAR que será detalhado mais a frente, nesta situação o MIDlet é chamado MIDlet Suite.

3.2.1 Ambiente de tempo de execução

Os dispositivos móveis possuem um software, o Application Manager (Gerenciador de


Aplicativos), responsável por instalar, executar e remover MIDlets. Esse software é projetado e
implementado pelo fabricante do dispositivo. Quando esse gerenciador de aplicativos iniciar a
execução de uma MIDlet, ele disponibilizará:
• Acesso à CLDC e a JVM de modo que as MIDlets podem fazer uso de todas as
classes definidas dentro da CLDC, tais como interfaces de entrada/saída e
conectividade de rede.
• Acesso às classes definidas pelo MIDP: essas bibliotecas definem e
implementam a interface com o usuário, o armazenamento persistente, o suporte
a rede e cronômetros.
• Acesso ao arquivo JAR: Se a MIDlet foi distribuída usando um arquivo JAR,
todas as classes ou outros recursos, tais como imagens, dentro dentro do arquivo
estarão disponíveis para a MIDlet.
• Acesso ao arquivo JAD.

3.2.2 Arquivo JAR - Java Archive

A distribuição de um aplicativo geralmente consiste em muitos arquivos. Além das


classes Java, outros arquivos, tais como imagens e dados do aplicativo, são bastante comuns.
Todas essas informações são empacotadas em um único arquivo conhecido como arquivo JAR.

41
Além dos arquivos de classe e recurso, um JAR contém um arquivo denominado
manifest.mf que é armazenado como parte do próprio arquivo JAR e carrega uma lista de
atributos para identificação da aplicação. A Tabela 3.4 mostra os atributos de sistema que podem
ser definidos dentro desse arquivo.

Tabela 3.4 - Atributos do arquivo JAR.

Atributo Objetivo Obrigatório


MIDlet-Name Nome do conjunto de MIDlets. Sim
MIDlet-Version Número da versão da MIDlet. Sim
MIDlet-Vendor Desenvolvedor da MIDlet. Sim
MIDlet-<n> Referência a uma MIDlet específica dentro de Sim
um conjunto de MIDlets. Esse atributo contém
até três informações:
1. Nome da MIDlet;
2. Ícone dessa MIDlet (opcional);
3. Nome da classe que o gerenciador de
aplicativos chamará pa ra carregar essa
MIDlet.
MicroEdition-Profile Qual perfil do J2ME é exigido pela(s) Sim
MIDlet(s).
MicroEdition-Configuration Qual a configuração do J2ME é exigida Sim
pela(s) MIDlet(s).
MIDlet-Icon Ícone usado pelo gerenciador de aplicativos. Não
Mostrado junto da MIDlet-Name no
dispositivo. Esse deve ser um arquivo de
imagem no formato PNG.
MIDlet-Description Texto descrevendo a MIDlet. Não
MIDlet-Info-URL URL que pode ter mais informações sobre a Não
MIDlet e/ou sobre o fornecedor.
42
3.2.3 Arquivo JAD - Java Aplication Descriptor

Além de um arquivo JAR, um arquivo JAD deve estar disponível como parte do
conjunto de MIDlets para fornecer informações sobre a(s) MIDlet(s) dentro do arquivo JAR. A
idéia por trás da inclusão de um arquivo JAD é:
1. Fornecer informações para o gerenciador de aplicativos sobre o conteúdo de um
arquivo JAR. Com esas informações, podem ser tomadas decisões quanto a uma
ou mais MIDlets serem convenientes para executar no dispositivo.
2. Fornecer um meio para que parâmetros sejam passados de uma MIDlet, sem ter
de fazer alterações no arquivo JAR.
A Tabela 3.5 mostra a lista de atributos de sistema que podem estar dentro de um
arquivo JAD.

Tabela 3.5 - Atributos do arquivo JAD.

Atributo Objetivo Obrigatório


MIDlet-Name Nome do conjunto de MIDlets. Sim
MIDlet-Version Número da versão da MIDlet. Sim
MIDlet-Vendor Desenvolvedor da MIDlet. Sim
MIDlet-<n> Referência a uma MIDlet específica dentro de Sim
um conjunto de MIDlets. Esse atributo contém
até três informações:
1. Nome da MIDlet;
2. Ícone dessa MIDlet (opcional);
3. Nome da classe que o gerenciador de
aplicativos chamará pa ra carregar essa
MIDlet.
MIDlet-Jar-URL URL do arquivo JAR. Sim
MIDlet-Jar-Size O tamanho do arquivo JAR, em bytes. Sim

43
MIDlet-Data-Size O número mínimo de bytes exigido para Não
armazenamento de dados persistentes.
MIDlet-Description Texto descrevendo a MIDlet. Não
MIDlet-Delete-Confirm Mensagens mostradas pa ra um usuá rio Não
confirmar um pedido de exclusão de um
conjunto de MIDlet.
MIDlet-Install-Notify URL a ser notificada sobre status da Não
instalação.

Para que o gerenciador de aplicativos execute uma MIDlet não se faz necessária a
existência de um arquivo JAD, esse arquivo simplesmente fornece um meio para que o
gerenciador saiba o que está contido no arquivo JAR. Com essa informação o gerenciador de
aplicativos pode tomar decisões, tais como se deve fazer o download ou não do aplicativo uma
vez que o atributo MIDlet-Jar-Size especifica o tamanho do arquivo, logo se um dispositivo
possuir uma capacidade de memória inferior ao tamanho do arquivo JAR o gerenciador de
aplicativos pode alertar para esse erro antes mesmo de se tentar descarregar todo o arquivo da
internet.

3.2.4 Pacotes Java

Um pacote Java é um conjunto de classes e interfaces. Os pacotes são úteis quando o


código-fonte torna-se extenso e o projeto de software passa a ser composto de vários arquivos-
fonte. O uso de pacotes ajuda a manter o código organizado.

3.2.5 Ambiente de desenvolvimento.

Para que se possa desenvolver e empacotr MIDlets, são necessáros pelo menos três
pacotes de software:
1. Java 2 SDK 1.4 ou superior, disponível em: http://Java.sun.com/j2se

44
2. CLDC 1.1 ou superior, disponível em: http://Java.sun.com/products/cldc
3. MIDP 2.0 ou superior: http://Java.sun.com/products/midp

3.2.5.1 Instalação do software SDK

Se faz necessária a instalação do J2SE-SDK para ter acesso ao compilador Java e ao


aplicativos para empacotar os arquivos JAR. A instalação do J2SE-SDK deverá ser feita
conforme as instruções fornecidas como parte do download.

3.2.5.1.1 Atualização da Variável de Ambiente PATH

Ao se trabalhar com o compilador Java por linha de comando, recomenda-se a


atualização da variável de ambiente PATH a fim de incluir o caminho para o diretório
(subdiretório bin do diretório de instalação) onde estão localizados os arquivos executáveis Java.
Isto permitirá que se execute o compilador Java a partir de qualquer diretório.

3.2.5.2 Instalação do CLDC e MIDP

A instalação do CLDC e do MIDP é feita descompactando o arquivo ZIP do download


dentro de um diretório na unidade de disco local.

3.2.5.2.1 Atualização das variáveis de ambiente

Também se recomenda a inclusão do subdiretório bin de ambas instalações na variavel


de ambiente PATH do sistema operacional. No caso do MIDP, é necessário ainda a inclusão de
outras duas variáveis de ambiente, a CLASSPATH e MIDP_HOME.
A variável CLASSPATH especifica onde procurar classes que não fazem parte da
plataforma Java (J2SE-SDK) em si. Nesse caso, atualizando essa variável a fim de fazer
45
referência às classes MIDP. Também é recomendado ter uma referência para o diretório corrente
como parte da variável CLASSPATH, isso pode ser feito incluindo a representação de diretório
corrente "." na variável de ambiente CLASSPATH.
Já a variável MIDP_HOME aponta para a localização do diretório \lib da instalação
MIDP.

3.2.5.3 Testando a instalação

Para verificar rapidamente se a instalação do J2SE-SDK, CLDC e MIDP foi realizada


corretamente, execute:
- Verificação do J2SE-SDK: Java -version
Este comando deverá retornar a versão do Java atualmente instalada.
- Verificação do CLDC: preverify
Este comando deverá retornar uma tela de ajuda informando a sintaxe de uso do
preverify.
- Verificação do MIDP: midp -version
Este comando deverá retornar a versão do midp atualmente instalada.

A Figura 3.1 mostra o resultado da execução desses testes.

46
Figura 3.1 - Testando a instalação do ambiente de desenvolvimento.

3.2.5.4 Desenvolvendo por meio de linha de comando

3.2.5.4.1 Compilando

Para compilar qualquer código-fonte Java e fazer a verificação prévia do arquivo de


classe resultante, é necessário:
1 - Compilar o código fonte, para isso, no diretório onde foi salvo o projeto do arquivo,
execute o comando:
Javac -bootclasspath c:\tcc\midp2.0fcs\classes Arquivo.Java
47
A opção "-bootclasspath c:\tcc\midp2.0fcs\classes" indica onde localizar os arquivos de
classe de partida (inicialização) do Java. Deve-se apontar para as classes do MIDP, caso
contrário as classes do J2SE-SDK serão utilizadas. O Caminho c:\tcc\midp2.0fcs foi o caminho
utilizado na nossa instalação de teste, deve ser alterado conforme o caminho que foi realizada a
instalação do midp.
A opção "Arquivo.Java" indica o arquivo que contém o código-fonte Java que deverá
ser compilado. Será gerado um arquivo Arquivo.class no mesmo diretório do arquivo Java.

2 - Realizar verificação prévia do arquivo de classe, introduzindo o seguinte no prompt


do comando:
preverify -classpath c:\tcc\midp2.0fcs\classes;. -d . Arquivo

A opção "-classpath c:\tcc\midp2.0fcs\classes;." especifica onde os arquivos da classe de


verificação prévia estão localizados. Isso inclui as classes do MIDP que são necessárias como
parte do processo de verificação do arquivo de classe Arquivo.class que está localizado no
diretório corrente, especificado pelo ".".

A compilação se faz necessária para transformar o código-fonte em código executável, e


a verificação prévia se faz necessária pois os arquivos não verificados previamente não podem
ser carregados pelo gerenciador de aplicativos, ou seja, pré-veificador funciona como uma
espécie de 'assinatura' no arquivo que libera a sua execução no dispositivo.

Como pode ser observado, a memorização dessa sequencia de comandos além de


trabalhoso é um processo desnecessário, recomendamos a criação de um arquivo de lote (.BAT)
para automatização desse processo. O arquivo se chamará midletc.bat e seu conteúdo será:

Javac -bootclasspath c:\tcc\midp2.0fcs\classes %1.Java


preverify -classpath c:\tcc\midp2.0fcs\classes;. -d . %1

O %1 será substituído pelo primeiro parâmetro passado ao arquivo durante a execução


48
na linha de comando.

Nesse caso a execução da compilação do exemplo acima se daria pelo comando midletc
Arquivo. Outros recursos poderiam ser adicionados ao midletc.bat, porém não serão enfocados
neste trabalho pois daremos preferência a utilização de outra ferramenta detalhada mais a frente.

3.2.5.4.2 Execução da MIDlet no simulador

Para testar o MIDlet, através do prompt de comando, usa-se o comando:

midp -classpath . Arquivo

3.2.5.4.3 Empacotando uma MIDlet

A simulação funciona bem para testes e depuração. Após esse passo para se transferir o
MIDlet para um dispositivo se faz necessário empacotar o MIDlet, conforme a sequencia abaixo:

1. Empacotar os arquivos de classe e todos os recursos (imagens, dados do


aplicativo, etc) em um arquivo JAR.
2. Criar um arquivo JAD que descreva o conteúdo das MIDlets existentes dentro de
um arquivo JAR.
3. Executar o conjunto de MIDlets (ou MIDlet Suíte) em um simulador ou
transferir para um dispositivo que suporte J2ME com perfil MID.

3.2.5.4.3.1 Criação do arquivo JAR

Devem ser colocados todos os arquivos de classe dentro de um mesmo diretório, em


seguida criado um arquivo chamado manifest.txt com as informações do aplicativo. Para criação

49
do arquivo JAR, deverá ser executado o comando a seguir:

jar cvfm [arquivo-destino.jar] [arquivo manifest.txt] [arquivos de classe do pacote]

3.2.5.4.3.2 Criação do arquivo JAD

Para a criação do arquivo JAD, basta utilizar um editor de texto qualquer e inserir as
informações relativas a aplicação conforme descrito anteriormente.

3.2.5.4.3.3 Execução de um arquivo JAR no simulador

A sintaxe de linha de comando para a execução de um arquivo JAD existente no


diretório corrente é a seguinte:

midp -classpath . -Xdescriptor Arquivo.jad

A sintaxe de linha de comando para a execução de um arquivo JAD armazenado em um


servidor WEB é a seguinte:

midp -transient http://www.rmb.eng.br/arq-renato/chatooth.jad

3.2.5.5 Kit de ferramentas J2ME

A Sun Microsystems disponibiliza em sua página na Internet um conjunto de


ferramentas para desenvolvimento de aplicativos para celulares e outros dispositivos móveis sem
fio, utilizando a plataforma J2ME. Este conjunto de ferramentas é denominado J2ME Wireless
ToolKit, e contem ferramentas de criação, utilitários e um dispositivo emulador. Alem dos
recursos para desenvolvedores, no WTK da Sun Microsystems ainda é possível consultar alguns
exemplos de códigos fornecidos com o Kit. A versão mais recente pode ser encontrada no site:
50
http://Java.sun.com/products/j2mewtoolkit

Para que seja possível a instalação e execução do WTK se faz necessária a instalação
prévia do SDK. O ambiente de aplicativos proposto anteriormente para o desenvolvimento por
linha de comando é recomendável.

3.2.5.5.1 Utilizando o WTK

O WTK quando instalado apresenta vários ícones para o usuário, fornecendo opções de
configuração do dispositivo de emulação, consulta a documentação (guia de usuário, faq´s,
especificações da Sun Microsystems, etc.), barra de ferramentas, configurações de utilitários e
uma opção de execução rápida de aplicativos MIDP, conforme Figura 3.2.

Figura 3.2 - Ferramentas do WTK.

No WTK a ferramenta de criação é chamada “KToolbar” (Figura 3.3), que oferece


opção de compilar o código a ser executado, gerando também o pacote suite deste MIDlet. O
código concluído deverá ser armazenado na pasta específica criada pelo WTK, de onde o Kit irá
buscar os dados para proceder com a compilação e criação da suíte. Somente após estes passos é
possível simular o funcionamento do aplicativo em um ambiente que emula um aparelho móvel
celular, ou então disponibilizá-lo para upload em dispositivos reais.

51
Figura 3.3 - Tela principal do KToolBar.

Ao se escolher a opção de criação de novo projeto (botão New Project), uma caixa de
diálogo será exibida similar a Figura 3.4. Nessa caixa deve ser fornecido o nome do projeto e o
nome da classe MIDlet.

Figura 3.4 - Tela de adição de novo projeto.

Uma vez escolhida a opção de criar projeto (botão Create Project), será mostrada uma
janela (Figura 3.5) solicitando as informações e configurações, essas configurações serão
utilizadas para criação dos arquivos JAD e de manifesto.

52
Figura 3.5 - Configurações do arquivo JAD.

Note que o atributo MIDlet-<n> não é mostrado na lista de atributos obrigatórios. Como
se trata de uma entrada para cada MIDlet do pacote, o WTK mostra esse atributo na aba MIDlets.
Conforme mostrado na Figura 3.6.

Figura 3.6 - Definição do atributo MIDlet-<n>.

Na guia Optional (Figura 3.7) será possível configurar os atributos que não são
obrigatórios do arquivo JAD.

53
Figura 3.7 - Campos opcionais do arquivo JAD.

Ao criar um novo projeto no WTK, uma lista de subdiretórios será criada dentro do
diretório principal do projeto. Cada subdiretório tem uma finalidade específica são eles:
\bin – Arquivos de manifesto, JAD e JAR;
\classes – Arquivos de classe gerados pelo compilador Java;
\res – Todos os arquivos de recursos (imagens, dados, etc);
\src – Código-fonte Java;
\tmpclasses – Arquivos de classe previamente verificados.

Configurando o simulador.

Ao executar MIDlets que acessam a internet, pode ser necessário configurar um servidor
de proxy. Se isso for necessário, essa configuração deverá ser feita através do menu Edit,
Preferences.

3.3 Pareando dispositivos Bluetooth

Para que seja possível transferir aplicativos do computador para o telefone celular se faz
necessário que os dispositivos estejam pareados, ou seja, façam parte de uma mesma PAN e
tenham relações de confiança estabelecidas. Para fazer isso um dispositivo (pc ou celular) deverá

54
adicionar o outro a sua lista de dispositivos pareados, e o outro dispositivo deverá aceitar a
conexão bem como poderá ser estabelecida uma senha para ser usada nas conexões futuras entre
os dispositivos. Será abordada a conexão adicionando o dispositivo no pc e aceitando no telefone
celular por se tratar de um procedimento mais genérico.
Antes de iniciar a busca, é necessário que os serviços de Bluetooth estejam ativos em
ambos os dispositivos, tanto no celular quanto no computador. Para carregar o serviço Bluetooth
no Windows XP, acesse o painel de controle, ferramentas administrativas, serviços. O serviço
Bluetooth Suppport Service deverá estar iniciado. Recomenda-se que o tipo de inicialização desse
serviço seja definido como automático para que nas execuções futuras não seja necessário alterar
essa configuração. A Figura 3.8 mostra a janela de configuração do serviço, onde é possível
alterar o modo de inicialização, bem como parar e reiniciar o serviço

Figura 3.8 - Configuração do serviço Bluetooth.

Já no telefone celular, nesse caso o equipamento Nokia 6230 pode-se verificar se o


55
Bluetooth está ativado através do ícone de serviço Bluetooth que é mostrado na extremidade
superior esquerda da tela quando ativado (ver Figura 3.9, sem ícone devido ao Bluetooth
desativado e figura com ícone e Bluetooth ativado Figura 3.10). Em caso de Bluetooth ativado é
necessário ativar o serviço através do menu configurações (Figura 3.11), conectividade (Figura
3.12), Bluetooth (Figura 3.13). Selecionar a opção Bluetooth (Figura 3.14) e ativar o serviço
(Figura 3.15). Em seguida deve-se configurar a visibilidade do dispositivo através da opção
Configurações Bluetooth (Figura 3.16), Visibilidade (Figura 3.17), escolhendo a opção visto por
todos para ativar a localização.

Figura 3.9 - Nokia 6230, tela Figura 3.10 - Nokia 6230, tela Figura 3.11 - Nokia 6230,
principal com Bluetooth principal com Bluetooth ativado. configurações.
desativado.

56
Figura 3.12 - Nokia 6230, menu Figura 3.13 - Nokia 6230, menu Figura 3.14 - Nokia 6230,
configurações. conectividade. configurações Bluetooth.

Figura 3.16 - Nokia 6230, menu Figura 3.17 - Nokia 6230,


Figura 3.15 - Nokia 6230, menu Bluetooth. configurações Bluetooth.
Bluetooth, ativar serviço.

Para facilitar a configuração e acesso ao Bluetooth, recomenda-se instalar o ícone do


Bluetooth na system tray, para isso, no Windows xp basta ir ao painel de controle, configurações
Bluetooth e na tela de configuração, selecionar a opção Mostrar ícone Bluetooth na área de
notificação, conforme mostrado na Figura 3.18.

57
Figura 3.18 - Ativando ícone Bluetooth na área de notificação.

Em seguida deve-se fazer o mesmo procedimento que foi feito no celular, em relação a
tornar o dispositivo localizável, para isso basta marcar a opção ativar localização na tela de
configurações de dispositivos Bluetooth, conforme mostrado na Figura 3.19.

58
Figura 3.19 - Ativando localização no PC.

Agora será feita a busca do celular a partir do computador, o procedimento é bem


simples. Na janela de dispositivos Bluetooth, que pode ser acessada clicando no ícone de
Bluetooth na system tray. A janela mostrada na Figura 3.19 será mostrada, deve-se clicar no
botão adicionar.

59
Figura 3.20 - Lista de dispositivos Bluetooth durante o primeiro acesso.

Será exibida a janela mostrada na Figura 3.21. Deverá ser marcada a opção: “Meu
dispositivo está instalado e pronto para ser localizado”.

60
Figura 3.21 - Tela de adição de dispositivo.

O windows fará uma busca pelos dispositivos próximos conforme mostrado na Figura
3.22 e em seguida exibirá uma lista dos dispositivos encontrados, conforme mostrado na Figura
3.23.

61
Figura 3.22 - Windows buscando por dispositivos próximos.

Figura 3.23 - Dispositivos localizados.

Ao clicar na opção avançar será mostrada uma tela conforme a da Figura 3.24. Nessa
62
tela é possível escolher se deverá ser utilizada uma senha para a conexão entre os dois
dispositivos. Qualquer das opções selecionadas terá o mesmo resultado.

Figura 3.24 - Escolha da chave de acesso.

Ao escolher o botão avançar, será mostrada a figura conforme Figura 3.25. Nesse ponto,
no equipamento celular será mostrada a tela perguntando se o usuário deseja parear com o
computador, conforme mostrado na Figura 3.26, e em seguida será requisitada a senha (Figura
3.27).

63
Figura 3.25 - Estabelecendo a conexão entre os dispositivos.

Figura 3.26 - Nokia 6230, tela de confirmação de Figura 3.27 - Nokia 6230, tela de requisição de senha
pareamento de dispositivo. para pareamento.

Uma vez fornecida a senha o celular realizará a troca de senhas com o computador
64
(Figura 3.28), caso não haja problemas a janela da Figura 3.29 será mostrada.

Figura 3.28 - Nokia 6230, confirmação de senha entre dispositivos sendo realizada.

Figura 3.29 - Janela de pareamento de dispositivos bem sucedida.

Uma vez que o dispositivo tenha sido pareado com sucesso, o nome do novo dispositivo
será exibido na lista de dispositivos Bluetooth do Windows (Figura 3.30). Essa lista agrupa os
dispositivos por categoria, nesse caso o Nokia 6230 por se tratar de um equipamento telefônico é
listado na categoria Telefones e Modems.

65
Figura 3.30 - Lista de dispositivos Bluetooth pareados.

Após o pareamento, durante a primeira tentativa de acesso, o celular irá mostrar uma tela
de confirmação se deseja aceitar conexões do computador (Figura 3.31). Para evitar que essa tela
seja exibida novamente no futuro, na tela de dispositivos pareados (Figura 3.32), acesse selecione
o computador e escolha “opções”, na tela seguinte (Figura 3.33) mude o valor de conexão
automática sem confirmação para Sim.

66
Figura 3.33 - Nokia 6230, tela de
Figura 3.31 - Nokia 6230, tela de Figura 3.32 - Nokia 6230, lista de
opções de dispositivo pareado.
confirmação de conexão. dispositivos pareados.

3.4 Instalando aplicativos no celular

A instalação de aplicativos no telefone celular varia de acordo com o fabricante e


modelo do equipamento. Neste projeto foram testados equipamentos da nokia série 60, mesmo os
modelos da mesma série possuem diferenças entre si. No modelo do Nokia 6600 os arquivos
podem ser transferidos via opção de transferência de arquivos via Bluetooth do windows, além de
ser possível instalar aplicativos que estão armazenados no cartão de memória. No modelo 6230
só foi possível realizar a transferência via Nokia PC Suíte. Em alguns modelos também é possível
instalar o aplicativo fazendo o download diretamente da internet.
Optou-se por detalhar o procedimento no aplicativo Nokia PC Suíte por se tratar da
maneira mais genérica de fazer instalação de aplicativos no celular, sendo compatível com todos
os modelos da nokia que foram testados.
No equipamento Nokia 6230, o software Nokia PC Suíte vem fornecido no CD que
acompanha o celular, na versão 5.8. A instalação é bem simples, bastando seguir as orientações
do CD. A comunicação entre o PC e o celular vai variar de acordo com o modelo de celular
escolhido e os recursos disponíveis no computador. No caso do Nokia 6230, pode ser feita via:
Infravermelho, Bluetooth ou cabo USB proprietário da Nokia modelo DKU-2.
Antes da utilização do software Nokia Pc Suíte é necessário que o celular esteja pareado
com o computador aonde o software encontra-se instalado. Uma vez pareado, deve-se configurar
a suíte da Nokia para conectar-se ao celular Bluetooth. Para isso basta acessar o aplicativo Nokia
Connection Manager, que faz parte do PC Suíte, que pode ser acessado facilmente através do
ícone localizado no system tray do Windows (ao lado do reógio do sistema). Será mostrada uma
67
tela conforme a Figura 3.34.

Figura 3.34 - Tela do Nokia Connection Manager na primeira execução.

Na tela do Nokia Connection Manager, seleciona-se o ícone do tipo de ligação o qual é


possível conectar o celular ao computador, a versão 5.8 do software aceita conexões por: cabo
paralelo, infravermelho, Bluetooth e cabo USB. No celular utilizado nesse projeto foi realizada
conexão via Bluetooth, para isso basta clicar no botão identificado na Figura 3.34.
Uma vez que seja a primeira conexão do celular com o computador, será mostrada uma
janela conforme a apresentada na Figura 3.35, para que seja atribuído um nome ao celular. Essa
tela não será exibida nas conexões futuras do mesmo celular.

68
Figura 3.35 - Nokia Connection Manager, adicionando novo telefone.

Uma vez que o celular já tenha sido cadastrado previamente, será exibida uma listagem
com os celulares com os quais é possível estabelecer conexão no momento. Deve-se selecionar o
celular para o qual deseja-se transferir o aplicativo e clicar no botão OK. Conforme mostrado na
Figura 3.36.

69
Figura 3.36 - Nokia Connection Manager, lista de telefones conhecidos.

Uma vez informado ao Nokia Connection Manager qual o celular que estará sendo
utilizado basta acionar o software Nokia Aplication Installer, que pode ser acessado através do
menu iniciar, conforme mostrado na Figura 3.37.

Figura 3.37 - Suíte de aplicativos que compoem o Nokia PC Suite.

A tela do Nokia Application Installer é mostrado na Figura 3.38. Na parte esquerda da


70
tela é mostrado o conteúdo do computador e na parte a direita da tela o conteúdo do celular. Para
instalar um aplicativo basta seleciona-lo do lado esquerdo e clicar no botão de transferir arquivo.
Após instalado o software aparecerá no lado direito da tela.

Figura 3.38 - Nokia Application Installer.

Observou-se que na versão 5.8 do Nokia PC Suíte existe uma falha que caso o Nokia
Aplication Installer seja carregado sem que o dispositivo esteja pareado ou conectado o software
não funcionará corretamente até a próxima reinicialização do sistema.

3.4.1 API MIDIP - Fundamentos

Uma MIDlet é um aplicativo construído com a classe MIDlet. O gerenciador de


aplicativos se comunica com uma MIDlet através de métodos dessa classe. Essa comunicação é
bidirecional, o que permite que o gerenciador de aplicativos faça uma pausa em uma MIDlet ou
que uma MIDlet requisite uma pausa ao gerenciador de aplicativos. O ciclo de vida de uma
MIDlet se resume a três estados:
1. Pausa: Uma MIDlet é colocada em pausa após o construtor ter sido chamado,

71
mas antes de ser iniciada a execução pelo gerenciador de aplicativos. Além disso,
após iniciada ela poderá alternar entre os estados ativo e pausa;
2. Ativa: A MIDlet está em execução;
3. Destruída: A MIDlet liberou todos os recursos que adquiriu e foi desligada pelo
gerenciador de aplicativos.
Cria-se uma MIDlet estendendo a classe MIDlet do J2ME. Essa classe é abstrata e inclui
três métodos abstratos, startApp(), destroyApp() e pauseApp(). De acordo com [16] a vantagem
de se usar uma classe abstrata é a “capacidade de encapsular o que considera,os uma
funcionalidade comum a todas as subclasses”, ou seja, com o uso desse recurso, qualquer
subclasse de uma MIDlet terá uma implementação desses três métodos e se essa subclasse for
declarada como abstrata, então esses métodos podem ser implementados mais abaixo na
hierarquia. A Tabela 3.6 detalha a classe Javax.microedition.midlet.MIDlet.

Tabela 3.6 - Classe Javax.microedition.midlet.MIDlet

Método Descrição
Comunicação do gerenciador de aplicativos com a MIDlet
abstract void destroyApp(boolean unconditional) A MIDlet está para ser desligada.
abstract void pauseApp() A MIDlet está para ser colocada no estado
de pausa.
abstract void startApp() A MIDlet foi colocada no estado ativo.
Comunicação da MIDlet com o gerenciador de aplicativos
final void notifyDestroyed() A MIDlet está pedindo para ser desligada.
final void notifyPaused() A MIDlet está pedindo para fazer uma
pausa.
final void resumeRequest() A MIDlet está pedindo para se tornar ativa
(após uma pausa).
Pedido de atributo da MIDlet para o gerenciador de aplicativos
final String getAppPropriety(String key) Obtém atributos dos arquivos JAR e/ou
JAD.

Cada MIDlet tem uma referência para UM objeto Display. Esse objeto pode recuperar
72
informações sobre a tela atual e inclui métodos para solicitar que elementos de tela (Form,
TextBox, etc) sejam exibidos, ou seja, esse objeto funciona como um gerenciador de tela que
controla o que é exibido e quando.
Embora haja apenas um objeto Display por MIDlet, dentro de uma MIDlet podem existir
muitos elementos de tela que podem ser exibidos, tais como Forms, TextBoxes, ChoiceGroups,
etc. Esses elementos de tela também são objetos, cada um deles é uma subclasse de Displayable,
de modo que existem métodos para alternar entre esses vários componentes que podem ser
exibidos. A Tabela 3.7 detalha a classes Display (Javax.microedition.lcdui.Display).

Tabela 3.7 - Classe Javax.microedition.lcdui.Display.

Método Descrição
static Display getDisplay(MIDlet m) Obtém o objeto Display dessa MIDlet.
Displayable getCurrent() Obtém o objeto Displayable corrente.
void setCurrent(Alert alert, Displayable Mostra um alerta, seguido do objeto
nextDisplayable) Displayable especificado.
void setCurrent(Displayable nextDisplayable) Mostra um novo objeto Displayable.
boolean isColor() A tela do dispositivo é colorida?
int numColors() Quantas cores (ou tons de cinza) estão
disponíveis?
void callSerially(Runnable r) Pede para que um objetivo executável seja
chamado após a repintura.

Como foi mencionado, um objeto Display pode exibir qualquer número de objetos
Displayable. O MIDIP inclui duas subclasses abstratas de Displayable: Screen e Canvas. Os
objetos da subclasse Screen (TextBox, List, Form e Alert) são todos componentes de alto nível da
interface com o usuários, sua implementação e apresentação no dispositivo são manipuladas pelo
programador. O objeto Canvas é usado para elementos gráficos personalizados e tratamento de
eventos de baixo nível, por esse motivo o Canvas é mais utilizado ao se escrever jogos. A
hierarquia da classe Displayable é mostrada na Figura 3.39 abaixo.

73
Figura 3.39 - Hierarquia da classe Display.

Conforme mostrado na Figura 3.39 pode-se observar que duas classes principais
compõem a API de baixo nível, Canvas e Graphics. A classe Canvas forma a tela de fundo, a
idéia por trás é similar a tela de desenho de um artista, essa tela tem uma altura e largura
específicas, e nela é desenhado o que o usuário final verá. O desenho é feito na tela com um
objeto Graphics uma vez que essa classe possui métodos para desenhar linhas, arcos, retângulos e
texto assim como especificar cor e fonte.

3.4.1.1 Sistema de coordenadas

A origem do desenho começa na extremidade superior esquerda da tela. Essa


extremidade é a localização 0,0. Os valores de x aumentam para a direita e os valores de y
aumentam para baixo. Ao se desenhar uma linha ou figura (arco, retângula, etc), a espessura da
linha, conhecida como pena, é sempre de 1 pixel.
Ao se trabalhar com um objeto Graphics, temos a opção de transladar a origem
conforme esse objeto a conhece, além disso ao se desenhar texto, existe um conceito adicional,
74
conhecido como ponto de âncora, que será detalhado mais a frente.

3.4.1.2 Desenhando texto

Existem três atributos associados a um objeto Font: o tipo, o estilo e o tamanho. A


Tabela 3.8 mostra as constantes definidas para cada atributo. Uma atenção especial deve ser dada
ao atributo estilo uma vez que, ao contrário do tipo e do tamanho, pode-se combinar atributos de
estilo utilizando um operador lógico OU ( | ).

Tabela 3.8- Atributos de texto.

Atributo Descrição Constante


Atributos de tipo de fonte.
FACE_SYSTEM Caracteres de sistema 0
FACE_MONOSPACE Caracteres monoespaçados 32
FACE_PROPORTIONAL Caracteres proporcionais 64
Atributos de estilo de fonte.
STYLE_PLAIN Caracteres normais 0
STYLE_BOLD Caracteres em negrito 1
STYLE_ITALIC Caracteres em itálico 2
STYLE_UNDERLINED Caracteres sblinhados 4
Atributos de tamanho de fonte.
SIZE_SMALL Caracteres pequenos 8
SIZE_MEDIUM Caracteres médios 0
SIZE_LARGE Caracteres grandes 16

3.4.1.3 Ponto de âncora

Ao se desenhar texto, além de se fornecer o objeto String a ser exibido, também deve se
especificar uma localização x e y. Dado que o sistema de coordenadas começa no canto superior

75
esquerdo da tela, seria razoável supor que esse valor x e y fosse um deslocamento a partir dessa
posição. [16]
Entretanto, para dar maior flexibilidade e tornar mais fácil o alinhamento do texto foi
introduzido o conceito de ponto de âncora. Os pontos de âncora são definidos em pares
horizontais e verticais, assim como as coordenadas x e y. A Tabela 3.9 mostra os valores
possíveis para esses pontos de âncora.

Tabela 3.9 - Pontos de âncora.

Ponto de âncora Descrição Direção


LEFT À esquerda do texto Horizontal
HCENTER No centro do texto Horizontal
RIGHT À direita do texto Horizontal
TOP No topo do texto Vertical
BASELINE Na linha de base do texto Vertical
BOTTOM Na base do texto Vertical

76
CAPÍTULO 4 – IMPLEMENTAÇÃO

Neste capítulo são apresentadas as implementações de softwares utilizando linguagem


Java para comunicação entre dispositivos utilizando o padrão Bluetooth de tecnologia de
transmissão de dados sem fio. Foram implementados três projetos:
1. ChaTooth: Aplicativo para comunicação entre celulares;
2. PC-PC: Aplicativo para comunicação entre dois computadores;
3. PC-Celular: Aplicativo para comunicação entre um servidor PC e um cliente
celular.
4.1 ChaTooth

O ChaTooth foi o aplicativo desenvolvido para estabelecer uma comunicação entre dois
celulares e permitir a troca de mensagens (chat) entre esses equipamentos. O pacote chatooth foi
construído baseado em exemplos contidos no Java Developers Journal, Documentação da API,
informações retiradas do site da SUN e da referência [16].
O aplicativo foi desenvolvido visando uma arquitetura cliente/servidor, onde o primeiro
dispositivo a executar o software torna-se automaticamente o servidor de chat e todos os
dispositivos que se conectarem após serão os clientes. Alguns termos foram usados no
desenvolvimento do projeto, para facilitar a compreensão, foram eles:
• Dispositivo servidor: Dispositivo que primeiro inicializa o software;
• Cliente: Todos os dispositivos que se conectarem ao servidor;
• Parceiro: Dispositivos localizados na área de abrangência do rádio Bluetooth (na
mesma piconet).
• Serviço servidor: Instância do programa ChaTooth sendo executada no
dispositivo servidor a fim de aguardar conexões dos clientes e manipular os
eventos.
Conforme mostrado anteriormente, para instalação de aplicativos em telefones celulares
da nokia é necessário que esses dispositivos estejam previamente pareados. No caso do serviço
ChaTooth a busca é feita de modo a localizar todos os dispositivos na mesma piconet,
independentemente do fato de eles se encontrarem pareados ou não, dessa forma não existe a
obrigatoriedade do pareamento prévio de dispositivos para uso do ChaTooth.
77
A construção do pacote ChaTooth foi realizada em dez arquivos Java de código fonte,
cujo código fonte completo está disponibilizado como anexo deste trabalho. A opção por esse
desmembramento em blocos foi feita a fim de facilitar a compreensão do código, as rotinas
implementadas em cada arquivo estão descritas na Tabela 4.1.

Tabela 4.1 - Arquivos Java do pacote ChaTooth e suas rotinas.

Arquivo Descrição
AUXEventos Configuração de constantes de eventos.
ChaTooth Pacote principal, principais funções:
• Manipular eventos de rede;
• Manipular comandos do usuário;
• Escrita na tela;
Empacotador Prepara a formatação da mensagem antes de enviar por meio do Bluetooth.
EntraUI Interface com o usuário para digitação da mensagem a ser enviada.
Kernel Interface de rede do chat, principais funções:
• Busca por dispositivos próximos;
• Serviço de servidor de chat;
• Busca por servidores próximos;
• Manipular e estabelecer conexões entre os dispositivos.
MensagemUI Desenho da tela
TX_Thread Envio de dados
RX_Thread Recebimento de dados
Parceiro Manipula informações dos parceiros.
NomeUI Interface com o usuário para digitação do nome a ser usado no chat.

O funcionamento desse programa pode ser visualizado no fluxograma da Figura 4.1.


Essa figura mostra a lógica de funcionamento do aplicativo sob uma visão macro, maiores
detalhes de funcionamento poderão ser observados no código fonte que foi disponibilizado como
anexo deste trabalho.

78
Figura 4.1 - Projeto ChaTooth, fluxograma de funcionamento.

4.2 PC-PC

Esta aplicação foi idealizada para servir de base ao próximo passo deste projeto, que é a
comunicação PC – Celular. Como apresentado anteriormente, a comunicação Celular – Celular já
foi estudada e implementada, e se faz necessário conhecer as particularidades deste novo
79
ambiente de desenvolvimento até agora não abordado neste projeto, que é o Bluetooth em PC’s.

4.2.1 Recursos

Para este desenvolvimento, foram utilizados conectores Bluetooth/USB, para permitir a


comunicação através da tecnologia Bluetooth em dispositivos que não a possuem de forma
integrada, como o PC.
Este conector Bluetooth/USB, ou Dongle como é chamado, atua de forma a permitir ao
sistema operacional utilizar os serviços da tecnologia Bluetooth, gerenciando seu funcionamento.
Para utilizar o Dongle fazendo-o interagir com o ambiente de desenvolvimento Java, foi
necessária a instalação de uma biblioteca chamada BlueCove, disponibilizada pelo
SourceForge.net (http://sourceforge.net/projects/bluecove/), que é uma implementação em código
aberto da API Bluetooth do Java para o ambiente Windows®. Com esta biblioteca carregada, as
configurações e chamadas de métodos da API Bluetooth se comportam semelhantes à ambientes
embarcados, não sendo necessário atribuir uma porta serial através do sistema operacional para
que se possa utilizar o rádio Bluetooth.
A aplicação alvo é um Chat, em que dois PC’s trocam mensagens instantâneas em modo
console, utilizando somente o dongle Bluetooth para a comunicação entre si.

4.2.2 A conexão

O primeiro passo para desenvolver esta aplicação, é definir a forma de busca e conexão
dos dispositivos. Neste projeto, foi definido que serão dois tipos de aplicativos, um servidor e um
cliente, de forma a simplificar a construção de cada um.
Para o servidor, definimos o endereço UUID e uma classe de serviço para o dispositivo.
Estas informações serão utilizadas para identificar o dispositivo local e os serviços que estão
disponíveis, em caso de dispositivos remotos realizarem uma busca. Como se trata de um
servidor, o método setDeviceServiceClasses() da interface ServiceRecord é utilizado para
permitir o envio de informações detalhadas aos clientes remotos, informando com detalhes os

80
serviços que estão rodando no servidor e seus parâmetros de configuração.
Para realizar a conexão, o método acceptAndOpen() da interface
L2CAPConnectionNotifier é chamado. Com esta chamada, o servidor aguardará até que o cliente
conecte, retornando a conexão já estabelecida.
A partir deste ponto a comunicação está estabelecida, e pode-se desenvolver o aplicativo
com base nesta conexão.
Porém, este processo descrito acima não é idêntico no aplicativo cliente, é necessário
definir o funcionamento do cliente de acordo com o processo apresentado para o servidor.
No cliente, primeiramente precisamos definir a forma de busca, que será o
startInquiry() da classe DiscoveryAgent. Esta forma de busca atualiza a lista de dispositivos

próximos. Com a lista de dispositivos próximos formada, o usuário terá de selecionar o


dispositivo desejado, informando qual é o servidor. Com base nesta seleção, o cliente chama o
método getConnectionURL() da Interface ServiceRecord para obter as informações necessárias
à realização da conexão com o serviço no servidor.
A conexão será solicitada, utilizando com a chamada do método Connector.open(),
que irá interagir com o método acceptAndOpen() em execução pelo servidor. Caso a conexão
não seja estabelecida, uma exceção será gerada, e aplicativo será finalizado.
Em caso de sucesso nas etapas acima, a conexão estará estabelecida, e o aplicativo
disponível para utilizá-la.

4.2.3 O Chat

A aplicação do Chat é uma forma simples de garantir a transmissão entre os dispositivos


com tráfego bidirecional e rápido, onde se pode acompanhar a estabilidade da comunicação.
Para desenvolver um aplicativo J2SE em modo console, uma dificuldade foi encontrada,
o prompt de escrita é o mesmo de leitura, ou seja, a tela e o cursor que recebem a digitação do
usuário local são a mesma que exibirá, string a string, as mensagens enviadas pelo usuário
remoto. Com esta implicação, a solução implementada foi a de estabelecer uma comunicação
half-duplex, em que uma palavra reservada “cambio” sinalizará a troca de direito de escrita,
alterando o modo leitura com o de escrita entre os usuários.
81
O envio de mensagens entre o dispositivo local e o remoto é feita através do método
writeUTF() da classe Java.io.DataOutputStream, enquanto que o recebimento é realizado pelo

método readUTF() da classe Java.io.DataInputStream.


Para a captura das mensagens no prompt é utilizado o método readLine() em conjunto
com a classe BufferedReader (Java.io.BufferedReader). Já para a exibição em tela, o método
utilizado é o println() da classe out (Java.lang.System.out).
Com este componentes de conexão e comunicação, o Chat PC – PC foi desenvolvido e
testado. As figuras a seguir mostram telas reais de uma conversação, onde a Figura 4.2
corresponde à tela do servidor e a Figura 4.3 corresponde à tela do cliente.

Figura 4.2 - Aplicativo PC-PC, tela servidor.

82
Figura 4.3 - Aplicativo PC-PC, tela cliente

4.3 PC-Celular

Este projeto é uma junção dos dois projetos anteriores, onde apresentamos a
comunicação entre celulares (utilizando o ambiente J2ME), e entre computadores pessoais
(utilizando o ambiente J2SE), ambos utilizando o rádio Bluetooth como meio de transmissão de
dados.
Com esta nova implementação, o objetivo é estabelecer uma comunicação ponto-a-ponto
desenvolvida em linguagem Java (nos ambientes J2ME e J2SE) entre dois dispositivos utilizando
tecnologia Bluetooth de comunicação sem fio.
Neste projeto são utilizados um dispositivo móvel com suporte ao perfil MIDP e a
Bluetooth, e um computador pessoal, utilizando um Dongle USB/Bluetooth.

4.3.1 Definições Iniciais

Para estabelecer a conexão entre os dispositivos, é necessário antes de tudo, definir o


modo de interação entre eles. Seguindo a mesma ideologia do projeto anterior, será construído

83
um servidor e um cliente, onde neste caso, o dispositivo em que cada tipo de aplicativo for ser
executado fará diferença. Haja vista esta necessidade, foi definido o dispositivo PC para suportar
o servidor, e o dispositivo móvel como ambiente de execução do cliente.
O servidor deste Chat é um aplicativo Java desenvolvido em J2SE, utilizando a SDK
1.5.0. A função deste aplicativo é prover o ambiente de conexão Bluetooth para aguardar a
conexão do cliente, e então rodar um comunicação ponto-a-ponto com troca de mensagens de
texto. O servidor do projeto de comunicação PC – PC atende a todas estas características,
portanto será mantido inalterado para ser utilizado também neste projeto, comprovando a
portabilidade do aplicativo.
O aplicativo cliente é desenvolvido em J2ME, e roda em um dispositivo portátil com
suporte ao perfil MIDP e Bluetooth, no caso um celular. Este celular irá estabelecer uma conexão
com um servidor de serviço específico – o PC – e então rodar um aplicativo de comunicação via
mensagens de texto – o Chat.
O estabelecimento da conexão se dá de forma semelhante ao projeto PC-PC, o que é
demonstrando a seguir no fluxograma e no detalhamento do funcionamento dos dois aplicativos
envolvidos neste projeto.

4.3.2 Funcionamento

Na Figura 4.4 é apresentado o fluxograma de funcionamento do servidor. Neste fluxo é


descrito de forma macro a seqüência de tarefas executadas pelo aplicativo, que já foram
detalhadas na seção anterior (ver projeto de comunicação PC – PC).
Primeiramente o servidor é criado, atribuindo parâmetros necessários como UUID e
classe do serviço, sendo executado em seguida. Com este primeiro passo, o servidor utilizando o
dongle Bluetooth é iniciado e entra em estado de espera, aguardando a conexão do cliente.
Através de uma thread, o servidor fica “escutando” até que uma conexão seja aberta e
aceita, estabelecendo a comunicação.
Em seguida o servidor entra no modo de recebimento de dados, aguardando que o
cliente envie uma mensagem, que quando recebida, será analisada e exibida. Esta análise visa
identificar se o cliente está passando alguma instrução para o servidor ou somente uma
mensagem simples.
84
As mensagens de instrução podem ser de dois tipos: cambio ou finalização. Na instrução
‘cambio’, o detentor do direito de escrita informa ao receptor da mensagem que finalizou seu
texto, e que o aplicativo receptor deterá, desde agora, o direito de escrita, obviamente o aplicativo
emissor do ‘cambio’ passa automaticamente ao modo de recebimento de dados. Já na instrução
de finalização, o usuário emissor do comando ‘exit’ indicará ao aplicativo local e ao remoto a
finalização da comunicação, o que encerra os dois aplicativos.
Tratadas as mensagens recebidas, o servidor executará a tarefa apropriada, podendo agir
de três maneiras: Encerrar o programa, caso seja solicitado através de uma mensagem contendo
apenas ‘exit’; passar para o modo de escrita e solicitar a entrada de dados pelo usuário local, caso
receba uma mensagem contendo apenas ‘cambio’; ou continuar no modo de recebimento de
dados, aguardando uma nova mensagem do aplicativo remoto.
No fluxograma de funcionamento do servidor, o comportamento do aplicativo em cada
uma das situações descritas acima pode ser identificado da seguinte maneira: O fluxo ‘A’ ilustra
o comportamento do aplicativo durante seu modo de recebimento de dados; já o fluxo ‘B’
representa o servidor quando o mesmo detém o direito de escrita.

85
Figura 4.4 - Aplicativo PC-Celular, fluxograma de funcionamento servidor.

A Figura 4.5 apresenta o fluxograma do MIDlet cliente, exibindo o comportamento do


aplicativo em cada tarefa executada. Percebe-se que, em linhas gerais, o fluxo do cliente é
bastante parecido com o do servidor, variando principalmente na forma de inicialização. Isso se
deve ao fato do ambiente de execução do MIDlet ser mais dinâmico, porem o mecanismo de
conexão deste cliente é bastante próximo ao do cliente desenvolvido no projeto de comunicação
PC – PC, variando principalmente nas interfaces e método de construção que são adaptados do
projeto Chatooth.

86
Figura 4.5 - Aplicativo PC-Celular, fluxograma de funcionamento cliente.

O aplicativo cliente, para iniciar sua operação, deve ser construído e carregado,
chamando para isso o método StartApp(). Depois de carregado, uma nova classe é carregada, a
BLUElet.Esta classe é a implementação da biblioteca BlueCove para MIDP, necessária para a

87
comunicação com um dispositivo remoto que esteja utilizando a biblioteca BlueCove. O
BLUElet é um aplicativo MIDP, com todas as características e atributos de um MIDlet.
Através da chamada do método StartApp() do BLUElet, o aplicativo inicia o rádio do
dispositivo local, realizando uma busca em seu raio de alcance pelos dispositivos Bluetooth
disponíveis. Esta busca é realizada através do método startInquiry(). Com esta busca, é
exibida uma lista para que o usuário possa selecionar o dispositivo em que está rodando o
servidor. Caso a lista esteja vazia ou o usuário local não estiver satisfeito com a lista exibida,
poderá solicitar uma nova busca, a fim de atualizar a lista de dispositivos próximos. A classe que
disponibiliza esta lista ao usuário no BLUElet é a RemoteDeviceUI, que a obtêm do próprio
BLUElet.
Uma vez que o usuário tenha selecionado o dispositivo desejado, o MIDlet irá verificar
se o dispositivo remoto possui o serviço desejado disponível, neste caso a busca é pelo aplicativo
servidor. Esta busca é realizada através do método searchServices() da classe
DiscoveryAgent, sendo chamada pelo BLUElet. Caso a busca seja bem sucedida, o aplicativo
cliente irá estabelecer a conexão com o servidor, caso contrário exibirá uma exceção informando
a falha ao usuário e finalizará o MIDlet.
Com a conexão estabelecida, o processo de comunicação através de mensagens é
iniciado. O MIDlet, como cliente, detêm o direito de escrita para a primeira mensagem. Por se
tratar de um aplicativo MIDP, a forma de entrada de texto é diferente do processo do cliente do
projeto anterior. Nesta tarefa, a classe EntraUI é invocada, através da thread do Chat, que chama
para exibição em tela o objeto digita, que é filho de uma classe TextBox
(Javax.microedition.lcdui.TextBox). Esta classe é a responsável pela criação da tela de entrada de
dados pelo usuário local, que a partir dela irá encaminhar as mensagens para que a thread as
envie ao servidor remoto.
O método de envio é semelhante ao do aplicativo cliente do projeto PC – PC, utilizando
a classe DataOutputStream. O recebimento também é idêntico ao processo citado no projeto
anterior, utilizando a classe DataInputStream.
A diferença neste projeto no que diz respeito ao envio e recebimento, é a possibilidade
de se trabalhar com os objetos das duas classes simultaneamente, o que não foi possível no caso
do J2SE em modo console. No projeto anterior, assim como no servidor deste projeto, para se
utilizar um objeto da classe DataInputStream é necessário que os objetos da classe
88
DataOutputStream sejam finalizados, e vice-versa, o que faz o programa ficar alternando entre
objetos quando há um ‘cambio’ no Chat.
Uma outra diferença, porém na área gráfica, é o modo de exibição das mensagens. O
MIDlet desenvolvido utiliza a classe MensagemUI, com herança da classe Canvas
(Javax.microedition.lcdui.Canvas) para exibição das mensagens do Chat, assim como no
primeiro projeto apresentado. A Canvas oferece suporte aos comandos de navegação e suporte a
fontes e telas gráficas mais detalhadas, o que é interessante para a exibição de grande quantidade
de texto. O método chamado para adicionar novas mensagens à tela é o addElement() da classe
MensagemUI construída, seguido de uma chamada ao método repaint() da mesma Canvas.
Com estas definições e implementações, o aplicativo de comunicação por mensagens
instantâneas entre o PC e o celular foi desenvolvido e testado, comprovando a compatibilidade
das linguagens e tecnologias utilizadas. O Chat, apesar de simples, comprova a confiabilidade da
comunicação, abrindo um leque de oportunidades a serem exploradas através da conexão
demonstrada neste projeto.

89
CAPÍTULO 5 – CONCLUSÃO

Este projeto objetivou servir de base para o desenvolvimento de aplicações para


dispositivos móveis utilizando tecnologia de transmissão de dados Bluetooth, fornecendo
informações importantes sobre esta tecnologia wireless e apresentando a linguagem de
programação nativa para estes dispositivos móveis, o JAVA.
Com o intuito de familiarizar o leitor com a tecnologia a ser implementada, este projeto
apresentou o padrão da tecnologia de comunicação sem fio Bluetooth, expondo seu
funcionamento enquanto padrão de comunicação de dados sem fio e apresentando outros
dispositivos de propostas similares, tais como a IEEE 802.11. Foi demonstrando suas diferenças e
peculiaridades, apresentando suas propriedades, limitações e finalidades, que foram de grande
importância durante o processo de implementação dos softwares de comunicação na terceira
etapa deste projeto.
Para permitir a implementação desta comunicação em dispositivos móveis, tais como
celulares e PDA’s, este projeto apresentou a linguagem de programação JAVA. Assim como suas
divisões e características, focando a plataforma J2ME, que se destina à micro dispositivos. Os
elementos de um aplicativo J2ME também foram apresentados, identificando o CLDC, o KVM e
o MIDP como elementos adequados à aplicação alvo deste projeto, que foram detalhados na
etapa seguinte. Juntamente com o detalhamento do MIDP, as ferramentas necessárias à criação
destas aplicações foram expostas neste trabalho, reforçando a força que a linguagem J2ME
apresenta no crescimento deste universo de aplicações móveis, apresentando a também a API
Bluetooth para Java.
Na seqüência deste trabalho, foram implementados três projetos de Chat, atuando nas
categorias celular-celular, PC-PC e PC-celular. Com estas implementações, este trabalho
estabeleceu e testou as três possibilidades de conexão entre estes dispositivos, demonstrando
através de fluxos, o comportamento destes aplicativos.
As possibilidades de desenvolvimento de novos aplicativos, embasados neste estudo do
padrão Bluetooth, ficam agora a cargo de novos estudos, facilitados pelos estudos da conexão, e
podendo agora serem focalizados no aplicativo final, não se detendo na camada de conexão.
As sugestões são inúmeras, aplicativos para controle remoto de outros dispositivos,

90
sincronização de dados entre dispositivos distintos, aplicativos rodando em redes pessoais móveis
etc. As possibilidades são e serão cada vez maiores, a medida que a tecnologia e a informação se
tornam cada vez mais acessíveis.
Com a utilização da biblioteca BlueCove, este trabalho demonstrou também uma
necessidade de integração de bibliotecas dos sistemas operacionais para permitir o acesso aos
dispositivos Dongle, que hoje necessitam de uma biblioteca adicional para que a interface se
torne transparente ao programador.

91
ANEXO 1
Projeto PC-PC
Cliente em J2SE / Console
Client_Main.Java

package cliente;

import Java.io.*;
import Javax.Bluetooth.*;

public class Client_Main implements CommandListener


{
public static UUID uuid = new UUID("102030405060708090A0B0C0D0E0F010",
false);
public static Client_Main instance;
public BLUEletConsole bluelet = null;
public SPP_Client spp_client = null;

public Client_Main()
{
instance = this;
}

public static void main(String[] args )


{
Client_Main app = new Client_Main();
app.startApp();
}

public void startApp()


{
bluelet = new BLUEletConsole(this);
bluelet.startApp();
spp_client = new SPP_Client();
bluelet.startInquiry( DiscoveryAgent.GIAC, new UUID[]{ uuid } );
bluelet.getUI().showui();
}

public static void quitApp()


{
instance = null;
System.exit(0);
}

public void commandAction( String c, MessageUI d )


{
if ( c.equals( BLUEletConsole.COMPLETED ) )
spp_client.send_SPP_message( bluelet.getFirstDiscoveredService());
}
}

92
ANEXO 2
Projeto PC-PC
Cliente em J2SE / Console
SPP_Client.Java

package cliente;

import Java.io.*;
import Javax.Bluetooth.*;
import Javax.microedition.io.*;

public class SPP_Client


{
public SPP_Client()
{
}

public void send_SPP_message(ServiceRecord r)


{
String url = r.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT,
false );
try
{
StreamConnection con = (StreamConnection) Connector.open( url );
log("Conectado ao Servidor. Digite uma mensagem...");

DataOutputStream out;
DataInputStream in;
String msg = "nada";
String s = "nada";
while
(!((s.toLowerCase()).equals("exit"))&&!((msg.toLowerCase()).equals("exit")))
{
out = con.openDataOutputStream();
while
(!((msg.toLowerCase()).equals("cambio"))&&!((msg.toLowerCase()).equals("exit")
))
{
BufferedReader leitor = new BufferedReader(new
InputStreamReader(System.in));
msg = leitor.readLine();
out.writeUTF( msg );
out.flush();
log("Enviado : '"+msg+"'");
}
if ((msg.toLowerCase()).equals("exit"))
break;
msg = "nada";
out.close();
s = "nada";
in = con.openDataInputStream();
while
(!((s.toLowerCase()).equals("exit"))&&!((s.toLowerCase()).equals("cambio")))
{

93
s = in.readUTF();
log("Recebido : '"+s+"'");
}
if ((s.toLowerCase()).equals("exit"))
break;
else
{
in.close();
log ("Digite uma mensagem:");
}
}
con.close();

} catch (Exception e)
{
e.printStackTrace();
}
}

public void log( String s )


{
System.out.println(s);
}
}

94
ANEXO 3
Projeto PC-PC
Cliente em J2SE / Console
BLUEletConsole.Java

package cliente;

import Java.util.Vector;
import Javax.Bluetooth.*;
import Java.io.*;

public class BLUEletConsole implements CommandListener


{
public static String COMPLETED = "COMPLETED";
public static String SELECTED = "SELECTED";
public static String BACK = "Back";

public static CommandListener callback;


public static BLUEletConsole instance;

public static Vector devices = new Vector();


public static Vector deviceClasses = new Vector();
public static Vector services = new Vector();
public static int selectedDevice = -1;

public int discoveryMode;


public UUID[] serviceUUIDs = null;

public int deviceReturnCode;


public int serviceReturnCode;

private RemoteDeviceUI remotedeviceui = null;


private LocalDevice device;
private DiscoveryAgent agent;

public BLUEletConsole(CommandListener listener)


{
this.callback = listener;
instance = this;
}

public void startApp() {

remotedeviceui = new RemoteDeviceUI();


remotedeviceui.showui();
}

public void pauseApp()


{
}

95
public void destroyApp(boolean unconditional)
{
}

public static void log(String s)


{
System.out.println(s);
}

public MessageUI getUI()


{
return remotedeviceui;
}

public ServiceRecord[] getDiscoveredServices()


{
ServiceRecord[] r = new ServiceRecord[ services.size() ];
services.copyInto( r );
return r;
}

public ServiceRecord getFirstDiscoveredService()


{
if ( services.size() > 0 )
return (ServiceRecord) services.elementAt(0);
else
return null;
}

public int getDeviceDiscoveryReturnCode()


{
return deviceReturnCode;
}

public int getServiceDiscoveryReturnCode()


{
return serviceReturnCode;
}

public RemoteDevice getSelectedDevice()


{
if ( selectedDevice != -1 )
return (RemoteDevice) devices.elementAt(selectedDevice);
else
return null;
}

public void startInquiry( int mode, UUID[] serviceUUIDs )


{
try
{
this.discoveryMode = mode;
this.serviceUUIDs = serviceUUIDs;

devices.removeAllElements();
96
deviceClasses.removeAllElements();

device = LocalDevice.getLocalDevice();
device.setDiscoverable(DiscoveryAgent.GIAC);
agent = device.getDiscoveryAgent();

boolean result = agent.startInquiry( mode, new Listener() );

remotedeviceui.setMsg("[Aguarde...]");

} catch ( BluetoothStateException e )
{
e.printStackTrace();
}

public void commandAction(String c, MessageUI d)


{
if ( d == remotedeviceui && c.equals("Search") )
{
startInquiry( discoveryMode, serviceUUIDs );

} else if ( d == remotedeviceui && c.equals("Back") )


{
callback.commandAction( BACK, remotedeviceui);

} else if ( d == remotedeviceui && c.equals("Select") )


{
selectedDevice = remotedeviceui.getSelectedIndex();
RemoteDevice remoteDevice = (RemoteDevice) devices.elementAt(
selectedDevice );

services.removeAllElements();

try
{
agent.searchServices(null,
serviceUUIDs,
remoteDevice,
new Listener() );

Thread t = new Thread( new Worker(ID_DEVICE_SELECTED) );


t.start();

} catch (BluetoothStateException ex)


{
ex.printStackTrace();
}

}
}

class Listener implements DiscoveryListener


{
97
public void deviceDiscovered(RemoteDevice remoteDevice,
DeviceClass deviceClass)
{
devices.addElement( remoteDevice );
deviceClasses.addElement( deviceClass );
}

public void inquiryCompleted(int complete)


{
deviceReturnCode = complete;

if ( devices.size() == 0 )
{
System.out.println("Nenhum dispositivo Bluetooth encontrado");
remotedeviceui.showui();

} else
{
remotedeviceui.showui();
}

public void servicesDiscovered(int transId, ServiceRecord[] records)


{
for ( int i=0; i< records.length; i ++ )
{
ServiceRecord record = records[i];
services.addElement( record );
}
}

public void serviceSearchCompleted(int transId, int complete)


{
serviceReturnCode = complete;

Thread t = new Thread( new Worker(ID_SERVICE_COMPLETED) );


t.start();

private final static int ID_SERVICE_COMPLETED = 1;


private final static int ID_DEVICE_COMPLETED = 2;
private final static int ID_DEVICE_SELECTED = 3;
class Worker implements Runnable
{
int cmd = 0;

public Worker( int cmd )


{
this.cmd = cmd;
}
public void run()
98
{
switch (cmd) {
case ID_SERVICE_COMPLETED:
callback.commandAction( COMPLETED, remotedeviceui);

break;
case ID_DEVICE_COMPLETED:
callback.commandAction( COMPLETED, remotedeviceui);

break;
case ID_DEVICE_SELECTED:
callback.commandAction( SELECTED, remotedeviceui);

break;
default:
break;

}
}
}

99
ANEXO 4
Projeto PC-PC
Cliente em J2SE / Console
RemoteDeviceUI.Java

package cliente;

import Javax.Bluetooth.*;
import Java.io.*;

class RemoteDeviceUI extends MessageUI


{
int selected = 0;

public RemoteDeviceUI()
{

addCommand( "Select" );
addCommand( "Search" );
addCommand( BLUEletConsole.BACK );

setCommandListener( BLUEletConsole.instance );
}

public void setMsg( String str )


{
System.out.println(str);

}
public void showui()
{

if (BLUEletConsole.devices.size() > 0)
{
System.out.println("[Found "+BLUEletConsole.devices.size()+" devices,
selected one of the following:");
for (int i = 0; i < BLUEletConsole.devices.size(); i++)
{
try
{
RemoteDevice device = (RemoteDevice)
BLUEletConsole.devices.elementAt(i);
String name = device.getFriendlyName(false);
System.out.println("["+i+"] "+name);

} catch (Exception e)
{
e.printStackTrace();
}
}

Thread t = new Thread()


{

100
public void run()
{
try
{
BufferedReader in = new BufferedReader(new
InputStreamReader(System.in));
String s = in.readLine();
selected = Integer.parseInt( s );
if ( listener != null )
listener.commandAction( "Select", RemoteDeviceUI.this);
} catch (Exception e)
{
e.printStackTrace();
}

}
};
t.start();

} else
{
}
}

public int getSelectedIndex()


{
return selected;
}

101
ANEXO 5
Projeto PC-PC
Cliente em J2SE / Console
MessageUI.Java

package cliente;

import Java.util.Vector;
import Java.io.*;

public class MessageUI


{
Vector commands = new Vector();
protected CommandListener listener = null;

public void addCommand( String s )


{
commands.add( s );
}

public void setCommandListener( CommandListener l )


{
listener = l;
}

public void showui()


{
for ( int i=0; i< commands.size(); i++ )
{
String s = (String) commands.elementAt( i );
System.out.println("["+i+"]"+s);
}

}
}

102
ANEXO 6
Projeto PC-PC
Cliente em J2SE / Console
CommandListener.Java

package cliente;

public interface CommandListener


{
public void commandAction( String command, MessageUI display );
}

103
ANEXO 7
Projeto PC-PC e PC-Cel
Servidor em J2SE / Console
Server_Main.Java

package servidor;

import Java.io.*;
import Javax.Bluetooth.*;

public class Server_Main


{
public static Server_Main instance;
public SPP_Server spp_server = null;
public Server_Main()
{
instance = this;
}

public static void main(String[] args )


{
Server_Main app = new Server_Main();
app.startApp();
}

public void startApp()


{
spp_server = new SPP_Server();
spp_server.run_server();
}

public static void quitApp()


{
instance = null;
System.exit(0);
}

public static void alert( Exception e)


{
System.out.println("Exception: "+e.getClass().getName()+"
"+e.getMessage());
}
}

104
ANEXO 8
Projeto PC-PC e PC-Cel
Servidor em J2SE / Console
SPP_Server.Java

package servidor;

import Javax.Bluetooth.*;
import Javax.microedition.io.*;
import Java.io.*;

public class SPP_Server implements Runnable


{
LocalDevice device;
DiscoveryAgent agent;
public final static UUID uuid = new UUID("102030405060708090A0B0C0D0E0F010",
false);

private final static int SERVICE_TELEPHONY = 0x400000;

public boolean done = false;

public StreamConnectionNotifier server;

public SPP_Server()
{
}

public void run_server()


{
try
{
device = LocalDevice.getLocalDevice();
device.setDiscoverable(DiscoveryAgent.GIAC);
Thread t = new Thread( this );
t.start();

} catch ( BluetoothStateException e )
{
e.printStackTrace();
}

public void run()


{
String appName = "TCC_Servidor";
StreamConnection c = null;
String url = "btspp://localhost:" + uuid.toString() +";name="+ appName;
try
{
server = (StreamConnectionNotifier)Connector.open( url );
ServiceRecord rec = device.getRecord( server );
rec.setAttributeValue( 0x0008, new DataElement( DataElement.U_INT_1,

105
0xFF ) );
rec.setDeviceServiceClasses( SERVICE_TELEPHONY );

} catch (Exception e)
{
e.printStackTrace();
log(e.getClass().getName()+" "+e.getMessage());
}

try {
log("Servidor aguardando por conexao do cliente...");
c = server.acceptAndOpen();
log("Conexao aceita. Recebendo...");
RemoteDevice rdev = RemoteDevice.getRemoteDevice( c );
String s = "nada";
String texto_local = "nada";
DataInputStream in;
DataOutputStream out;
while
(!((texto_local.toLowerCase()).equals("exit"))&&!((s.toLowerCase()).equals("ex
it")))
{
in = c.openDataInputStream();
s = in.readUTF();
log("Recebido: '"+s+"' ");
if ((s.toLowerCase()).equals("exit"))
break;
if ((s.toLowerCase()).equals("cambio"))
{
in.close();
out = c.openDataOutputStream();
log ("Digite uma mensagem:");
while
(!((texto_local.toLowerCase()).equals("exit"))&&!((texto_local.toLowerCase()).
equals("cambio")))
{
BufferedReader leitor = new BufferedReader(new
InputStreamReader(System.in));
texto_local = leitor.readLine();
out.writeUTF( texto_local );
out.flush();
log("Enviado: '"+texto_local+"'");
}
out.close();
if ((texto_local.toLowerCase()).equals("exit"))
break;
texto_local = "nada";
}
}
c.close();
try
{
Server_Main.instance.spp_server.done = true;
if ( Server_Main.instance.spp_server.server != null )
Server_Main.instance.spp_server.server.close();
}
106
catch (IOException ex)
{
}
Server_Main.instance.quitApp();
} catch (Exception e)
{
e.printStackTrace();
Server_Main.alert(e);
}
}

public void log(String s)


{
System.out.println(s);
}

107
ANEXO 9
Projeto PC-Cel
Cliente em J2ME / MIDP
Client_MIDP.Java

package client_MIDP;

import Java.io.*;
import Javax.Bluetooth.*;
import Javax.microedition.lcdui.*;
import Javax.microedition.midlet.*;

public class Client_MIDlet extends MIDlet implements CommandListener


{
public boolean flag = false;
public static Client_MIDlet principal;
public EntraUI digita;
public static Display display;
public TelaUI recarregar = null;
BLUElet bluelet = null;
SPP_Client spp_client = null;
public final static UUID uuid = new UUID("102030405060708090A0B0C0D0E0F010",
false);

public Client_MIDlet()
{
principal = this;
}

public void startApp()


{
display = Display.getDisplay(this);
bluelet = new BLUElet( this, this );
bluelet.startApp();
digita = new EntraUI();
recarregar = new TelaUI();
spp_client = new SPP_Client();
display.setCurrent( recarregar );
bluelet.startInquiry( DiscoveryAgent.GIAC, new UUID[]{ uuid } );
display.setCurrent( bluelet.getUI() );
}

public void pauseApp()


{
bluelet.pauseApp();
}

public void destroyApp(boolean unconditional)


{
bluelet.destroyApp( unconditional );
}

public static void quitApp()


{

108
principal.destroyApp(true);
principal.notifyDestroyed();
principal = null;
}

public void commandAction(Command c, Displayable d)


{
if ( c.equals( BLUElet.COMPLETED ) )
{
Thread cliente = new Thread( new chama_cliente() );
cliente.start();

} else if ( c.equals( BLUElet.SELECTED ) )


{
display.setCurrent( recarregar );
} else if (c.getLabel().equals("Enviar"))
{
flag = true;
display.setCurrent( recarregar );
} else if (c.getLabel().equals("Sair"))
{
quitApp();
} else
{
display.setCurrent( recarregar );
}

public static void alert( Exception e, Displayable next_screen )


{
Alert alert = new Alert( "TCC_Cliente ", "Exception:
"+e.getClass().getName()+" "+e.getMessage(), null, AlertType.INFO );
alert.setTimeout( Alert.FOREVER );
display.setCurrent( alert, next_screen );

public static void alert( String m, Displayable next_screen )


{
Alert alert = new Alert( "TCC_Cliente ", m, null, AlertType.INFO );
alert.setTimeout( Alert.FOREVER );
display.setCurrent( alert, next_screen );

public class chama_cliente implements Runnable


{
public void run()
{
spp_client.send_SPP_message( bluelet.getFirstDiscoveredService(),
"Digite algo!" );
}
}

}
109
ANEXO 10
Projeto PC-Cel
Cliente em J2ME / MIDP
SPP_Client.Java

package client_MIDP;

import Java.io.*;
import Javax.Bluetooth.*;
import Javax.microedition.io.*;

public class SPP_Client


{

public SPP_Client()
{
}

public void send_SPP_message(ServiceRecord r, String msg)


{
String url = r.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT,
false );

try
{
StreamConnection con = (StreamConnection) Connector.open( url );
log("Conectado ao Servidor. Digite uma mensagem...");
DataOutputStream out = con.openDataOutputStream();
DataInputStream in = con.openDataInputStream();
String s = "nada";
while
(!((s.toLowerCase()).equals("exit"))&&!((msg.toLowerCase()).equals("exit")))
{
while
(!((msg.toLowerCase()).equals("cambio"))&&!((msg.toLowerCase()).equals("exit")
))
{
Client_MIDlet.display.setCurrent( Client_MIDlet.principal.digita
);
if (Client_MIDlet.principal.flag)
{
if (Client_MIDlet.principal.digita.size() == 0)
Client_MIDlet.principal.digita.setString(" ");
msg = Client_MIDlet.principal.digita.getString();
Client_MIDlet.principal.flag = false;

Client_MIDlet.principal.digita.delete(0,Client_MIDlet.principal.digita.size())
;
out.writeUTF( msg );
out.flush();
log("Enviado : '"+msg+"'");
}
}
Client_MIDlet.display.setCurrent( Client_MIDlet.principal.recarregar

110
);
if ((msg.toLowerCase()).equals("exit"))
{
con.close();
Client_MIDlet.principal.quitApp();
}
msg = "nada";
s = "nada";
while
(!((s.toLowerCase()).equals("exit"))&&!((s.toLowerCase()).equals("cambio")))
{
s = in.readUTF();
log("Recebido : '"+s+"'");
}
if ((s.toLowerCase()).equals("exit"))
{
con.close();
Client_MIDlet.principal.quitApp();
}
}
con.close();

} catch (Exception e)
{
e.printStackTrace();
Client_MIDlet.alert( e, Client_MIDlet.principal.recarregar );
}

public void log( String s )


{
System.out.println(s);
Client_MIDlet.principal.recarregar.add(s);
}

111
ANEXO 11
Projeto PC-Cel
Cliente em J2ME / MIDP
BLUElet.Java

package client_MIDP;

import Java.util.*;
import Javax.Bluetooth.*;
import Javax.microedition.lcdui.*;
import Javax.microedition.midlet.*;

public class BLUElet implements CommandListener


{
public static Command COMPLETED = new Command( "COMPLETED", Command.SCREEN,
1 );
public static Command SELECTED = new Command( "Selecionar", Command.SCREEN,
1 );
public static Command SAIR = new Command( "Sair", Command.BACK, 2 );

public static MIDlet host;


public static CommandListener callback;
public static BLUElet instance;
public static Display display;

public static Vector devices = new Vector();


public static Vector deviceClasses = new Vector();
public static Vector services = new Vector();
public static int selectedDevice = -1;

public int discoveryMode;


public UUID[] serviceUUIDs = null;
public int deviceReturnCode;
public int serviceReturnCode;

private RemoteDeviceUI remotedeviceui = null;


private LocalDevice device;
private DiscoveryAgent agent;

public BLUElet(MIDlet host, CommandListener listener)


{
this.host = host;
this.callback = listener;
instance = this;
}

public void startApp() {

display = Display.getDisplay(host);
remotedeviceui = new RemoteDeviceUI();
remotedeviceui.showui();
}

112
public void pauseApp()
{
}

public void destroyApp(boolean unconditional)


{
}

public Screen getUI()


{
return remotedeviceui;
}

public ServiceRecord[] getDiscoveredServices()


{
ServiceRecord[] r = new ServiceRecord[ services.size() ];
services.copyInto( r );
return r;
}

public ServiceRecord getFirstDiscoveredService()


{
if ( services.size() > 0 )
return (ServiceRecord) services.elementAt(0);
else
return null;
}

public int getDeviceDiscoveryReturnCode()


{
return deviceReturnCode;
}

public int getServiceDiscoveryReturnCode()


{
return serviceReturnCode;
}

public RemoteDevice getSelectedDevice()


{
if ( selectedDevice != -1 )
return (RemoteDevice) devices.elementAt(selectedDevice);
else
return null;
}

public void startInquiry( int mode, UUID[] serviceUUIDs )


{
try
{
this.discoveryMode = mode;
this.serviceUUIDs = serviceUUIDs;

devices.removeAllElements();
deviceClasses.removeAllElements();
113
device = LocalDevice.getLocalDevice();
device.setDiscoverable(DiscoveryAgent.GIAC);
agent = device.getDiscoveryAgent();

boolean result = agent.startInquiry( mode, new Listener() );


remotedeviceui.setMsg("[Aguarde...]");

} catch ( BluetoothStateException e )
{
e.printStackTrace();
}

public void commandAction(Command c, Displayable d)


{
if ( d == remotedeviceui && c.getLabel().equals("Procurar") )
{
startInquiry( discoveryMode, serviceUUIDs );

} else if ( d == remotedeviceui && c.getLabel().equals("Sair") )


{
Client_MIDlet.principal.quitApp();

} else if ( d == remotedeviceui && c.getLabel().equals("Selecionar") )


{
selectedDevice = remotedeviceui.getSelectedIndex();
RemoteDevice remoteDevice = (RemoteDevice) devices.elementAt(
selectedDevice );
services.removeAllElements();

try
{
agent.searchServices(null,
serviceUUIDs,
remoteDevice,
new Listener() );

display.callSerially(new Worker(ID_DEVICE_SELECTED));

} catch (BluetoothStateException ex)


{
ex.printStackTrace();
}

}
}

class Listener implements DiscoveryListener


{

public void deviceDiscovered(RemoteDevice remoteDevice,


DeviceClass deviceClass)
{
devices.addElement( remoteDevice );
114
deviceClasses.addElement( deviceClass );
}

public void inquiryCompleted(int complete)


{
deviceReturnCode = complete;

if ( devices.size() == 0 )
{
Alert alert = new Alert( "Bluetooth", "Nenhum dispositivo Bluetooth
encontrado", null, AlertType.INFO );
alert.setTimeout(3000);
remotedeviceui.showui();
display.setCurrent( alert, remotedeviceui );

} else
{
remotedeviceui.showui();
display.setCurrent( remotedeviceui );
}

public void servicesDiscovered(int transId, ServiceRecord[] records)


{
for ( int i=0; i< records.length; i ++ )
{
ServiceRecord record = records[i];
services.addElement( record );
}
}

public void serviceSearchCompleted(int transId, int complete)


{
serviceReturnCode = complete;
display.callSerially( new Worker( ID_SERVICE_COMPLETED ) );

private final static int ID_SERVICE_COMPLETED = 1;


private final static int ID_DEVICE_COMPLETED = 2;
private final static int ID_DEVICE_SELECTED = 3;

class Worker implements Runnable


{
int cmd = 0;

public Worker( int cmd )


{
this.cmd = cmd;
}
public void run()
{
switch (cmd) {
115
case ID_SERVICE_COMPLETED:
callback.commandAction( COMPLETED, remotedeviceui);

break;
case ID_DEVICE_COMPLETED:
callback.commandAction( COMPLETED, remotedeviceui);

break;
case ID_DEVICE_SELECTED:
callback.commandAction( SELECTED, remotedeviceui);

break;
default:
break;

}
}
}

116
ANEXO 12
Projeto PC-Cel
Cliente em J2ME / MIDP
RemoteDeviceUI.Java

package client_MIDP;

import Javax.microedition.lcdui.*;
import Javax.Bluetooth.*;

class RemoteDeviceUI extends List


{
public RemoteDeviceUI()
{
super("Dispositivos Bluetooth", List.IMPLICIT);
addCommand( new Command( "Selecionar", Command.SCREEN, 1 ) );
addCommand( new Command( "Procurar", Command.SCREEN, 2 ) );
addCommand( BLUElet.SAIR );
setCommandListener( BLUElet.instance );
}
public void setMsg( String str )
{
super.deleteAll();
append( str, null );
}
public void showui()
{
super.deleteAll();
if (BLUElet.devices.size() > 0)
{
for (int i = 0; i < BLUElet.devices.size(); i++)
{
try
{
RemoteDevice device = (RemoteDevice) BLUElet.devices.elementAt(i);
String name = device.getFriendlyName(false);
append(name, null);

} catch (Exception e)
{
e.printStackTrace();
}
}
} else
{
append("[Nao Encontrado]", null);
}
}
}

117
ANEXO 13
Projeto PC-Cel
Cliente em J2ME / MIDP
MensagemUI.Java

package client_MIDP;

import Javax.microedition.lcdui.*;
import Java.util.*;

public class MensagemUI extends Canvas


{

public Vector msgs = new Vector();


int midx = 0;
int w, h;
int fh;
Font f;
int x0=0, y0=0;

public int bookmarkId = 1;

public int backTo = 0;

public MensagemUI()
{
addCommand(new Command("Sair", Command.BACK, 1));
}

protected void paint(Graphics g)


{

if ( f == null )
{
f = Font.getFont( Font.FACE_MONOSPACE, Font.STYLE_PLAIN,
Font.SIZE_SMALL );
w = this.getWidth();
h = this.getHeight();
fh = f.getHeight();
}

int y = fh;

g.setColor( 255, 255, 255 );


g.fillRect( 0, 0, w, h );
g.setColor( 0, 0, 0 );
g.setFont( f );

g.translate(-x0, -y0);

for ( int i= midx; i< msgs.size(); i++ )


{
String s = (String)msgs.elementAt(i);

118
g.drawString( s, 0, y, Graphics.BASELINE | Graphics.LEFT );
y += fh;
}

public void keyPressed( int key )


{
if ( getGameAction( key ) == Canvas.RIGHT )
{
x0+=20;
} else if ( getGameAction( key ) == Canvas.LEFT )
{
x0-=20;
} else if ( getGameAction( key ) == Canvas.UP )
{
y0-=20;
} else if ( getGameAction( key ) == Canvas.DOWN )
{
y0+=20;
}
repaint();
}

public void clear()


{
msgs.removeAllElements();
midx = 0;
x0 = 0;
y0 = 0;
bookmarkId = 1;
repaint();
}

public void add( String s )


{
msgs.addElement( s );
repaint();
}

public void addNoRepaint( String s )


{
msgs.addElement( s );
}
}

119
ANEXO 14
Projeto PC-Cel
Cliente em J2ME / MIDP
EntraUI.Java

package client_MIDP;

import Javax.microedition.lcdui.*;

public class EntraUI extends TextBox {

public EntraUI() {
super("Digite a Mensagem", "", 200, TextField.ANY);
addCommand(new Command("Enviar", Command.SCREEN, 1));
addCommand(new Command("Voltar", Command.SCREEN, 2));
setCommandListener( Client_MIDlet.principal );
}

public void showUI()


{
this.setString("");
}

120
ANEXO 15
Projeto PC-Cel
Cliente em J2ME / MIDP
TelaUI.Java

package client_MIDP;

import Javax.microedition.lcdui.*;

public class TelaUI extends MensagemUI


{

public TelaUI()
{
}

121
ANEXO 16
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
Chatooth.Java

package chatooth;

import Javax.microedition.midlet.*;
import Javax.microedition.lcdui.*;
import Java.io.*;

public class Chatooth extends MIDlet implements AUXEventos, CommandListener


{
public static Chatooth principal;
public static Display tela;

public EntraUI entrada;


public MensagemUI mensagem;
public NomeUI nome;

public Kernel btnet;

public Chatooth()
{
principal = this;
}

public void startApp() {

tela = Display.getDisplay(this );

entrada = new EntraUI();


mensagem = new MensagemUI();
nome = new NomeUI();
tela.setCurrent( nome );

public void pauseApp() {


}

public void destroyApp(boolean unconditional) {


btnet.disconnect();
}

public static void sairApp() {


principal.destroyApp(true);
principal.notifyDestroyed();
principal = null;
tela = null;
}

122
public void handleAction( String event, Object param1, Object param2 )
{

if ( event.equals( AUXEventos.EVENT_JOIN ) )
{
parceiro endpt = (parceiro) param1;
String msg = endpt.remoteName + " entrou no chat;";
Empacotador packet = new Empacotador(Kernel.SIGNAL_HANDSHAKE,
endpt.remoteName, msg );

mensagem.msgs.addElement( packet );
mensagem.repaint();

} else if ( event.equals( AUXEventos.EVENT_SENT ) )


{

} else if ( event.equals( AUXEventos.EVENT_RECEIVED ) )


{
parceiro endpt = (parceiro) param1;
Empacotador msg = (Empacotador) param2;
mensagem.msgs.addElement( msg );
mensagem.repaint();

} else if ( event.equals( AUXEventos.EVENT_LEAVE ) )


{
parceiro endpt = (parceiro) param1;
String msg = endpt.remoteName + " saiu do chat;";
Empacotador packet = new Empacotador(Kernel.SIGNAL_TERMINATE,
endpt.remoteName, msg );
mensagem.msgs.addElement( packet );
mensagem.repaint();
}
}

public void commandAction(Command c, Displayable d)


{
if ( d == entrada && c.getLabel().equals("Enviar") )
{
String msg = entrada.getString();
btnet.sendString( msg );

Empacotador packet = new Empacotador( Kernel.SIGNAL_MESSAGE,


btnet.localName, msg );
mensagem.msgs.addElement( packet );
tela.setCurrent( mensagem );
mensagem.repaint();

} else if ( d == entrada && c.getLabel().equals("Voltar") )


{
tela.setCurrent( mensagem );

} else if ( d == nome && ( c.getLabel().equals("Chat")) )


{
btnet = new Kernel();

String localName = nome.text.getString();


123
btnet.init( localName, this );

btnet.query();

tela.setCurrent( mensagem );

} else if ( d == mensagem && c.getLabel().equals("Escrever") )


{
tela.setCurrent( entrada );
entrada.showUI();

} else if ( d == mensagem && c.getLabel().equals("Limpar") )


{
mensagem.msgs.removeAllElements();
mensagem.repaint();

} else if ( d == mensagem && c.getLabel().equals("Sair do Chat") )


{
sairApp();
}
}

public static void log_ui(String source, String s)


{
Empacotador packet = new Empacotador(Kernel.SIGNAL_MESSAGE, source, s );
principal.mensagem.msgs.addElement(packet);
principal.mensagem.repaint();

}
}

124
ANEXO 17
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
NomeUI.Java

package chatooth;

import Javax.microedition.lcdui.*;

public class NomeUI extends Form


{

TextField text;
public NomeUI()
{
super("Informe seu nome");
addCommand(new Command("Chat", Command.SCREEN, 1));
setCommandListener( Chatooth.principal );
append( new StringItem( "", "Informe um nome e selecione a opcao CHAT." )
);
append( text = new TextField( "Nome", "", 10, TextField.ANY ) );
}
}

125
ANEXO 18
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
MensagemUI.Java

package chatooth;

import Javax.microedition.lcdui.*;
import Java.util.*;

public class MensagemUI extends Canvas


{

Vector msgs = new Vector();


int midx = 0;
int w, h;
int fh;
Font f;
int x0=0, y0=0;

public MensagemUI()
{
addCommand(new Command("Escrever", Command.SCREEN, 1));
addCommand(new Command("Limpar", Command.SCREEN, 2));
addCommand(new Command("Sair do Chat", Command.SCREEN, 3));
setCommandListener( Chatooth.principal );
}

protected void paint(Graphics g)


{
if ( f == null )
{
f = Font.getFont( Font.FACE_MONOSPACE, Font.STYLE_PLAIN,
Font.SIZE_SMALL );
w = this.getWidth();
h = this.getHeight();
fh = f.getHeight();
}
int y = fh;

g.setColor( 255, 255, 255 );


g.fillRect( 0, 0, w, h );
g.setColor( 0, 0, 0 );
g.setFont( f );
g.translate(-x0, -y0);

for ( int i= midx; i< msgs.size(); i++ )


{
Empacotador p = (Empacotador)msgs.elementAt(i);
String s = p.sender+": "+p.msg;
g.drawString( s, 0, y, Graphics.BASELINE | Graphics.LEFT );
y += fh;

126
}

}
public void keyPressed( int key )
{
if ( getGameAction( key ) == Canvas.RIGHT )
{
x0+=10;
} else if ( getGameAction( key ) == Canvas.LEFT )
{
x0-=10;
} else if ( getGameAction( key ) == Canvas.UP )
{
y0-=10;
} else if ( getGameAction( key ) == Canvas.DOWN )
{
y0+=10;
}
repaint();
}

127
ANEXO 19
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
EntraUI.Java

package chatooth;

import Javax.microedition.lcdui.*;

public class EntraUI extends TextBox {

public EntraUI() {
super("Digite a Mensagem", "", 200, TextField.ANY);
addCommand(new Command("Enviar", Command.SCREEN, 1));
addCommand(new Command("Voltar", Command.SCREEN, 2));
setCommandListener( Chatooth.principal );
}

public void showUI()


{
this.setString("");
}

128
ANEXO 20
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
Kernel.Java

package chatooth;

import Javax.microedition.io.*;
import Javax.Bluetooth.*;
import Java.io.*;
import Java.util.*;
import Javax.Bluetooth.RemoteDevice;
import Javax.Bluetooth.DeviceClass;
import Javax.Bluetooth.ServiceRecord;

public class Kernel implements Runnable


{
public final static int SIGNAL_HANDSHAKE = 0;
public final static int SIGNAL_MESSAGE = 1;
public final static int SIGNAL_TERMINATE = 3;
public final static int SIGNAL_HANDSHAKE_ACK = 4;
public final static int SIGNAL_TERMINATE_ACK = 5;

private final static UUID uuid = new


UUID("102030405060708090A0B0C0D0E0F010", false);

private final static int SERVICE_TELEPHONY = 0x400000;

LocalDevice localDevice = null;


DiscoveryAgent agent = null;
StreamConnectionNotifier server;
AUXEventos callback = null;

boolean desconecta_todos = false;

String localName = "";

Vector dispositivos_proximos = new Vector();

Vector vetordebusca = new Vector();

Hashtable registroparceiro = new Hashtable();

Object lock = new Object();

Timer timer = new Timer();

public Kernel()
{
}

public void init(String name, AUXEventos callback)

129
{
try {
this.localName = name;
this.callback = callback;

localDevice = LocalDevice.getLocalDevice();
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
agent = localDevice.getDiscoveryAgent();

Thread thread = new Thread( this );


thread.start();

}
catch (BluetoothStateException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}

public void disconnect()


{
desconecta_todos = true;
try {
server.close();
}
catch (IOException ex) {
}

for ( int i=0; i < dispositivos_proximos.size(); i++ )


{
parceiro endpt = (parceiro) dispositivos_proximos.elementAt( i );
endpt.putString( Kernel.SIGNAL_TERMINATE, "end" );
endpt.sender.stop();
endpt.reader.stop();
}
}

public void query()


{
try {
agent.startInquiry(DiscoveryAgent.GIAC, new Listener());
}
catch (BluetoothStateException e)
{
e.printStackTrace();
}
}

public parceiro buscaParceiroporID( RemoteDevice rdev )


{
for ( int i=0; i < dispositivos_proximos.size(); i++ )
{
130
parceiro endpt = (parceiro) dispositivos_proximos.elementAt( i );
if ( endpt.remoteDev.equals( rdev ) )
{
return endpt;
}
}
return null;
}

public parceiro buscaParceiroporTrans( int id )


{
for ( int i=0; i < vetordebusca.size(); i++ )
{
parceiro endpt = (parceiro) vetordebusca.elementAt( i );
if ( endpt.transId == id )
{
return endpt;
}
}
return null;
}

public void sendString( String s )


{
for ( int i=0; i < dispositivos_proximos.size(); i++ )
{
parceiro endpt = (parceiro) dispositivos_proximos.elementAt( i );
endpt.putString( Kernel.SIGNAL_MESSAGE, s );
}
}

public void cleanupRemoteparceiro( parceiro endpt )


{
endpt.reader.stop();
endpt.sender.stop();
dispositivos_proximos.removeElement( endpt );

public void run()


{
StreamConnection c = null;
try
{
server = (StreamConnectionNotifier)Connector.open("btspp://localhost:"
+ uuid.toString() +";name=ChaTooth");

ServiceRecord rec = localDevice.getRecord( server );

rec.setAttributeValue( 0x0008, new DataElement( DataElement.U_INT_1,


0xFF ) );

rec.setDeviceServiceClasses(SERVICE_TELEPHONY);

131
} catch (Exception e)
{
e.printStackTrace();
}

while( !desconecta_todos)
{
try {
Chatooth.principal.log_ui( "", "Pronto para aceitar conexões." );
Chatooth.principal.log_ui( "", "Aguarde..." );

c = server.acceptAndOpen();

RemoteDevice rdev = RemoteDevice.getRemoteDevice( c );


parceiro endpt = buscaParceiroporID( rdev );
if ( endpt != null )
{
} else
{
endpt = new parceiro( this, rdev, c);

Thread t1 = new Thread( endpt.sender );


t1.start();

Thread t2 = new Thread( endpt.reader );


t2.start();

dispositivos_proximos.addElement( endpt );

}
catch (IOException e) {
e.printStackTrace();
if (c != null)
try {
c.close();
}
catch (IOException e2) {
}

}
finally {
}
}
}

class Listener implements DiscoveryListener


{

public void deviceDiscovered(RemoteDevice remoteDevice,


DeviceClass deviceClass)
{

try
132
{
parceiro endpt = new parceiro(Kernel.this, remoteDevice, null);
vetordebusca.addElement( endpt );

} catch (Exception e)
{
e.printStackTrace();
}
}

public void inquiryCompleted(int transId)


{
timer.schedule( new DoServiceDiscovery(), 100 );
}

public void servicesDiscovered(int transId, ServiceRecord[] svcRec)


{
try {
for ( int i=0; i< svcRec.length; i++ )
{
parceiro endpt = buscaParceiroporTrans( transId );
registroparceiro.put( svcRec[i], endpt );
}
}
catch (Exception e) {
e.printStackTrace();
}
}

public void serviceSearchCompleted(int transID, int respCode)


{
for ( Enumeration records = registroparceiro.keys();
records.hasMoreElements(); )
{
try {
ServiceRecord rec = (ServiceRecord) records.nextElement();
String url = rec.getConnectionURL(
ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false );
StreamConnection con = (StreamConnection)Connector.open( url );
parceiro endpt = (parceiro) registroparceiro.get( rec );
if ( endpt != null )
{
endpt.con = con;
Thread t1 = new Thread( endpt.sender );
t1.start();
Thread t2 = new Thread( endpt.reader );
t2.start();
dispositivos_proximos.addElement( endpt );
endpt.putString( Kernel.SIGNAL_HANDSHAKE, localName );
} else
{
}

} catch (Exception e)
{
e.printStackTrace();
133
}
}

registroparceiro.clear();

synchronized( lock )
{
lock.notifyAll();
}

class DoServiceDiscovery extends TimerTask


{
public void run()
{
for (int i = 0; i < vetordebusca.size(); i++) {
parceiro endpt = (parceiro) vetordebusca.elementAt(i);
try {
endpt.transId = agent.searchServices(null,
new UUID[] { uuid },
endpt.remoteDev,
new Listener());

synchronized( lock )
{
try {
lock.wait();
}
catch (InterruptedException ex) {
}
}
}
catch (BluetoothStateException e) {
e.printStackTrace();

vetordebusca.removeAllElements();

Chatooth.principal.log_ui( "", "Você pode começar a teclar agora" );

134
ANEXO 21
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
parceiro.Java

package chatooth;

import Javax.Bluetooth.*;
import Javax.microedition.io.*;
import Java.io.*;
import Java.util.*;

public class parceiro


{
RemoteDevice remoteDev;
DeviceClass remoteClass;
String remoteUrl;
StreamConnection con;
int transId = -1;

TX_Thread sender;
RX_Thread reader;

String localName;
String remoteName;

AUXEventos callback;

Kernel btnet;

Vector msgs = new Vector();

public parceiro( Kernel btnet, RemoteDevice rdev, StreamConnection c )


{
this.btnet = btnet;

remoteDev = rdev;

try {
remoteName = rdev.getFriendlyName(false);
}
catch (IOException ex) {
remoteName = "Desconhecido";
}
localName = btnet.localName;
callback = btnet.callback;
con = c;

sender = new TX_Thread();


sender.endpt = this;

reader = new RX_Thread();


reader.endpt = this;

135
}

public synchronized void putString( int signal, String s )


{
msgs.addElement( new Empacotador( signal, s ) );
synchronized( sender )
{
sender.notify();
}
}

public synchronized Empacotador getString()


{

if ( msgs.size() > 0 )
{
Empacotador s = (Empacotador) msgs.firstElement();
msgs.removeElementAt(0);
return s;
} else
{
return null;
}
}

public synchronized boolean peekString()


{
return ( msgs.size() > 0 );
}

136
ANEXO 22
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
Empacotador.Java

package chatooth;

public class Empacotador


{
public int signal;
public String sender;
public String msg;

public Empacotador(int signal, String msg)


{
this.signal = signal;
this.msg = msg;
}

public Empacotador(int signal, String sender, String msg)


{
this.signal = signal;
this.sender = sender;
this.msg = msg;
}

public Empacotador()
{
}
}

137
ANEXO 23
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
TX_Thread.Java

package chatooth;

import Java.io.*;

public class TX_Thread implements Runnable


{
public parceiro endpt;

private boolean done = false;

public TX_Thread()
{
}

public void stop()


{
done = true;
}

public void run()


{
try
{
DataOutputStream dataout = endpt.con.openDataOutputStream();
while( !done )
{

if ( ! endpt.peekString() )
{
synchronized (this) {
this.wait(5000);
}
}

Empacotador s = endpt.getString();

if ( s != null )
{
dataout.writeInt(s.signal);
dataout.writeUTF(s.msg );
dataout.flush();
}

if ( s != null && s.signal == Kernel.SIGNAL_TERMINATE )


{
stop();
}

138
dataout.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
}

139
ANEXO 24
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
RX_Thread.Java

package chatooth;

import Java.io.*;

public class RX_Thread implements Runnable


{
public parceiro endpt;

private boolean done = false;

public RX_Thread() {
}

public void stop()


{
done = true;
}

public void run()


{
try
{
DataInputStream datain = endpt.con.openDataInputStream();

while ( !done )
{
int signal = datain.readInt();

if ( signal == Kernel.SIGNAL_MESSAGE )
{
String s = datain.readUTF();
Empacotador packet = new Empacotador( Kernel.SIGNAL_MESSAGE,
endpt.remoteName, s );

endpt.callback.handleAction( AUXEventos.EVENT_RECEIVED, endpt,


packet );

} else if ( signal == Kernel.SIGNAL_HANDSHAKE )


{
String s = datain.readUTF();
endpt.remoteName = s;

endpt.putString( Kernel.SIGNAL_HANDSHAKE_ACK, endpt.localName );

endpt.callback.handleAction( AUXEventos.EVENT_JOIN, endpt, null );

} else if ( signal == Kernel.SIGNAL_TERMINATE )


{
endpt.putString( Kernel.SIGNAL_TERMINATE_ACK, "end" );

140
endpt.callback.handleAction( AUXEventos.EVENT_LEAVE, endpt, null );

endpt.btnet.cleanupRemoteparceiro( endpt );

stop();

} else if ( signal == Kernel.SIGNAL_HANDSHAKE_ACK )


{
String s = datain.readUTF();
endpt.remoteName = s;

} else if ( signal == Kernel.SIGNAL_TERMINATE_ACK )


{
} else
{
}

datain.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
}

141
ANEXO 25
Projeto Chatooth
Cliente/Servidor em J2ME / MIDP
AUXEventos.Java

package chatooth;

public interface AUXEventos


{
public final static String EVENT_JOIN = "join";
public final static String EVENT_LEAVE = "leave";
public final static String EVENT_RECEIVED = "received";
public final static String EVENT_SENT = "sent";

public void handleAction( String action, Object param1, Object param2 );


}

142
REFERÊNCIAS BIBLIOGRÁFICAS

[1] TORRES, Gabriel. Redes de computadores: Curso completo. Rio de Janeiro: Axcel
Books, 2001.

[2] MAIA, Roberto M.F. Bluetooth, Promessas de uma nova tecnologia. 2003, 77f.
(Trabalho de conclusão de curso) Curso de sistema de informação. Faculdade
Integrada de Recife.

[3] HURA, Gurdeep S. Data and computer communications: networking and


internetworking. CRC PRESS, 2001

[4] JÚNIOR, Alberto L. D. Sistema identificador semelhantes utilizando tecnologia


Wireless interface Bluetooth. 2005, 41f. (Trabalho de Conclusão de Curso).
Departamento de Ciências Exatas e Engenharias, Universidade Potiguar – UnP.

[5] HAARTSEN, Jaap C. "The Bluetooth Radio System", IEEE Personal Communication.
Fevereiro de 2000.

[6] Specification of Bluetooth System, extraído do site www.Bluetooth.org no dia 30 de


Março de 2005.

[7] TAN, Godfrey, Self-organizing Bluetooth Scatternets. 2002, 73.f (Dissertação de


Mestrado). Massachusetts Institute of Technology - MIT.

[8] Introdução ao mundo Java, extraído do site www.fundao.pro.br no dia 01 de Abril de


2005.

[9] SILVA, Gustavo C. C. Sistema identificador de personalidades semelhantes


utilizando tecnologia Wireless interface com o usuário (MIDP JAVA). 2004, 64f.
(Trabalho de Conclusão de Curso). Departamento de Ciências Exatas e Engenharias,
Universidade Potiguar – UnP.

[10] RUUSKANEN, Juha-Pekka. MDIP – Mobile Device Information Profile. Artigo


extraído do site www.citeseer.com em 18 de Março de 2005.

[11] GUPTA, Vikas, DASS, Avnish e CHAUHAN, Yashraj. Wireless programming with
J2ME – Cracking the code. E-book Editora: Hungry Minds, 2002.

143
[12] WHITE, James; HEMPHILL, David. Java to micro edition – Java in small things. E-
book Editora: Manning Plublication Co.

[13] Extraído do website da Sun Microsystems. www.Sun Microsystems.com em 01 de


Abril de 2005.

[14] KAMMANN, Jens. Mobile services over short range communication. Workshop
Commercial Radio Sensors and Communication Techniques, 2001, Austria.

[15] Especificação do MIDP (JSR-37) extraído do site


http://jcp.org/aboutJava/communityprocess/final/jsr037/index.html em 25 de março de
2005.

[16] MUCHOW, John W. Core J2ME – Tecnologia & MIDP. São Paulo, Pearson Books,
2004.

144