Realizzare applicazioni Bluetooth in Java

I parte: Introduzione alla tecnologia Bluetooth e alla specifica JSR-82di e

Il Bluetooth è uno standard per la comunicazione wireless a corto raggio, impiegato per la realizzazione di una Personal Area Network (PAN), ossia di una rete informatica in grado di interconnettere diversi dispositivi (telefoni cellulari, personal digital assistants, laptop, ecc.) vicini a un singolo utente. Scopo di questo articolo è l‘introduzione ai concetti base della tecnologia Bluetooth e della specifica JSR-82 [2], con i quali realizzeremo la prima parte del nostro esempio, ovvero il discovery di un dispositivo Bluetooth.

Introduzione al Bluetooth

Il Bluetooth, noto anche con la sigla IEEE 802.15.1, è uno standard aperto per comunicazione wireless a corto raggio. Sulla base della distanza coperta, i dispositivi Bluetooth vengono classificati in 3 classi, come mostrato nella tabella di figura 1.

Figura 1 - Le tre classi dei dispositivi Bluetooth.

Le caratteristiche principali dello standard sono:

Tecnologia radio a bassa potenza e portata limitata nella banda 2.4GHz (ISM);

Supporto per voce e dati con velocità  di trasferimento da 723.1 kbit/s per la versione 1.2 fino a 2.1Mbit/s per la versione 2.0;

I dispositivi non devono essere necessariamente in â??vistaâ? (come ad esempio nel caso della tecnologia a infrarossi).

Ogni dispositivo Bluetooth è univocamente identificato e indirizzabile mediante un indirizzo IEEE 802 a 48 bit. Quando due o più dispositivi sono connessi fra loro formano una rete PAN, denominata Piconet, alla quale possono partecipare al più otto dispositivi.

Lo scopo di una connessione Bluetooth è quella di mettere in comunicazione i layer che si occupano del livello applicativo, detti Profiles. In altri termini, possiamo immaginare i Profiles come un insieme di protocolli di livello applicativo che utilizzano i layer più bassi dello stack Bluetooth come protocollo di trasporto. Per la realizzazione del nostro esempio, faremo riferimento al Profile denominato Generic Object Exchange Profile (GOEP), all‘interno del quale è definito il protocollo OBEX (OBject EXchange), che permette ad un dispositivo di scambiare file in modalità  push con un altro dispositivo. Vale la pena qui ricordare anche il Profile denominato Serial Port Profile (SPP), all‘interno del quale sono definiti i due protocolli L2CAP e RFCOMM, utilizzati per lo scambio di stream di dati [1].

La specifica JSR-82

La specifica JSR-82 definisce lo standard Java per l‘accesso alla tecnologia Bluetooth [2]: è importante sottolineare che tale specifica non rappresenta l‘implementazione di uno stack, ma definisce soltanto le interfacce alle quali un Vendor deve attenersi per realizzare un suo stack conforme allo standard (analogamente a quanto accade ad esempio per la tecnologia JDBC).

Il vantaggio dello sviluppare applicazioni Bluetooth in Java secondo la specifica JSR-82 rispetto all‘uso di API basate sul linguaggio C/C++ (o native) è essenzialmente quello di avere un codice indipendente dello stack e dalle interfaccie di trasmissione radio. Per contro (ovviamente), tali API permettono un controllo limitato sull‘hardware.

JSR-82 è stata progettata per esser supportata da calcolatori dotati di risorse limitate, per cui assume la struttura di un‘estensione (opzionale) della piattaforma J2ME (Java 2 Micro Edition). Nello stesso tempo, è compatibile con la piattaforma J2SE (Java 2 Standard Edition), permettendo anche di far comunicare tramite Bluetooth un componente sviluppato per l‘ambiente J2ME con uno sviluppato per l‘ambiente J2SE.

La JSR-82 consiste nei seguenti package indipendenti [3]:

  • javax.microedition.io: per la gestione di connessioni Bluetooth (L2CAP e RFCOMM);
  • javax.obex: implementa le funzioni OBEX;
  • javax.bluetooth: rappresenta il Core delle API Java Bluetooth, mette a disposizione delle applicazioni funzionalità  dei profili Bluetooth Generic Access Profile e Service Discovery.

Segue una breve descrizione delle classi funzionali alla prima parte della nostro esempio, ovvero il discovery di un dispositivo (device discovery):

La classe javax.bluetooth.LocalDevice rappresenta il dispositivo Bluetooth locale. Contiene metodi per accedere alle proprietà  generali relative al dispositivo (tra cui indirizzo Bluetooth e il nome) e il metodo setDiscoverable per rendere individuabile il dispositivo, mettendolo in modalità  di inquiry scanning.

La classe javax.bluetooth.RemoteDevice rappresenta un dispositivo Bluetooth remoto. Contiene metodi per accedere alle proprietà  generali del dispositivo (tra cui indirizzo Bluetooth e il nome) e metodi per l‘autenticazione e la cifratura delle connessioni, secondo quanto previsto dal Generic Access Profile.

La classe javax.bluetooth.DiscoveryAgent fornisce metodi sia per il device discovery sia per il service discovery. Il metodo startInquiry permette di avviare la sessione di inquiry per l‘individuazione dei dispositivi a portata di comunicazione.

L‘interfaccia javax.bluetooth.DiscoveryListener consente all‘applicazione di ricevere gli eventi legati alle richieste di device e service discovery. L‘applicazione utente dovrà  fornire un‘implementazione ai metodi di quest‘interfaccia per reagire a tali eventi. In particolare, riguardo alla fase di inquiry, ogni volta che viene trovato un nuovo dispositivo, la libreria Java Bluetooth chiamerà  il metodo deviceDiscovered fornendo come argomento il RemoteDevice individuato. Al termine della procedura sarà  invocato il metodo inquiryCompleted, avente come argomento un codice che indica se l‘inquiry è stata completata regolarmente o se si è verificato un errore.

Cosa ci serve per iniziare

Per poter iniziare a implementare lo scenario di trasferimento di un‘immagine dal PC al telefono cellulare, abbiamo bisogno di quanto segue:

  • Un adattatore Bluetooth USB da collegare al nostro PC (ad esempio il NILOX BLUETOOTH Adapter USB 2.0 CLASSE 1).
  • Uno stack Bluetooth conforme alla specifica JSR-82. Lo stack che abbiamo utilizzato per la realizzazione dell‘esempio è BlueCove. Si tratta di una stack open source per piattaforma Windows (lo stack dipende del particolare Sistema Operativo. Per l‘installazione far riferimento alla specifica documentazione). Per lo sviluppo sotto Linux si può far riferimento dello stack BlueZ, anch‘esso open source.
  • Le librerie JSR-82. Queste possono essere scaricate dal sito della Sun oppure, come nel nostro caso, possono essere comprese nello packaging dello stack.
  • Un IDE per sviluppare applicazioni J2SE (ad esempio Eclipse).
  • Un telefono cellulare dotato della tecnologia Bluetooth.

Il discovery di un dispositivo

Ecco il codice Java che realizza il discovery di un dispositivo.

import java.io.*;
import java.util.*;
import javax.bluetooth.*;

public class DiscoveryListenerImpl implements DiscoveryListener {
private Hashtable devices;
public BTDiscoveryListener() {
this.devices = new Hashtable();
}
/* Metodo definito dall‘interfaccia DiscoveryListener */
public void startInquiry() {
try {
// Accesso al LocalDevice per iniziare la scansione dei dispositivi
LocalDevice localDevice = LocalDevice.getLocalDevice();
DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent();
// Inizio della scansione dei dispositivi. La libreria avvia un nuovo Thread
// per lo svolgimento di questa operazione
// discoveryAgent.startInquiry(DiscoveryAgent.LIAC, this);
} catch (Exception e) {
e.printStackTrace();
}
}
/* Metodo definito dall‘interfaccia DiscoveryListener:
viene invocato automaticamente ogni volta che viene trovato un nuovo dispositivo */
public void deviceDiscovered(
javax.bluetooth.RemoteDevice remoteDevice,
javax.bluetooth.DeviceClass deviceClass) {
// Mettiamo il dispositivo trovato in una Hashtable
devices.put(remoteDevice.getBluetoothAddress(), remoteDevice);
}
/* Metodo definito dall‘interfaccia DiscoveryListener:
viene invocato automaticamente quando termina l‘operazione di discovery */
public void inquiryCompleted(int param) {
if (param == DiscoveryListener.INQUIRY_COMPLETED
|| param == DiscoveryListener.INQUIRY_TERMINATED) {
// Se l‘operazione di discovery termina correttamente, stampiamo a video i
// dispositivi trovati e memorizzati nell‘Hashtable
Enumeration enumeration = devices.elements();
while(enumeration.hasMoreElements()) {
RemoteDevice device = enumeration.nextElement();
try {
System.out.println("Device [" + device.getBluetoothAddress()
+ ", " + device.getFriendlyName(true) + "]");
} catch (IOException e) {
System.err.println("Impossibile recuperare il nome del dispositivo: "
+ device.getBluetoothAddress());
}
}
} else {
System.out.println("Nessun dispositivo trovato.");
}
}
public void serviceSearchCompleted(int arg0, int arg1) {}
public void servicesDiscovered(int arg0, ServiceRecord[] arg1) {}

}
public class BluetoothExample {
public static void main(String[] args) {
DiscoveryListenerImpl listener = new BTDiscoveryListener();
listener.startInquiry();
}

}

In particolare, la classe DiscoveryListenerImpl rappresenta l‘implementazione dell‘interfaccia javax.bluetooth.DiscoveryListener di cui abbiamo parlato al paragrafo precedente. Secondo tale implementazione, ogni volta che un nuovo dispositivi viene trovato, questo viene inserito in una Hashtable. Al termine dell‘operazione di discovery, nel caso in cui l‘operazione sia terminata correttamente, i dispositivi cosଠtrovati verranno stampati a video.

Per testare il codice è necessario assicurarsi che l‘adattatore Bluetooth sia stato collegato al PC e che il telefonino sia stato configurato e predisposto per accettare connessioni Bluetooth.

Conclusioni

In questo articolo abbiamo accennato a quali siano le principali caratteristiche del Bluetooth. Abbiamo visto quale sia il ruolo della specifica JSR-82 nello sviluppo di applicazioni basate su questa tecnologia su piattaforma Java e come, per iniziare a lavorare, sia necessario procurasi un‘implementazione di uno stack Bluetooth compatibile con JSR-82. Abbiamo inoltre sottolineato la necessità  di utilizzare un adattatore USB Bluetooth per abilitare il nostro PC a comunicare attraverso questo protocollo. Nel prossimo articolo, vedremo come utilizzare i dispositivi trovati in fase di discovery per inviare loro un file, anzichà© stamparlo semplicemente a video.

Riferimenti

[1] Standard Bluetooth

http://www.bluetooth.org

[2]

http://jcp.org/aboutJava/communityprocess/final/jsr082/

[3]

http://java.sun.com/javame/reference/apis/jsr082

Condividi

Pubblicato nel numero
116 marzo 2007
Francesco Saverio Profiti ha conseguito la laurea in Ingegneria Informatica presso l‘Università degli Studi Roma Tre nel 2003. Durante la sua carriera lavorativa si è occupato, prima da programmatore, poi da analista e infine da architetto di applicazioni di classe enterprise sia in ambiente Java EE sia in ambiente .NET.…
Claudio Biancalana è dottorando in Ingegneria Informatica presso il Dipartimento di Informatica e Automazione dell‘Università degli Studi Roma Tre. L‘attività di ricerca scientifica svolta finora ha riguardato l‘Intelligenza Artificiale e la Categorizzazione Automatica di Testi (ATC, Automated Text Categorization). Dal 2003 collabora attivamente presso il laboratorio di Intelligenza Artificiale dell‘Università…
Ti potrebbe interessare anche