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