Uso di Bluetooth su Android 1.x e Android 2.x, con demo basata su Arduino Bluetooth e SensPod. Talk presentato alla conferenza whymca 2010 (http://www.whymca.org).
Agenda
• Speaker
• Bluetooth & Android
• È tempo di hacking!
• Bluetooth su Android 1.x
• Bluetooth su Android 2.x
• Demo
• Conclusioni
Speaker
• Mobile Development Architect @ beeweeb SpA
– http://www.beeweeb.com
• Author of “Java Micro Edition network programming”
– Hoepli Editore, 2007
– http://www.gerdavax.it/jmebook
• Author of Bluetooth API for Android 1.x
– http://code.google.com/p/android-bluetooth
• Founder of QuadraSpace Project
– http://www.quadraspace.org
Android & Bluetooth, hacking e applicazioni
Bluetooth su Android
• early Android
– Wrapper Java su Bluez
• Android 0.9
– Sparisce l’API Bluetooth!
• Android 1.x
– Nessuna API per gli sviluppatori
• Android 2.x
– Introduce una API che consente il discovery di device remoti, di aprire
connessioni RFCOMM client e server
Android & Bluetooth, hacking e applicazioni
L’importanza di Bluetooth
• Senza una API dedicata non è possibile:
– Discovery di device e servizi
– Trasferimento file con Bluetooth FTP e OBEX
– Connessioni a GPS, gamepad, apparati medicali
– Controllo remoto di moduli embedded e sensor network
– Applicazioni di robotica (LEGO Mindstorms, etc...)
Android & Bluetooth, hacking e applicazioni
Tanti device la’ fuori...
Android & Bluetooth, hacking e applicazioni
È tempo di hacking!
Android & Bluetooth, hacking e applicazioni
Strumenti per hacking sano
• Le utility di sistema di Android sono scritte in Java, come
le applicazioni di terze parti
– “Se possono farlo loro, possiamo farlo anche noi!”
• Il sorgente di Android è disponibile!
– http://source.android.com
• I servizi di sistema sono accessibili attraverso un
meccanismo di query basato su chiavi stringa
– Context.getSystemService(String name)
• Java fornisce uno sofisticato motore di introspezione
Android & Bluetooth, hacking e applicazioni
System Service & Reflection
• Il Bluetooth Service è accessibile come qualsiasi altro
Android Service:
Object bluetoothService = context.getSystemService(“bluetooth”);
A questo punto, ottenuta la classe, si può utilizzare la
reflection per conoscerne (e invocarne!) i metodi:
Class bluetoothServiceClass = bluetoothService.class;
Method[] bluetoothMethods = bluetoothServiceClass.getMethods();
Android & Bluetooth, hacking e applicazioni
Metodi disponibili
O !
P O
public android.bluetooth.BluetoothDevice(android.bluetooth.IBluetoothDevice)
P S
public boolean android.bluetooth.BluetoothDevice.cancelBondProcess(java.lang.String)
public void android.bluetooth.BluetoothDevice.cancelDiscovery()
public boolean android.bluetooth.BluetoothDevice.cancelPin(java.lang.String)
O ES
public boolean android.bluetooth.BluetoothDevice.createBond(java.lang.String)
public boolean android.bluetooth.BluetoothDevice.disable()
public boolean android.bluetooth.BluetoothDevice.disconnectRemoteDeviceAcl(java.lang.String)
R L
public boolean android.bluetooth.BluetoothDevice.enable()
public java.lang.String android.bluetooth.BluetoothDevice.getAddress()
T P
public int android.bluetooth.BluetoothDevice.getBluetoothState()
public int android.bluetooth.BluetoothDevice.getBondState(java.lang.String)
public java.lang.String android.bluetooth.BluetoothDevice.getCompany()
public int android.bluetooth.BluetoothDevice.getDiscoverableTimeout()
public java.lang.String android.bluetooth.BluetoothDevice.getManufacturer()
public java.lang.String android.bluetooth.BluetoothDevice.getName()
public int android.bluetooth.BluetoothDevice.getRemoteClass(java.lang.String)
M
public java.lang.String android.bluetooth.BluetoothDevice.getRemoteCompany(java.lang.String)
public [B android.bluetooth.BluetoothDevice.getRemoteFeatures(java.lang.String)
public java.lang.String android.bluetooth.BluetoothDevice.getRemoteManufacturer(java.lang.String)
O
public java.lang.String android.bluetooth.BluetoothDevice.getRemoteName(java.lang.String)
public java.lang.String android.bluetooth.BluetoothDevice.getRemoteRevision(java.lang.String)
C
public boolean android.bluetooth.BluetoothDevice.getRemoteServiceChannel
(java.lang.String,short,android.bluetooth.IBluetoothDeviceCallback)
public java.lang.String android.bluetooth.BluetoothDevice.getRemoteVersion(java.lang.String)
public java.lang.String android.bluetooth.BluetoothDevice.getRevision()
public int android.bluetooth.BluetoothDevice.getScanMode()
public java.lang.String android.bluetooth.BluetoothDevice.getVersion()
public boolean android.bluetooth.BluetoothDevice.isAclConnected(java.lang.String)
public boolean android.bluetooth.BluetoothDevice.isDiscovering()
...
Android & Bluetooth, hacking e applicazioni
Bluetooth API for Android 1.x
• Esporta le funzionalità del BluetoothService attraverso
l’uso della reflection e alcune classi di utility
• Funzionalità:
– accensione/spegnimento Bluetooth
– modifica visibilità
– inquiry di dispositivi remoti
– discovery della porta RFCOMM port di un servizio
– apertura connessioni RFCOMM client
• Funziona senza la necessità di accesso root
• Check it out!
– http://code.google.com/p/android-bluetooth
Android & Bluetooth, hacking e applicazioni
Permission
• Primo passo: per accedere alle funzionalità Bluetooth
occorre dichiarare due Permission nel Manifest
dell’applicazione:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
Android & Bluetooth, hacking e applicazioni
Classi
• LocalBluetoothDevice
– è il singleton del modulo Bluetooth locale
– permette attivazione/disattivazione, discovery, pairing
– notifica gli eventi attraverso l’interfaccia LocalBluetoothDeviceListener
• RemoteBluetoothDevice
– è un riferimento ad un device Bluetooth remoto
– permette apertura/chiusura di socket RFCOMM client
– notifica gli eventi attraverso l’interfaccia
RemoteBluetoothDeviceListener
• BluetoothSocket
– rappresenta una connessione client su porta RFCOMM
– fornisce InputStream e OutputStream verso il device remoto
Android & Bluetooth, hacking e applicazioni
Da rilasciare con il
Device discovery metodo close() quando
il contesto viene distrutto
LocalBluetoothDevice local = LocalBluetoothDevice.init(context);
local.setListener(new LocalBluetoothDeviceListener() {
public void scanStarted() {
// e’ partita la scansione...
}
public void scanCompleted(ArrayList<String> devices) {
// scansione completata
}
});
local.scan(); // avvia la scansione...
Android & Bluetooth, hacking e applicazioni
Socket RFCOMM
RemoteBluetoothDevice dev = local.getRemoteBluetoothDevice(address);
dev.setListener(new RemoteBluetoothDeviceListener() {
public void paired() {
// si aprono socket e stream I/O...
BluetoothSocket socket = dev.openSocket(1);
InputStream input = socket.getInputStream();
3
OutputStream output = socket.getOutputStream();
}
public void pinRequested() {
// mostra la dialog per l’inserimento del PIN 2
}
});
dev.pair(); 1
Android & Bluetooth, hacking e applicazioni
Non sono ancora
Frammentazione disponibili terminali con
Android 2.2 “Froyo”
1.1 1.5 1.6 2.0 2.0.1 2.1
100
80
60
40
20
0
01/2010 04/2010 1h 05/2010 2h 05/2010
Android & Bluetooth, hacking e applicazioni
Chi la usa?
• Oltre 2600 download!
• Utilizzata in progetti commerciali e free:
– Ha ispirato la realizzazione di Bluetooth File Transfer di Medieval
Software, l’applicazione di trasferimento file di maggior successo
nell’Android Market (oltre 1 milione di download)
– È utilizzata in Amarino (sviluppato al MIT), primo framework di controllo
di Arduino attraverso Android
– È utilizzata in GoPayment di Intuit Inc., per il pagamento con carta di
credito attraverso swiper e stampante BT
– È utilizza in SensLink di Sensaris per la lettura dei dati rilevati dai
sensori “indossabili” SensPod
Android & Bluetooth, hacking e applicazioni
Principali limitazioni
• Non è possibile registrare un servizio sul database SDP
(Service Discovery Protocol), benché sia possibile
creare socket server RFCOMM (in sviluppo)
• Se si utilizza la funzionalità di device inquiry subito dopo
l’avvio del telefono, la chiamata nativa interferisce con
un processo di scansione del sistema e lo stack
Bluetooth diventa inutilizzabile
• Problemi di compatibilità con HTC Hero e LG GW620
“LinkMe”
Android & Bluetooth, hacking e applicazioni
Permission su socket dbus
Le applicazioni di terze parti
non possono accedere servizio
SDP Bluetooth via dbus
Android & Bluetooth, hacking e applicazioni
Nessuna novità sul
L’API di Android 2.x fronte Bluetooth in
Android 2.2 “Froyo”
• Bluetooth ufficialmente nell'SDK!
• Funzionalità:
– accensione/spegnimento Bluetooth
– inquiry di dispositivi remoti
– apertura connessioni RFCOMM client e server
• Android style: basato su Intents and Receivers
• Alcune importanti limitazioni
– Nessun controllo diretto sul pairing
– Accesso diretto ai canali RFCOMM non consentito
– Discovery dei servizi non supportato
– Visibility non attivabile automaticamente da applicazione
– Servizio OBEX già registrato dal sistema...
Android & Bluetooth, hacking e applicazioni
Classi
• BluetoothAdapter
– È il singleton che gestisce le risorse del modulo Bluetooth locale
– Notifica gli eventi attraverso Broadcast Receiver
• BluetoothDevice
– Rappresenta il riferimento ad un device Bluetooth remoto
• BluetoothSocket
– Gestisce i client socket RFCOMM indirizzati attraverso record SDP
– Non consente l’indirizzamento diretto ad un canale RFCOMM noto
• BluetoothServerSocket
– Consente la creazione di server socket
• BluetoothClass
– Definisce le costanti di DEVICE & SERVICE CLASS di Bluetooth
Android & Bluetooth, hacking e applicazioni
Attivazione Bluetooth
• Benché l’applicazione possa attivare autonomamente il
servizio Bluetooth, l’uso della via procedurale deve
essere accompagnato da apposita informativa all’utente
• Il sistema offre una Action
(ACTION_REQUEST_ENABLE) che delega al sistema
operativo l’interazione con l’utente e l’attivazione dello
stack Bluetooth in caso di conferma:
Intent enableBt = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBt, REQUEST_ENABLE_BT);
Android & Bluetooth, hacking e applicazioni
Visibility
• Solo le utility del sistema operativo possono rendere il
dispositivo visibile sulla rete Bluetooth
• Per rendere visibile TEMPORANEAMENTE il terminale
Android è necessario, ancora una volta, lanciare un
Intent:
Intent enableBt = new Intent
(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(enableBt, REQUEST_ENABLE_DISCOVERABLE);
Android & Bluetooth, hacking e applicazioni
Discovery in Android 2.x
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
context.registerReceiver(receiver, filter);
adapter.startDiscovery();
Android & Bluetooth, hacking e applicazioni
Broadcast Receiver
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context ctx, Intent intent) {
final String action = intent.getAction();
if (action.equals() {
// let’s show a progress dialog ;-)
} else if (action.equals(BluetoothDevice.ACTION_FOUND)) {
BluetoothDevice device = (BluetoothDevice)
intent.getParcelableExtra
(BluetoothDevice.EXTRA_DEVICE);
// process device
} else if (action.equals
(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
// done
}
}
};
Android & Bluetooth, hacking e applicazioni
Socket e I/O Stream
// dato un BluetoothDevice valido...
UUID uuidOfTargetService = UUID.nameUUIDFromBytes
(“2d26618601fb47c28d9f10b8ec891363”);
BluetoothSocket socket = device.createRfcommSocketToServiceRecord
(uuidOfTargetService);
socket.connect();
InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream();
....
socket.close();
Android & Bluetooth, hacking e applicazioni
Hacking su Android 2.x
• I progettisti di Android hanno... mangiato la foglia :-)
– La reflection è arginata da un più ferreo meccanismo di permission. Ad
esempio, il metodo setScanMode
public boolean android.bluetooth.BluetoothAdapter.setScanMode(int)
esiste nella libreria standard ma non è menzionato nella
documentazione ufficiale. Il tentativo di invocarlo via reflection solleva
un’eccezione di sicurezza:
java.lang.SecurityException: Need WRITE_SECURE_SETTINGS permission:
Neither user 10097 nor current process has
android.permission.WRITE_SECURE_SETTINGS.
Android & Bluetooth, hacking e applicazioni
Hacking su Android 2.x
• Altri metodi hanno comportamenti imprevedibili. Ad
esempio:
public android.bluetooth.BluetoothSocket
android.bluetooth.BluetoothDevice.createInsecureRfcommSocket(int)
public android.bluetooth.BluetoothSocket
android.bluetooth.BluetoothDevice.createRfcommSocket(int)
consentono di aprire un RFCOMM client socket ad un
canale assegnato e funzionano senza eccezioni su
Motorola Milestone e Google Nexus One. Su HTC
Legend, invece, il parametro intero è interpretato come
UUID subclass e non come numero di canale! Crash!
Android & Bluetooth, hacking e applicazioni
Android controlla Arduino
• Utilizzando Arduino Bluetooth è possibile
realizzare un termometro remoto e un
semplice attuatore che accende un LED
Android & Bluetooth, hacking e applicazioni
Arduino
• “Arduino is an open-source electronics prototyping
platform based on flexible, easy-to-use hardware and
software. [...] It can sense the environment by receiving
input from a variety of sensors and can affect its
surroundings by controlling lights, motors, and other
actuators”
• Rigorosamente MADE IN ITALY!
• http://www.arduino.cc
Android & Bluetooth, hacking e applicazioni
Hardware utilizzato:
Sorgente Arduino • Arduino Bluetooth
• Prototype shield e breadboard
• LM35 Temperature Sensor
int LED_PIN = 13; int LM35_PIN = 2;
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
if (Serial.available() > 0) {
int inByte = Serial.read();
switch (inByte) {
case '1':
digitalWrite(LED_PIN, HIGH);
Serial.write('1');
break;
case '0':
void readTemp() {
digitalWrite(LED_PIN, LOW);
int temp = analogRead(LM35_PIN);
Serial.write('0');
break; temp= ( 5.0 * temp * 100.0) / 1024.0;
case 'r': Serial.write(temp);
readTemp(); }
break;
}
}
Android & Bluetooth, hacking e applicazioni
Sorgente Android
// definiamo i comandi...
byte LED_ON_REQUEST = ‘1’;
byte LED_OFF_REQUEST = ‘0’;
byte READ_TEMPERATURE = ‘r’;
[...]
// all’interno del Thread inviamo comandi e leggiamo le risposte...
output.write(request);
final int response = input.read();
if (request == 'r') {
handler.post(new Runnable() {
public void run() {
String temp = Integer.toString(response);
Toast.makeText(Controller.this, "LM35 Sensor: " + temp + "°C", 4000).show();
});
}
Android & Bluetooth, hacking e applicazioni
Sensori industriali
• Il supporto Bluetooth può essere utilizzato per ricevere
dati da sensori wireless industriali
• Nell’ambito del progetto opensource
QuadraSpace, il primo prototipo di
data sampler mobile è costituito da
un HTC Dream (1.6) connesso ad un
SensPod in grado di acquisire
temperatura e umidità, ossidi di azoto
(NOx) e CO2
– http://www.sensaris.com
Android & Bluetooth, hacking e applicazioni
Conclusioni
• Il protocollo Bluetooth è ormai consolidato e consente
l’interfacciamento a dispositivi utilizzati in numerosi
domini applicativi
• Pur con qualche limitazione, è possibile disporre di
funzionalità base Bluetooth sia su codebase 1.x
(attraverso il progetto android-bluetooth) sia su
codebase 2.x (attraverso l’API ufficiale)
• Sono in fase di sviluppo estensioni HDP (Heath Device
Profile), eL2CAP e MCAP per l’interfacciamento a device
medicali
Android & Bluetooth, hacking e applicazioni
Risorse
• Android
– http://developer.android.com
– http://source.android.com
• Bluetooth API for Android 1.x e Easy Bluetooth
– http://code.google.com/p/android-bluetooth
• Arduino
– http://www.arduino.cc
• QuadraSpace Project
– http://www.quadraspace.org
Android & Bluetooth, hacking e applicazioni
GRAZIE!
Stefano Sanna
– Blog: http://www.gerdavax.it
– email: gerdavax AT gmail DOT com
– Skype: gerdavax
– Twitter: @gerdavax
• Ringrazio Emanuele Di Saverio che ha collaborato alla realizzazione delle versione originale di
queste slide e della demo su Arduino, presentati a Java Day 2010 (Roma)
Android & Bluetooth, hacking e applicazioni