miércoles, 30 de marzo de 2011

Bluetooth

Bluetooth es una especificación industrial para Redes Inalámbricas de Área Personal (WPANs) que posibilita la transmisión de voz y datos entre diferentes dispositivos mediante un enlace por radiofrecuencia en la banda ISM de los 2,4 GHz. Los principales objetivos que se pretenden conseguir con esta norma son:

  • Facilitar las comunicaciones entre equipos móviles y fijos.

  • Eliminar cables y conectores entre éstos.

  • Ofrecer la posibilidad de crear pequeñas redes inalámbricas y facilitar la sincronización de datos entre equipos personales.

En la actualidad, una gran variedad de dispositivos electrónicos disponen de conexión bluetooth, entre ellos el más generalizado es el teléfono móvil, por este motivo este manual está centrado en la unión de éstas tecnologías.

La combinación de Java con Bluetooth nos permite diseñar aplicaciones versátiles, portables y con un número creciente de clientes potenciales

  1. Estado del arte


Bluetooth

Mientras que el hardware Bluetooth había avanzado mucho, hasta hace relativamente poco no había manera de desarrollar aplicaciones java Bluetooth – hasta que apareció JSR 82, que estandarizó la forma de desarrollar aplicaciones Bluetooth usando Java. Ésta esconde la complejidad del protocolo Bluetooth detrás de unos APIs que permiten centrarse en el desarrollo en vez de los detalles de bajo nivel del Bluetooth.

Estos APIs para Bluetooth están orientados para dispositivos que cumplan las siguientes características:

• Al menos 512K de memoria libre (ROM y RAM) (las aplicaciones necesitan memoria adicional).

• Conectividad a la red inalámbrica Bluetooth.

• Que tengan una implementación del J2ME CLDC.

Bluecove

Existen varias librerías para programar dispositivos bluetooth en Java, entre ellas Bluecove es una librería de código abierto ampliamente extendida, con lo que es estable.

La librería Bluecove no es más que un conjunto de clases del API JSR-82 contenidas en un archivo .jar, el cual habrá que añadir al classpath en el momento de la compilación y la ejecución para que funcione.

Bluecove es una implementación libre del API JSR-82 en J2SE. Gracias a Bluecove y haciendo unos pequeños cambios en el código fuente es posible portar una aplicación Bluetooth J2ME a J2SE.

Los APIs Java para Bluetooth definen dos paquetes que dependen del paquete CLDC javax.microedition.io:

  • javax.bluetooth

  • javax.obex



J2ME


La plataforma Java Micro Edition, o anteriormente Java 2 Micro Edition(J2ME), es una especificación de un subconjunto de la plataforma Java orientada a proveer una colección certificada de APIs de desarrollo de software para dispositivos con recursos restringidos. Está orientado a productos de consumo como PDAs, teléfonos móviles o electrodomésticos.

Java ME se ha convertido en una buena opción para crear juegos en teléfonos móviles debido a que se puede emular en un PC durante la fase de desarrollo y luego subirlos fácilmente al teléfono. Al utilizar tecnologías Java el desarrollo de aplicaciones o videojuegos con estas APIs resulta bastante económico de portar a otros dispositivos.

Java ME fue desarrollado mediante el Java Community Process bajo la especificación JSR 68. La evolución de la plataforma ha propiciado el abandono de las Java Specification Request (peticiones de especificación para Java) en favor de JSRs separadas para las distintas versiones de Java ME.



OBEX

OBEX es un protocolo diseñado por el IrDA para intercambiar objetos entre clientes y servidor, mediante el establecimiento de una sesión.

OBEX implementa la transferencia de objetos estableciendo una sesión, similar al protocolo HTTP. Para iniciarla se usa una petición CONNECT y para terminar ésta una petición DISCONECT. Entre estas dos peticiones, el cliente puede traer objetos del servidor mediante GET, o enviarlos mediante PUT. Los objetos pueden ser archivos, arrays de bytes, etc.

El cliente puede cambiar el archivo o carpeta en uso mediante la petición SETPATH. Otras operaciones permitidas son; ABORT, CREATE-EMPTY, PUT-DELETE. OBEX, como HTTP, tiene métodos que le permiten pasar información adicional entre el cliente y el servidor mediante el uso de cabeceras.


  1. Instalación



Antes de utilizar la librería es necesario tener disponible una versión de Java (JDK) y el entorno en el que trabajar, el cual puede ser Eclipse o NetBeans, en este manual se hará en Eclipse (Ganymede).

Una vez esté montado el entorno con la última versión de Java y el entorno instalado, descargar las últimas versiones disponibles de la librería Bluecove desde la siguiente ubicación: http://sourceforge.net/project/showfiles.php?group_id=114020

  • bluecove-*.jar: módulo principal, incluye el soporte para las pilas de Mac OS X, WIDCOMM, BlueSoleil and Microsoft Bluetooth.

  • bluecove-gpl-*.jar: adiciona el soporte para la pila en Linux.

Descargar estos archivos JAR en una ubicación conocida. Por ejemplo en la carpeta \Documentos\Bluetooth

Crear un nuevo proyecto Java desde el entorno Eclipse, en el la barra de herramientas seleccionar:

File -> New Proyect –> Java Proyect

Importar el JAR en el proyecto:

  1. En la capeta de proyecto pulsar sobre el botón derecho del ratón y seleccionar Propierties

  1. Seleccionar “Java Build Path” y pulsar sobre la pestaña “Libraries”, en esta zona se listarán todas las librerías. Para utilizar la librería puede hacerse mediante una variable o añadiendo el JAR diréctamente. Esta segunda opción es menos portable pero más rápida.

Ilustración 2

  1. Pulsar sobre “Add External JARs”, esta opción abrirá una ventana de exploración para que se seleccione el JAR que se descargó previamente. En este ejemplo la librería estaba dentro de Documentos\Bluetooth.

Ilustración 3


  1. Una vez sea seleccionada pulsar sobre Abrir, de esta forma se incluirá en las librerías del proyecto.


Ilustración 4

  1. Ejemplos prácticos


La anatomía de una aplicación Bluetooth está dividida en cuatro partes:

  • Inicialización de la pila.

  • Descubrimiento de dispositivos y servicios.

  • Manejo del dispositivo.

  • Comunicación.

Inicialización

Los dispositivos Bluetooth que implementen este API pueden permitir que múltiples aplicaciones se estén ejecutando concurrentemente. El BCC previene que una aplicación pueda perjudicar a otra. El BCC es un conjunto de capacidades que permiten al usuario resolver peticiones conflictivas de aplicaciones definiendo unos valores específicos para ciertos parámetros de la pila Bluetooth.

El BCC puede ser una aplicación nativa, una aplicación en un API separado, o sencillamente un grupo de parámetros fijados por el proveedor que no pueden ser cambiados por el usuario. Hay que destacar, que el BCC no es una clase o un interfaz definido en esta especificación, pero es una parte importante de su arquitectura de seguridad.

La pila Bluetooth es la responsable de controlar el dispositivo Bluetooth, por lo que es necesario inicializarla antes de hacer cualquier otra cosa. El proceso de inicialización consiste en un número de pasos cuyo propósito es dejar el dispositivo listo para la comunicación inalámbrica.

Desafortunadamente, la especificación deja la implementación del BCC a los vendedores, y cada vendedor maneja la inicialización de una manera diferente. En un dispositivo puede haber una aplicación con un interfaz GUI, y en otra puede ser una serie de configuraciones que no pueden ser cambiados por el usuario.

Esto produce una gran variedad de pilas distintas, llegándose a situaciones en la que la pila del dispositivo es incompatible con la pila implementada por las librerías. Por lo que hay que asegurarse de la compatibilidad entre el hardware y el software empleados.

Descubriendo dispositivos Bluetooth.

Algo básico en el manejo de aplicaciones que utilizan bluetooth es la detección de dispositivos a los que se podrá conectar. Para ello se hará uso de la librería javax.bluetooth.

Implementación

En este ejemplo, cuando se identifica a un nuevo dispositivo Bluetooth (ver deviceDiscovered) se obtiene su dirección, de ser posible su nombre y se agrega en la lista de dispositivos encontrados “dispositivosEncontrados”.


Ilustración 5

Para descubrir dispositivos se parte de un objeto que implementa DiscoveryListener, el cual define que se debe hacer cuando se encuentra un nuevo dispositivo y cuando se termina la búsqueda.



Ilustración 6


Para ejecutar finalmente la búsqueda de dispositivos de acuerdo con el comportamiento definido anteriormente, se crea un objeto sobre el cual se sincronizarán las próximas acciones. Con él se inicia la búsqueda de dispositivos accediendo al Agente Descubridor del Dispositivo Local.



Ilustración 7

Finalmente se verifica que la búsqueda haya comenzado exitosamente y se espera para garantizar su ejecución.


if (started)

{

System.out.println("Starting Device Discovery process ...");

/**

* Wait for Discovery Process end

*/

inquiryCompletedEvent.wait();

System.out.println("There was " + devicesDiscovered.size() + " device(s) found");

}



La salida de la aplicación.

La aplicación de demostración deberá imprimir por consola la información de los dispositivos Bluetooth que se encuentren cerca durante el tiempo que dure la búsqueda. Algo similar a lo siguiente.

Ilustración 8

En la respuesta anterior se puede apreciar que la aplicación detectó exitosamente a un teléfono móvil.

Cliente - Servidor.


En este apartado se explicarán algunos detalles de la implementación, tanto del cliente J2ME como del servidor J2SE. Ya se ha visto la teoría acerca de la inicialización, búsqueda de dispositivos y servicios.

OBEX, descrito anteriormente permite la autenticación entre cliente y servidor.


Conexión del cliente.


Para crear una conexión OBEX, el cliente le debe pasar el string apropiado al Connector.open(), y este devolverá un objeto javax.obex.ClientSession.

Para establecer la conexión OBEX el cliente crea un objeto javax.obex.HeaderSet usando el método createHeaderSet() del interfaz ClientSession. Finalmente el cliente facilita el objeto HeaderSet al método connect() de la interfaz ClientSession.

Para determinar si la petición ha tenido éxito o no, se usa el método getResponseCode() del interfaz HeaderSet, que devuelve un código de respuesta mandado por el servidor, que viene definido en la clase javax.obex.ResponseCodes.

Para la petición DISCONECT, se procede del mismo modo, excepto que en vez de usar el método connect() se usa el método disconnect().

Para completar una operación SETPATH, el cliente llama al método setPath() en el objeto ClientSession. Para especificar el nombre del directorio destino, pone el nombre llamando al método setHeader() del HeaderSet. Si la cabecera es muy larga se lanzará una excepción java.io.IOException.

Para completar una operación GET o PUT, el cliente crea un objeto javax.obex.HeaderSet con el método createHeaderSet(). Después de establecer los valores de cabecera, el cliente llama a los métodos put() o get() del objeto javax.obex.ClientSession.

Para abortar un PUT o un GET, el cliente llama al método abort() del objeto javax.obex.Operation. El método abort() llama además al método close() del objeto Operation.

En cualquier aplicación basada en Bluetooth, una vez inicializada la pila, se procedería a buscar los dispositivos cercanos para luego buscar los servicios que ofrecen y que nos interesan. Para ello lo típico es mostrar en pantalla los dispositivos encontrados para luego seleccionar uno de ellos y buscar sus servicios.

Una vez leído los dispositivos disponibles ya tendremos la dirección bluetooh servidor de nuestro PC.

Si todos los pasos anteriores se han llevado a cabo correctamente, solo falta obtener la URL del servidor para abrir la conexión y enviar el mensaje.


Conexión del servidor.


Para crear una conexión servidora, el servidor invoca a Connector.open(), que le devuelve un objeto javax.obex.SessionNotifier. Este objeto espera a que el cliente cree una capa de transporte llamando a acceptAndOpen().

El servidor debe crear una nueva clase que extienda la clase javax.obex.serverRequestHandler e implementar aquellos métodos de OBEX a los que da soporte. Las aplicaciones servidoras no deben llamar al método abort(), ya que si no el argumento Operation, que es parte de los métodos onGet() y onPut(), lanzará una java.io.IoException.

Una vez que se comprueba el funcionamiento correcto de ambas partes, hay que asegurar la compatibilidad entre J2ME y J2SE. El principal problema que conlleva esto es la falta de librerías deBluetooth en J2SE, por lo que se tuvo que recurrir a Bluecove.






6 comentarios:

  1. Hola! me gustaria saber que manejador de pila utilizaste? Ya que he estado implementando el codigo que aparece en tu blog, pero me sale un error.

    Exception in thread "main" javax.bluetooth.BluetoothStateException: BluetoothStack not detected

    ResponderEliminar
  2. Hola que tal espero que estén muy bien.

    Me podrían proporcionar todo el proyecto se los agradeseria

    ResponderEliminar
  3. me pasas el código porfavor lo agradeceria mucho

    ResponderEliminar
    Respuestas
    1. http://www.mediafire.com/file/1j5zr4mcima/pruebaBluetooth.rar#!

      EL CODIGO !

      Eliminar