Bluetooth Hacking
Stefano Sanna - JUG Sardegna
Emanuele Di Saverio - JUG Roma
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
•
Emanuele Di Saverio
• Senior Solution Engineer Android @ beeweeb SpA
• Autore del libro “Java Micro Edition”, Hoepli (2007)
• Main designer Bluetooth API for Android 1.x
• 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
•
Android 0.9
•
Android 1.x
•
Android 2.x
• Wrapper Java su Bluez
• Sparisce l’API Bluetooth!
• Nessuna API per gli sviluppatori
• 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:
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();
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
I metodi disponibili
O
!
P
O
P
S
O
S
R
T PLE
M
O
C
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.bluetoot
h.IBluetoothDeviceCallback)
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...
3
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();
2
1
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
Retrocompatibilità!
• Astrazione 1.x vs 2.0
•
....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 Arduino
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':
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
DEMO!
Starring:
Motorola Milestone (Android 2.0), HTC Magic (Android 1.6) and Arduino Bluetooth
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Risorse
•
Android
•
Bluetooth API for Android 1.x e Easy Bluetooth
•
Arduino
• http://developer.android.com
• http://source.android.com
• http://code.google.com/p/android-bluetooth
• http://www.arduino.cc
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
Riferimenti
•
Stefano Sanna
•
Emanuele Di Saverio
• gerdavax AT gmail DOT com
• http://www.gerdavax.it
• emanuele DOT disaverio AT gmail DOT com
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010
GRAZIE!
Stefano & Emanuele & i rispettivi JUG!
Stefano Sanna & Emanuele di Saverio – JUG Sardegna / JUG Roma
Javaday IV – Roma – 30 gennaio 2010