android bluetooth hacking
DESCRIPTION
Presentata a Java Day 2010 ROMA.Bluetooth e' la tecnologia di wireless piu' utilizzata per l'interfacciamento a corto raggio tra device mobili. Android 1.x non offre agli sviluppatori la possibilita' di accedere allo stack Bluetooth e anche la versione 2.0 del sistema operativo pone alcune limitazioni rispetto alle potenzialita' della piattaforma. Questo talk descrive la tecnica per accedere a tutte le funzionalita', oltre ad una descrizione delle nuove feature di Android 2.0 e una demo con Arduino Bluetooth.TRANSCRIPT
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Stefano Sanna - JUG SardegnaEmanuele Di Saverio - JUG Roma
Bluetooth Hacking
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Sommario
• Chi siamo
• L’importanza del Bluetooth sui device mobili• Android & Bluetooth: storia di un amore mancato
• Happy hacking!
• La Bluetooth API per Android 1.x• L’API ufficiale di Android 2.0• Demo: Android per controllare Arduino Bluetooth
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Chi siamo
• Stefano Sanna• Senior Solution Engineer Android @ beeweeb SpA• Autore del libro “Java Micro Edition”, Hoepli (2007)• Main designer Bluetooth API for Android 1.x
• Emanuele Di Saverio• Scrum Master and Senior Developer @ beeweeb SpA• SCMAD, SCJP• Committer Easy-Bluetooth framework for Android
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
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
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
L’importanza del supporto 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...)
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Tanti device la’ fuori...
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Happy Hacking!
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
System service & Reflection
• Il Bluetooth Service è accessibile come qualsiasi altro Android Service:
A questo punto, ottenuta la classe, si può utilizzare la reflection per conoscerne (e invocarne!) i metodi:
Object bluetoothService = context.getSystemService(“bluetooth”);
Class bluetoothServiceClass = bluetoothService.class;
Method[] bluetoothMethods = bluetoothServiceClass.getMethods();
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
I metodi disponibili
public android.bluetooth.BluetoothDevice(android.bluetooth.IBluetoothDevice)public boolean android.bluetooth.BluetoothDevice.cancelBondProcess(java.lang.String)public void android.bluetooth.BluetoothDevice.cancelDiscovery()public boolean android.bluetooth.BluetoothDevice.cancelPin(java.lang.String)public boolean android.bluetooth.BluetoothDevice.createBond(java.lang.String)public boolean android.bluetooth.BluetoothDevice.disable()public boolean android.bluetooth.BluetoothDevice.disconnectRemoteDeviceAcl(java.lang.String)public boolean android.bluetooth.BluetoothDevice.enable()public java.lang.String android.bluetooth.BluetoothDevice.getAddress()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)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)public java.lang.String android.bluetooth.BluetoothDevice.getRemoteName(java.lang.String)public java.lang.String android.bluetooth.BluetoothDevice.getRemoteRevision(java.lang.String)public boolean android.bluetooth.BluetoothDevice.getRemoteServiceChannel(java.lang.String,short,android.bluetooth.IBluetoothDeviceCallback)
TROPPO
COMPLESSO!
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Permission
• Primo passo: per accedere alle funzionalità Bluetooth occorre dichiarare due Permission nel Manifest:
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Discovery device remoti
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...
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Apertura di un socket RFCOMM client
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(); OutputStream output = socket.getOutputStream(); }
public void pinRequested() { // mostra la dialog per l’inserimento del PIN }});
dev.pair(); 1
2
3
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Device compatibili
• HTC Dream• HTC Magic• HTC Tattoo
• Samsung Galaxy i7500• Samsung Galaxy i5700
• Huawei U8220
• Sony-Ericsson XPERIA X10
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Bluetooth API for Android 1.x
• Unica libreria opensource (Apache 2.0) che per l’accesso allo stack Bluetooth su Android 1.x• Funzionalità:• accensione/spegnimento Bluetooth• discovery di dispositivi remoti e 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
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Bluetooth API for Android 1.x
• Oltre 1000 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• È 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
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Principali limitazioni
• Non è possibile registrare un servizio sul database SDP (Service Discovery Protocol), benché sia possibile creare socket server RFCOMM
• 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
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Permission su socket dbus
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
L’API di Android 2.x
• Android 2.0 : Bluetooth ufficialmente nell'SDK!
• Yay!• Niente controllo diretto sul pairing• Niente accesso diretto ai canali RFCOMM• Niente discovery dei servizi
...not so :\• Android style: basato su Intents and Receivers• paradigma Publish/Subscribe, un po’ macchinoso!
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Discovery in Android 2.x
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//also can register for DISCOVERY_STARTED Action
context.registerReceiver(receiver, filter);
adapter.startDiscovery();
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
BroadcastReceiver
private final BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context ctx, Intent intent) {
final String action = intent.getAction();
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 :o)}
}};
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Socket e stream I/O
//given a valid “BluetoothDevice”...
UUID uuidOfTargetService = UUID.nameUUIDFromBytes(“2d26618601fb47c28d9f10b8ec891363”);
BluetoothSocket socket = rbd.createRfcommSocketToServiceRecord(uuidOfTargetService);
socket.connect();
InputStream input = socket.getInputStream();OutputStream output = socket.getOutputStream();
....
socket.close();
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Buone pratiche su Android
• È importante tenere a mente le buone usanze di programmazione Android (e Java!):
• operazioni di I/O sempre su un Thread separato
• aggiornare la UI via Handler
• deregistrare i Receivers prima di terminare un Context
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Serve ancora una libreria custom?
• Malgrado l’API di Android 2.0, una libreria Bluetooth avrebbe ancora la sua utilità!
• Accesso alle feature nascoste (via reflection)• Esposizione di una API più semplice• Astrazione 1.x vs 2.0 Retrocompatibilità!
• ....in lavorazione Easy Bluetooth• Check it out:
http://android-bluetooth.googlecode.com/svn/
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Android controlla Arduino
• Vogliamo utilizzare Android per controllare via Bluetooth un LED e leggere una temperatura
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
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
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Sorgente Arduinoint 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': digitalWrite(LED_PIN, LOW); Serial.write('0'); break; case 'r': readTemp(); break; }}
Hardware utilizzato:
• Arduino Bluetooth• Prototype shield e breadboard• LM35 Temperature Sensor
void readTemp() { int temp = analogRead(LM35_PIN); temp= ( 5.0 * temp * 100.0) / 1024.0; Serial.write(temp);}
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
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();
});}
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Starring:
Motorola Milestone (Android 2.0), HTC Magic (Android 1.6) and Arduino Bluetooth
DEMO!
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
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
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Riferimenti
• Stefano Sanna• gerdavax AT gmail DOT com• http://www.gerdavax.it
• Emanuele Di Saverio• emanuele DOT disaverio AT gmail DOT com
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Stefano & Emanuele & i rispettivi JUG!
GRAZIE!