Então amigos, agradeço todos os comentários e conforme foi combinado, estou postando a segunda parte do post sobre desenvolvimento bluetooth utilizando JAVA.
No primeiro post, tratei da base da tecnologia bluetooth, além de algumas informações obre a plataforma Java SE e ME.
Hoje venho apresentá-los o Marge Framework. Essa sequência terá um TERCEIRO post, que será composta pelos códigos comentados por mim, para que possa facilitar a compreensão e aprendizagem de vocês. Lembrando que, qualquer dúvida, podem deixar nos comentários, ou mandar email, eu terei grande satisfação em ajudá-los.
O conteúdo desse post é uma adaptação/compactação dos trabalhos apresentado pelos seus próprios criadores. Esses documentos podem ser encontrados aqui.
O projeto Marge é um framework desenvolvido em Java – que utiliza a biblioteca JSR 82 – com intuito de ajudar a criação de aplicações Bluetooth que fazem parte de um contexto comum.
A idéia principal do projeto é reduzir a curva de aprendizado para desenvolvedores que pretendem criar aplicações com Bluetooth com objetivo de torná-los mais produtivos, fazendo-os concentrar o foco do desenvolvimento apenas na parte lógica do software.
O framework se responsabilizará por abstrair as outras partes relacionadas à comunicação Bluetooth – como as conexões, protocolos, trocas de mensagens, pesquisa por dispositivos e serviços – de uma maneira fácil e suportando diferentes configurações.
O projeto Marge não propõe apenas uma biblioteca para simplificar o uso de Blueooth em Java, mas sim toda uma arquitetura definida pelo framework.
Abaixo temos a imagem detalhada de onde se dá o uso do Marge na arquitetura para desenvolvimento Bluetooth.
Na primeira camada temos o sistema operacional, seguido de uma pilha de protocolos Bluetooth, e de uma camada de integração entre a máquina virtual Java e a chamada para a pilha. Acima da máquina virtual Java está a JSR 82, a API que especifica o Bluetooth sobre a qual o Marge foi desenvolvido. Acima do Marge, encontram-se as aplicações.
O projeto Marge é livre e possui o código aberto registrado sobre a licensa LGPL (GNU Lesser General Public License) e hospedado pelo portal java.net no endereço http://marge.dev.java.net.
O projeto faz parte da comunidade Mobile and Embedded do portal java.net, que é responsável pelo projetos de código aberto em Java ME.
Pacotes e classes
O framework Marge contém 24 classes divididas em 7 pacotes. Cada pacote irá ser detalhado abaixo.
O pacote net.java.dev.marge.communication contém a estrutura básica para comunicação. Este pacote contém as seguintes classes:
- ClientCommunication: Interface que define métodos para um cliente Bluetooth poder se conectar.
- Communicable: Classe abstrata que define um esqueleto de como funciona a conexão e as trocas de mensagens entre o cliente e servidor.
- CommunicationListener: Interface que define métodos relativos ao fechamento da conexão, recebimento de mensagens, erros durante o recebimento e troca de mensagens.
- ServerCommunication: Interface que define métodos para um servidor Bluetooth poder conectar.
O pacote net.java.dev.marge.communication.l2cap contém as classes especializadas para a comunicação utilizando o protocolo L2CAP.
- ClientL2CAPCommunication: Classe que implementa a conexão em L2CAP por parte do cliente.
- L2CAPCommunication: Classe abstrata que define um esqueleto de como funciona a conexão e as trocas de mensagens entre o cliente e servidor L2CAP.
- ServerL2CAPCommunication: Classe que implementa a conexão em L2CAP por parte do servidor.
O pacote net.java.dev.marge.communication.rfcomm, contém as classes especializadas para a comunicação utilizando o protocolo RFCOMM.
- ClientRFCOMMCommunication: Classe que implementa a conexão em RFCOMM por parte do cliente.
- RFCOMMCommunication: Classe abstrata que define um esqueleto de como funciona a conexão e as trocas de mensagens entre o cliente e servidor RFCOMM.
- ServerRFCOMMCommunication: Classe que implementa a conexão em RFCOMM por parte do servidor.
O pacote net.java.dev.marge.entity contém as entidades básicas do framework.
- Client: Interface que define métodos de um cliente genérico.
- ClientDevice: Classe que define a estrutura de um dispositivo cliente.
- Device: Classe abstrata que define a estrutura de um dispositivo genérico.
- Server: Interface que define métodos de um servidor genérico.
- ServerDevice: Classe que define a estrutura de um dispositivo servidor.
O pacote net.java.dev.marge.entity.config contém as configurações necessárias para que o framework instancie um cliente ou servidor.
- ClientConfiguration: Classe abstrata de configuração de um cliente.
- Configuration: Classe abstrata de configuração genérica.
- ServerConfiguration: Classe abstrata de configuração de um servidor
O pacote net.java.dev.marge.factory contém as fábricas, responsáveis pela instanciação de clientes e servidores para cada protocolo.
- AbstractCommunicationFactory: Interface que define métodos para criação de dispositivos clientes e servidores.
- L2CAPFactory: Classe que define métodos para criação de dispositivos clientes e servidores que usam o protocolo L2CAP para comunicação.
- RFCOMMCommunicationFactory: Classe que define métodos para criação de dispositivos clientes e servidores que usam o protocolo RFCOMM para comunicação.
O pacote net.java.dev.marge.inquiry contém as classes especializadas pelas buscas de dispositivos e serviços que envolvem o protocolo SDP, utilizado para descoberta de serviços.
- DevicesFoundListener: Interface que contém métodos relativos a busca de dispositivos.
- Discoverer: Classe que realiza a busca de dispositivos e serviços.
- ServicesFoundListener: Interface que contém métodos relativos a busca de serviços.
Como começar?
Para criar uma instância de um servidor – representado pela classe ServerDevice do pacote net.java.dev.marge.entity – ou cliente – representado pela classe ClientDevice desse mesmo pacote – primeiramente é necessário definir o protocolo de comunicação a ser adotado.
- Caso se decida pelo RFCOMM, todas as instâncias criadas, do tipo cliente ou servidor, serão instanciadas através da fábrica RFCOMMComunicationFactory;
- Caso seja a L2CAP, será usada a fábrica L2CAPComunicationFactory.
As fábricas pertencem ao pacote net.java.dev.marge.factory e possuem os métodos createClient e createServer, que retornam o tipo específico de Device que contém os métodos que podem ser invocados.
Cada um desses métodos recebe como parâmetro uma instância concreta da classe Configuration do pacote net.java.dev.marge.entity.config, podendo ser uma ServerConfiguration ou ClientConfiguration.
Inicialmente, essas configurações já possuem alguns valores padrão para funcionar, porém eles podem ser alterados manualmente caso necessário.
Um ServerConfiguration deve obrigatoriamente receber, no construtor, um CommunicationListener, que é uma interface pertencente ao pacote net.java.dev.marge.communication que define métodos para tratamento das seguintes situações: quando uma mensagem é recebida; quando ocorre um erro na recepção de uma mensagem; quando ocorre um erro no envio de uma mensagem; e quando uma conexão é estabelecida.
Um ClientConfiguration deve também obrigatoriamente receber um CommunicationListener no construtor, porém também deve receber um objeto que implemente a interface DevicesFoundListener, do pacote net.java.dev.marge.inquiry, que contém métodos associados à busca por dispositivos e a possíveis erros encontrados nessa busca; e um objeto que implemente a interface ServicesFoundListener, deste mesmo pacote, que contém métodos associados à busca por serviços e a possíveis erros encontrados.
- Um servidor RFCOMM é criado através da configuração mandada por parâmetro para a fábrica.
- Após isso, a sua escuta é iniciada.
- Quando alguém se conectar a ele, o listener2, definido pela interface net.java.dev.marge.communication.ConnectionListener, irá avisá-lo.
- Após a conexão, o servidor pode enviar normalmente mensagens para o cliente conectado e ele será também notificado, pelo mesmo listener, das mensagens que forem recebidas.
- Em seguida são mostrados alguns trechos de código que demonstram como o framework é utilizado pelo servidor.
Instanciando um servidor com a comunicação RFCOMM e iniciando sua escuta:
AbstractCommunicationFactory factory = new RFCOMMCommunicationFactory(); ServerConfiguration sconf = new ServerConfiguration(new CommunicationListenerImpl()); ServerDevice server = (ServerDevice) factory.createServer(sconf); server.start();
Servidor enviando uma mensagem:
server.send("Test message");
- Um cliente RFCOMM é criado através da configuração mandada por parâmetro para a fábrica.
- Após isso, ele faz uma busca por dispositivos com Bluetooth ligado. O listener, definido pela interface net.java.dev.marge.inquiry.DevicesFoundListener, retorna os dispositivos encontrados.
- Depois faz-se uma busca pelos serviços desejados no dispositivo encontrado escolhido. O listener, definido pela interface net.java.dev.marge.inquiry.ServicesFoundListener, retorna o serviço, caso ele seja encontrado.
- Com esse serviço, o dispositivo cliente se conecta ao servidor e é notificado pelo listener, definido pela interface net.java.dev.marge.communication.ConnectionListener, que houve a conexão.
- Após a conexão, o cliente pode enviar normalmente mensagens para o servidor e ele será também notificado, pelo mesmo listener, das mensagens que forem recebidas.
A seguir são apresentados alguns trechos de código relacionados ao uso do framework no cliente:
Instanciando um cliente com comunicação RFCOMM e iniciando um busca por dispositivos:
AbstractCommunicationFactory factory = new RFCOMMCommunicationFactory(); ClientConfiguration cconf = new ClientConfiguration(new ServiceListenerImpl(), new DevicesListenerImpl(), new CommunicationListenerImpl())); ClientDevice client = (ClientDevice) factory.createClient(cconf); client.startInquiry(DiscoveryAgent.GIAC);
Cliente iniciando uma busca por serviços em um determinado dispositivo encontrado:
client.searchServices(client.getUuidset(), remoteDeviceFound);
Cliente conectando-se a um serviço encontrado previamente:
client.connect(serviceRecordFound);
Cliente enviando uma mensagem:
client.send("Test message");
Dúvidas, críticas e sugestões. Usem os comentários, ou mandem email para gabriel@ecomp.eng.br
Terei grande satisfação em ajudar!
Até o próximo post!