UNIVERSIDADE FEDERAL DE SANTA CATARINAF3... · universidade federal de santa catarina departamento...
Transcript of UNIVERSIDADE FEDERAL DE SANTA CATARINAF3... · universidade federal de santa catarina departamento...
UNIVERSIDADE FEDERAL DE SANTA CATARINA
JNC MOBILE – SISTEMA DE ACESSO REMOTO PARA DISPOSITIVOS MÓVEIS
Andrei Luciano Krause Rafael Augusto da Silva
Florianópolis – SC 2005/1
UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
CURSO DE CIÊNCIAS DA COMPUTAÇÃO
JNC MOBILE – SISTEMA DE ACESSO REMOTO PARA DISPOSITIVOS MÓVEIS
Andrei Luciano Krause Rafael Augusto da Silva
Trabalho de conclusão de curso apresentado como parte dos requisitos para a obtenção do grau de Bacharel em Ciências da Computação.
Florianópolis – SC 2005/1
Andrei Luciano Krause Rafael Augusto da Silva
JNC MOBILE – SISTEMA DE ACESSO REMOTO PARA DISPOSITIVOS MÓVEIS
Trabalho de conclusão de curso apresentado como parte dos requisitos para a obtenção do grau de Bacharel em Ciências da Computação. Orientador: Prof. Dr. José Eduardo De Lucca
Banca examinadora
Prof. MSc. Fernando Augusto da Silva Cruz Prof. Dr. Mário Antônio Ribeiro Dantas
iii
AGRADECIMENTOS
Agradeço aos meus pais, à minha noiva Vanessa e aos meus amigos Rafael Augusto da Silva e Augusto Boal. Todos foram fundamentais.
Andrei Luciano Krause Aos meus pais pelo incentivo. Ao professor De Lucca pela confiança e apoio. Ao amigo Andrei pela grande parceria. Em especial à minha esposa Renata, pelo auxílio, compreensão e companheirismo. Muito obrigado!
Rafael Augusto da Silva
iv
RESUMO
Os dispositivos móveis figuram atualmente no mercado como mercadorias em franca expansão. Desta forma, é necessário que os serviços oferecidos por estes aparelhos, sejam cada vez mais de excelência, proporcionando o máximo de utilidade aos usuários. O objetivo desta pesquisa é justamente apresentar um software capaz de oferecer o poder de processamento de uma estação de trabalho com a praticidade, mobilidade e conectividade dos dispositivos móveis como aparelhos celulares. A ferramenta neste documento apresentada, possibilita o acesso remoto de um computador através de um simples telefone celular, oferecendo ao seu usuário, a experiência de utilizar softwares disponíveis apenas para máquinas com processamento mais robusto. Conheça também as ferramentas que possibilitam a concepção deste novo paradigma de programação e criação de softwares. PALAVRAS-CHAVE: Computação Móvel. Computação Remota. J2ME. Dispositivos
Móveis. VNC.
v
ABSTRACT
The mobile devices appear currently in the market as merchandises in frank expansion. Of this form, it is necessary that the services offered for these devices, are each time more than excellency, providing the maximum of utility to the users. The objective of this research is exactly to present a software capable to offer the power of processing of a workstation with the practice, mobility and connectivity of the mobile devices as cell phones. The tool in this presented document, makes possible the remote access of a computer through a simple cellular telephone, offering its user, the experience to use softwares available only for machines with more robust processing. It also knows the tools that make possible the conception of this new paradigm of programming and software development.
KEYWORDS: Mobile computation. Remote computation. J2ME. Móbile devices. VNC.
vi
LISTA DE FIGURAS
Figura 1 – Plataforma J2ME.................................................................................. 19 Figura 2 – Arquitetura Eclipse ............................................................................... 23 Figura 3 – IDE AJDT do Eclipse............................................................................ 26 Figura 4 – Acesso remoto com VNC ..................................................................... 27 Figura 5 – Acesso remoto através de dispositivo móvel ....................................... 29 Figura 6 – Acesso remoto através de dispositivo móvel com servidor bridge ....... 30 Figura 7 – Compactação da imagem enviada ao cliente....................................... 30 Figura 8 – Programa servidor................................................................................ 35 Figura 9 – Programa cliente – Celular................................................................... 36 Figura 10 – Teclas do celular para o servidor VNC............................................... 38 Figura 11 – Tela do VNC para celular – módulo PC ............................................. 38 Figura 12 – Telas do VNC para celular – módulo J2ME – Celular ........................ 39 Figura 13 – Telas do VNC para celular – módulo J2ME – Celular ........................ 40 Figura 14 – Telas do VNC para celular – módulo J2ME – Celular ........................ 40 Figura 15 – Telas do VNC para celular – módulo J2ME – Celular ........................ 41 Figura 16 – Classes da aplicação cliente .............................................................. 42 Figura 17 – Classes da aplicação servidor............................................................ 43 Figura 18 – Classes da aplicação servidor............................................................ 44 Figura 19 – Diagrama de seqüência UML............................................................. 45 Figura 20 – Ambiente de programação ................................................................. 46
vii
SUMÁRIO
RESUMO .............................................................................................. iv ABSTRACT .......................................................................................... v LISTA DE FIGURAS ............................................................................ vi 1 INTRODUÇÃO ................................................................................ 09 1.1 Delimitação do tema ................................................................... 09 1.2 Objetivo geral .............................................................................. 10 1.3 Objetivos específicos ................................................................. 10 1.4 Justificativa.................................................................................. 11 1.5 Problema ...................................................................................... 11 1.6 Metodologia ................................................................................. 12 2 DISPOSITIVOS, TECNOLOGIAS E SISTEMAS MÓVEIS ............. 13 2.1 Computação móvel ..................................................................... 13 2.2 Dispositivos móveis.................................................................... 14 2.2.1 Notebooks, laptops e palmtops ................................................... 14 2.2.2 PDAs (Personal Digital Assistants) ............................................. 15 2.2.3 Celulares ..................................................................................... 16 2.3 Protocolos de comunicação sem fio ......................................... 17 2.4 Java 2 Micro Edition – J2ME ...................................................... 18 2.4.1 Arquitetura J2ME......................................................................... 18 2.4.2 Configurações ............................................................................. 19 2.4.3 Perfis ........................................................................................... 20 2.4.4 Pacotes ....................................................................................... 21 2.5 Eclipse.......................................................................................... 21 2.5.1 Plataforma Eclipse....................................................................... 22 2.5.2 Arquitetura................................................................................... 23 2.5.3 IDEs............................................................................................. 25 2.6 Virtual Network Computing – VNC ............................................ 26
viii
3 JNC MOBILE - SISTEMA DE ACESSO REMOTO PARA DISPOSITIVOS MÓVEIS ................................................................ 29
3.1 Descrição do sistema ................................................................. 29 3.2 RFB Protocol ............................................................................... 31 3.2.1 Entrada........................................................................................ 31 3.2.2 Representação dos pixels ........................................................... 32 3.2.3 Raw Encoding ............................................................................. 32 3.2.4 Copy Rectangle Encoding ........................................................... 32 3.2.5 Mensagens de protocolo ............................................................. 32 3.2.6 Diretivas do protocolo auxiliar ..................................................... 33 3.3 Desenvolvimento da aplicação .................................................. 34 3.3.1 Programa servidor ....................................................................... 35 3.3.2 Programa cliente ......................................................................... 36 3.3.3 Telas do sistema ........................................................................ 37 3.3.4 Diagrama de classes ................................................................... 41 3.3.5 Diagrama de seqüência UML...................................................... 45 3.3.6 Ambiente de desenvolvimento ................................................... 45 4 TRABALHOS FUTUROS ............................................................... 47 5 CONSIDERAÇÕES FINAIS............................................................ 49 REFERÊNCIAS .................................................................................... 51 APÊNDICES......................................................................................... 53 APÊNDICE A – Código Fonte da Aplicação Cliente ........................ 54 APÊNDICE B – Código Fonte da Aplicação Servidor...................... 67 APÊNDICE C – Artigo ......................................................................... 101
9
1 INTRODUÇÃO
Nesta pesquisa o leitor irá realizar sua leitura em quatro capítulos. O primeiro
capítulo tem por motivação apresentar os objetivos da pesquisa, delimitar o tema por
esta proposto, justificar e apresentar a metodologia empregada neste estudo.
Dando continuidade ao documento, tem-se o segundo capítulo, que aborda
as questões referentes aos dispositivos móveis escolhidos, a computação móvel e
as tecnologias e ferramentas empregadas para o desenvolvimento da pesquisa.
Assim, é chegada a hora de apresentar o desenvolvimento da aplicação,
como se deu o processo de implementação e uma explicação mais apurada de seu
funcionamento.
Por fim, o quarto capítulo, onde são apresentados alguns trabalhos futuros
derivados desta pesquisa.
1.1 Delimitação do tema
Com a popularização dos dispositivos móveis, um novo paradigma de
serviços foi criado. Assim, para atender e suportar estes serviços os dispositivos
móveis, que têm na forma dos telefones celulares seus mais evidentes
representantes, sofreram transformações para poder corresponder aos anseios
gerados por estes novos serviços. Aparelhos que eram utilizados apenas para fazer
ligações, passaram rapidamente a figurar como agendas eletrônicas, câmeras
fotográficas digitais, gravadores de som digital, e mais recentemente, no Brasil,
computadores de mão.
10
Mesmo com estas funcionalidades sendo oferecidas, o poder computacional
destes dispositivos ainda não proporciona uma experiência muito confortável,
limitando os serviços à sua capacidade reduzida de memória e poder de
processamento.
Uma maneira de oferecer poder computacional e proporcionar acesso a
serviços exclusivos das estações de trabalho é o acesso remoto via dispositivos
móveis a estações de trabalho. Com o poder de mobilidade e conectividade dos
dispositivos móveis, aliados a inovadora tecnologia J2ME da Sun, esta pesquisa visa
apresentar uma solução capaz de conectar remotamente uma estação de trabalho a
um aparelho móvel.
1.2 Objetivo geral
Desenvolver um sistema de acesso remoto para dispositivos móveis possibilitando o
gerenciamento de estações de trabalho à distância.
1.3 Objetivos específicos
• Identificar a melhor linguagem de programação para produção de sistemas para
dispositivos móveis.
• Definir um tipo de dispositivo móvel para desenvolvimento da aplicação.
• Criar um software cliente para dispositivos móveis capaz de gerenciar uma
estação de trabalho a partir de um software servidor.
11
1.4 Justificativa
Como os dispositivos móveis atuais não proporcionam poder computacional
equiparado as estações de trabalho, e a facilidade de mobilidade e conectividade
proporcionada por aparelhos móveis é fato, a motivação desta pesquisa tem seu
alicerce em tentar unir o poder computacional das estações de trabalho, com a
facilidade de acesso a serviços dos dispositivos móveis. Para tal, é apresentado
como solução para este problema, o desenvolvimento de uma aplicação cliente –
servidor, onde um dispositivo móvel realiza uma conexão remota a uma estação de
trabalho.
1.5 Problema
Com o crescimento do número de dispositivos móveis no cotidiano da
sociedade, e do incremento de funcionalidades destes aparelhos, os anseios por
serviços mais robustos e específicos tornam-se necessários.
Um relevante serviço para profissionais da área de TI (Tecnologia e
Informação) seria a capacidade de gerenciarem remotamente diferentes dispositivos
fixos, como estações de trabalho a partir de seus celulares, PDAs (Personal Digital
Assistants), entre outros.
Assim, para esta pesquisa defini-se o seguinte questionamento: como
desenvolver um sistema de acesso remoto para dispositivos móveis possibilitando o
gerenciamento de estações de trabalho à distância?
12
1.6 Metodologia
Esta pesquisa, segundo sua natureza, classifica-se como aplicada, pois
objetiva gerar conhecimentos para aplicação prática dirigidos à solução de
problemas específicos. Envolve verdades e interesses locais. (GIL, 1991)
Quanto a abordagem do problema a pesquisa é caracterizada como
qualitativa que, segundo Gil (1991, p. 41) “possui uma relação dinâmica entre o
mundo real e o sujeito, isto é, um vínculo indissociável entre o mundo objetivo e a
subjetividade do sujeito que não pode ser traduzido em números”. A interpretação
dos fenômenos e a atribuição dos significados são básicos no processo de pesquisa
qualitativa.
De acordo com os objetivos a pesquisa é considerada explicativa, pois visa
identificar os fatores que determinam ou contribuem para a ocorrência dos
fenômenos. “Aprofunda o conhecimento da realidade porque explica arazão, o
‘porquê’ das coisas” (GIL, 1991, p. 42)
Por fim, do ponto de vista dos procedimentos técnicos, a pesquisa é de
cunho: bibliográfico, elaborada a partir de material já publicado (sites e livros);
documental, a partir de materiais que não receberam tratamento analítico (Manual
de dispositivos móveis); e experimental, através da determinação do objeto de
estudo, da seleção das variáveis, das formas de controle e da observação dos
efeitos produzidos. (GIL, 1991)
13
2 DISPOSITIVOS, TECNOLOGIAS E SISTEMAS MÓVEIS
2.1 Computação móvel
Em decorrência dos anos 90, o mercado foi invadido por um volume
crescente de desenvolvimento em áreas de tecnologia celular móvel, redes sem fios
e comunicação via satélites. De acordo com a popularização tomada por estas
tecnologias, o acesso a informações remotas cresce vertiginosamente através de
novos serviços oferecidos aos usuários.
A evolução e popularização de dispositivos móveis como celulares,
notebooks, PDAs (Personal Digital Assistants), dispositivos dedicados móveis (GPS
– Global Positional System), entre outros, torna possível a determinação do seguinte
conceito: “Computação móvel pode ser representada como um novo paradigma
computacional que permite que usuários desse ambiente tenham acesso a serviços
independentemente de sua localização, podendo inclusive, estar em movimento.”
(FIGUEIREDO; NAKAMURA, 2003, p.16)
As palavras chaves para computação móvel são: processamento, mobilidade
e comunicação.
De acordo com Mateus e Loureiro (1998 apud FIGUEIREDO; NAKAMURA,
2003, p.17) a computação móvel é denominada a quarta revolução da computação,
logo após o advento dos grandes centros de processamento na década de sessenta,
o surgimento dos terminais uma década mais tarde, e as redes de computadores
nos anos oitenta. Ampliando o conceito de computação distribuída, graças a
comunicação sem fio, que elimina a necessidade do usuário estar conectado à uma
infra-estrutura estática.
14
2.2 Dispositivos móveis
Para estar de acordo com a definição de computação móvel apresentada no
capítulo anterior, os dispositivos móveis devem possuir tamanho reduzido bem como
capacidade de trocar informações via rede, realizar processamento, ser de fácil
transporte e não fazer uso de cabos tanto para conectar-se à rede de dados como a
um suporte de energia.
Os dispositivos mais utilizados para o propósito de computação móvel são:
• Notebooks, Laptos, Palmtops;
• PDAs (Personal Digital Assistants);
• Celulares (Smartphones).
Segue abaixo um breve discurso sobre estes dispositivos.
2.2.1 Notebooks, laptops e palmtops
Equipamentos como notebooks e laptops podem ser considerados
verdadeiras estações de trabalho móvel, pois com o avanço tecnológico no processo
de miniaturização de componentes, hoje é possível encontrar estes aparelhos com
capacidades semelhantes e em alguns casos superiores ao desempenho de
estações de trabalho fixas. E com um forte aliado, proporções de tamanho bem
inferiores a um desktop completo.
Mesmo com recursos comparáveis ao de uma estação de trabalho comum,
notebooks e laptops ainda não são a solução de mobilidade ideal, pois necessitam
quase sempre de uma base onde possam ser apoiados para operarem, possuem
baterias com duração pequena (aproximadamente três horas de uso ininterrupto), o
que faz com que o usuário esteja sempre em busca de um acesso a energia elétrica.
15
Já os Palmtops, resolvem alguns destes empecilhos, por serem semelhantes
aos notebooks e laptops, entretanto, mesmo assim, não correspondem a uma
experiência móvel confortável. Limitando ainda mais as capacidades de
processamento e armazenamento, bem como dificultando os métodos de entrada e
saída de dados.
2.2.2 PDAs (Personal Digital Assistants)
Um PDA típico, pode assumir as funções de um telefone celular, aparelho de
fax, Web browser e organizador pessoal. São conhecidos também como handhelds
(dispositivos de mão). Infelizmente devido ao tamanho reduzido, suas características
de processamento e armazenamento ficam comprometidas, assim como suas
opções de entrada e saída nada confortáveis (os dados são inseridos com o auxílio
de uma caneta e um software para reconhecimento de escrita, por exemplo).
Estes aparelhos têm como objetivo real, substituir agendas eletrônicas,
oferecendo recursos mais avançados para este propósito e agregar serviços de
telefonia, fax, Internet, em um único dispositivo. Seu uso também pode ser
observado em linhas de montagem ou restaurantes, onde simples softwares para
conferência e controle podem ser facilmente utilizados para automatizar serviços em
um ambiente onde não há espaço físico para suportar uma estação de trabalho.
Imagine um garçom anotando seu pedido em um notebook apoiado sobre os pratos
de sua mesa.
Os PDAs são reconhecidos por proporcionar entretenimento multimídia com
qualidade muito satisfatória, reproduzindo vídeos e áudio, batendo fotos, etc.
As baterias também figuram como problema nestes dispositivos, mas agora
sua duração pode ir de muitas horas até alguns dias.
16
2.2.3 Celulares
Desenvolvidos inicialmente com o único propósito de levar a comunicação
além das barreiras da telefonia fixa convencional, os celulares chegaram para
transpor barreiras e permitir que qualquer indivíduo em qualquer lugar do planeta,
possa comunicar-se com qualquer outro indivíduo em um ponto qualquer do globo.
Entretanto, com o avanço tecnológico e a evolução das gerações da telefonia celular
estes aparelhos adquiriram um novo status no qual passam a figurar como
dispositivos capazes de processamento e armazenamento de dados, principalmente
junto a Internet, conforme tabela 1.
Geração 1G 2G 2,xG 3G 4G
Transmissão de Dados Analógica (AMPS);
Transmissão Digital de Dados (TDMA, CDMA e GSM);
Disponibilização de aplicações pré-3G
Evolução CDMA e GSM;
Elevação das taxas de transmissão de dados;
Taxas de 9600bps
Taxas de 9600bps a 14400bps;
Taxas de até 2Mbps;
Características
Surgimento de aplicações WAP.
Surgimento de aplicações multimídia.
Tecnologias e aplicações ainda em discussão.
Quadro 1 – Gerações da telefonia celular Fonte: Figueiredo e Nakamura, 2003, p.19
As características e problemas apresentados pelos celulares assemelham-se
com as citadas nos PDAs. Porém, com um revés a mais, a interação com o
dispositivo é ainda maior, limitando-se na maioria dos casos, as teclas do aparelho.
A solução parece ter sido incorporar aos telefones celulares as funções de um PDA,
17
gerando assim um novo dispositivo reconhecido pelo nome de Smartphone. É
apostando no custo reduzido destes aparelhos e nos serviços por eles oferecidos
que procura-se realizar uma experiência móvel de qualidade e de uso satisfatório.
2.3 Protocolos de comunicação sem fio
São duas as principais tecnologias para redes sem fio, que têm sido
utilizadas em soluções de computação móvel, o padrão IEEE 802.11 (redes infra-
estruturdas) e o padrão Bluetooth (redes AdHoc).
a) IEEE 802.11: O IEEE (Institute of Electrical and Electronics Engineers Inc.) é o
órgão responsável por padronizar as camadas físicas e de enlace para redes sem
fio. Seu padrão, o 802.11 ou Wi-Fi como também é chamado, em sua concepção
original, prevê velocidades de operação de 1 e 2Mbps, já a versão 802.11b,
proporciona velocidades de até 11Mbps, e por fim, a versão 802.11g, sugere
velocidades de até 54Mbps. Mecanismos de autenticação e criptografia são
suportados através do WEP (Wired Equivalent Privacy), entretanto por motivos de
falta de segurança, estuda-se a adoção de uma nova versão, o WPA (Wi-Fi
Protected Access). É a tecnologia ideal para substituir infra-estrutura cabeada.
b) Bluetooth: Padronizado pelo Bluetooth SIG, que é composto por empresas tais
como Lucent, Microsoft, IBM, Intel, Motorola, Toshiba, Nokia e mais de outras
2000 companhias, o Bluetooth é um sistema para comunicações de pequeno
alcance (menos de 10 metros). Surgiu da necessidade de se eliminar cabos de
conexão entre equipamentos. Fazendo uso de micro-rádios embutidos em um
chip, e utilizando uma tecnologia denominada transmissão por salto de freqüência,
é capaz de operar na faixa de freqüência de 2,4 Ghz. Opera no modo “full duplex”,
18
recebe e envia ao mesmo tempo, e possui taxas de transferência de até 1Mbps
com baixo consumo de energia. Promete tornar-se padrão de mercado devido as
possibilidades de aplicação e por ser suportado por dispositivos de diversos
fabricantes.
2.4 Java 2 Micro Edition – J2ME
Basicamente J2ME é um termo que refere-se a uma coleção de APIs e
máquinas virtuais que tornam possível o uso de Java em dispositivos móveis. Com o
J2ME é possível levar ao mundo dos dispositivos móveis, os benefícios da
tecnologia Java, como flexibilidade na interface com o usuário, um modelo de
segurança eficaz, suporte a diferentes tipos de aplicações , entre outros.
A plataforma J2ME está presente na maioria dos dispositivo móveis atuais,
facilitando ao usuário a aquisição de novos serviços e mais inteligentes. Assim, a
plataforma J2ME segue como propenso padrão a ser adotado no desenvolvimento
de aplicações mobile.
2.4.1 Arquitetura J2ME
Toda a arquitetura J2ME define, configurações, perfis e pacotes opcionais,
como elementos de uma aplicação Java completa. Assim, a plataforma é capaz de
atender aos requerimentos de diferentes dispositivos e mercados.
Cada combinação destes elementos otimiza a capacidade de
processamento, armazenamento e interfaces de entrada e saída para cada
dispositivo particularmente. O resultado é uma plataforma de desenvolvimento Java
comum, capaz de atender a diferentes tipos de equipamentos e fabricantes.
19
Figura 1 – Plataforma J2ME Fonte: Sun Microsystems, 2005
2.4.2 Configurações
As configurações consistem de uma máquina virtual e de um pequeno
conjunto de classes. Este conjunto provê as funcionalidades básicas de uma faixa
de dispositivos que compartilham características como conexão de rede e
gerenciamento de memória. Existem duas configurações em J2ME:
a) Connected Limited Device Configuration (CLDC): a menor das duas
configurações. Desenvolvida para dispositivos com conexões de rede
20
intermitentes, processadores lentos e memória limitada. Usada em dispositivos
com CPUs de 16 ou 32 bits e com no mínimo de 128KB a 512KB de memória
disponível para suportar a plataforma Java e aplicações associadas. Os
equipamentos que costumam utilizar esta configuração são os telefones celulares,
PDAs e pagers.
b) Connected Device Configuration (CDC): esta configuração é disponibilizada em
dispositivos mais robustos, com CPUs de 32 bits ou mais e com no mínimo 2Mb
de memória disponível. Encontra-se em PDAs de alta perfomance, gateways
residenciais entre outros. Nesta configuração tem-se uma máquina virtual Java
completa, bem como muito mais recursos do J2SE.
2.4.3 Perfis
Para proporcionar uma solução completa, as configurações devem estar
vinculadas a APIs de alto nível, ou a perfis, para ser possível definir o modelo de
ciclo de vida da aplicação, a interface com o usuário e o tipo de acesso a
dispositivos específicos. Assim, tem-se como principais perfis os que seguem:
a) Mobile Information Device Profile (MIDP): desenvolvido para telefones celulares e
PDAs. Oferece o núcleo de funcionalidades requeridas por aplicações móveis,
incluindo interface com usuário, conectividade, armazenamento e gerenciamento
da aplicação. O MIDP em conjunto com o CLDC, representa uma solução
completa que maximiza as capacidades do dispositivo e minimiza o consumo de
memória e energia.
b) Foundation Profile (FP): este é o perfil de mais baixo nível para o CDC. Ele
permite uma implementação do CDC em sistemas embarcados sem o uso de
interface com o usuário. Em caso de necessidade de implementar uma interface
21
com o usuário, este perfil pode ser combinado com outros dois, o Personal Profile
e o Personal Basis Profile.
c) Personal Profile (PP): utilizado em dispositivos que exigem uma GUI completa ou
suporte a applets para internet, como PDAs de alta perfomance e consoles de
vídeo game. Inclui todas as libraries do AWT (Java Abstract Window Toolkit).
d) Personal Basis Profile (PBP): é um subconjunto do perfil Personal Profile. Provê
suporte a aplicações network-connected em dispositivos que suportam gráficos
em nível básico ou que requeiram o uso de ferramentas gráficas específicas.
Exemplos, tv set-top boxes, quiosques de informações e outros.
2.4.4 Pacotes
A plataforma J2ME pode ser estendida combinando-se vários pacotes
opcionais com CLDC ou CDC e seus perfis. Criados para mercados específicos,
vários pacotes apresentam APIs defaults para uso em tecnologias conhecidas e
tecnologias em desenvolvimento ou expansão, como o suporte a Bluetooth, Web
services, etc. Assim, os fabricantes de dispositivos podem inserir em seus produtos
os pacotes necessários para suportar as funcionalidades oferecidas por seus
dispositivos.
2.5 ECLIPSE
Criado pela extinta OTI (Object Technology International), famosa por sua
tecnologia de orientação a objetos para Smalltalk e Java, o Eclipse apresenta um
novo modelo de software open source. Com a aquisição da OTI pela IBM, o
lançamento do Eclipse deu-se com o anúncio da doação de quarenta milhões de
22
dólares (valor estimado da versão 1.0 do Eclipse) da IBM para a comunidade open
source, sob uma licença open source (a CPL). Desta forma, o Eclipse tornou-se um
dos principais exemplos de softwares open source com estrutura de softwares
proprietários. Outros casos que podem ser citados são: Linux, MySQL (MySQL AG),
NetBeans e OpenOffice (Sun), entre outros.
O projeto Eclipse fez com que o modelo “livre+comercial” chegasse a uma
nova ordem de grandeza, pois nunca um software open source obteve tanto
investimento e de forma continuada.
Os objetivos do projeto são sem fins lucrativos, descrevendo um modelo
muito semelhante a iniciativas de organismos responsáveis por padronizações como
a OMG ou a W3C. Entretanto, órgãos como a OMG e o W3C, produzem apenas
especificações, já a Fundação Eclipse cria produtos. Assim, surge uma nova
tendência na evolução do open source.
2.5.1 Plataforma Eclipse
O Eclipse costuma ser visto como apenas uma IDE Java. E efetivamente, é
este papel que presta o principal pacote oferecido pela plataforma, o Eclipse SDK.
Porém, o objetivo real e concreto da plataforma, é oferecer suporte a criação de
diversas ferramentas.
Com um microkernel capaz de gerenciar plug-ins, toda a funcionalidade real
da ferramenta é fornecida por essas extensões. Baseado nesta afirmação, a
plataforma adquire uma arquitetura peculiar, a qual é melhor explorada no item a
seguir.
23
2.5.2 Arquitetura
Os principais componentes da arquitetura do Eclipse podem ser
contemplados na figura a seguir.
Figura 2 – Arquitetura Eclipse Fonte: Java Magazine, 2005
A plataforma é o “coração” dos IDEs. Os plug-ins assinalados em amarelo,
são específicos da linguagem Java, dependentes do JDT o compilador Java utilizado
pelo Eclipse, direta ou indiretamente.
Segue uma breve descrição dos principais componentes da arquitetura:
a) Runtime de plataforma: é o responsável por inicializar e gerenciar plug-ins. É o
programa principal.
b) Workspace: gerente de recursos (arquivos e diretórios). Do ponto de vista do
usuário final, mostra-se como uma estrutura de diretórios que contém os projetos
24
do Eclipse. Cabe ao Workspace então, gerenciar esta estrutura de diretórios,
implementando recursos como marcadores, além de projetos e eventos de
alteração de recursos (que são utilizados pelo componente Team para
manutenção do histórico local e pelos compiladores para compilação incremental).
O uso de GUIs (interfaces gráficas), não é usado em momento algum nestes
processos.
c) SWT e JFace: são de toolkits de GUI. O toolkit principal é o SWT, cabendo ao
JFace, o papel de framework MVC que permite programação de alto nível.
d) Workbench: implementa as entidades básicas de GUI, como a estrutura de
Perspectivas, Views e Editores, menus, caixas de configuração, e outros recursos
genéricos de interfaces gráficas. Oferece suporte a todas as funcionalidades de
GUI do Workspace.
e) Team: realiza o controle de versões e histórico de alterações de recursos. Não
oferece suporte a um gerenciador de versões específico, mas possui subsídios
para que plug-ins possam ser criados para qualquer gerenciador. Estende o
Workspace para gerar versionamento local de recursos, sem utilizar servidor de
repositório.
f) Debug: define a arquitetura, conceitos e suporte GUI fundamentais para
depuração de programas, tais como, processos, breakpoints, visualização de
variáveis, filtros, etc.
g) Help: compõe-se de um servidor e um visualizador de help próprios, que permite
construir help on-line a partir de conteúdo HTML. Recursos como pesquisa,
navegação e indexação também são providos pelo Help.
h) Update: onde ocorre o gerenciamento de atualizações automáticas.
25
2.5.3 IDEs
A plataforma Eclipse oferece diversos IDEs para diferentes tipos de
desenvolvimento. Assim, para construção deste projeto, foi necessário a escolha e
utilização de algumas possibilidades oferecidas pela plataforma. A seguir, segue
uma lista com os principais IDEs e ferramentas oferecidas pelo Eclipse, com
destaque para as utilizadas neste projeto.
a) JDT (Java Development Tooling): é a parte do projeto Eclipse mais conhecida. O
JDT é o IDE para aplicações Java. Possui suporte aos projetos Java, edição e
compilação dos fontes, depuração de aplicações, assistentes para criação de
classes e interfaces e etc. Para a concepção deste projeto foi esta a IDE Eclipse
utilizada.
b) PDE (Plug-in Development Environment): esta IDE suporta a criação de plug-ins
para o Eclipse em Java. Oferece assistentes para criação dos plug-ins, editores
para configuração dos mesmos, deployment, gerador de testes, entre outros.
c) CDT (C/C++ Development Tools): viabiliza a construção de projetos para as
linguagens C/C++. Atualmente esta IDE é voltada para a plataforma Linux e
ferramentas GNU.
d) AJDT (Aspect Development Tools): implementa suporte a Programação Orientada
a Aspectos (AOP).
e) COBOL: como pode-se esperar pelo nome, esta IDE traz suporte a antiga
programação praticada nos mainframes, o COBOL.
Na figura a seguir, é possível se ter uma idéia de como a plataforma Eclipse
apresenta-se graficamente, a imagem traz o IDE AJDT em funcionamento.
26
Figura 3 – IDE AJDT do Eclipse Fonte: Java Magazine, 2005
2.6 Virtual Network Computing – VNC
O VNC foi criado pelo Laboratório de Pesquisas da Olivetti & Oracle. No ano
de 1999, a AT&T adquiriu o laboratório, e posteriormente em 2002, fechou a divisão
de pesquisas do mesmo. Seu nome deriva de um computador com rede ATM
chamado Videotile, que consistia apenas de um LCD com uma caneta e uma rápida
conexão de rede ATM. Assim o VNC é essencialmente uma versão deste
computador.
Com o VNC, é possível controlar remotamente uma estação de trabalho
apenas com o uso de um simples programa cliente ou visualizador como também é
27
chamado. Outra característica interessante é o fato de não ser necessário que os
dispositivos utilizados (cliente – servidor) sejam do mesmo tipo e/ou possuam
mesmo sistema operacional.
Figura 4 – Acesso remoto com VNC
Fonte: Real VNC, 2005
Um software de controle remoto como o VNC, possui uma gama muito
grande de benefícios, pois torna possível controlar uma estação de trabalho através
de uma rede seja ela fixa ou sem fio, como se o indivíduo estivesse operando
pessoalmente a estação acessada remotamente.
Como destaque de uso pessoal desta ferramenta, pode-se imaginar o
seguinte cenário: auxiliar ou realizar uma tarefa de atualização de software na
estação de trabalho de uma pessoa que mora em um outro país. Com o uso do
VNC, é possível que você mesmo realize a tarefa no computador da pessoa que
28
solicitou auxílio, enquanto esta acompanha todos os passos em frente seu
computador, como se ela mesma estivesse realizando todo o procedimento.
Existem dezenas de implementações deste conceito, utilizando o mesmo
protocolo (RFB - vide seção 3.2 adiante), o que permite a interoperação de clientes e
servidores de versões/origem distintas. São exemplos de implementações do VNC
os seguintes softwares:
a) realVNC [http://www.realvnc.com/]: programa original.
b) tightVNC [http://www.tightvnc.com/]: otimizado para low-bandwidth.
c) tridiaVNC [http://www.tridiavnc.com/]: mais opções de gerenciamento.
d) ultraVNC [http://www.ultravnc.com/]: possui vários extras, transferência de
arquivos, chat, drivers de vídeo, etc.
e) win2VNC [http://sourceforge.net/projects/win2vnc/]: um desktop virtual entre duas
estações de trabalho.
Assim, por constatar as facilidades que tal software proporciona, esta
pesquisa propõe-se à apresentar uma solução cliente para ser embarcada em
dispositivos móveis, para propiciar as facilidades oferecidas pelo VNC com a
liberdade e facilidade de operar-lo através de um equipamento móvel.
29
3 JNC MOBILE - SISTEMA DE ACESSO REMOTO PARA
DISPOSITIVOS MÓVEIS
3.1 Descrição do sistema
O JNC Mobile, tem como proposta, apresentar um software cliente para
dispositivos móveis capaz de controlar remotamente uma estação de trabalho ou
outro dispositivo móvel, que esteja configurado com um servidor VNC e com um
servidor Bridge escrito em Java, que realizará a comunicação entre as aplicações
cliente e servidor VNC.
Figura 5 – Acesso remoto através de dispositivo móvel Fonte: Elaborada pelos autores, 2005
O dispositivo móvel escolhido para a implementação e testes do software foi
um telefone celular. Ainda, devido a não padronização entre os diferentes
fabricantes de celulares, a Nokia foi escolhida como fabricante para realização dos
testes em aparelhos emulados.
Como o servidor VNC é fornecido apenas em linguagem C++, e todo o
projeto visa o uso da tecnologia Java, e o conhecimento dos desenvolvedores em
C++ não é satisfatório, a solução encontrada foi o desenvolvimento de um servidor
na linguagem Java, onde as requisições do cliente são recepcionadas por este
30
servidor bridge e encaminhadas ao servidor VNC. Desta forma também foi obtida
uma certa liberdade de como os dados devem chegar ao servidor VNC,
possibilitando o tratamento de requisições e desvios de controle por parte do
servidor bridge.
Figura 6 – Acesso remoto através de dispositivo móvel com servidor bridge Fonte: Elaborada pelos autores, 2005
As requisições recebidas pelo servidor bridge são passadas ao servidor VNC
através do Protocolo RFB (Remote Frame Buffer). Por sua vez, o servidor VNC
retorna ao bridge o status (imagem) do desktop, e este encarrega-se de transmitir a
informação ao dispositivo móvel.
O servidor bridge acumula além da responsabilidade de tradutor entre o
programa cliente e o servidor VNC, a função de compactação da imagem enviada ao
cliente.
Figura 7 – Compactação da imagem enviada ao cliente Fonte: Elaborada pelos autores, 2005
31
A imagem fornecida pelo servidor – PC – é capturada pelo – Bridge – que
verifica as coordenadas que estão sendo requisitadas pelo dispositivo móvel e as
converte para que estas possam ser exibidas na tela. Por exemplo: o celular envia,
após efetuar conexão, comandos de zoom mais e comandos de mudança de
posição da tela, ao receber a requisição, o servidor Bridge captura a tela do PC,
“corta” a parte que o cliente requisitou e redimensiona para o tamanho da tela do
dispositivo móvel.
Assim, conclui-se o processo cliente – servidor bridge – servidor VNC.
3.2 RFB Protocol
O protocolo RFB (Remote Frame Buffer) foi desenvolvido pela AT&T para
ser usado em seu programa de Virtual Networking Computer (VNC), porém
atualmente, vários outros programas utilizam-se do protocolo RFB para interagir com
servidores VNC.
O princípio básico do protocolo RFB é:
- Desenhe uma imagem a partir das coordenadas 0,0 até as coordenadas x,x.
Para otimizar a tarefa principal que o protocolo RFB se propõe a realizar, é
disponibilizado um conjunto de diretivas que possibilitam configurar o tipo de
codificação e compactação em que a imagem será transmitida e exibida.
3.2.1 Entrada
O protocolo entende que A “Entrada” de dados será baseada em teclado e
mouse de dois botões, portanto, para enviar eventos de teclado e mouse é
necessário que se implemente tal interface.
32
No caso de dispositivos móveis que não possuem estes recursos, é
necessário emulá-los a partir de recursos disponíveis, ou seja, o teclado numérico e
as teclas de direção. Para deixar o software mais compatível com outros dispositivos
móveis, optou-se por não utilizar as teclas de direção, e sim, emulá-las através das
teclas numéricas.
3.2.2 Representação dos pixels
Logo após a autenticação do cliente, o servidor verifica qual o tipo de
codificação será utilizada, para isso o protocolo RFB oferece 5 tipos de codificações:
Raw Encoding, Copy Rectangle Encoding, RRE encoding, CoRRE encoding e
Hextile encoding, porém apenas duas são relevantes para o trabalho em questão.
3.2.3 Raw Encoding
Consiste em escrever linha por linha os pixeis da imagem, é a forma mais
demorada (n x n pixels = n * n operações), porém é a mais simples.
3.2.4 Copy Rectangle Encoding
Desenha apenas as partes da imagem que foram modificadas, por exemplo:
- Redesenhe apenas o retângula x=15, y=15, largura =40, altura=30.
3.2.5 Mensagens de protocolo
O protocolo RFB fornece um sistema de mensagens que permitem os
programas se comunicarem de forma simples e segura, o funcionamento de um
33
programa que se conecta à um servidor VNC consiste em basicamente dois
estágios:
a) Fase de Conexão ou Handshaking: consiste em verificar a versão do protocolo,
autenticação, inicialização do cliente e inicialização do servidor.
b) Fase normal de processamento: é nesta fase que são enviadas mensagens
cliente-servidor, todas as mensagens contém o tipo de dados e o conteúdo da
mensagem propriamente dito.
As diretivas do protocolo RFB tiveram que ser parcialmente implementadas
pela equipe deste projeto para que o servidor bridge (em JAVA) tivesse a
possibilidade de acessar os comando e ler as informações vindas do Servidor VNC.
Foram utilizadas também, algumas classes JAVA disponibilizadas na internet:
a) RFBProtocol.java [http://www.tightvnc.com]: classe que implementa o protocolo
entre o servidor Bridge e o servidor VNC.
b) DesCipher.java [http://www.acme.com]: utilizada para cifrar a senha enviada ao
servidor VNC pelo servidor Bridge .
c) AnimatedMemoryImageSource.java [http://www.tightvnc.com]: responsável por
manipular a imagem enviada pelo servidor VNC.
Todas estas classes são regidas pela GPL (General Public License),
atestando assim seu uso livre.
3.2.6 Diretivas do protocolo auxiliar
Um protocolo auxiliar teve de ser implementado para que o dispositivo móvel
tivesse acesso ao servidor bridge, sendo assim algumas diretivas foram definidas e
lidas pelo programa através de variáveis statics do JAVA:
34
Quadro 2 – Diretivas do protocolo auxiliar Fonte: Elaborado pelos autores, 2005
3.3 Desenvolvimento da aplicação
Para o desenvolvimento desta aplicação foram criados dois aplicativos, um
servidor, que deve ser instalado na estação de trabalho a ser controlada
remotamente, e um cliente, instalado no dispositivo móvel. A seguir segue uma
descrição mais apurada destas aplicações.
35
3.3.1 Programa servidor
Esta parte da aplicação deve ser instalada na máquina que se deseja
controlar remotamente. Na seqüência é apresentada uma figura com as classes que
compõe a aplicação servidor.
Figura 8 - Programa servidor
Fonte: elaborada pelos autores, 2005.
Breve descrição das funcionalidades de cada classe:
a) DP: contém apenas constantes do protocolo auxiliar implementado pela equipe,
esta classe deve ser igual para os dois programas – cliente, servidor – para que
não haja conflitos de ações entre os programas.
b) RFBProtocol: classe adaptada de versão encontrada na internet, serve para
comunicar-se com o servidor VNC original, contém programação de baixo nível
(bytes, hexadecimal, deslocamento de bits).
c) TratadorDeComandos: funciona como um processador de protocolo de ações do
cliente, tratando e devolvendo os dados requisitados, é nesta classe que é
utilizado o protocolo auxiliar.
d) PainelDeAutenticacao: classe de Interface com o usuário, contém os campos para
entrada de dados como: endereço do servidor, porta, senha, etc...
e) AnimatedMemoryImageSource: classe adaptada que facilita o redimensionamento
de imagens.
36
f) DesCipher: classe para a cifragem de senha.
g) Log: utilizado principalmente na fase de desenvolvimento para acompanhar as
ações que estavam sendo realizadas, é uma boa alternativa quando o debug não
é necessário.
h) TratadorDeImagem: utilizada para tratamento da imagem recebida do servidor, o
objeto criado a partir desta classe gerencia a posição e o ZOOM que deve ser
levado em conta na hora de fornecer a imagem ao cliente.
i) TratadorDoMouse: classe utilizada pelo tratador da imagem para calcular o
redimensionamento e posicionamento da imagem, a cada ação no celular o
tratador de mouse é acionado para informar que houve uma mudança na posição
ou no zoom da figura.
3.3.2 Programa cliente
Através desta aplicação é que o dispositivo acessa remotamente o programa
servidor instalado na estação de trabalho alvo. A exemplo da aplicação servidor,
segue a listagem de classes do programa e suas descrições.
Figura 9 - Programa cliente – Celular
Fonte: elaborada pelos autores, 2005.
37
Breve descrição das funcionalidades de cada classe:
a) Protocol: classe que sobre escreve a classe da J2ME do celular, é uma tentativa
de tornar a aplicação compatível com a MIDP 1.0, já que esta versão não suporta
sockets.
b) Conexao: responsável por manter a conexão com o servidor “ponte”, utiliza a
classe DP, implementando o protocolo auxiliar.
c) Cliente: contém a inicialização do programa, determina o tamanho da tela, e a
conexão a ser feita, atribui propriedades as telas.
d) Log: muito utilizado na fase de implementação, já que as ferramentas usadas para
desenvolvimento não possuíam um fácil debuger para J2ME.
e) Main: apenas para iniciar a aplicação, padrões para MIDP.
f) TelaAjuda: contém uma pequena figura com a explicação dos comandos.
g) TelaInicial: campos para entrada do endereço do servidor “ponte” e senha.
h) TelaPrincipal: contém a estrutura onde será exibida a tela do desktop
compartilhado.
3.3.3 Telas do sistema
A seguir estão as definições das teclas do celular, o que elas representam
para o servidor VNC:
38
Figura 10 – Teclas do celular para o servidor VNC Fonte: elaborada pelos autores, 2005.
Tela do VNC para celular – módulo PC:
Figura 11 - Tela do VNC para celular – módulo PC Fonte: elaborada pelos autores, 2005.
39
Na tela apresentada são informados os dados para que o Servidor VNC
fique disponível para os dispositivos móveis, a seguir a descrição dos campos:
a) Host VNC: Endereço IP ou nome do computador onde o servidor VNC se encontra
rodando, inclusive para acesso via PC.
b) Senha: Senha para acesso ao serviço VNC.
c) Porta: É a porta na qual está rodando o serviço VNC.
d) Senha externa: É a senha que terá que ser informada no celular para acessar o
serviço.
e) Porta externa: É a porta na qual rodará o serviço, a qual deverá ser informada no
celular.
Telas do VNC para celular – módulo J2ME - Celular:
Figura 12 - Telas do VNC para celular – módulo J2ME - Celular Fonte: elaborada pelos autores, 2005.
Tela onde são informados os dados para conexão com o computador que
disponibilizará o serviço VNC para dispositivos móveis, é nescessário informar o
endereço e a senha.
40
Figura 13 - Telas do VNC para celular – módulo J2ME - Celular Fonte: elaborada pelos autores, 2005.
Esta tela mostra a tela do computador que está com o serviço VNC rodando,
após a conexão é mostrada a tela completa, sem efeitos de ZOOM ou deslocamento
da tela.
Figura 14 - Telas do VNC para celular – módulo J2ME - Celular Fonte: elaborada pelos autores, 2005.
Nesta figura se observa a tela do computador remoto após serem enviados
alguns comandos de ZOOM e deslocamento de tela, facilitando assim a visualização
dos itens que estão disponíveis no computador.
41
Figura 15 - Telas do VNC para celular – módulo J2ME - Celular Fonte: elaborada pelos autores, 2005.
Tela do celular mostrando o computador remoto, neste caso foi utilizado
ZOOM máximo para exibição.
3.3.4 Diagrama de classes
Será apresentado a seguir o diagrama de classes para as aplicações cliente
e servidor.
42
a) Aplicação cliente:
Figura 16 – Classes da aplicação cliente Fonte: elaborada pelos autores, 2005.
43
b) Aplicação servidor:
Figura 17 – Classes da aplicação servidor Fonte: elaborada pelos autores, 2005.
44
Figura 18 – Classes da aplicação servidor Fonte: elaborada pelos autores, 2005.
45
3.3.5 Diagrama de seqüência UML
Figura 19 – Diagrama de seqüência UML Fonte: elaborada pelos autores, 2005.
3.3.6 Ambiente de desenvolvimento
Para o desenvolvimento da aplicação, o seguinte ambiente de programação
foi elaborado sobre um sistema operacional Windows XP:
a) J2SE (SDK) 1.5.0_02: esta é a plataforma Java fundamental. Neste pacote
encontram-se as classes Java necessárias para a criação do sistema, compilador
Java, a extensão J2ME, que evidentemente permite o uso de Java em aplicações
para dispositivos móveis, e outros requerimentos para desenvolvimento de
projetos em linguagem Java.
b) Wireless Toolkit 2.2 (WTK): Pode ser definido como uma “caixa de ferramentas”
para desenvolvimento de aplicações J2ME. O conjunto de serviços oferece:
ambiente para emulação, opções para otimização de desempenho,
documentação, exemplos de aplicações, etc.
46
c) VNC: uma versão free do VNC foi utilizada para servir de servidor principal.
Assim,o servidor Bridge criado na pesquisa realizou a interface entre o servidor
VNC e o cliente instalado no dispositivo móvel.
d) Eclipse 3.1: É a versão utilizada da plataforma Eclipse. O IDE escolhido foi o JDT,
como já foi explanado anteriormente. Apenas a ferramenta Eclipse já oferece um
total ambiente de programação, e com certeza foi um dos softwares utilizados que
mais contribuiu para o desenvolvimento rápido e eficaz do JNC Móbile. Segue
abaixo uma figura demonstrando o ambiente de desenvolvimento.
Figura 20 - Ambiente de programação Fonte: elaborada pelos autores, 2005.
47
4 TRABALHOS FUTUROS
Como trabalhos futuros, um grande número de opções pode ser explorado.
Entretanto, surge como mais claro para os autores, a abordagem dos seguintes
tópicos possíveis:
a) Possibilitar o cadastro de tarefas automáticas no servidor Bridge: ao instalar o
servidor bridge na estação de trabalho a ser controlada remotamente, o usuário
poderá cadastrar tarefas junto a esta máquina que posteriormente poderão ser
executadas pela aplicação cliente disponível no dispositivo móvel. Assim, tarefas
como shutdown, restart, ativar desfragmentador de disco, uma rotina de trabalho,
rodar anti-vírus, entre outras, poderá ser facilmente executadas com uma simples
seleção em um menu de tarefas da aplicação cliente. Com esta funcionalidade, a
experiência de uso do JNC se tornará muito mais amigável e interessante.
b) Permitir a entrada de texto a partir do cliente: com esta funcionalidade o usuário
será capaz de digitar palavras utilizando-se do teclado de seu aparelho móvel.
Assim, torna-se possível a escrita de textos ou comandos no servidor, apenas
digitando as letras da mesma maneira que se faz com a escrita de mensagens em
aparelhos celulares.
c) Construir um servidor completo em Java: infelizmente ainda é necessário para a
aplicação descrita nesta pesquisa, o uso de um servidor VNC escrito em C++.
Desta forma, o uso de um servidor bridge tornou-se indispensável. Então, como
trabalho futuro, espera-se que apenas um servidor seja requerido para o
funcionamento de todo o sistema, o que facilitaria sua instalação e configuração.
d) Implementar um protocolo genérico para controle remoto: como trabalho mais
audacioso, os pesquisadores propõe a implementação de um protocolo para
controle remoto genérico. Assim, um único protocolo poderia ser utilizado para
48
tratar o envio e recebimento de textos, imagens, comandos para dispositivos
diversos, como câmeras de vídeo, comandos para robôs domésticos, etc. Este
protocolo visaria tornar possível padronizar a utilização de recursos, agilizando o
trabalho de empresas de software no desenvolvimento de aplicações de caráter
remoto.
49
5 CONSIDERAÇÕES FINAIS
O mercado de dispositivos móveis está crescendo vertiginosamente. O
público foi acometido por uma onda de consumo onde todo equipamento ou serviço
deve ser móvel e de conectividade imediata. Aparelhos como DVDs, videogames,
computadores, assumiram novos conceitos ao serem miniaturizados e munidos de
conexão sem fios a diferentes tipos de mídia, seja esta a Internet ou outro
dispositivo. Desta forma, um novo tipo de relacionamento entre máquinas e a
sociedade está se formando. Para facilitar está transição, e dispor-se de maneira
competitiva e atual, os pesquisadores buscaram com êxito, conhecer e conceber
soluções para dispositivos móveis.
Objetivos como identificar qual tecnologia empregar para solução de
problemas móveis, foram prontamente atendidos ao definir-se o uso da tecnologia
Java 2 ME. Tecnologia que já vem embutida na maioria dos dispositivos móveis do
mercado e que visa marcar presença em mais de 90% destes dispositivos até 2007.
A escolha de aparelhos celulares para a concepção do sistema deu-se
principalmente a três fatores: são dispositivos genuinamente móveis; quando se trata
de se discutir dispositivos móveis, quase sempre são os primeiros a serem
lembrados como pertencentes a esta classe, estando assim fortemente ligados ao
que o público associa como solução móvel; era o dispositivo móvel ao alcance dos
pesquisadores para o desenvolvimento da pesquisa.
O uso de uma tecnologia nascida para realizar esta tarefa, como é o caso do
J2ME, e a utilização de ferramentas como o Wireless Toolkit da Sun, e o Eclipse,
somente não foram maiores facilitadores da pesquisa por conta da incompatibilidade
existente entre os aparelhos celulares. Este problema de padrões na indústria
50
parece estar se resolvendo com a iniciativa de atualização do profile do J2ME MIDP,
que agora figura em sua segunda versão. Entretanto, infelizmente não havia a
disposição para experimento neste trabalho um dispositivo móvel provido desta
funcionalidade. Vale lembrar que a incompatibilidade existe até mesmo entre
aparelhos do mesmo fabricante, dificultando ainda mais a criação e difusão de
soluções para dispositivos móveis como celulares.
Excluindo-se estes obstáculos, a pesquisa alcançou seus objetivos. A
implementação de um sistema para acesso remoto via dispositivos móveis foi
realizada com sucesso. Os pesquisadores tornaram possível o controle de uma
estação de trabalho utilizando-se apenas um simples aparelho celular. Desta
maneira, um imprevisto que clame por um acesso a uma máquina, devidamente
ligada e conectada a Internet e com o JNC disponível, pode facilmente ser acessada
de qualquer local e com a maior discrição possível atualmente, fazendo com que seu
usuário manipule apenas seu simples aparelho telefônico.
É importante lembrar que a fluidez do uso da aplicação é fortemente
comprometido por limitações de acessibilidade impostas pelos aparelhos celulares,
dispõe-se apenas das teclas do aparelho, e o visor reduzido também torna a
visualização de um desktop completo um desafio. Mas como caráter principalmente
acadêmico que tem esta pesquisa, e com o alcance dos objetivos almejados pelos
pesquisadores, é com satisfação que se apresenta o JNC Mobile como uma solução
real para acesso remoto para dispositivos móveis.
51
REFERÊNCIAS
AN INTRODUCTION to J2ME. Wikipedia. Disponível em:
<http://en.wikipedia.org/wiki/An_Introduction_to_J2ME> Acesso: 27 mar. 2005.
CARNIEL, Juliano D.; KÜHL, Daniel. J2ME: como começar? Web Móbile. Rio de
Janeiro. Ano 1. ed. 2. p. 58-66. Mar. 2005.
DOEDERLEIN, Osvaldo. O projeto Eclipse: arquitetura, subprojetos, planos e
ferramentas. Java Magazine. Rio de Janeiro. Ano 3. ed. 23. p. 28-44. abr. 2005.
FIGUEIREDO, Carlos M. S.; NAKAMURA, Eduardo. Computação móvel: novas
oportunidades e novos desafios. T&C Amazônia. Ano 1. n. 2. Jun. 2003.
GIL, Antônio Carlos. Como elaborar projetos de pesquisa. 3 ed. São Paulo: Atlas,
1991.
JAVATM 2 Platform, Micro Edition. Sun Microsystems. Disponível em:
<http://java.sun.com/> Acesso: 27 mar. 2005.
JAVA 2 Platform, Micro Edition (J2ME); JSR 68 Overview. Sun Microsystems.
Disponível em: <http://java.sun.com/> Acesso: 27 mar. 2005.
META VNC - a window aware VNC. Meta VNC. Disponível em:
<http://metavnc.sourceforge.net/> Acesso: 27 mar. 2005.
52
MOBILE Information Device Profile (MIDP); JSR 37, JSR 118 Overview. Sun
Microsystems. Disponível em: <http://java.sun.com/products/midp/> Acesso: 27
mar. 2005.
TAUBER, Daniel. What's J2ME? OnJava. 2001. Disponível em:
<http://www.onjava.com/pub/a/onjava/2001/03/08/J2ME.html> Acesso: 27 mar. 2005.
THE J2ME Frequently Asked Questions List. BellSouthpwp. Disponível em:
<http://bellsouthpwp.net/m/c/mcpierce/j2mefaq.html> Acesso: 27 mar. 2005.
VIRTUAL Network Computing. Wikipedia. Disponível em:
<http://pt.wikipedia.org/wiki/Virtual_Network_Computing> Acesso: 27 mar. 2005
WHAT is VNC. RealVNC. Disponível em: <http://www.realvnc.com/what.html>
Acesso: 27 mar. 2005.
APÊNDICES
APÊNDICE A – Código Fonte da Aplicação Cliente
123456789
10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package rede;
import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import javax.microedition.io.Connector;import javax.microedition.io.HttpConnection;import javax.microedition.lcdui.Image;import ui.Log;import ui.TelaPrincipal;public class Conexao extends Thread {
private int comando;private int largura;private int altura;private TelaPrincipal tela;private String host;private String senha;
public Conexao(String _host, String _senha) {host = _host;senha = _senha;
}
public void run() {iniciaValores();while (true) {
long numMillisecondsToSleep = 500; // 1/5 segundostry {
Thread.sleep(numMillisecondsToSleep);} catch (InterruptedException e) {
e.printStackTrace();}if (tela != null) {
atualizaTela();}
}}
public void iniciaValores() {HttpConnection c = null;InputStream input = null;try {
String urlConexao = host + "/" + largura + "x" + altura;Log.info(urlConexao);c = (HttpConnection) Connector.open(urlConexao,
Connector.READ_WRITE);c.setRequestMethod(HttpConnection.GET);Log.info("pass2");input = c.openInputStream();Log.info("pass3");
} catch (Exception e) {e.printStackTrace();
} finally {if (input != null)
try {input.close();
} catch (IOException e) {e.printStackTrace();
}if (c != null)
try {c.close();
} catch (IOException e) {e.printStackTrace();
}}enviaComando(DP.INICIA_TRATADOR_DE_IMAGENS);atualizaTela();
}
public boolean alterou() {return true;
}
public void enviaComando(int _comando) {comando = _comando;
Conexao.java 5/7/2005 19:42
Page 1 of 3
7778798081828384858687888990919293949596979899
100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
}
public void atualizaTela() {try {
HttpConnection c;c = (HttpConnection) Connector.open(host + "/" + comando,
Connector.READ_WRITE);comando = DP.GET_IMAGEM;c.setRequestMethod(HttpConnection.GET);Log.info("pass2");InputStream input = c.openInputStream();Log.info(c.getType());Log.info("pass3");Image im;tela.setImagem(getImage(input));tela.repaint();c.close();
} catch (Exception e) {e.printStackTrace();
}}
private Image getImage(InputStream iStrm) throws IOException {Image im = null;try {
Log.info("carregando imagem");int bufferSize = 256;byte byteInput[] = new byte[bufferSize];ByteArrayOutputStream imageBuffer = new ByteArrayOutputStream(1024);int size = 0;while ((size = iStrm.read(byteInput, 0, bufferSize)) != -1) {
Log.info("escrevendo");imageBuffer.write(byteInput, 0, size);
}// get byte from buffer streambyte byteImage[] = imageBuffer.toByteArray();Log.info("read byte " + byteImage.length);// convert byte to image ...im = Image.createImage(byteImage, 0, byteImage.length);return im;// ByteArrayOutputStream bStrm = new ByteArrayOutputStream();//// int ch;// while ((ch = iStrm.read()) != -1)// bStrm.write(ch);//// // Place into image array// byte imageData[] = bStrm.toByteArray();//// // Create the image from the byte array// Log.info(imageData.length);// im = Image.createImage(imageData, 0, imageData.length);
} catch (Exception e) {e.printStackTrace();
} finally {// Clean upif (iStrm != null)
iStrm.close();}return (im == null ? null : im);
}
public void fechar() {enviaComando(DP.FINALIZAR_CONEXAO);
}
public int getAltura() {return altura;
}
public void setAltura(int altura) {this.altura = altura;
}
public int getLargura() {return largura;
Conexao.java 5/7/2005 19:42
Page 2 of 3
153154155156157158159160161162163164165166
}
public void setLargura(int largura) {this.largura = largura;
}
public TelaPrincipal getTela() {return tela;
}
public void setTela(TelaPrincipal tela) {this.tela = tela;
}}
Conexao.java 5/7/2005 19:42
Page 3 of 3
123456789101112131415161718192021
package rede;
public class DP {public static final int INICIA_TRATADOR_DE_IMAGENS = 10;public static final int CONEXAO_OK = 11;public static final int GET_IMAGEM = 12;public static final int FINALIZAR_CONEXAO = 13;public static final int CMD_BT_MOUSE1 = 14;public static final int CMD_BT_MOUSE2 = 15;public static final int CMD_TELA_PARA_CIMA = 16;public static final int CMD_TELA_PARA_BAIXO = 17;public static final int CMD_TELA_PARA_DIREITA = 18;public static final int CMD_TELA_PARA_ESQUERDA = 19;public static final int CMD_MOUSE_PARA_CIMA = 20;public static final int CMD_MOUSE_PARA_BAIXO = 21;public static final int CMD_MOUSE_PARA_DIREITA = 22;public static final int CMD_MOUSE_PARA_ESQUERDA = 23;public static final int CMD_ZOOM_MAIS = 24;public static final int CMD_ZOOM_MENOS = 25;public static final int IMAGEM_RECEBIDA = 26;
}
DP.java 5/7/2005 19:42
Page 1 of 1
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package ui;
import javax.microedition.lcdui.Command;import javax.microedition.lcdui.CommandListener;import javax.microedition.lcdui.Display;import javax.microedition.lcdui.Displayable;import javax.microedition.midlet.MIDlet;import rede.Conexao;public class Cliente implements CommandListener {
private Display display;private Command cmOk;private Command cmVoltar;private Command cmSair;private Command cmAjuda;private Conexao conexao;private TelaAjuda telaAjuda;private TelaPrincipal telaPrincipal;private TelaInicial telaInicial;private MIDlet midletPrincipal;
public Cliente(Display d, MIDlet m) {midletPrincipal = m;display = d;startApp();
}
private void criaComandos() {cmOk = new Command("Ok", Command.SCREEN, 2);cmVoltar = new Command("Voltar", Command.BACK, 1);cmSair = new Command("Sair", Command.EXIT, 1);cmAjuda = new Command("Ajuda", Command.HELP, 2);
}
private void preparaTelas() {telaAjuda = new TelaAjuda("Ajuda");telaAjuda.addCommand(cmOk);telaAjuda.addCommand(cmVoltar);telaAjuda.setCommandListener(this);telaPrincipal = new TelaPrincipal();telaPrincipal.addCommand(cmSair);telaPrincipal.addCommand(cmAjuda);telaPrincipal.setCommandListener(this);telaInicial = new TelaInicial("Mobile VNC");telaInicial.addCommand(cmSair);telaInicial.addCommand(cmOk);telaInicial.setCommandListener(this);
}
public void startApp() {criaComandos();preparaTelas();display.setCurrent(telaInicial);
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void commandAction(Command comando, Displayable tela) {if (comando == cmVoltar) {
display.setCurrent(telaPrincipal);}if (comando == cmOk) {
if (telaAjuda.isShown()) {display.setCurrent(telaPrincipal);
}if (telaInicial.isShown()) {
iniciaConexao();}
}if (comando == cmAjuda) {
display.setCurrent(telaAjuda);}if (comando == cmSair) {
Cliente.java 5/7/2005 19:42
Page 1 of 2
7778798081828384858687888990919293
conexao.fechar();destroyApp(false);midletPrincipal.notifyDestroyed();
}}
private synchronized void iniciaConexao() {Log.info("Conectando em..." + telaInicial.getTxtEndereco().getString());conexao = new Conexao(telaInicial.getTxtEndereco().getString(),
telaInicial.getTxtSenha().getString());conexao.setLargura(telaPrincipal.getWidth());conexao.setAltura(telaPrincipal.getHeight());conexao.start();telaPrincipal.setConexao(conexao);display.setCurrent(telaPrincipal);
}}
Cliente.java 5/7/2005 19:42
Page 2 of 2
123456789101112
package ui;
public class Log {public synchronized static void info(String texto) {
// Log.info("Info: "+texto);}
public synchronized static void erro(String texto) {Log.info("Erro: " + texto);
}}
Log.java 5/7/2005 19:43
Page 1 of 1
123456789101112131415161718192021
package ui;
import javax.microedition.lcdui.Display;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;public class Main extends MIDlet {
public Main() {super();
}
protected void startApp() throws MIDletStateChangeException {Cliente c = new Cliente(Display.getDisplay(this), this);
}
protected void pauseApp() {}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {}
}
Main.java 5/7/2005 19:43
Page 1 of 1
12345678910111213141516171819
package ui;
import java.io.IOException;import javax.microedition.lcdui.Form;import javax.microedition.lcdui.Image;public class TelaAjuda extends Form {
public TelaAjuda(String nome) {super(nome);Image imagemDeAjuda = Image.createImage(5, 5);Log.info("Carregando imagem de ajuda");try {
imagemDeAjuda = Image.createImage("/ajuda.jpg");} catch (IOException e) {
e.printStackTrace();}Log.info("Finalizando carregamento");append(imagemDeAjuda);
}}
TelaAjuda.java 5/7/2005 19:43
Page 1 of 1
12345678910111213141516171819202122232425
package ui;
import javax.microedition.lcdui.Form;import javax.microedition.lcdui.TextField;public class TelaInicial extends Form {
private TextField txtEndereco;private TextField txtSenha;
public TelaInicial(String nome) {super(nome);txtEndereco = new TextField("Endereço", "http://192.168.152.38:8080",
40, TextField.ANY);txtSenha = new TextField("Senha", "testevnc", 8, TextField.ANY);append(txtEndereco);append(txtSenha);
}
public TextField getTxtEndereco() {return txtEndereco;
}
public TextField getTxtSenha() {return txtSenha;
}}
TelaInicial.java 5/7/2005 19:44
Page 1 of 1
123456789
10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package ui;
import javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Image;import rede.Conexao;import rede.DP;public class TelaPrincipal extends Canvas {
private Conexao conexao;private int keyCode;private boolean movimentaMouse;private Image imagem;
public TelaPrincipal() {imagem = Image.createImage(132, 100);
}
public void keyReleased(int keyCode) {this.keyCode = keyCode;
}
public void keyRepeated(int keyCode) {this.keyCode = keyCode;
}
public void keyPressed(int keyCode) {this.keyCode = keyCode;Log.info("codigo=" + keyCode);switch (keyCode) {case KEY_NUM1: // Clique botao esquerdo do mouse
enviaComando(DP.CMD_BT_MOUSE1);break;
case KEY_NUM2: // Movimenta tela/mouse para cimaif (movimentaMouse) {
enviaComando(DP.CMD_MOUSE_PARA_CIMA);} else {
enviaComando(DP.CMD_TELA_PARA_CIMA);}break;
case KEY_NUM3: // Clique botao direito do mouseenviaComando(DP.CMD_BT_MOUSE2);break;
case KEY_NUM4: // Movimenta tela/mouse para esquerdaif (movimentaMouse) {
enviaComando(DP.CMD_MOUSE_PARA_ESQUERDA);} else {
enviaComando(DP.CMD_TELA_PARA_ESQUERDA);}break;
case KEY_NUM5:break;
case KEY_NUM6: // Movimenta tela/mouse para direitaif (movimentaMouse) {
enviaComando(DP.CMD_MOUSE_PARA_DIREITA);} else {
enviaComando(DP.CMD_TELA_PARA_DIREITA);}break;
case KEY_NUM7: // Zoom menosenviaComando(DP.CMD_ZOOM_MENOS);break;
case KEY_NUM8: // Movimenta tela/mouse para baixoif (movimentaMouse) {
enviaComando(DP.CMD_MOUSE_PARA_BAIXO);} else {
enviaComando(DP.CMD_TELA_PARA_BAIXO);}break;
case KEY_NUM9: // Zoom maisenviaComando(DP.CMD_ZOOM_MAIS);break;
case KEY_NUM0: // Troca movimento de tela/mousemovimentaMouse = !movimentaMouse;break;
default:break;
TelaPrincipal.java 5/7/2005 19:44
Page 1 of 2
7778798081828384858687888990919293949596979899
100101102103104105
}}
public Conexao getConexao() {return conexao;
}
public void setConexao(Conexao conexao) {this.conexao = conexao;conexao.setTela(this);
}
protected void paint(Graphics g) {g.drawImage(imagem, 0, 0, Graphics.LEFT | Graphics.TOP);
}
private synchronized void enviaComando(int comando) {Log.info("Comando=" + comando);conexao.enviaComando(comando);
}
public Image getImagem() {return imagem;
}
public void setImagem(Image imagem) {this.imagem = imagem;
}}
TelaPrincipal.java 5/7/2005 19:44
Page 2 of 2
APÊNDICE B – Código Fonte da Aplicação Servidor
123456789101112131415161718192021
package app.rede;
public class DP {public static final int INICIA_TRATADOR_DE_IMAGENS = 10;public static final int CONEXAO_OK = 11;public static final int GET_IMAGEM = 12;public static final int FINALIZAR_CONEXAO = 13;public static final int CMD_BT_MOUSE1 = 14;public static final int CMD_BT_MOUSE2 = 15;public static final int CMD_TELA_PARA_CIMA = 16;public static final int CMD_TELA_PARA_BAIXO = 17;public static final int CMD_TELA_PARA_DIREITA = 18;public static final int CMD_TELA_PARA_ESQUERDA = 19;public static final int CMD_MOUSE_PARA_CIMA = 20;public static final int CMD_MOUSE_PARA_BAIXO = 21;public static final int CMD_MOUSE_PARA_DIREITA = 22;public static final int CMD_MOUSE_PARA_ESQUERDA = 23;public static final int CMD_ZOOM_MAIS = 24;public static final int CMD_ZOOM_MENOS = 25;public static final int IMAGEM_RECEBIDA = 26;
}
DP.java 5/7/2005 19:32
Page 1 of 1
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package app.rede;
import java.awt.image.BufferedImage;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;import app.util.Log;public class LeitorDeComando {
ServerSocket serverSocket = null;
public LeitorDeComando(int porta) {try {
serverSocket = new ServerSocket(porta, 100);} catch (IOException e) {
e.printStackTrace();System.exit(1);
}}
public void fechaFechaConexao() {if (serverSocket != null) {
try {serverSocket.close();
} catch (IOException e) {e.printStackTrace();
}}
}Socket socket = null;private OutputStream output = null;private Request request = null;
public int getComando() {InputStream input = null;Log.info("aguardando");try {
socket = serverSocket.accept();Log.info("conectado");input = socket.getInputStream();output = socket.getOutputStream();request = new Request(input);int comando = request.parse();return comando;
} catch (IOException e) {e.printStackTrace();
}return 0;
}
public TelaCelular getTelaCelular() {InputStream input = null;Log.info("aguardando");try {
socket = serverSocket.accept();Log.info("conectado");input = socket.getInputStream();output = socket.getOutputStream();request = new Request(input);TelaCelular tela = request.getTela();Response response = new Response(output);response.setRequest(request);response.enviaTelaDeBoasVinas();socket.close();return tela;
} catch (IOException e) {e.printStackTrace();
}return null;
}
public void enviaImagem(BufferedImage imagem) {try {
Response response = new Response(output);response.setRequest(request);
LeitorDeComando.java 5/7/2005 19:33
Page 1 of 2
7778798081828384
response.sendStaticResource(imagem);socket.close();
} catch (IOException e) {e.printStackTrace();
}}
}
LeitorDeComando.java 5/7/2005 19:33
Page 2 of 2
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
package app.rede;
import java.io.IOException;import java.io.InputStream;import app.util.Log;public class Request {
private InputStream input;private String uri;
public Request(InputStream input) {this.input = input;
}
public int parse() {StringBuffer request = new StringBuffer(2048);int i;byte[] buffer = new byte[2048];try {
i = input.read(buffer);} catch (IOException e) {
e.printStackTrace();i = -1;
}for (int j = 0; j < i; j++) {
request.append((char) buffer[j]);}uri = parseUri(request.toString());Log.info("uri=" + uri);int comando = Integer.parseInt(uri.toString().substring(1));return comando;
}
public TelaCelular getTela() {// Read a set of characters from the socketStringBuffer request = new StringBuffer(2048);int i;byte[] buffer = new byte[2048];try {
i = input.read(buffer);} catch (IOException e) {
e.printStackTrace();i = -1;
}for (int j = 0; j < i; j++) {
request.append((char) buffer[j]);}uri = parseUri(request.toString());Log.info("URI=" + uri);String[] valores = uri.substring(1).split("x");TelaCelular tela = new TelaCelular();tela.setLargura(Integer.parseInt(valores[0].trim()));tela.setAltura(Integer.parseInt(valores[1].trim()));return tela;
}
private String parseUri(String requestString) {int index1, index2;index1 = requestString.indexOf(' ');if (index1 != -1) {
index2 = requestString.indexOf(' ', index1 + 1);if (index2 > index1)
return requestString.substring(index1 + 1, index2);}return null;
}
public String getUri() {return uri;
}}
Request.java 5/7/2005 19:34
Page 1 of 1
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
package app.rede;
import java.awt.image.BufferedImage;import java.awt.image.RenderedImage;import java.io.ByteArrayOutputStream;import java.io.OutputStream;import javax.imageio.ImageIO;import app.util.Log;public class Response {
private static final int BUFFER_SIZE = 1024;Request request;OutputStream output;
public Response(OutputStream output) {this.output = output;
}
public void setRequest(Request request) {this.request = request;
}
public void sendStaticResource(BufferedImage imagemCelular) {int leido = 0;byte datosBytes[] = new byte[256];try {
String respuesta = "HTTP/1.0 200 OK\n";respuesta += "Date: Mon, 5 Nov 2008 23:59:59GMT\n";respuesta += "Content-Type: image/jpeg\n";respuesta += "\r\n";output.write(respuesta.getBytes());output.flush();Log.info("enviando imagem");ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write((RenderedImage) imagemCelular, "jpeg", baos);byte[] bytes = baos.toByteArray();ImageIO.write((RenderedImage) imagemCelular, "jpeg", output);System.out.println(output.toString());System.out.println("terminando envio");
} catch (Exception e) {e.printStackTrace();
}}
public void enviaTelaDeBoasVinas() {try {
String respuesta = "HTTP/1.0 200 OK\n";respuesta += "Date: Mon, 5 Nov 2008 23:59:59GMT\n";respuesta += "Content-Type: text/playn\n";respuesta += "\r\n";output.write(respuesta.getBytes());output.flush();String boasVinas = "Conectado!!!";output.write(boasVinas.getBytes(), 0, boasVinas.getBytes().length);output.flush();
} catch (Exception e) {e.printStackTrace();
}}
}
Response.java 5/7/2005 19:34
Page 1 of 1
123456789
10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
//Classe retirada do site http://www.tightvnc.com/ com licensa GPL//e modificada para atender as necessidades do programa//Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved.//Copyright (C) 2001,2002 Constantin Kaplinsky. All Rights Reserved.//Copyright (C) 2000 Tridia Corporation. All Rights Reserved.//Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.package app.rede;
import java.awt.Event;import java.awt.event.MouseEvent;import java.io.BufferedInputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;import app.util.DesCipher;public class RFBProtocol {
final String versionMsg = "RFB 003.003\n";final int ConnFailed = 0, NoAuth = 1, VncAuth = 2;final int VncAuthOK = 0, VncAuthFailed = 1, VncAuthTooMany = 2;private static final boolean COMPARTILHAR_DESKTOP = true;final static int FramebufferUpdate = 0, SetColourMapEntries = 1, Bell = 2,
ServerCutText = 3;final int SetPixelFormat = 0, FixColourMapEntries = 1, SetEncodings = 2,
FramebufferUpdateRequest = 3, KeyEvent = 4, PointerEvent = 5,ClientCutText = 6;
final static int EncodingRaw = 0, EncodingCopyRect = 1, EncodingRRE = 2,EncodingCoRRE = 4, EncodingHextile = 5;
final int HextileRaw = (1 << 0);final int HextileBackgroundSpecified = (1 << 1);final int HextileForegroundSpecified = (1 << 2);final int HextileAnySubrects = (1 << 3);final int HextileSubrectsColoured = (1 << 4);String vncHost;int vncPort;Socket sock;DataInputStream is;OutputStream os;public boolean inNormalProtocol = false;
//// Constructor. Just make TCP connection to RFB server.//public RFBProtocol(String vncHost, int vncPort) {
this.vncHost = vncHost;this.vncPort = vncPort;try {
sock = new Socket(vncHost, vncPort);is = new DataInputStream(new BufferedInputStream(sock
.getInputStream(), 16384));os = sock.getOutputStream();
} catch (UnknownHostException e) {e.printStackTrace();
} catch (IOException e) {e.printStackTrace();
}}
public void close() {try {
sock.close();} catch (Exception e) {
e.printStackTrace();}
}//// Read server's protocol version message//int serverMajor, serverMinor;
void readVersionMsg() throws IOException {byte[] b = new byte[12];is.readFully(b);if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ')
|| (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9')
RFBProtocol.java 5/7/2005 19:34
Page 1 of 8
7778798081828384858687888990919293949596979899
100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
|| (b[6] < '0') || (b[6] > '9') || (b[7] != '.')|| (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')|| (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) {
throw new IOException("Host " + vncHost + " port " + vncPort+ " is not an RFB server");
}serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');
}
public boolean connectAndAuthenticate(String password) throws IOException {boolean authenticationDone = false;readVersionMsg();System.out.println("RFB server supports protocol version "
+ serverMajor + "." + serverMinor);writeVersionMsg();switch (readAuthScheme()) {case NoAuth:
System.out.println("No authentication needed");authenticationDone = true;break;
case VncAuth:byte[] challenge = new byte[16];is.readFully(challenge);String pw = password;if (pw.length() > 8)
pw = pw.substring(0, 8); // truncate to 8 charsbyte[] key = new byte[8];pw.getBytes(0, pw.length(), key, 0);for (int i = pw.length(); i < 8; i++) {
key[i] = (byte) 0;}DesCipher des = new DesCipher(key);des.encrypt(challenge, 0, challenge, 0);des.encrypt(challenge, 8, challenge, 8);os.write(challenge);int authResult = is.readInt();switch (authResult) {case VncAuthOK:
System.out.println("VNC authentication succeeded");authenticationDone = true;break;
case VncAuthFailed:System.out.println("VNC authentication failed");break;
case VncAuthTooMany:throw new IOException("VNC authentication failed - "
+ "too many tries");default:
throw new IOException("Unknown VNC authentication result "+ authResult);
}break;
}return authenticationDone;
}
//// Write our protocol version message//void writeVersionMsg() throws IOException {
byte[] b = new byte[12];versionMsg.getBytes(0, 12, b, 0);os.write(b);
}
//// Find out the authentication scheme.//int readAuthScheme() throws IOException {
int authScheme = is.readInt();switch (authScheme) {case ConnFailed:
int reasonLen = is.readInt();byte[] reason = new byte[reasonLen];is.readFully(reason);
RFBProtocol.java 5/7/2005 19:34
Page 2 of 8
153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
throw new IOException(new String(reason, 0));case NoAuth:case VncAuth:
return authScheme;default:
throw new IOException("Unknown authentication scheme from RFB "+ "server " + authScheme);
}}
//// Do the rest of the protocol initialisation.//public void doProtocolInitialisation(int[] encodings, int nEncodings)
throws IOException {System.out.println("sending client init");writeClientInit();readServerInit();System.out.println("Desktop name is " + desktopName);System.out.println("Desktop size is " + framebufferWidth + " x "
+ framebufferHeight);setEncodings(encodings, nEncodings);
}
//// setEncodings() - send the current encodings from the options frame// to the RFB server.//void setEncodings(int[] encodings, int nEncodings) {
try {if (inNormalProtocol) {
writeSetEncodings(encodings, nEncodings);}
} catch (Exception e) {e.printStackTrace();
}}
//// Write the client initialisation message//void writeClientInit() throws IOException {
if (COMPARTILHAR_DESKTOP) {os.write(1);
} else {os.write(0);
}}//// Read the server initialisation message//public String desktopName;public int framebufferWidth, framebufferHeight;int bitsPerPixel, depth;boolean bigEndian, trueColour;int redMax, greenMax, blueMax, redShift, greenShift, blueShift;
void readServerInit() throws IOException {framebufferWidth = is.readUnsignedShort();framebufferHeight = is.readUnsignedShort();bitsPerPixel = is.readUnsignedByte();depth = is.readUnsignedByte();bigEndian = (is.readUnsignedByte() != 0);trueColour = (is.readUnsignedByte() != 0);redMax = is.readUnsignedShort();greenMax = is.readUnsignedShort();blueMax = is.readUnsignedShort();redShift = is.readUnsignedByte();greenShift = is.readUnsignedByte();blueShift = is.readUnsignedByte();byte[] pad = new byte[3];is.read(pad);int nameLength = is.readInt();byte[] name = new byte[nameLength];is.readFully(name);desktopName = new String(name, 0);
RFBProtocol.java 5/7/2005 19:34
Page 3 of 8
229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
inNormalProtocol = true;}
//// Read the server message type//int readServerMessageType() throws IOException {
return is.read();}//// Read a FramebufferUpdate message//int updateNRects;
void readFramebufferUpdate() throws IOException {is.readByte();updateNRects = is.readUnsignedShort();
}// Read a FramebufferUpdate rectangle headerint updateRectX, updateRectY, updateRectW, updateRectH, updateRectEncoding;
void readFramebufferUpdateRectHdr() throws IOException {updateRectX = is.readUnsignedShort();updateRectY = is.readUnsignedShort();updateRectW = is.readUnsignedShort();updateRectH = is.readUnsignedShort();updateRectEncoding = is.readInt();if ((updateRectX + updateRectW > framebufferWidth)
|| (updateRectY + updateRectH > framebufferHeight)) {throw new IOException("Framebuffer update rectangle too large: "
+ updateRectW + "x" + updateRectH + " at (" + updateRectX+ "," + updateRectY + ")");
}}// Read CopyRect source X and Y.int copyRectSrcX, copyRectSrcY;
void readCopyRect() throws IOException {copyRectSrcX = is.readUnsignedShort();copyRectSrcY = is.readUnsignedShort();
}
//// Read a ServerCutText message//String readServerCutText() throws IOException {
byte[] pad = new byte[3];is.read(pad);int len = is.readInt();byte[] text = new byte[len];is.readFully(text);return new String(text, 0);
}
//// Write a FramebufferUpdateRequest message//void writeFramebufferUpdateRequest(int x, int y, int w, int h,
boolean incremental) throws IOException {byte[] b = new byte[10];b[0] = (byte) FramebufferUpdateRequest;b[1] = (byte) (incremental ? 1 : 0);b[2] = (byte) ((x >> 8) & 0xff);b[3] = (byte) (x & 0xff);b[4] = (byte) ((y >> 8) & 0xff);b[5] = (byte) (y & 0xff);b[6] = (byte) ((w >> 8) & 0xff);b[7] = (byte) (w & 0xff);b[8] = (byte) ((h >> 8) & 0xff);b[9] = (byte) (h & 0xff);os.write(b);
}
//// Write a SetPixelFormat message//
RFBProtocol.java 5/7/2005 19:34
Page 4 of 8
305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
void writeSetPixelFormat(int bitsPerPixel, int depth, boolean bigEndian,boolean trueColour, int redMax, int greenMax, int blueMax,int redShift, int greenShift, int blueShift) throws IOException {
byte[] b = new byte[20];b[0] = (byte) SetPixelFormat;b[4] = (byte) bitsPerPixel;b[5] = (byte) depth;b[6] = (byte) (bigEndian ? 1 : 0);b[7] = (byte) (trueColour ? 1 : 0);b[8] = (byte) ((redMax >> 8) & 0xff);b[9] = (byte) (redMax & 0xff);b[10] = (byte) ((greenMax >> 8) & 0xff);b[11] = (byte) (greenMax & 0xff);b[12] = (byte) ((blueMax >> 8) & 0xff);b[13] = (byte) (blueMax & 0xff);b[14] = (byte) redShift;b[15] = (byte) greenShift;b[16] = (byte) blueShift;os.write(b);
}
//// Write a FixColourMapEntries message. The values in the red, green and// blue arrays are from 0 to 65535.//void writeFixColourMapEntries(int firstColour, int nColours, int[] red,
int[] green, int[] blue) throws IOException {byte[] b = new byte[6 + nColours * 6];b[0] = (byte) FixColourMapEntries;b[2] = (byte) ((firstColour >> 8) & 0xff);b[3] = (byte) (firstColour & 0xff);b[4] = (byte) ((nColours >> 8) & 0xff);b[5] = (byte) (nColours & 0xff);for (int i = 0; i < nColours; i++) {
b[6 + i * 6] = (byte) ((red[i] >> 8) & 0xff);b[6 + i * 6 + 1] = (byte) (red[i] & 0xff);b[6 + i * 6 + 2] = (byte) ((green[i] >> 8) & 0xff);b[6 + i * 6 + 3] = (byte) (green[i] & 0xff);b[6 + i * 6 + 4] = (byte) ((blue[i] >> 8) & 0xff);b[6 + i * 6 + 5] = (byte) (blue[i] & 0xff);
}os.write(b);
}
//// Write a SetEncodings message//void writeSetEncodings(int[] encs, int len) throws IOException {
byte[] b = new byte[4 + 4 * len];b[0] = (byte) SetEncodings;b[2] = (byte) ((len >> 8) & 0xff);b[3] = (byte) (len & 0xff);for (int i = 0; i < len; i++) {
b[4 + 4 * i] = (byte) ((encs[i] >> 24) & 0xff);b[5 + 4 * i] = (byte) ((encs[i] >> 16) & 0xff);b[6 + 4 * i] = (byte) ((encs[i] >> 8) & 0xff);b[7 + 4 * i] = (byte) (encs[i] & 0xff);
}os.write(b);
}
//// Write a ClientCutText message//public void writeClientCutText(String text) throws IOException {
byte[] b = new byte[8 + text.length()];b[0] = (byte) ClientCutText;b[4] = (byte) ((text.length() >> 24) & 0xff);b[5] = (byte) ((text.length() >> 16) & 0xff);b[6] = (byte) ((text.length() >> 8) & 0xff);b[7] = (byte) (text.length() & 0xff);text.getBytes(0, text.length(), b, 8);os.write(b);
}//// A buffer for putting pointer and keyboard events before being sent. This
RFBProtocol.java 5/7/2005 19:34
Page 5 of 8
381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
// is to ensure that multiple RFB events generated from a single Java Event// will all be sent in a single network packet. The maximum possible// length is 4 modifier down events, a single key event followed by 4// modifier up events i.e. 9 key events or 72 bytes.//byte[] eventBuf = new byte[72];int eventBufLen;//// Write a pointer event message. We may need to send modifier key events// around it to set the correct modifier state. Also buttons 2 and 3 are// represented as having ALT and META modifiers respectively.//int pointerMask = 0;
void writePointerEvent(int tipoEventoMouse, int botao, int x, int y)throws IOException {
int mask2 = 4;if (tipoEventoMouse == MouseEvent.MOUSE_PRESSED) {
if (botao == MouseEvent.BUTTON2) {pointerMask = mask2;
} else {pointerMask = 1;
}} else {
if (tipoEventoMouse == MouseEvent.MOUSE_RELEASED) {pointerMask = 0;
}}eventBufLen = 0;if (x < 0)
x = 0;if (y < 0)
y = 0;eventBuf[eventBufLen++] = (byte) PointerEvent;eventBuf[eventBufLen++] = (byte) pointerMask;eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff);eventBuf[eventBufLen++] = (byte) (x & 0xff);eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff);eventBuf[eventBufLen++] = (byte) (y & 0xff);if (pointerMask == 0) {
writeModifierKeyEvents(0);}os.write(eventBuf, 0, eventBufLen);
}
//// Write a key event message. We may need to send modifier key events// around it to set the correct modifier state. Also we need to translate// from the Java key values to the X keysym values used by the RFB protocol.//public void sendCtrlAltDel() {
try {Event ctrlAltDelEvent = new Event(null, 0, null);ctrlAltDelEvent.key = 127;ctrlAltDelEvent.modifiers = Event.CTRL_MASK | Event.ALT_MASK;ctrlAltDelEvent.id = Event.KEY_PRESS;writeKeyEvent(ctrlAltDelEvent);ctrlAltDelEvent.id = Event.KEY_RELEASE;writeKeyEvent(ctrlAltDelEvent);
} catch (Exception e) {e.printStackTrace();
}}
void writeKeyEvent(Event evt) throws IOException {int key = evt.key;boolean down = false;if ((evt.id == Event.KEY_PRESS) || (evt.id == Event.KEY_ACTION))
down = true;if ((evt.id == Event.KEY_ACTION)
|| (evt.id == Event.KEY_ACTION_RELEASE)) {//// A KEY_ACTION event should be one of the following. If not then// just// ignore the event.//
RFBProtocol.java 5/7/2005 19:34
Page 6 of 8
457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
switch (key) {case Event.HOME:
key = 0xff50;break;
case Event.LEFT:key = 0xff51;break;
case Event.UP:key = 0xff52;break;
case Event.RIGHT:key = 0xff53;break;
case Event.DOWN:key = 0xff54;break;
case Event.PGUP:key = 0xff55;break;
case Event.PGDN:key = 0xff56;break;
case Event.END:key = 0xff57;break;
case Event.F1:key = 0xffbe;break;
case Event.F2:key = 0xffbf;break;
case Event.F3:key = 0xffc0;break;
case Event.F4:key = 0xffc1;break;
case Event.F5:key = 0xffc2;break;
case Event.F6:key = 0xffc3;break;
case Event.F7:key = 0xffc4;break;
case Event.F8:key = 0xffc5;break;
case Event.F9:key = 0xffc6;break;
case Event.F10:key = 0xffc7;break;
case Event.F11:key = 0xffc8;break;
case Event.F12:key = 0xffc9;break;
default:return;
}} else {
//// A "normal" key press. Ordinary ASCII characters go straight// through.// For CTRL-<letter>, CTRL is sent separately so just send <letter>.// Backspace, tab, return, escape and delete have special keysyms.// Anything else we ignore.//if (key < 32) {
if ((evt.modifiers & Event.CTRL_MASK) != 0) {key += 96;
} else {
RFBProtocol.java 5/7/2005 19:34
Page 7 of 8
533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
switch (key) {case 8:
key = 0xff08;break;
case 9:key = 0xff09;break;
case 10:key = 0xff0d;break;
case 27:key = 0xff1b;break;
}}
} else if (key >= 127) {if (key == 127) {
key = 0xffff;} else {
// JDK1.1 on X incorrectly passes some keysyms straight// through, so// we do too. JDK1.1.4 seems to have fixed this.if ((key < 0xff00) || (key > 0xffff))
return;}
}}eventBufLen = 0;writeModifierKeyEvents(evt.modifiers);writeKeyEvent(key, down);//// Always release all modifiers after an "up" event//if (!down) {
writeModifierKeyEvents(0);}os.write(eventBuf, 0, eventBufLen);
}
//// Add a raw key event with the given X keysym to eventBuf.//void writeKeyEvent(int keysym, boolean down) throws IOException {
eventBuf[eventBufLen++] = (byte) KeyEvent;eventBuf[eventBufLen++] = (byte) (down ? 1 : 0);eventBuf[eventBufLen++] = (byte) 0;eventBuf[eventBufLen++] = (byte) 0;eventBuf[eventBufLen++] = (byte) ((keysym >> 24) & 0xff);eventBuf[eventBufLen++] = (byte) ((keysym >> 16) & 0xff);eventBuf[eventBufLen++] = (byte) ((keysym >> 8) & 0xff);eventBuf[eventBufLen++] = (byte) (keysym & 0xff);
}//// Write key events to set the correct modifier state.//int oldModifiers;
void writeModifierKeyEvents(int newModifiers) throws IOException {if ((newModifiers & Event.CTRL_MASK) != (oldModifiers & Event.CTRL_MASK))
writeKeyEvent(0xffe3, (newModifiers & Event.CTRL_MASK) != 0);if ((newModifiers & Event.SHIFT_MASK) != (oldModifiers & Event.SHIFT_MASK))
writeKeyEvent(0xffe1, (newModifiers & Event.SHIFT_MASK) != 0);if ((newModifiers & Event.META_MASK) != (oldModifiers & Event.META_MASK))
writeKeyEvent(0xffe7, (newModifiers & Event.META_MASK) != 0);if ((newModifiers & Event.ALT_MASK) != (oldModifiers & Event.ALT_MASK))
writeKeyEvent(0xffe9, (newModifiers & Event.ALT_MASK) != 0);oldModifiers = newModifiers;
}}
RFBProtocol.java 5/7/2005 19:34
Page 8 of 8
1234567891011121314151617181920212223
package app.rede;
public class TelaCelular {private int altura;private int largura;
public int getAltura() {return altura;
}
public void setAltura(int altura) {this.altura = altura;
}
public int getLargura() {return largura;
}
public void setLargura(int largura) {this.largura = largura;
}}
TelaCelular.java 5/7/2005 19:35
Page 1 of 1
123456789
10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package app.rede;
import java.awt.Color;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Image;import java.awt.Toolkit;import java.awt.event.MouseEvent;import java.awt.image.BufferedImage;import java.awt.image.DirectColorModel;import java.io.IOException;import app.util.AnimatedMemoryImageSource;import app.util.Log;import app.util.TratadorDeImagem;import app.util.TratadorDoMouse;public class TratadorDeComandos extends Thread {
private String senhaLocal;private TratadorDeImagem tratadorDeImagens;private TratadorDoMouse tratadorDoMouse;private int portaLocal;private String senhaExterna;private boolean botao1DoMousePressionado;private boolean botao2DoMousePressionado;private int portaExterna;private LeitorDeComando leitor;int largura = 0;int altura = 0;private BufferedImage imagemOriginal;private BufferedImage imagemCelular;private int[] encodings = new int[10];private RFBProtocol protocoloRFB;private DirectColorModel cm;private Color[] colors;private byte[] pixels;private Graphics pig;private Graphics sg;private int comandoDoCelular;private Image paintImage;private boolean connected;private boolean needToResetClip;private int nVezes = 0;private String hostRodandoVNC;private boolean mouseAtivado;
public TratadorDeComandos(String _hostRodandoVNC, String _senhaLocal,int _portaLocal, String _senhaExterna, int _portaExterna) {
senhaLocal = _senhaLocal;senhaExterna = _senhaExterna;portaExterna = _portaExterna;portaLocal = _portaLocal;hostRodandoVNC = _hostRodandoVNC;
}
private void aguardaConexaoComCelular() {try {
leitor = new LeitorDeComando(portaExterna);Log.info("Aguardando conexao na porta " + portaExterna);TelaCelular telaCelular = leitor.getTelaCelular();largura = telaCelular.getLargura();altura = telaCelular.getAltura();
} catch (Exception e) {e.printStackTrace();
}}
public void run() {Log.info("Iniciando tratamento de comandos");while (true) {
try {aguardaConexaoComCelular();// Fazendo conexão localprotocoloRFB = new RFBProtocol(hostRodandoVNC, portaLocal);// protocoloRFB = new RFBProtocol("localhost", portaLocal);protocoloRFB.connectAndAuthenticate(senhaLocal);protocoloRFB.writeClientInit();protocoloRFB.readServerInit();
TratadorDeComandos.java 5/7/2005 19:35
Page 1 of 4
7778798081828384858687888990919293949596979899
100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
Log.info("Nome: " + protocoloRFB.desktopName);Log.info("Resolução: " + protocoloRFB.framebufferWidth + " x "
+ protocoloRFB.framebufferHeight);protocoloRFB.setEncodings(encodings, 1);protocoloRFB.writeSetPixelFormat(8, 8, false, true, 7, 7, 3, 0,
3, 6);cm = new DirectColorModel(8, 7, (7 << 3), (3 << 6));colors = new Color[256];for (int i = 0; i < 256; i++) {
colors[i] = new Color(cm.getRGB(i));}pixels = new byte[protocoloRFB.framebufferWidth
* protocoloRFB.framebufferHeight];AnimatedMemoryImageSource amis = new AnimatedMemoryImageSource(
protocoloRFB.framebufferWidth,protocoloRFB.framebufferHeight, cm, pixels);
Image rawPixelsImage = Toolkit.getDefaultToolkit().createImage(amis);
imagemOriginal = new BufferedImage(protocoloRFB.framebufferWidth,protocoloRFB.framebufferHeight,BufferedImage.TYPE_INT_RGB);
Graphics2D g = imagemOriginal.createGraphics();pig = imagemOriginal.createGraphics();sg = imagemOriginal.createGraphics();processaProtocolo();Log.info("Finalizando conexao");leitor.fechaFechaConexao();
} catch (IOException e1) {e1.printStackTrace();
}}
}
private synchronized void processaProtocolo() throws IOException {protocoloRFB.writeFramebufferUpdateRequest(0, 0,
protocoloRFB.framebufferWidth, protocoloRFB.framebufferHeight,true);
while (comandoDoCelular != DP.FINALIZAR_CONEXAO) {int msgType = protocoloRFB.readServerMessageType();Log.info("Mensagem do Servidor: " + msgType);// ---------------------------------switch (msgType) {case RFBProtocol.FramebufferUpdate:
protocoloRFB.readFramebufferUpdate();for (int i = 0; i < protocoloRFB.updateNRects; i++) {
protocoloRFB.readFramebufferUpdateRectHdr();switch (protocoloRFB.updateRectEncoding) {case RFBProtocol.EncodingRaw:
desenhaImagem(protocoloRFB.updateRectX,protocoloRFB.updateRectY,protocoloRFB.updateRectW,protocoloRFB.updateRectH);
break;default:
throw new IOException("Unknown RFB rectangle encoding "+ protocoloRFB.updateRectEncoding);
}}break;
case RFBProtocol.SetColourMapEntries:throw new IOException(
"Can't handle SetColourMapEntries message");case RFBProtocol.Bell:
System.out.print((char) 7);break;
case RFBProtocol.ServerCutText:String s = protocoloRFB.readServerCutText();break;
case -1: // EOF, disconnectconnected = false;break;
default:throw new IOException("Unknown RFB message type " + msgType);
}// ---------------------------------
TratadorDeComandos.java 5/7/2005 19:35
Page 2 of 4
153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
comandoDoCelular = leitor.getComando();switch (comandoDoCelular) {case DP.CMD_ZOOM_MENOS:
tratadorDeImagens.zoomMenos(tratadorDoMouse);break;
case DP.CMD_ZOOM_MAIS:tratadorDeImagens.zoomMais(tratadorDoMouse);break;
case DP.CMD_TELA_PARA_CIMA:tratadorDeImagens.moveParaCima();break;
case DP.CMD_TELA_PARA_BAIXO:tratadorDeImagens.moveParaBaixo();break;
case DP.CMD_TELA_PARA_ESQUERDA:tratadorDeImagens.moveParaEsquerda();break;
case DP.CMD_TELA_PARA_DIREITA:tratadorDeImagens.moveParaDireita();break;
case DP.CMD_MOUSE_PARA_BAIXO:tratadorDoMouse.moveParaBaixo();processaEventoDoMouse(MouseEvent.MOUSE_MOVED, 0);break;
case DP.CMD_MOUSE_PARA_CIMA:tratadorDoMouse.moveParaCima();processaEventoDoMouse(MouseEvent.MOUSE_MOVED, 0);break;
case DP.CMD_MOUSE_PARA_DIREITA:tratadorDoMouse.moveParaDireita();processaEventoDoMouse(MouseEvent.MOUSE_MOVED, 0);break;
case DP.CMD_MOUSE_PARA_ESQUERDA:tratadorDoMouse.moveParaEsquerda();processaEventoDoMouse(MouseEvent.MOUSE_MOVED, 0);break;
case DP.CMD_BT_MOUSE1:if (botao1DoMousePressionado) {
processaEventoDoMouse(MouseEvent.MOUSE_RELEASED,MouseEvent.BUTTON1);
} else {processaEventoDoMouse(MouseEvent.MOUSE_PRESSED,
MouseEvent.BUTTON1);}botao1DoMousePressionado = !botao1DoMousePressionado;break;
case DP.CMD_BT_MOUSE2:if (botao2DoMousePressionado) {
processaEventoDoMouse(MouseEvent.MOUSE_RELEASED,MouseEvent.BUTTON2);
} else {processaEventoDoMouse(MouseEvent.MOUSE_PRESSED,
MouseEvent.BUTTON2);}botao2DoMousePressionado = !botao2DoMousePressionado;break;
case DP.INICIA_TRATADOR_DE_IMAGENS:iniciaTratador();break;
default:break;
}sendImage();// TODO ver tempo entre atualizaçõesprotocoloRFB.writeFramebufferUpdateRequest(0, 0,
protocoloRFB.framebufferWidth,protocoloRFB.framebufferHeight, false);
/* * long numMillisecondsToSleep = 250; // 1/4 segundos try { * Thread.sleep(numMillisecondsToSleep); } catch * (InterruptedException e) { e.printStackTrace(); } */
}}
private void desenhaImagem(int x, int y, int w, int h) throws IOException {
TratadorDeComandos.java 5/7/2005 19:35
Page 3 of 4
229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
// TODO verificar se precisa desenhar cada umLog.info("Desenhando x=" + x + " y=" + y + " w=" + w + " h=" + h);Graphics2D g = imagemOriginal.createGraphics();for (int j = 0; j < protocoloRFB.framebufferHeight; j++) {
for (int k = 0; k < protocoloRFB.framebufferWidth; k++) {int pixel = protocoloRFB.is.read();g.setColor(colors[pixel]);g.fillRect(k, j, 1, 1);
}}g.drawImage(imagemOriginal, 0, 0, null);if (imagemCelular != null) {
imagemCelular.getGraphics().drawImage(imagemOriginal, 0, 0,tratadorDeImagens.getLargura(),tratadorDeImagens.getAltura(), tratadorDeImagens.getRetX(),tratadorDeImagens.getRetY(), tratadorDeImagens.getRetX2(),tratadorDeImagens.getRetY2(), null);
}nVezes++;
}
public synchronized void iniciaTratador() {tratadorDeImagens = new TratadorDeImagem(largura, altura,
protocoloRFB.framebufferWidth, protocoloRFB.framebufferHeight);tratadorDoMouse = new TratadorDoMouse(protocoloRFB.framebufferWidth,
protocoloRFB.framebufferHeight);imagemCelular = new BufferedImage(tratadorDeImagens.getLargura(),
tratadorDeImagens.getAltura(), BufferedImage.TYPE_INT_RGB);}
private synchronized void sendImage() {try {
leitor.enviaImagem(imagemCelular);} catch (Exception e) {
e.printStackTrace();}
}
public void processaEventoDoMouse(int tipoEvento, int botao) {if (protocoloRFB.inNormalProtocol) {
synchronized (protocoloRFB) {try {
protocoloRFB.writePointerEvent(tipoEvento, botao,tratadorDoMouse.getX(), tratadorDoMouse.getY());
} catch (Exception e) {e.printStackTrace();
}protocoloRFB.notify();
}}
}}
TratadorDeComandos.java 5/7/2005 19:35
Page 4 of 4
123456789
10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package app.ui;
import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JTextField;import app.rede.TratadorDeComandos;import app.util.Log;public class PainelDeAutenticacao extends JFrame {
private javax.swing.JPanel jContentPane = null;private JTextField txtSenhaLocal = null;private JButton jButton = null;private JLabel jLabel = null;private JTextField txtSenhaExterna = null;private JLabel jLabel1 = null;private JTextField txtPortaLocal = null;private JTextField txtPortaExterna = null;private JLabel jLabel2 = null;private JLabel jLabel3 = null;private JButton jButton1 = null;private TratadorDeComandos tratadorDeComandos;private JTextField txtHost = null;private JLabel jLabel4 = null;
private JTextField getTxtSenhaLocal() {if (txtSenhaLocal == null) {
txtSenhaLocal = new JTextField();txtSenhaLocal.setBounds(136, 45, 146, 20);txtSenhaLocal.setText("testevnc");
}return txtSenhaLocal;
}
private JButton getJButton() {if (jButton == null) {
jButton = new JButton();jButton.setBounds(184, 183, 95, 26);jButton.setText("Iniciar");jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {tratadorDeComandos = new TratadorDeComandos(txtHost
.getText(), txtSenhaLocal.getText(), Integer
.parseInt(txtPortaLocal.getText()), txtSenhaExterna
.getText(), Integer.parseInt(txtPortaExterna
.getText()));tratadorDeComandos.start();jButton.setEnabled(false);
}});
}return jButton;
}
private void iniciarServidor() {}
private JTextField getTxtSenhaExterna() {if (txtSenhaExterna == null) {
txtSenhaExterna = new JTextField();txtSenhaExterna.setBounds(135, 102, 150, 20);txtSenhaExterna.setText("x");
}return txtSenhaExterna;
}
private JTextField getTxtPortaLocal() {if (txtPortaLocal == null) {
txtPortaLocal = new JTextField();txtPortaLocal.setBounds(136, 68, 66, 20);txtPortaLocal.setText("5900");
}return txtPortaLocal;
}
PainelDeAutenticacao.java 5/7/2005 19:36
Page 1 of 3
7778798081828384858687888990919293949596979899
100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
private JTextField getTxtPortaExterna() {if (txtPortaExterna == null) {
txtPortaExterna = new JTextField();txtPortaExterna.setBounds(136, 128, 69, 20);txtPortaExterna.setText("8080");
}return txtPortaExterna;
}
private JButton getJButton1() {if (jButton1 == null) {
jButton1 = new JButton();jButton1.setBounds(61, 183, 92, 27);jButton1.setText("Fechar");jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {Log.info("Saindo da aplicação");System.exit(0);
}});
}return jButton1;
}
/** * This method initializes jTextField * * @return javax.swing.JTextField */private JTextField getTxtHost() {
if (txtHost == null) {txtHost = new JTextField();txtHost.setBounds(136, 19, 144, 20);txtHost.setText("192.168.152.38");
}return txtHost;
}
public static void main(String[] args) {PainelDeAutenticacao painel = new PainelDeAutenticacao();painel.initialize();
}
private void initialize() {this.setSize(365, 270);this.setContentPane(getJContentPane());this.setTitle("VNC para celular - módulo PC");this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {Log.info("fechando aplicação");System.exit(0);
}});this.show();
}
private javax.swing.JPanel getJContentPane() {if (jContentPane == null) {
jLabel4 = new JLabel();jLabel3 = new JLabel();jLabel2 = new JLabel();jLabel1 = new JLabel();jLabel = new JLabel();jContentPane = new javax.swing.JPanel();jContentPane.setLayout(null);jLabel.setBounds(79, 45, 45, 20);jLabel.setText("Senha:");jLabel1.setBounds(28, 98, 92, 25);jLabel1.setText("Senha Externa:");jLabel2.setBounds(82, 71, 39, 16);jLabel2.setText("Porta:");jLabel3.setBounds(30, 129, 95, 17);jLabel3.setText("Porta Externa:");jLabel4.setBounds(62, 19, 59, 17);jLabel4.setText("Host VNC:");jContentPane.add(getTxtSenhaLocal(), null);
PainelDeAutenticacao.java 5/7/2005 19:36
Page 2 of 3
153154155156157158159160161162163164165166167168
jContentPane.add(getJButton(), null);jContentPane.add(jLabel, null);jContentPane.add(getTxtSenhaExterna(), null);jContentPane.add(jLabel1, null);jContentPane.add(getTxtPortaLocal(), null);jContentPane.add(getTxtPortaExterna(), null);jContentPane.add(jLabel2, null);jContentPane.add(jLabel3, null);jContentPane.add(getJButton1(), null);jContentPane.add(getTxtHost(), null);jContentPane.add(jLabel4, null);
}return jContentPane;
}} // @jve:decl-index=0:visual-constraint="10,10"
PainelDeAutenticacao.java 5/7/2005 19:36
Page 3 of 3
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
//// Código com licensa GPL; // Retirado do site http://www.tightvnc.com///package app.util;
import java.awt.image.*;public class AnimatedMemoryImageSource implements ImageProducer {
int width;int height;ColorModel cm;byte[] pixels;ImageConsumer ic;
public AnimatedMemoryImageSource(int w, int h, ColorModel c, byte[] p) {width = w;height = h;cm = c;pixels = p;
}
public void addConsumer(ImageConsumer c) {if (ic == c)
return;if (ic != null) {
ic.imageComplete(ImageConsumer.IMAGEERROR);}ic = c;ic.setDimensions(width, height);ic.setColorModel(cm);ic.setHints(ImageConsumer.RANDOMPIXELORDER);ic.setPixels(0, 0, width, height, cm, pixels, 0, width);ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
}
public boolean isConsumer(ImageConsumer c) {return (ic == c);
}
public void removeConsumer(ImageConsumer c) {if (ic == c)
ic = null;}
public void requestTopDownLeftRightResend(ImageConsumer c) {}
public void startProduction(ImageConsumer c) {addConsumer(c);
}
void newPixels(int x, int y, int w, int h) {if (ic != null) {
ic.setPixels(x, y, w, h, cm, pixels, width * y + x, width);ic.imageComplete(ImageConsumer.SINGLEFRAMEDONE);
}}
}
AnimatedMemoryImageSource.java 5/7/2005 19:38
Page 1 of 1
123456789
10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
//Boa parte do código foi desenvolvido por Dave Zimmerman <[email protected]>//Retirado do site www.acme.compackage app.util;
public class DesCipher {public DesCipher(byte[] key) {
setKey(key);}// Key routines.private int[] encryptKeys = new int[32];private int[] decryptKeys = new int[32];
// / Set the key.public void setKey(byte[] key) {
deskey(key, true, encryptKeys);deskey(key, false, decryptKeys);
}
// Turn an 8-byte key into internal keys.private void deskey(byte[] keyBlock, boolean encrypting, int[] KnL) {
int i, j, l, m, n;int[] pc1m = new int[56];int[] pcr = new int[56];int[] kn = new int[32];for (j = 0; j < 56; ++j) {
l = pc1[j];m = l & 07;pc1m[j] = ((keyBlock[l >>> 3] & bytebit[m]) != 0) ? 1 : 0;
}for (i = 0; i < 16; ++i) {
if (encrypting)m = i << 1;
elsem = (15 - i) << 1;
n = m + 1;kn[m] = kn[n] = 0;for (j = 0; j < 28; ++j) {
l = j + totrot[i];if (l < 28)
pcr[j] = pc1m[l];else
pcr[j] = pc1m[l - 28];}for (j = 28; j < 56; ++j) {
l = j + totrot[i];if (l < 56)
pcr[j] = pc1m[l];else
pcr[j] = pc1m[l - 28];}for (j = 0; j < 24; ++j) {
if (pcr[pc2[j]] != 0)kn[m] |= bigbyte[j];
if (pcr[pc2[j + 24]] != 0)kn[n] |= bigbyte[j];
}}cookey(kn, KnL);
}
private void cookey(int[] raw, int KnL[]) {int raw0, raw1;int rawi, KnLi;int i;for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
raw0 = raw[rawi++];raw1 = raw[rawi++];KnL[KnLi] = (raw0 & 0x00fc0000) << 6;KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;++KnLi;KnL[KnLi] = (raw0 & 0x0003f000) << 12;KnL[KnLi] |= (raw0 & 0x0000003f) << 16;KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;KnL[KnLi] |= (raw1 & 0x0000003f);
DesCipher.java 5/7/2005 19:38
Page 1 of 5
7778798081828384858687888990919293949596979899
100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
++KnLi;}
}// Block encryption routines.private int[] tempInts = new int[2];
// / Encrypt a block of eight bytes.public void encrypt(byte[] clearText, int clearOff, byte[] cipherText,
int cipherOff) {squashBytesToInts(clearText, clearOff, tempInts, 0, 2);des(tempInts, tempInts, encryptKeys);spreadIntsToBytes(tempInts, 0, cipherText, cipherOff, 2);
}
// / Decrypt a block of eight bytes.public void decrypt(byte[] cipherText, int cipherOff, byte[] clearText,
int clearOff) {squashBytesToInts(cipherText, cipherOff, tempInts, 0, 2);des(tempInts, tempInts, decryptKeys);spreadIntsToBytes(tempInts, 0, clearText, clearOff, 2);
}
// The DES function.private void des(int[] inInts, int[] outInts, int[] keys) {
int fval, work, right, leftt;int round;int keysi = 0;leftt = inInts[0];right = inInts[1];work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;right ^= work;leftt ^= (work << 4);work = ((leftt >>> 16) ^ right) & 0x0000ffff;right ^= work;leftt ^= (work << 16);work = ((right >>> 2) ^ leftt) & 0x33333333;leftt ^= work;right ^= (work << 2);work = ((right >>> 8) ^ leftt) & 0x00ff00ff;leftt ^= work;right ^= (work << 8);right = (right << 1) | ((right >>> 31) & 1);work = (leftt ^ right) & 0xaaaaaaaa;leftt ^= work;right ^= work;leftt = (leftt << 1) | ((leftt >>> 31) & 1);for (round = 0; round < 8; ++round) {
work = (right << 28) | (right >>> 4);work ^= keys[keysi++];fval = SP7[work & 0x0000003f];fval |= SP5[(work >>> 8) & 0x0000003f];fval |= SP3[(work >>> 16) & 0x0000003f];fval |= SP1[(work >>> 24) & 0x0000003f];work = right ^ keys[keysi++];fval |= SP8[work & 0x0000003f];fval |= SP6[(work >>> 8) & 0x0000003f];fval |= SP4[(work >>> 16) & 0x0000003f];fval |= SP2[(work >>> 24) & 0x0000003f];leftt ^= fval;work = (leftt << 28) | (leftt >>> 4);work ^= keys[keysi++];fval = SP7[work & 0x0000003f];fval |= SP5[(work >>> 8) & 0x0000003f];fval |= SP3[(work >>> 16) & 0x0000003f];fval |= SP1[(work >>> 24) & 0x0000003f];work = leftt ^ keys[keysi++];fval |= SP8[work & 0x0000003f];fval |= SP6[(work >>> 8) & 0x0000003f];fval |= SP4[(work >>> 16) & 0x0000003f];fval |= SP2[(work >>> 24) & 0x0000003f];right ^= fval;
}right = (right << 31) | (right >>> 1);work = (leftt ^ right) & 0xaaaaaaaa;leftt ^= work;right ^= work;
DesCipher.java 5/7/2005 19:38
Page 2 of 5
153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
leftt = (leftt << 31) | (leftt >>> 1);work = ((leftt >>> 8) ^ right) & 0x00ff00ff;right ^= work;leftt ^= (work << 8);work = ((leftt >>> 2) ^ right) & 0x33333333;right ^= work;leftt ^= (work << 2);work = ((right >>> 16) ^ leftt) & 0x0000ffff;leftt ^= work;right ^= (work << 16);work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;leftt ^= work;right ^= (work << 4);outInts[0] = right;outInts[1] = leftt;
}// Tables, permutations, S-boxes, etc.private static byte[] bytebit = { (byte) 0x01, (byte) 0x02, (byte) 0x04,
(byte) 0x08, (byte) 0x10, (byte) 0x20, (byte) 0x40, (byte) 0x80 };private static int[] bigbyte = { 0x800000, 0x400000, 0x200000, 0x100000,
0x080000, 0x040000, 0x020000, 0x010000, 0x008000, 0x004000,0x002000, 0x001000, 0x000800, 0x000400, 0x000200, 0x000100,0x000080, 0x000040, 0x000020, 0x000010, 0x000008, 0x000004,0x000002, 0x000001 };
private static byte[] pc1 = { (byte) 56, (byte) 48, (byte) 40, (byte) 32,(byte) 24, (byte) 16, (byte) 8, (byte) 0, (byte) 57, (byte) 49,(byte) 41, (byte) 33, (byte) 25, (byte) 17, (byte) 9, (byte) 1,(byte) 58, (byte) 50, (byte) 42, (byte) 34, (byte) 26, (byte) 18,(byte) 10, (byte) 2, (byte) 59, (byte) 51, (byte) 43, (byte) 35,(byte) 62, (byte) 54, (byte) 46, (byte) 38, (byte) 30, (byte) 22,(byte) 14, (byte) 6, (byte) 61, (byte) 53, (byte) 45, (byte) 37,(byte) 29, (byte) 21, (byte) 13, (byte) 5, (byte) 60, (byte) 52,(byte) 44, (byte) 36, (byte) 28, (byte) 20, (byte) 12, (byte) 4,(byte) 27, (byte) 19, (byte) 11, (byte) 3 };
private static int[] totrot = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21,23, 25, 27, 28 };
private static byte[] pc2 = { (byte) 13, (byte) 16, (byte) 10, (byte) 23,(byte) 0, (byte) 4, (byte) 2, (byte) 27, (byte) 14, (byte) 5,(byte) 20, (byte) 9, (byte) 22, (byte) 18, (byte) 11, (byte) 3,(byte) 25, (byte) 7, (byte) 15, (byte) 6, (byte) 26, (byte) 19,(byte) 12, (byte) 1, (byte) 40, (byte) 51, (byte) 30, (byte) 36,(byte) 46, (byte) 54, (byte) 29, (byte) 39, (byte) 50, (byte) 44,(byte) 32, (byte) 47, (byte) 43, (byte) 48, (byte) 38, (byte) 55,(byte) 33, (byte) 52, (byte) 45, (byte) 41, (byte) 49, (byte) 35,(byte) 28, (byte) 31, };
private static int[] SP1 = { 0x01010400, 0x00000000, 0x00010000,0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404,0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000,0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004,0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000,0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000,0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004,0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400,0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000,0x01010004 };
private static int[] SP2 = { 0x80108020, 0x80008000, 0x00008000,0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000,0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020,0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000,0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000,0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000,0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020,0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000,0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020,0x00108000 };
private static int[] SP3 = { 0x00000208, 0x08020200, 0x00000000,0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208,
DesCipher.java 5/7/2005 19:38
Page 3 of 5
229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008,0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208,0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200,0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200,0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008,0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208,0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008,0x00020200 };
private static int[] SP4 = { 0x00802001, 0x00002081, 0x00002081,0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081,0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001,0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080,0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080,0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000,0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001,0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080,0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000,0x00802080 };
private static int[] SP5 = { 0x00000100, 0x02080100, 0x02080000,0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100,0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100,0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000,0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000,0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000,0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000,0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100,0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100,0x40000100 };
private static int[] SP6 = { 0x20000010, 0x20400000, 0x00004000,0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010,0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010,0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000,0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000,0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000,0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010,0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010,0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010,0x20004010 };
private static int[] SP7 = { 0x00200000, 0x04200002, 0x04000802,0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002,0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800,0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802,0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000,0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002,0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800,0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802,0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800,0x00200002 };
private static int[] SP8 = { 0x10001040, 0x00001000, 0x00040000,0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000,0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040,0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040,0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040,0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040,0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
DesCipher.java 5/7/2005 19:38
Page 4 of 5
305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000,0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000,0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000,0x10041000 };
// Routines taken from other parts of the Acme utilities.// / Squash bytes down to ints.public static void squashBytesToInts(byte[] inBytes, int inOff,
int[] outInts, int outOff, int intLen) {for (int i = 0; i < intLen; ++i)
outInts[outOff + i] = ((inBytes[inOff + i * 4] & 0xff) << 24)| ((inBytes[inOff + i * 4 + 1] & 0xff) << 16)| ((inBytes[inOff + i * 4 + 2] & 0xff) << 8)| (inBytes[inOff + i * 4 + 3] & 0xff);
}
// / Spread ints into bytes.public static void spreadIntsToBytes(int[] inInts, int inOff,
byte[] outBytes, int outOff, int intLen) {for (int i = 0; i < intLen; ++i) {
outBytes[outOff + i * 4] = (byte) (inInts[inOff + i] >>> 24);outBytes[outOff + i * 4 + 1] = (byte) (inInts[inOff + i] >>> 16);outBytes[outOff + i * 4 + 2] = (byte) (inInts[inOff + i] >>> 8);outBytes[outOff + i * 4 + 3] = (byte) inInts[inOff + i];
}}
}
DesCipher.java 5/7/2005 19:38
Page 5 of 5
123456789101112
package app.util;
public class Log {public static void info(String texto) {
// System.out.println("Info: "+texto);}
public static void erro(String texto) {System.out.println("Erro: " + texto);
}}
Log.java 5/7/2005 19:38
Page 1 of 1
123456789
10111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package app.util;
import java.awt.image.BufferedImage;public class TratadorDeImagem {
private int largura;private int fatorDeMovimento;private int altura;private int alturaOriginal;private int larguraOriginal;private int retX;private int retY;private int retX2;private int retY2;private int fatorDeZoomX;private int fatorDeZoomY;
public TratadorDeImagem(int _largura, int _altura, int _larguraOriginal,int _alturaOriginal) {
int t = _larguraOriginal / _largura;largura = _largura;altura = (int) Math.round(_alturaOriginal / t);alturaOriginal = _alturaOriginal;larguraOriginal = _larguraOriginal;retX = 0;retY = 0;retY2 = alturaOriginal;retX2 = larguraOriginal;fatorDeMovimento = 100;fatorDeZoomX = 100;fatorDeZoomY = (int) Math.round(((fatorDeZoomX * altura) / largura));
}
public BufferedImage redimensionaImagem(BufferedImage imagem) {BufferedImage image = new BufferedImage(largura, altura,
BufferedImage.TYPE_INT_RGB);image.getGraphics().drawImage(imagem, 0, 0, largura, altura, retX,
retY, retX2, retY2, null);// imagem.getGraphics().drawImage(image, 0, 0,largura,altura, null);// Graphics g=image.getGraphics();// / g.drawImage(imagem,x,y,width,height,this);return image;
}
public synchronized void moveParaEsquerda() {if (retX != 0) {
if ((retX - fatorDeMovimento) >= 0) {retX = retX - fatorDeMovimento;retX2 = retX2 - fatorDeMovimento;
} else {int fatorTemporario = fatorDeMovimento - retX;retX = 0;retX2 = retX2 - fatorTemporario;
}}
}
public synchronized void moveParaDireita() {if (retX2 != larguraOriginal) {
if ((fatorDeMovimento + retX2) <= larguraOriginal) {retX = retX + fatorDeMovimento;retX2 = retX2 + fatorDeMovimento;
} else {int fatorTemporario = larguraOriginal - retX2;retX2 = larguraOriginal;retX = retX + fatorTemporario;
}}
}
public synchronized void moveParaBaixo() {if (retY2 != alturaOriginal) {
if ((fatorDeMovimento + retY2) <= alturaOriginal) {retY = retY + fatorDeMovimento;retY2 = retY2 + fatorDeMovimento;
} else {int fatorTemporario = alturaOriginal - retY2;
TratadorDeImagem.java 5/7/2005 19:39
Page 1 of 3
7778798081828384858687888990919293949596979899
100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
retY2 = alturaOriginal;retY = retY + fatorTemporario;
}}
}
public synchronized void moveParaCima() {if (retY != 0) {
if ((retY - fatorDeMovimento) >= 0) {retY = retY - fatorDeMovimento;retY2 = retY2 - fatorDeMovimento;
} else {int fatorTemporario = fatorDeMovimento - retY;retY = 0;retY2 = retY2 - fatorTemporario;
}}
}
public synchronized void zoomMais(TratadorDoMouse tMouse) {if (((retX2 - retX) - fatorDeZoomX) >= largura) {
int fatorX = fatorDeZoomX / 2;int fatorY = fatorDeZoomY / 2;retX2 = retX2 - fatorX;retY2 = retY2 - fatorY;retX = retX + fatorX;retY = retY + fatorY;tMouse.zoomMais();
} else {int fatorDeZoomTemporario = (retX2 - retX) - largura;if (fatorDeZoomTemporario != 0) {
int fatorX = (int) Math.round(fatorDeZoomTemporario / 2);int fatorDeZoomTemporarioY = (int) Math
.round(((fatorDeZoomTemporario * altura) / largura));int fatorY = (int) Math.round(fatorDeZoomTemporarioY / 2);retX2 = retX2 - fatorX;retY2 = retY2 - fatorY;retX = retX + fatorX;retY = retY + fatorY;
}}
}
public synchronized void zoomMenos(TratadorDoMouse tMouse) {if (((retX2 - retX) + fatorDeZoomX) <= larguraOriginal) {
int fatorX = fatorDeZoomX / 2;int fatorY = fatorDeZoomY / 2;retX2 = retX2 + fatorX;retY2 = retY2 + fatorY;retX = retX - fatorX;retY = retY - fatorY;tMouse.zoomMenos();
}}
public int getAltura() {return altura;
}
public void setAltura(int altura) {this.altura = altura;
}
public int getAlturaOriginal() {return alturaOriginal;
}
public void setAlturaOriginal(int alturaOriginal) {this.alturaOriginal = alturaOriginal;
}
public int getFatorDeMovimento() {return fatorDeMovimento;
}
public void setFatorDeMovimento(int fatorDeMovimento) {
TratadorDeImagem.java 5/7/2005 19:39
Page 2 of 3
153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
this.fatorDeMovimento = fatorDeMovimento;}
public int getFatorDeZoomX() {return fatorDeZoomX;
}
public void setFatorDeZoomX(int fatorDeZoomX) {this.fatorDeZoomX = fatorDeZoomX;
}
public int getFatorDeZoomY() {return fatorDeZoomY;
}
public void setFatorDeZoomY(int fatorDeZoomY) {this.fatorDeZoomY = fatorDeZoomY;
}
public int getLargura() {return largura;
}
public void setLargura(int largura) {this.largura = largura;
}
public int getLarguraOriginal() {return larguraOriginal;
}
public void setLarguraOriginal(int larguraOriginal) {this.larguraOriginal = larguraOriginal;
}
public int getRetX() {return retX;
}
public void setRetX(int retX) {this.retX = retX;
}
public int getRetX2() {return retX2;
}
public void setRetX2(int retX2) {this.retX2 = retX2;
}
public int getRetY() {return retY;
}
public void setRetY(int retY) {this.retY = retY;
}
public int getRetY2() {return retY2;
}
public void setRetY2(int retY2) {this.retY2 = retY2;
}}
TratadorDeImagem.java 5/7/2005 19:39
Page 3 of 3
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
package app.util;
public class TratadorDoMouse {private int fatorDeMovimento;private int alturaOriginal;private int larguraOriginal;private int x;private int y;private int fatorDeZoom;private int fatorDeMovimentoInicial;
public TratadorDoMouse(int _larguraOriginal, int _alturaOriginal) {alturaOriginal = _alturaOriginal;larguraOriginal = _larguraOriginal;x = (int) (Math.round(larguraOriginal) / 2);y = (int) (Math.round(alturaOriginal) / 2);fatorDeMovimento = 60;fatorDeMovimentoInicial = 60;fatorDeZoom = 10;
}
public synchronized void moveParaEsquerda() {if ((x - fatorDeMovimento) > 0) {
x = x - fatorDeMovimento;} else {
x = 0;}
}
public synchronized void moveParaDireita() {if ((x + fatorDeMovimento) < larguraOriginal) {
x = x + fatorDeMovimento;} else {
x = larguraOriginal;}
}
public synchronized void moveParaBaixo() {if ((y + fatorDeMovimento) < alturaOriginal) {
y = y + fatorDeMovimento;} else {
y = alturaOriginal;}
}
public synchronized void moveParaCima() {if ((y - fatorDeMovimento) > 0) {
y = y - fatorDeMovimento;} else {
y = 0;}
}
public synchronized void zoomMais() {if ((fatorDeMovimento - fatorDeZoom) > fatorDeZoom) {
fatorDeMovimento = fatorDeMovimento - fatorDeZoom;} else {
fatorDeMovimento = fatorDeZoom;}Log.info("Fator de mov em:" + fatorDeMovimento);
}
public synchronized void zoomMenos() {if ((fatorDeMovimento + fatorDeZoom) < fatorDeMovimento) {
fatorDeMovimento = fatorDeMovimento + fatorDeZoom;} else {
fatorDeMovimento = fatorDeMovimentoInicial;}Log.info("Fator de mov em:" + fatorDeMovimento);
}
public int getX() {return x;
}
public void setX(int x) {
TratadorDoMouse.java 5/7/2005 19:39
Page 1 of 2
7778798081828384858687
this.x = x;}
public int getY() {return y;
}
public void setY(int y) {this.y = y;
}}
TratadorDoMouse.java 5/7/2005 19:39
Page 2 of 2
APÊNDICE C – Artigo
JNC MOBILE – SISTEMA DE ACESSO REMOTO PARA DISPOSITIVOS MÓVEIS
Andrei L. Krause e Rafael A. da Silva1
RESUMO
Apesar de a popularização dos dispositivos móveis ter corroborado para o desenvolvimento de vários serviços e funcionalidades, o poder de processamento e a capacidade de armazenamento destes dispositivos ainda são muito limitados. Em razão disso, os aplicativos desenvolvidos para estes tipos de dispositivos devem manter uma certa simplicidade. Este trabalho propõe uma aplicação que viabiliza o acesso remoto a estações de trabalho via um dispositivo móvel. Com a mobilidade e a conectividade dos dispositivos móveis aliados ao poder de processamento de estações de trabalho, é possível executar tarefas complexas a partir de um dispositivo móvel.
Palavras-chave: Computação móvel. Computação remota. J2ME. Dispositivos móveis. VNC.
ABSTRACT
The mobile devices appear currently in the market as merchandises in frank expansion. Of this form, it is necessary that the services offered for these devices, are each time more than excellency, providing the maximum of utility to the users. The objective of this research is exactly to present a software capable to offer the power of processing of a workstation with the practice, mobility and connectivity of the mobile devices as cell phones. The tool in this presented document, makes possible the remote access of a computer through a simple cellular telephone, offering its user, the experience to use softwares available only for machines with more robust processing. It also knows the tools that make possible the conception of this new paradigm of programming and software development.
Keywords: Mobile computation. Remote computation. J2ME. Móbile devices. VNC.
1 [email protected]; [email protected]. Acadêmicos do Curso de Bacharelado em Ciências da Computação da Universidade Federal de Santa Catarina.
1. INTRODUÇÃO
A evolução e a popularização de dispositivos móveis como celulares, notenooks, PDAs (Personal Digital Assistants), dispositivos discados móveis (GPS – Global Positional System), entre outros, têm oferecido uma gama de serviços e funcionalidades. Para suportar estes serviços, os dispositivos móveis, que têm na forma dos telefones celulares seus mais evidentes representantes, evoluiram consideravelmente. Aparelhos que eram utilizados apenas para fazer ligações, passaram rapidamente a figurar como agendas eletrônicas, câmeras fotográficas digitais, gravadores de som digital e computadores de mão.
Mesmo com tantas funcionalidades sendo oferecidas, o poder de processamento e a capacidade de armazenamento destes dispositivos ainda são muito limitados. Uma maneira de oferecer poder computacional e proporcionar acesso a serviços exclusivos das estações de trabalho é o acesso remoto via dispositivos móveis a estações de trabalho. Com o poder de mobilidade e conectividade dos dispositivos móveis, aliados a inovadora tecnologia J2ME da Sun, esta pesquisa visa apresentar uma solução capaz de conectar remotamente uma estação de trabalho a um aparelho móvel.
Inicialmente, o capítulo 2 discorre sobre os dispositivos móveis e suas características. O capítulo 3 apresenta o Java 2 Micro Edition (J2ME) e trata da importância desta API para o desenvolvimento do trabalho. O capítulo 4 apresenta os princípios do VNC (Virtual Network Computing) que serviram como base para a idéia proposta. Por fim, o capítulo 5 apresenta o trabalho desenvolvido.
2. DISPOSITIVOS MÓVEIS
Em geral, os dispositivos móveis possuem as seguintes características: tamanho reduzido, capacidade de trocar informações via rede, poder de processamento limitado, facilidade de transporte e ausência de cabos para conexão à rede e à energia. Os dispositivos mais utilizados para o propósito de computação móvel são notebooks, laptos, palmtops, PDAs (Personal Digital Assistants) e celulares (smartphones).
Mesmo com recursos comparáveis ao de uma estação de trabalho comum, notebooks e laptops não são soluções de mobilidade ideal, pois necessitam de uma base de apoio para serem operados e possuem baterias de curta duração. Os Palmtops resolvem alguns destes empecilhos, mas limitam ainda mais as capacidades de processamento e armazenamento e dificultam os métodos de entrada e saída de dados. Apesar de assumirem funções de um telefone celular,
aparelho de fax, Web browser e organizador pessoal, os PDAs também têm pouco poder de processamento e armazenamento, além de apresentarem opções de entrada e saída pouco práticas.
Desenvolvidos inicialmente com o único propósito de levar a comunicação além das barreiras da telefonia fixa convencional, os celulares chegaram para transpor barreiras. A tabela 1 apresenta a evolução dos celulares a cada geração.
Geração Características 1G Transmisão de
dados analógica (AMPS).
Taxas de 9600bps
2G Transmissão Digital de Dados (TDMA, CDMA e GSM).
Taxas de 9600bps a 14400bps. Surgimento de
aplicações WAP.
2,xG Disponibilização de aplicações pré-3G.
3G Evolução CDMA e GSM.
Taxas de até 2Mbps. Surgimento de aplicações multimídia.
4G Elevação das taxas de transmissão de dados.
Tecnologias e aplicações ainda em discussão.
Quadro 1 – Gerações da telefonia celular Fonte: Figueiredo e Nakamura, 2003, p.19.
As características e problemas apresentados pelos celulares assemelham-se com os citados nos PDAs. Além disso, a interação com o dispositivo é ainda maior, limitando-se na maioria dos casos, as teclas do aparelho. A solução foi incorporar aos celulares as funções de um PDA, gerando assim um novo dispositivo reconhecido pelo nome de Smartphone.
3. JAVA 2 MICRO EDITION – J2ME
Basicamente J2ME é um termo que se refere a uma coleção de APIs e máquinas virtuais que tornam possível o uso de Java em dispositivos móveis. Com o J2ME é possível levar ao mundo dos dispositivos móveis, os benefícios da tecnologia Java, como flexibilidade na interface com o usuário, um modelo de segurança eficaz, suporte a diferentes tipos de aplicações, entre outros.
Figura 1 – Plataforma J2ME
Fonte: Sun Microsystems, 2005
A plataforma J2ME está presente na maioria dos dispositivos móveis atuais, facilitando ao usuário a aquisição de novos serviços. A figura 1 ilustra a plataforma J2ME.
Toda a arquitetura J2ME define configurações, perfis e pacotes opcionais como elementos de uma aplicação Java completa. Assim, a plataforma é capaz de atender aos requisitos de diferentes dispositivos e mercados. A combinação destes elementos otimiza a capacidade de processamento, armazenamento e interfaces de entrada e saída para cada dispositivo particular. O resultado é uma plataforma de desenvolvimento Java comum, capaz de atender a diferentes tipos de equipamentos e fabricantes.
4. VIRTUAL NETWORK COMPUTING – VNC
O VNC possibilita que uma estação de trabalho seja controlada remotamente apenas com o uso de um simples programa cliente (visualizador). Outra característica interessante é o fato de não ser necessário que os dispositivos utilizados (cliente – servidor) sejam do mesmo tipo e/ou possuam mesmo sistema operacional.
Figura 2 – Acesso remoto com VNC
Fonte: Real VNC, 2005
Um software de controle remoto como o VNC, proporciona uma variedade de benefícios, pois torna possível controlar uma estação de trabalho através de uma rede, fixa ou sem fio, como se o indivíduo estivesse operando pessoalmente a estação acessada remotamente.
Constatando as facilidades que tal software proporciona, esta pesquisa propõe-se à apresentar uma solução cliente para ser embarcada em dispositivos móveis.
5. JNC MOBILE – SISTEMA DE ACESSO REMOTO PARA DOSPOSITIVOS MÓVEIS
O JNC Mobile é uma aplicação que possibilita a um dispositivo móvel controlar remotamente uma estação de trabalho. O dispositivo móvel escolhido foi um telefone celular da fabricante Nokia. Como é ilustrado na figura 3, o acesso remoto necessita da seguinte arquitetura: um sofware cliente, um software servidor VNC e um bridge. Esse último é responsável por receber as requisições do cliente e encaminhá-las ao servidor VNC.
Figura 3 – Acesso remoto através de dispositivo móvel com servidor bridge
Fonte: Elaborada pelos autores, 2005
As requisições recebidas pelo bridge são encaminhadas ao servidor VNC através do Protocolo RFB (Remote Frame Buffer). Por sua vez, o servidor VNC retorna ao bridge o status (imagem) do desktop, e este encarrega-se de transmitir a informação ao dispositivo móvel. Como ilustra a figura 4, o bridge acumula, além da responsabilidade de tradutor entre o programa cliente e o servidor VNC, a função de compactação da imagem enviada ao cliente.
Figura 4 – Compactação da imagem enviada ao cliente
Fonte: Elaborada pelos autores, 2005
A imagem fornecida pelo servidor VNC é capturada pelo bridge, que verifica as coordenadas que estão sendo requisitadas pelo dispositivo móvel e as converte para que possam ser exibidas na tela.
A figura 5 apresenta um exemplo de utilização da aplicação. O celular mostra a tela do computador que está sendo acessado remotamente. O usuário tem opções para, através das convenções criadas para as teclas do celular, realizar as operações de zoom in e zoom out, além de movimentar o mouse e gerar cliques.
Figura 5 – Teclas do celular para o servidor VNC
Fonte: elaborada pelos autores, 2005.
CONSIDERAÇÕES FINAIS
A tecnologia Java 2 ME mostrou-se de grande importância no desenvolvimento do trabalho, oferecendo uma série de facilidades. Além disso, apresenta-se como uma forte tendência, visto que está embutida na maioria dos dispositivos móveis do mercado e visa marcar presença em mais de 90% destes dispositivos até 2007.
Uma dificuldade encontrada durante o desenvolvimento do trabalho foi a falta de padronização na indústria. Constatou-se incompatibilidade até mesmo entre aparelhos do mesmo fabricante. Este problema parece estar sendo resolvido com a iniciativa de atualização do profile do J2ME MIDP, que agora figura em sua segunda versão.
Apesar das limitações de acessibilidade impostas pelos aparelhos celulares, da dificuldade de manipular as teclas do aparelho, e do tamanho reduzido do visor, e, considerando o caráter acadêmico do trabalho, é com satisfação que se apresenta o JNC Mobile como uma solução real para acesso remoto para dispositivos móveis.
REFERÊNCIAS
FIGUEIREDO, Carlos M. S.; NAKAMURA, Eduardo. Computação móvel: novas oportunidades e novos desafios. T&C Amazônia. Ano 1. n. 2. Jun. 2003.
JAVATM 2 Platform, Micro Edition. Sun Microsystems. Disponível em: <http://java.sun.com/> Acesso: 27 mar. 2005.
MOBILE Information Device Profile (MIDP); JSR 37, JSR 118 Overview. Sun Microsystems. Disponível em: <http://java.sun.com/products/midp/> Acesso: 27 mar. 2005.
WHAT is VNC. RealVNC. Disponível em: <http://www.realvnc.com/what.html> Acesso: 27 mar. 2005.