Está en la página 1de 14

1-Introduccin

1.1-Que es Bluetooth? Bluetooth es una tecnologa de comunicacin que utiliza seales de radio de corto alcance parar reemplazar los cables que comunican las redes comnmente. Su principal objetivo es ser utilizado por pequeos dispositivos, por lo que tena que ser una tecnologa barata, pequea y de bajo coste. La especificacin de Bluetooth nos define un canal de comunicacin de 720Kb segundo como mximo, con un alcance ptimo de 10 metros o de 100 metros dependiendo del dispositivo. 1.2-Historia El nombre de tecnologa proviene de un rey dans y noruego Harald Bltand cuyo apellido se traducira al Ingles como Bluetooth, fue famoso por unificar a las tribus noruegas, danesas y suecas. Al igual que Harald uni esas tribus, se esperaba que el bluetooth uniese los dispositivos mviles, los ordenadores y los perifricos. Los orgenes de las comunicaciones Bluetooth comenzaron en 1994, cuando Ericsson empez a investigar alternativas para comunicar mviles con ciertos accesorios. Para ello decidieron que para que esta tecnologa tuviese xito tendra que ser un estndar abierto y no propietario. Por lo que a principios de 1998 Ericsson se uni a Intel, IBM, Nokia y Toshiba para formar el Bluetooth Special Interest Group (SIG) para desarrollar esta tecnologa. Ms compaas se aadieron posteriormente, y en julio de 1999 SIG publico la primera versin 1.0 de la especificacin Bluetooth. 1.3-Estructura Red Bluetooth Los terminales Bluetooth utilizan unas pequeas redes de comunicaciones llamadas piconets. En estas pequeas redes se pueden llegar a conectar 8 dispositivos, donde uno ser el dispositivo maestro, siendo este en principio el primer dispositivo que establece la piconet. La unidad maestra ser la encargada de controlar el trfico de esta red. El resto de dispositivos sern unidades esclavas, las cuales se conectan directamente con el dispositivo maestro para poder interactuar con las dems. El siguiente esquema muestra una piconet:

Varias de estas Piconets pueden establecer comunicacin entre ellas formando una scatternet, de esta forma pueden comunicarse ms dispositivos, o aprovechar ms el ancho de banda, ya que de estas forma al tener diferentes canales cada piconet, los dispositivos que necesiten comunicarse en mayor medida se ven menos limitados.

1.4-Protocolos de Bluetooth La pila de protocolos Bluetooth esta formada por muchos protocolos pero solo unos cuantos nos interesan para las JABWT (Java APIs for Bluetooth Wireless technology), podemos ver un esquema de estos protocolos y una descripcin de los definidos por j2me:

Logical Link Control and Adaptation Protocol (L2CAP): este protocolo proporciona servicios de datos orientados o no a conexin a los protocolos de las capas superiores. Tambin multiplexa entre las conexiones lgicas creadas por las capas superiores. Service Discovery Protocol (SDP): este protocolo nos permite encontrar los servicios que nos ofrecen otros dispositivos. RFCOMM: Este protocolo proporciona una emulacin de los puertos serie sobre L2CAP. Object Exchange protocol (OBEX): es un protocolo adoptado, no es propio de la tecnologa bluetooth que nos permite intercambiar objetos entre dispositivos.

Un elemento a tener en cuenta es el Bluetooth Control Center (BCC) que se encarga de controlar peticiones conflictivas entre aplicaciones. El BCC no esta definido para las especificaciones JABWT, suele venir definido por el fabricante y por lo tanto es transparente al usuario y al desarrollador. Depende del fabricante la disponibilidad de cambio del BCC. 1.5- Perfiles Bluetooth Un perfil Bluetooth nos define formas estandarizadas de usar protocolos para ciertos modelos. O dicho de otra forma, define como pueden ser utilizadas las diferentes partes del estndar Bluetooth para cierto uso.

Un dispositivo Bluetooth puede soportar uno o ms de estos perfiles, hay cuatro de estos perfiles: Generis Access Profile (GAP) : Es la base de todos los perfiles, el resto esta basado en este perfil. GAP nos define los procedimientos bsicos para establecer conexiones entre 2 dispositivos, incluyendo el descubrir dispositivos Bluetooth, sus configuraciones y procedimientos relacionados con la seguridad. Serial Port Profile (SPP) : Define los requerimientos necesarios para que los dispositivos Bluetooth configuren conexiones emuladas de cable serie usando RFCOMM entre dos dispositivos. Service Discovery Aplication Profile (SDAP): Describe las operaciones necesarias para encontrar dispositivos. Este perfil define los protocolos y procedimientos requeridos por las aplicaciones para localizar servicios en otros dispositivos. Generis Object Exchange Profile (GOEP): Este perfil es el utilizado con OBEX.

1.6-Que es J2ME? Java 2 Platform Micro Edition. Desarrollada por Sun como una plataforma para la programacin de dispositivos inalmbricos. El J2ME permite que los desarrolladores usen Java y las herramientas inalmbricas J2ME para crear aplicaciones y programas para dispositivos mviles estos dispositivos inalmbricos tienen menos potencia y mucha menor capacidad grfica que los PC de escritorio. Por ello, J2ME representa una versin simplificada de J2SE pensada para dispositivos con estas limitaciones. J2ME se basa en dos elementos: configuraciones y perfiles. Las configuraciones suministran el conjunto de libreras y la maquina virtual adecuada para cierta categora de dispositivos mviles, en J2ME hay dos categoras la Conected Device Configuration (CDC) orientada a dispositivos de gama alta y la Conected Limited Device Configuration (CLDC1 y CLDC1.1) para dispositivos ms limitados como pda o telefona celular. Los perfiles son APIs integradas por encima de las configuraciones CLDC, para proveer un ambiente de funcionamiento ms especifico para cada dispositivo. Estos dispositivos pueden ser PDAs, telefona celular, o set-top boxes. El perfil administra la aplicacin, la interfaz de usuario, las redes y la transmisin de datos. El perfil utilizado en J2ME es el de Mobile Information Device Profile (MIDP 1 y MIDP 2). Las libreras necesarias para la utilizacin de Bluetooth con J2ME estn incluidas en las Java Specification Request 82 (JSR-82).

2-Buscando Dispositivos
2,1-Visin General Dado que los dispositivos que incluyen Bluetooth suelen moverse de su posicin continuamente, estos han de ser capaces de localizar nuevos dispositivos dinmicamente en cualquier lugar. Adems a de ser capaz de reconocer que servicios ofrece cada dispositivo en rango de localizacin. La localizacin de dispositivos y los servicios que estos ofreces son procesos diferentes, por lo que dedicar un tema a cada uno. A una bsqueda de dispositivos se le denomina inquiry (Investigacin). Cuando un dispositivo realiza una inquiry, el resto de dispositivos responder a sta o no dependiendo de su mtodo de descubrimiento (discoverable mode) asignado, esta respuesta estar compuesta por una direccin bluetooth de 6 bytes. Hay dos tipos de inquirys : generales y limitadas. Una inquiry general encontrar todos los dispositivos en el rea, mientras que una inquiry limitada encontrar aquellos dispositivos que solo puedan ser localizados por un cierto periodo de tiempo, por lo que las conexiones con estos dispositivos no son estables. Un ejemplo de dispositivo ideal para poner en estado general seria una impresora, mientras que un telfono sera ms adecuado ponerlo en modo limitado. Lgicamente la mayora de dispositivos pueden adems ponerse en modo oculto, para que ninguna de estas inquiry los detecten. 2.2-Dispositivo Local La clase LocalDevice nos proporciona acceso a datos del dispositivo utilizado. Esta clase tiene un constructor privado que nos impide crear un objeto LocalDevice nuevo, por lo que solo podremos obtener una referencia del mismo con el mtodo LocalDevice.getLocalDevice(), este mtodo puede lanzar un BLuetoothStateException si no funciona correctamente el sistema Bluetooth. Una vez obtenido este objeto podemos conseguir bastantes datos importantes del mismo. Para obtener la direccin de nuestro dispositivo tenemos que usar la clase getBluetoothAddress(), para el nombre GetFriendlyName, el tipo de mtodo de descubrimiento lo obtenemos con getDiscoverable(), este ultimo retorna unas constantes que estn incluidas de modo esttico en el objeto DiscoveryAggent. Para modificarlo podremos usar la funcin setDiscoverable(), per puede dar un BluetoothStateException en caso de Error. La clase LocalDevice tiene adems un mtodo llamado getProperty() para obtener informacin adicional, aunque es recomendable usarlo de forma esttica. Este mtodo es parecido al System.getProperty de J2SE, y algunas de estas propiedades son las siguientes: Propiedad bluetooth.connected.devices.max bluetooth.api.version bluetooth.sd.attr.retrievable.max bluetooth.connected.inquiry.scan Descripcin Mximo numero de dispositivos conectados. Versin de JABWT soportada. Mximo numero de atributos por servicio. Posibilidad de recibir inquirys cuando se esta conectando con otro dispositivo.

Bluetooth.conected.inquiry

Posibilidad de realizar inquirys cuando se esta conectando con otro dispositivo.

El siguiente ejemplo muestra como se obtiene los datos del objeto LocalDevice y el resultado de leer algunas de las propiedades del mismo.
public class BTInfo extends MIDlet implements CommandListener { Display display; LocalDevice local; Form infoForm; public BTInfo() {} protected void startApp() throws MIDletStateChangeException { display=Display.getDisplay(this); infoForm= new Form("Informacin del Dispositivo:"); display.setCurrent(infoForm); local=null; local=LocalDevice.getLocalDevice(); } catch (BluetoothStateException e) { infoForm.append("Error al buscar el dispositivo local."); } infoForm.append("Direccin:"+local.getBluetoothAddress()+"\n"); infoForm.append("Nombre:"+local.getFriendlyName()+"\n"); int modo=local.getDiscoverable(); StringBuffer texto=new StringBuffer("Modo de descubrimiento: "); switch (modo) { case DiscoveryAgent.NOT_DISCOVERABLE: texto.append("OCULTO"); break; case DiscoveryAgent.GIAC: texto.append("GENERAL"); break; case DiscoveryAgent.LIAC: texto.append("LIMITADO"); break; default: texto.append("0x"+Integer.toString(modo,16)); break; } infoForm.append(texto.toString()+"\n"); //Leo Propiedades infoForm.append("Versin API:"+LocalDevice.getProperty("bluetooth.api.version")+"\n"); infoForm.append("Mximo numero de atributos:"+LocalDevice.getProperty("bluetooth.sd.attr.retrievable.max")+"\n"); infoForm.append("Mx Disp. Conectados:"+LocalDevice.getProperty("bluetooth.connected.devices.max")+"\n"); infoForm.append("Mult. Inquiry resp. soportado:"+LocalDevice.getProperty("bluetooth.connected.inquiry.scan")+"\n"); infoForm.append("Mult. Inquiry inic. soportado:"+LocalDevice.getProperty("bluetooth.connected.inquiry")+"\n"); infoForm.addCommand(new Command("Salir",Command.EXIT,1)); infoForm.setCommandListener(this); } public void commandAction(Command c, Displayable d) { if (c.getCommandType()==Command.EXIT){ notifyDestroyed(); } } protected void pauseApp() {} protected void destroyApp(boolean arg0) throws MIDletStateChangeException {} try {

El resultado que obtenemos de este ejemplo en un dispositivo en modo oculto es el siguiente:

2.3-Descubrir Dispositivos JAWT nos ofrece dos clases para la bsqueda de dispositivos, la clase DiscoveryAgent y la interfaz DiscoveryListernet, esta interfaz requiere que se implemente los mtodos servicesDiscovered, serviceSerachCompleted, inquiryCompleted y deviceDiscovered. Cada dispositivo Bluetooth dispone de un objeto DiscoveryAgent que nos ofrece metodos para comenzar Inquirys. La interfaz DiscoveryListener es utilizada por la clase DiscoveryAgente para pasar dispositivos y servicios a la aplicacin. El objeto DiscoveryAgent se obtiene del metodo LocalDevice.getDiscoveryAgent(). A travs de la funcin DiscoveryAgent.retrieveDevices() obtendremos los dispositivos encontrados. Esta funcin pide como parmetro un entero que indica el tipo de dispositivos a buscar, ya que para algunos de estos dispositivos no hay que hacer una Inquiry. Estos tipos de dispositivos estn guardados como constantes en la clase DiscoveryAgent y son: DiscoveryAgent.PREKNOW: Lista de dispositivos conocidos. DiscoveryAgent.CACHED: Lista de dispositivos de la ultima bsqueda.

DiscoveryAgent.GIAC: Lista de dispositivos encontrado en una inquiry de tipo General. DiscoveryAgent.LIAC: Lista de dispositivos encontrado en una inquiry de tipo Limitado.

Hay que tener en cuenta que tanto para el PREKNOW como el CACHED no hay que realizar ninguna bsqueda y el nmero de dispositivos guardados es controlado por el software del fabricante. Para comenzar una inquir deberemos llamar al mtodo startInquiry del DiscoveryAgent, que requiere como parmetro el tipo de inquiry (GIAC/LIAC). El mtodo retornar true si el dispositivo acepta ese tipo de inquiry sino devolver false, adems disparar un BLuetoothStateException sino se a podido completar la inquiry. Una vez comenzada la bsqueda, JABWT retornar eventos deviceDiscovered() a la aplicacin cada vez que se encuentre un dispositivo Bluetooth. Este metodo suministrar el objeto RemoteDevice y el DeviceClass. El objeto RemoteDecive contiene funcionalidad similar a la del LocalDevice, y el DeviceClass la clase de dispositivo. Otro evento es el InquiryCompleted con el que podremos saber si la bsqueda a finalizado correctamente o no, ya que nos aporta un entero que indica el tipo de finalizacin. Este tipo esta incluido en el objeto DiscoveryListener, siendo DiscoveryListener.INQUIRY_COMPLETED la que indica una finalizacin correcta. A continuacin muestro un ejemplo en el que se buscan todos los dispositivos conocidos o en cache y se realiza una inquiry en modo Genrico:
public class Descubrir extends MIDlet implements DiscoveryListener,CommandListener { private List listaDispositivos=null; private DiscoveryAgent agente; private LocalDevice local=null; public Descubrir() {super();} public void commandAction(Command c, Displayable d){ if (c.getCommandType()==Command.EXIT){ agente.cancelInquiry(this); notifyDestroyed(); } } protected void startApp() throws MIDletStateChangeException { listaDispositivos=new List("Lista de Dispositivos",List.IMPLICIT); listaDispositivos.addCommand(new Command("Salir",Command.EXIT,1)); listaDispositivos.setCommandListener(this); Display.getDisplay(this).setCurrent(listaDispositivos); try { local=LocalDevice.getLocalDevice(); agente=local.getDiscoveryAgent(); } catch (BluetoothStateException e) { throw new MIDletStateChangeException( "No se encontro el dispositivo Bluetooth."); } //Realizo una inquiry en modo general try { agente.startInquiry(DiscoveryAgent.GIAC,this); } catch (BluetoothStateException e) { throw new MIDletStateChangeException( "No se pudo realizar la inquiry."); } //Obtengo los dispositivos Conocidos RemoteDevice[] list = agente.retrieveDevices(DiscoveryAgent.PREKNOWN); if (list!=null) for (int i=0;i<list.length;i++) listaDispositivos.insert(0,list[i].getBluetoothAddress()+"-P",null); //Obtengo los dispositivos en Cache

list = agente.retrieveDevices(DiscoveryAgent.CACHED); if (list!=null) for (int i=0;i<list.length;i++) listaDispositivos.insert(0,list[i].getBluetoothAddress()+"-C",null);

protected void pauseApp() {} protected void destroyApp(boolean arg0) throws MIDletStateChangeException {} public void deviceDiscovered(RemoteDevice arg0, DeviceClass arg1) { listaDispositivos.insert(0,arg0.getBluetoothAddress()+"-I",null); } public void servicesDiscovered(int arg0, ServiceRecord[] arg1) {} public void serviceSearchCompleted(int arg0, int arg1) {} public void inquiryCompleted(int arg0) { Alert dialog=null; if (arg0!=DiscoveryListener.INQUIRY_COMPLETED){ dialog=new Alert("Bluetooth Error","LA inquiry fallo",null,AlertType.ERROR); }else{ dialog=new Alert("Inquiry Realizada","LA busqueda de dispositivos finalizo correctamente.",null,AlertType.INFO); } dialog.setTimeout(Alert.FOREVER); Display.getDisplay(this).setCurrent(dialog); } }

Este ejemplo se ejecut en el emulado de sun, probando a la vez con dos emulaciones ejecutados de un ejemplo incluido del mismo Wireless Toolkit:

2.5-Datos Obtenidos de cada Dispositivo Con las bsquedas realizadas conseguimos los objetos RemoteDevice y DeviceClass. Del primer objeto y gracias a la funcin getBluetoothAdress obtenemos la direccin del dispositivo, con la funcin getFriendlyName el nombre del mismo. Adems podemos aportar cierta seguridad con los metodos encript, autentcate y authorize.

El objeto DeviceClass retorna un entero que representa los servicios disponibles en el dispositivo. Este entero contiene tanto el servicio como el tipo de dispositivo. Para obtener el tipo de dispositivo hay que usar la clase getMajorDeviceClass, para el tipo de servicio hay que usar el mtodo getServiceClasses.

3-Buscando Servicios
3.1-Visin General Una vez localizados los dispositivos que tenemos en el rea, el prximo paso antes de comunicarnos con otro dispositivo es buscar los servicios que este nos ofrece. En la bsqueda de dispositivos se realizaba un proceso de localizacin para todos los dispositivos en alcance, pero el proceso de localizar los servicios involucra nicamente dos dispositivos. Estos dos dispositivos buscaran un identificador del servicio en comn, para despus realizar la comunicacin. La bsqueda de servicios es un modelo cliente-servidor. El servidor ofrece un servicio que los clientes pueden localizar cuando estos realicen una bsqueda de dispositivos y le pregunten al servidor que servicios tiene. El servidor retornar un objeto con los servicios que tiene registrados en la Base de Datos de Bsqueda de Servicios (BDBS), que manejar la BCC y como ya especifique anteriormente los procesos realizados por la BCC suelen resultar transparentes al programador. Cuando el servidor recibe una peticin de consulta de un servicio, buscar en la BDBS el servicio especificado. Un cliente tendr que realizar una consulta para saber si el servidor dispone del servicio adecuado, pero el servidor internamente tiene que realizar ms procesos para ofrecer un servicio: 1. 2. 3. 4. 5. Crear un registro de servicio que describa el servicio a ofrecer por la aplicacin. Aadir el servicio a la BDBS del servidor para que los clientes puedan localizarlo. Registra las medidas de seguridad adecuadas para el servicio. Aceptar las conexiones de los clientes que pidan un servicio existente en la BDBS. Modificar el registro del servicio en la BDBS si se modifican las caractersticas de servicio durante todo este proceso. 6. Borrar o bloquear el registro del servicio de la BDBS cuando no se deba acceder a este. (Que se cierre la aplicacin por ejemplo).

3.2-Crear un Servicio

Para crear un nuevo servicio en el servidor, lo nico que tenemos que hacer es llamar al mtodo open() del objeto Connection pasndole como parmetro una URL con unas caractersticas determinadas. Al llamar a la funcin open nos retornara un objeto notifier al que se le aplicar una interfaz determinada dependiendo del protocolo. Una vez obtenido el objeto notifier hemos creado el servicio, pero no lo hemos guardado en la BDSB ni publicado, para ello llamaremos a la funcin acceptandOpen del objeto notifier. Esta funcin nos retornara un objeto conection que usara otra interfaz dependiendo del protocolo.
Las diferentes interfaces a utilizar as como la lnea de la url que define el protocolo, estn indicadas en la siguiente tabla:

Protocolo Diferencia en URL Notifier RFCOMM btspp: L2CAP OBEX btl2cap: btgoep:

Connector

StreamConnectionNotifier StreamConnection L2CAPConnectionNotifier L2CAPConnection SessionNotifier SessionConnection

Un ejemplo de una de estas url utilizando el protocolo RFCOMM seria:


Connector.open("btspp://localhost:68EA123423D425D65EED00B0D23D12EC;name=Prueba");

Esta URL internamente se transformar en un conjunto de objetos DataElement los cuales pueden ser: 1. 2. 3. 4. 5. 6. 7. 8. 9. Null Integer Unsigned integer URL UUID String Boolean DATALT -Array de DataElement alternativos DATSEQ -Array de DataElement secunciales

La lista de URL que he llamado anteriormente se convierte en una serie de valores. Concretamente con la URL ofrecida indicamos 2 parametros: el ServiceClassIdList y el Service RecordHandle. Hay otros dos parmetros que se crean automticamente el ProtocolDescriptorList que define datos para cada protocolo y el ServiceRecordHandle que asigna un valor al servidor.

ServiceClassIdList: es un DATSEQ formado por dos elementos. El primer elemento esta formado por el cdigo hexadecimal de 32 dgitos "68EA123423D425D65EED00B0D23D12EC", este nmero se utilizar para crear un UUID de 128 bits y se pondr en un objeto de tipo UUID. El segundo valor es un UUID de 16 bit que nos indica el tipo de protocolo, en este caso el 0x1101 indicado por la palabra btspp de la url. Con estos dos elementos podemos definir el servicio que ofrecemos. ServiceName: Indica el nombre del servicio que ofrecemos, en este caso el nombre ser prueba.

Una vez acabada la notificacin deberemos cerrar el notifier con el mtodo close(), esto borrar internamente el servicio de la BDSB, con lo que el servicio no se podr localizar hasta que lo volvamos a instanciar con otro acceptAndOpen. Podemos modificar el registro del Servicio para aadir ms informacin. Esto se tiene que realizar antes de que el servicio sea aadido a la BDSB va un acceptAndOpen. Para ello tenemos que enviar el objeto notifier obtenido a la funcin getRecord(notifier) que contiene el objeto LocalDevice local, esto nos retornara un objeto ServiceRecord. Al objeto ServiceRecord se le puede aadir cualquier elemento a travs de la funcin setAtributeValue del mismo, esta funcin requiere un cdigo hexadecimal para definir el DataElement que es el segundo parmetro.

El valor hexadecimal no puede estar comprendido entre 0x000D a 0x01FF que estn reservados. Adems hay dos atributos standars, el 0x000A para la url de documentacin del servicio y el 0x0101 para un String con la descripcin del servicio. Un ejemplo del cdigo necesario para crear un servicio y modificar el atributo de descripcin seria:

LocalDevice local= LocalDevice.getLocalDevice(); try{ StreamConnectionNotifier notifier= (StreamConnectionNotifier) Connector.open("btspp://localhost: 68EA123423D425D65EED00B0D23D12EC;name=Prueba"); catch(IOException e){return null;} ServiceRecord record = local.getRecord(notifier); record.setAttributeValue(0x0101, new DataElement(Dataelement.STRING, "Que gran juego! Es para dos personas, juguemos!")); StreamConnection conn=notifier.acceptAndOpen(); //Comunicacin conn.close(); notifier.close();

3,2-Buscar Servicios El proceso de bsqueda de servicios es bastante similar al de dispositivos, la clase tambin tiene que implementar la interfaz DiscoveryListener, adems de utilizar el objeto DiscoveryAgent para realizar la bsqueda. En el capitulo anterior cuando encontrbamos un dispositivo un evento llamaba a la funcin DeviceDiscovery y all obtenamos la clase RemoteDevice que guardbamos en un array, esta clase es importante por que la utilizaremos para buscar los servicios. La bsqueda de dispositivos comienza con una llamada a la funcin DiscoveryAgent.searchServices() que retornar un id de la transaccin de bsqueda de dispositivo si no hay error. La funcin searchServices requiere cuatro parmetros: 1. Array de atributos a obtener, estos son atributos extras que queremos obtener, por ejemplo el nombre del servicio (0x100). 2. Array de UUID: El UUID del servicio a buscar. 3. El objeto RemoteDevice del dispositivo donde queremos buscar el servicio. 4. El objeto que implemente DiscoveryListener donde llegarn los eventos. Este puede ser el mismo objeto. Una vez comenzada la bsqueda los eventos llegarn al Listener indicado. Los servicios encontrados llegarn a la funcin servicesDiscovered() donde se obtendrn los objetos ServiceRecords correspondientes. Cuando la bsqueda finalice un evento llegar a la funcin serviceSearchCompleted() que recibir un entero que indica el estado en que acabo esta bsqueda, este entero puede ser uno de las siguientes constantes definidas estticamente en el objeto DiscoveryListener:

SERVICE_SEARCH_COMPLETED: Se encontr algn servicio. SERVICE_SEARCH_TERMINATED: La bsqueda fue cancelada por una llamada a la funcin cancelServiceSearch(). SERVICE_SEARCH_ERROR: Ocurrio un error durante la bsqueda.

SERVICE_SEARCH_NO_RECORDS: No se encontr ningn servicio para los UUID indicados. SERVICE_SEARCH_DEVICE_NOT_REACHABLE: El dispositivo no se encontr. (se apago o salio de alcance).

El ejemplo que muestro a continuacin realiza una bsqueda de dispositivos y los coloca en una lista, despus podremos seleccionar cualquiera de estos dispositivos y al presionar sobre uno de ellos nos mostrar el nombre de los servicios que contiene el mismo.

public class ServiceDiscoverer extends MIDlet implements CommandListener, DiscoveryListener { private List listaDispositivos=null; private DiscoveryAgent agente; private Command parar; private Vector servicios; private Vector dispositivos; private LocalDevice local=null; private boolean buscando; public ServiceDiscoverer() {} protected void startApp() throws MIDletStateChangeException { buscando=false; listaDispositivos=new List("Lista de Dispositivos",List.IMPLICIT); listaDispositivos.addCommand(new Command("Salir",Command.EXIT,1)); listaDispositivos.addCommand(parar=new Command("Parar",Command.OK,1)); listaDispositivos.setCommandListener(this); Display.getDisplay(this).setCurrent(listaDispositivos); try { local=LocalDevice.getLocalDevice(); agente=local.getDiscoveryAgent(); } catch (BluetoothStateException e) { throw new MIDletStateChangeException( "No se encontro el dispositivo Bluetooth."); } dispositivos=new Vector(); //Realizo una inquiry en modo general try { buscando=true; agente.startInquiry(DiscoveryAgent.GIAC,this); while (buscando) { synchronized (this) { try { wait(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } catch (BluetoothStateException e) { throw new MIDletStateChangeException("No se pudo realizar la inquiry."); } } protected void pauseApp() {} protected void destroyApp(boolean arg0) throws MIDletStateChangeException {} public void commandAction(Command arg0, Displayable arg1) { if (arg0.getCommandType()==Command.EXIT){ if (buscando) agente.cancelInquiry(this); notifyDestroyed(); }

if (arg0.getCommandType()==Command.OK){ if (buscando){ buscando=false; agente.cancelInquiry(this); }else{ if (dispositivos.size()!=0){ int indice=listaDispositivos.getSelectedIndex(); RemoteDevice d=(RemoteDevice)dispositivos.elementAt(indice); try { System.out.println("Lista:"+d.getFriendlyName(true)); servicios=new Vector(); listaDispositivos.deleteAll(); //Con esto buscamos todos los servicios del perfil puerto serie (RFCOMM) agente.searchServices(new int[]{0x100},new UUID[]{new UUID(0x1101)},d,this); //Con la siguiente linea buscariamos un servicio propio //agente.searchServices(new int[]{0x100},new UUID[]{new UUID("86b4d249fb8844d6a756ec265dd1f6a3",false)},d,this); } catch (IOException e) { Display.getDisplay(this).setCurrent(new Alert("Error al leer datos del dispositivo","Error lectura",null,AlertType.ERROR)); } } }//fin if buscando }//if command OK } public void deviceDiscovered(RemoteDevice arg0, DeviceClass arg1) { try { listaDispositivos.insert(0,arg0.getFriendlyName(true)+"-I",null); dispositivos.insertElementAt(arg0,0); } catch (IOException e) { Display.getDisplay(this).setCurrent(new Alert("Error al leer el nombre del dispositivo","Error lectura",null,AlertType.ERROR)); } } public void servicesDiscovered(int arg0, ServiceRecord[] arg1) { for (int i=0;i<arg1.length;i++){ listaDispositivos.insert(0,((DataElement)arg1[i].getAttributeValue(0x0100) ).getValue().toString(),null); servicios.addElement(arg1[i]); } } public void serviceSearchCompleted(int arg0, int arg1) { if (DiscoveryListener.SERVICE_SEARCH_COMPLETED==arg1){ System.out.println("PERFECTO"); listaDispositivos.removeCommand(parar); }else{ Display.getDisplay(this).setCurrent(new Alert("El dispositivo no tenia el servicio adecuado","Sin servicio",null,AlertType.ERROR)); } } public void inquiryCompleted(int arg0) { Alert dialog=null; buscando=false; if (arg0!=DiscoveryListener.INQUIRY_COMPLETED || dispositivos.size()==0){ listaDispositivos.removeCommand(parar); dialog=new Alert("Bluetooth Error","La busqueda no encontro resultados",null,AlertType.INFO); dialog.setTimeout(Alert.FOREVER); Display.getDisplay(this).setCurrent(dialog); }else{

dialog=new Alert("Inquiry Realizada","La busqueda de dispositivos finalizo correctamente.",null,AlertType.INFO); listaDispositivos.removeCommand(parar); parar=new Command("Elegir",Command.OK,1); listaDispositivos.addCommand(parar); dialog.setTimeout(Alert.FOREVER); Display.getDisplay(this).setCurrent(dialog); } } }

3.3-Obtener la direccin del servidor. Una vez tenemos el ServiceRecord del dispositivo con el que queremos empezar la comunicacin lo que tenemos que obtener es su URL. Para ello tenemos que llamar a la funcin getConnectionURL() del mismo, que nos retornar un string con la cadena necesaria para conectarnos al otro dispositivo, como explicar en el prximo capitulo.

También podría gustarte