La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Bluetooth orienté java : JSR82 + Android

Présentations similaires


Présentation au sujet: "Bluetooth orienté java : JSR82 + Android"— Transcription de la présentation:

1 Bluetooth orienté java : JSR82 + Android
jean-michel Douin, douin au cnam point fr version du 22 Novembre 2011 Notes de cours et mise en œuvre

2 Sommaire Le contexte Les protocoles et profils JSR82, Principes
Bluetooth, caractéristiques, brève présentation Les protocoles et profils JSR82, Principes Deux paquetages, Usage identique pour J2SE et J2ME Découverte Des périphériques BT et des services Android, en première approche Client Communication RFComm btspp:// OBEX btgoep:// …

3 Bibliographie utilisée
La doc de l’API jsr82, Recherche google : Un exposé de Macherel Bruno ppt M2PGI – UFRIMA Une présentation de Apurva Kumar(www.research.ibm.com/people/k/kapurva) Un exposé de Camille Diou, université de Metz, The JavaBluetooth Stack is a 100% (no native) Java implementation of the Bluetooth Specifications Version 1.1. It currently supports HCI, L2CAP and SDP. pour un grand nombre de JVM … souvent référencé

4 Préambule Le contexte J2SE 6.0, update 11 WindowsXP/SP2,
Le contexte J2SE 6.0, update 11 WindowsXP/SP2, Outil de développement Bluej … PC/clé Iogear GBU341W6, GBU421W6 librairie bluecove , « on winsock » Les MIDlet Outils NetBeans 6.5, WTK CLDC1.1, MIDP2.0 sur PC avec le micro-emulator sur mobiles : sony ericsson S500i, W580i, Motorola K1 KRZR Note: à priori, le WTK ne permet qu’une émulation du BT HTC Galaxy Tab, 2.2 API 8, HTC Magic

5 Marketing Aux alentours de 10 à 100 mètres (BT 2.0, class 1, class 2)
Source :

6 Bluetooth Protocole de communication sans fil
peu chère, peu consommatrice d’énergie…, adapté aux mobiles Spécifications ici Bluetooth is not a one-on-one data transmission technology so it can communicate with up to eight devices within its transmission radius at one time Vocable « habituel » : Découverte multicast des services Client/serveur, serveur/serveur

7 Mesures, à vérifier… Figures extraites BT 2.0 10-100m …
de BT m … Performances : à vérifier …

8 Des chiffres Ondes radios : 2400 – 2483,5 MHz
Débits annoncés : 1 Mb/s .. 2 Mb/s Portée : 1 à plus de 100m (1 à 100mW) Class 3 Devices 100mW plus de 100 meters Class 2 Devices 10mW plus de 10 meters Class 1 Devices 1mW de meters Communication par paquets Encadrés par des blocs de données de contrôles

9 Principe : des ondes autour de nous
Découverte aux alentours Plusieurs périphériques peuvent répondre à une demande de services

10 Principe : des ondes autour de nous
Le périphérique possesseur du service est connu

11 Vocabulaire : Piconet Un Maître et ses esclaves
Esclaves affranchis  Maître

12 Vocabulaire : Scatternets
Un Scatternet = plusieurs piconets

13 Scatternets se font et se défont

14 Combien ? 255 appareils, 7 communications simultanées

15 Protocoles et profils L2CAP RFCOMM OBEX SDP TCS
Logical Link Control and adaptation Protocol Envoi de paquets avec un protocole donné vers le gestionnaire approprié. RFCOMM Émulation de ports séries au dessus de L2CAP. OBEX Object Exchange Protocol. Analogue à HTTP/GET-POST, FTP SDP Service Discovery Protocol (SDP). TCS telephony control specification

16 Où sommes nous ?

17 Profils Profils ou Capacités d’un périphériques BT à …
ftp version bluetooth, Téléphonie sans fil, Imprimer des documents, Découverte des services (SDP), .. Applications dédiées -> Recensement des capacités d’un appareil BT Describe configuration of the Bluetooth stack for different types of applications. Specify minimum requirements from Bluetooth layers for each profile. Generic access profile give recommendations and common requirements for access procedures.

18 De la documentation originale

19 En résumé

20 Bluetooth, existentiel
Qui suis-je ? Je me présente Qui êtes vous ? Aux alentours Parmi vous qui possède ce service ? Avez d’autres services à proposer ? Quels sont-ils ? UUID ou identification d’un service … Adéquation UUID/URL UUID prédéfinis, UUID pour une application Quels protocoles ? Où suis-je, où vais-je ? … pas facile voir blipnet ericsson

21 J2SE / JSR82 Deux paquetages Qui suis-je ?, qui est là ?, répondez …
javax.bluetooth.*; Nommage, Découverte Recherche de services Communication btspp://localhost:{UUID} + (flux habituels) Un protocole répandu OBEX java.obex.*; btgoep://localhost:localhost:{UUID} + (flux habituels) tcpobex://1905 Irdaobex://localhost:1900 Session Transfert d’objets put, get

22 android.bluetooth Android Qui suis-je ?, qui est là ?, répondez …

23 Qui suis-je ? Chaque périphérique BT possède
Une adresse (physique) sur 48 bit et unique (MAC adresse) Un nom lui est associé (en général)

24 Premier exemple : quelle est mon adresse BT ?
import javax.bluetooth.LocalDevice; public class QuiSuisJe{ public static void main(String[] args)throws Exception{ LocalDevice localDevice = LocalDevice.getLocalDevice(); System.out.println(localDevice.getBluetoothAddress() + " : " + localDevice.getFriendlyName()); } Depuis un PC, J2SE javac -cp .;bluecove jar QuiSuisJe.java java -cp .;bluecove jar QuiSuisJe

25 Sur simulateur de mobile et sur mobile : QuiSuisJe
A cette URL téléchargez sur votre poste Puis exécutez > run_microemulateur.bat Sur votre mobile installez cette Midlette BTQuiSuisJe.jar

26 Sur Android * QuiSuisJe ?
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); String name = btAdapter.getAddress(); * Sur un mobile, bluetooth non pris en compte par l’émulateur

27 Bluetooh et nommage Devrons nous connaître les adresses physiques ?
0019EF0117DA Devrons nous connaître les adresses physiques ? Non merci … Sauf les fixes … Une UUID associera nom logique / adresse physique Universal Unique IDentifier -> UUID nous utiliserons

28 La suite Initialisation de la pile (protocole)
A la recherche d’un service Android J2SE/JSR82 Découverte de périphériques BT Aux alentours Nommage/UUID Universally Unique IDentifier (128 bits), existe en version courte Communication java.io.*, etc… Découverte des services Au sein de chaque entité Nommage/UUID Universally Unique IDentifier (128 bits)

29 Un service se trouve sur ce périphérique
Il nous faut L’adresse MAC du périphérique Être appairé (Android) Ex. "00:19:EF:01:17:9C" UUID (128bits) Qui identifie le service (" A0-B0C0D0E0F0FF");

30 Android Architecture retenue
Recherche du service bluetooth au sein d’une sous-classe d’AsyncTask Communication dans un Thread, Synchronisation en utilisant une SynchronousQueue

31 Sous-classe d’AsyncTask
Proposition private class ConnexionBT extends AsyncTask<String,String,BluetoothSocket>{ protected void onPreExecute() { protected BluetoothSocket doInBackground( String... args) { protected void publishProgress(String... infos) { protected void onPostExecute(BluetoothSocket btSocket) {

32 protected void onPostExecute(BluetoothSocket btSocket) {
Exemple private UUID MY_UUID = UUID.fromString(" A0-B0C0D0E0F0FF"); private class ConnexionBT extends AsyncTask<String,String,BluetoothSocket>{ private ProgressDialog dialog = null; private BluetoothDevice btDevice; protected void onPreExecute() { dialog = ProgressDialog.show(…); } protected BluetoothSocket doInBackground(String... args) { try{ this.btDevice = btAdapter.getRemoteDevice(args[0]); MAC btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID); btAdapter.cancelDiscovery(); btSocket.connect(); }catch(Exception e){} return btSocket; protected void onPostExecute(BluetoothSocket btSocket) { os = btSocket.getOutputStream();

33 Communication sur os : dans un Thread
public class Sender extends Thread{ private BlockingQueue<byte[]> queue; public Sender(){ queue = new SynchronousQueue<byte[]>(); this.start(); } public boolean offer(byte[] cmd){ return queue.offer(cmd); public void close(){ this.interrupt(); public void run(){ while(!isInterrupted()){ try { byte[] cmd = queue.take(); os.write(cmd); } catch (Exception e) {

34 J2SE/Un client // à la découverte du service …
connString = agent.selectService(new UUID(" A0B0C0D0E0F0BB", false), ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); StreamConnection conn = (StreamConnection)Connector.open(connString); OutputStream out = conn.openOutputStream(); Reader in = new InputStreamReader(conn.openInputStream()); String str = "http://jfod.cnam.fr:8999/ds2438/\n"; out.write(str.getBytes()); out.flush(); String response = readFile(in); // dans un Thread private static String readFile(InputStream in) throws IOException { StringWriter data = new StringWriter(); int aByte; while((aByte = in.read())!=-1){ data.write( (byte)aByte); } return data.toString();

35 Parmi mes voisins … Parmi les périphériques BT aux alentours
Quel est celui qui possède ce service … Apparenté à la découverte multicast… Un service : un UUID new UUID(" A0B0C0D0E0F011" ,false) 128 bits … pourquoi pas celui-ci … Plusieurs BT peuvent répondre pour un service souhaité « dépôt d’un fichier », mp3 … redondance

36 A typical usecase

37 A la découverte de … obtention d’un agent
import javax.bluetooth.LocalDevice; import javax.bluetooth.DiscoveryAgent; public class ALaDécouverteDe{ public static void main(String[] args) throws Exception{ LocalDevice local = LocalDevice.getLocalDevice(); local.setDiscoverable( DiscoveryAgent.GIAC ); // GIAC General inquire Access Code DiscoveryAgent agent = local.getDiscoveryAgent(); un agent capable de tout faire Sélection d’un service Effectuer une recherche exhaustive

38 Adéquation UUID / URL LocalDevice local = LocalDevice.getLocalDevice(); local.setDiscoverable( DiscoveryAgent.GIAC ); // General inquire Access Code DiscoveryAgent agent = local.getDiscoveryAgent(); UUID uuid = new UUID(" A0B0C0D0E0F011", false); String connString = agent.selectService(uuid, ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); System.out.println("connString : " + connString); Un exemple d’affichage : connString: btspp://0019EF01194C:1;authenticate=false;encrypt=false;master=false 0019EF01194C l’adresse physique :1 le port de communication

39 Un service comme un autre
Nous avons Un service -> un UUID un UUID -> une URL Une URL -> une communication Une syntaxe de type J2ME Une communication Un flux d’octets, btspp:// Un flux structuré, btgeop://

40 Exemple de service/UUID/J2SE
C’est un serveur … protocole btspp:// StreamConnectionNotifier notifier = (StreamConnectionNotifier)Connector.open( "btspp://localhost: A0B0C0D0E0F010"); attente d’une requête StreamConnection conn = notifier.acceptAndOpen();

41 Un serveur au complet StreamConnectionNotifier notifier =
public class SimpleBTSPPServer { public static void main(String[] args) throws Exception{ LocalDevice local = LocalDevice.getLocalDevice(); local.setDiscoverable(DiscoveryAgent.GIAC); StreamConnectionNotifier notifier = (StreamConnectionNotifier)Connector.open( "btspp://localhost:" + " A0B0C0D0E0F010"); StreamConnection conn = notifier.acceptAndOpen(); InputStream in = conn.openInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); int data; while ((data = in.read()) != -1) { out.write(data); } System.out.println(" message recu : " + out.toString()); in.close(); conn.close(); notifier.close(); note : ci-dessus vous avez un serveur d’une seule connexion… c’est peu… UUID

42 Le client à la recherche de cet UUID
Les essentiels agent .selectService … String connString = agent.selectService( new UUID(" A0B0C0D0E0F010", false), ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); StreamConnection StreamConnection conn = (StreamConnection) Connector.open(connString);

43 Un exemple de client de ce service
public static void main(String[] args) throws Exception{ LocalDevice local = LocalDevice.getLocalDevice(); local.setDiscoverable( DiscoveryAgent.GIAC ); DiscoveryAgent agent = local.getDiscoveryAgent(); String connString = agent.selectService( new UUID(" A0B0C0D0E0F010", false), ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); StreamConnection conn = (StreamConnection) Connector.open(connString); OutputStream out = conn.openOutputStream(); out.write("next".getBytes()); out.flush(); out.close(); conn.close(); }

44 Android, même principe Extrait de     BluetoothServerSocket btServerSocket;   btServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);

45 Un premier exemple : une passerelle BT/HTTP
BT/Web Pourquoi faire ?

46 Autre exemple une borne Bluetooth/HTTP
Un service Bluetooth, PC, J2SE relié au web Attend une connexion BT, réception d’une URL (en String) Effectue la requête Retourne la page reçue Un client Bluetooth Recherche ce service Envoie une URL Affiche le résultat

47 Démonstration : le serveur
Le Proxy BT<->HTTP est une application JavaWebStart Il suffit de cliquer ici UUID = A0B0C0D0E0F0A Réception d’une URL Envoi du fichier, précédé de la taille de celui-ci, Le client reste connecté

48 Démonstration : Côté client
Le client BT / sur un autre poste est également une application JavaWebStart (depuis un autre poste) Effectue une requête en toutes les 10mn Le ds2438 est un capteur d’humidité relative Côté client un navigateur ? Sur mobile Opera mini, sources java disponibles ? Analogue à l’usage d’un proxy mais au protocole btspp://

49 Côté client/mobile Le client BT sur votre mobile,
téléchargez cette midlette BTProxyHTTPClient.jar Le client BT sur un émulateur de mobile Téléchargez tous les fichiers, puis exécuter run_microemulateur.bat

50 Une Variante de BTProxyHTTP
Une connexion par client Envoi d’une URL, Réception du fichier Fermeture de la connexion

51 Quelques traces Côté serveur Côté client
Côté client un autre exemple voir page suivante Application extraite de

52 Un client … du classique
// à la découverte du service connString = agent.selectService(new UUID(" A0B0C0D0E0F0BB", false), ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); StreamConnection conn = (StreamConnection)Connector.open(connString); OutputStream out = conn.openOutputStream(); Reader in = new InputStreamReader(conn.openInputStream()); String str = "http://jfod.cnam.fr:8999/ds2438/\n"; out.write(str.getBytes()); out.flush(); String response = readFile(in); private static String readFile(InputStream in) throws IOException { StringWriter data = new StringWriter(); int aByte; while((aByte = in.read())!=-1){ data.write( (byte)aByte); } return data.toString();

53 Le serveur en quelques lignes
LocalDevice local = LocalDevice.getLocalDevice(); local.setDiscoverable(DiscoveryAgent.GIAC); StreamConnectionNotifier notifier = (StreamConnectionNotifier)Connector.open("btspp://localhost:" + " A0B0C0D0E0F0BB" + ";name=BTProxyHTTP2"); while(true){ StreamConnection conn = notifier.acceptAndOpen(); new ConnexionBT(conn).start(); } ConnexionBT Un Thread à chaque connexion Bluetooth et Un Thread pour chaque requête HTTP ! Protocole : envoi de l’URL « http:// … » puis attente du résultat

54 Le serveur suite, classe interne ConnexionBT
private static class ConnexionBT extends Thread{ private StreamConnection conn; private String url; public ConnexionBT(StreamConnection conn){this.conn = conn;} public void run(){ try{ OutputStream out = conn.openOutputStream(); Reader in = new InputStreamReader(conn.openInputStream()); this.url = readLine(in); if (url!=null) { ConnexionHTTP connect = new ConnexionHTTP(url); System.out.print(" -> une requete en " + this.url); String result = connect.result(); System.out.println(", page lue et envoyée : " + result.length() + " octet(s), iso "); byte data[] = result.getBytes("iso "); // le contenu out.write(data); out.flush(); } out.close(); in.close(); conn.close(); }catch(Exception e){} }}

55 Découverte suite Avec BTProxyHTTP, BTProxyHTTP2
L’URL est connue agent.selectService(new UUID(" A0B0C0D0E0F0BB", false), ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false); Notion de familles de services Quelles sont ces familles ? Quels sont les services ?

56 Quels sont les services aux alentours ?
Tout d’abord quels sont les périphériques BT aux alentours ? Grâce à mon agent agent.startInquiry() : patience… au moins 10 secondes … ensuite Recherche des services bien connus ? OBEX : push obex, ftp, Etc …

57 Obtention de la liste de tous les périphériques bluetooth aux alentours

58 Comment ? startInquiry  deviceDiscovered

59 En Java : un listener appelé par l’API
L’interface DiscoveryListener 4 méthodes, 2 pour la découverte des périphériques 2 pour la découverte des services public void deviceDiscovered( RemoteDevice rd, DeviceClass cod ) ; public void inquiryCompleted( int status ); public void serviceSearchCompleted( int transID, int respCode ) ; public void servicesDiscovered( int transID, ServiceRecord[] rec);

60 Exemple : Liste des périphériques BT, startInquiry
public class BTDeviceList{ private static Object inquiry = new Object(); private static Vector<RemoteDevice> devices = new Vector<RemoteDevice>(); public static void main(String argv[]) throws Exception{ LocalDevice local = LocalDevice.getLocalDevice(); DiscoveryAgent agent = local.getDiscoveryAgent(); agent.startInquiry( DiscoveryAgent.GIAC, new DeviceDiscover()); System.out.println("start device inquiry ..."); synchronized(inquiry){ inquiry.wait();} // attente … en sec. System.out.println("device list : " + devices); }

61 Exemple suite : le listener…
private static class DeviceDiscover implements DiscoveryListener{ public void deviceDiscovered( RemoteDevice rd, DeviceClass cod ) { devices.addElement(rd); } public void inquiryCompleted( int status ) { synchronized(inquiry) { try { inquiry.notify(); } catch(Exception e) {} public void serviceSearchCompleted( int transID, int respCode ) {} public void servicesDiscovered( int transID, ServiceRecord[] rec){}

62 Démonstration Il suffit de cliquer ici
Des affichages sur la console sont effectués Il vous faut sélectionner l’option Afficher La Console panneau de configuration, Java, puis dans l’onglet Avancé Ou bien en téléchargeant l’archive java -cp bluecove jar;BTDeviceList.jar BTDeviceList

63 Un schéma/résumé extrait de la bibliographie

64 Un autre exemple plus compact …
public static void main(String[] args) throws Exception{ LocalDevice localDevice = LocalDevice.getLocalDevice(); DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent(); discoveryAgent.startInquiry(DiscoveryAgent.GIAC, new DiscoveryListener(){ public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod){ try{ System.out.println(" New device discovered : " + btDevice.getFriendlyName(true) + " (" + btDevice.getBluetoothAddress() + ")" ); } catch(Exception e){e.printStackTrace();} } public void inquiryCompleted(int discType){ System.out.println("inquiryCompleted");System.exit(0); public void servicesDiscovered(int transID, ServiceRecord[] servRecord){} public void serviceSearchCompleted(int transID, int respCode){} });

65 Quels services ?, filtrage possible ?
bluecove.inquiry.duration Device Inquiry time in seconds defaults to 11 seconds. General Inquiry Access Code GIAC Limited Inquiry Access Code LIAC Notez que pour aller plus vite Nous pouvons retrouver les périphériques déjà découverts De DiscoveryAgent methode retrieveDevices(): RemoteDevice[] retrieveDevices(int option); ... Avec comme option CACHED périphériques déjà découverts dans le passé PREKNOWN la liste des pré-configuré … ? À éclaicir Mais aucune garantie que le périphérique est toujours accessible, Il a été découvert dans le passé, c’est tout

66 Exemple : PREKNOW / CACHED
private void addDevices_PREKNOW_AND_CACHED(){ RemoteDevice[] list = null; list = agent.retrieveDevices(DiscoveryAgent.PREKNOWN); if(list!=null){ System.out.println(list.length + " preknow"); for(int i = 0; i < list.length; i++){ devices.addElement(list[i]); } list = agent.retrieveDevices(DiscoveryAgent.CACHED); System.out.println(list.length + " devices cached");

67 Cached CACHED Détecté lors d’un précédent inquiry …
La pile s’en charge … évite (parfois) le recours à la phase inquiry …

68 Diagramme d’états, ou un résumé
La suite

69 Services -> Nouvelles questions ?
Quels sont les services ? Quel filtre pour l’obtention des services ? Comment ? Démonstration Autorisez le bluetooth de vos mobiles …

70 À la recherche des services (famille listener)

71 Exemple, UUID et plus Sur chaque périphérique découvert
discoveryAgent.searchServices(attrSet, uuidSet, remoteDevice, this); Avec UUID[] uuidSet = {new UUID(0x0100)}; // 0x0100 au dessus de L2CAP // 0x105 only searches btspp services int[] attrSet = {0x0100, 0x0003, 0x0004}; // 0x0100 ProtocolDescriptorList // 0x0003 ServiceID UUID // 0x0004 ProtocolDescriptorList

72 Un lundi après-midi au Cnam, 3ème étage
LocalDevice properties: VIVALDI ( A34C7) New device discovered : LMI84 (0019EF01194C) New device discovered : La Tigresse (00180FD94A7C) Searching for Services on: LMI84 (0019EF01194C) A new service is discovered: Service Discovery A new service is discovered: S e r v i c e u t i l i s a t e u r a d - h o c p e r s o n n e l Searching for Services on: La Tigresse (00180FD94A7C) A new service is discovered: Dial-up networking A new service is discovered: Nokia PC Suite A new service is discovered: COM 1 A new service is discovered: Audio Gateway A new service is discovered: SIM ACCESS A new service is discovered: OBEX Object Push A new service is discovered: OBEX File Transfer A new service is discovered: SyncML Client

73 Exemple liste de tous les services

74 Comment ? Les périphériques découverts: Les services découverts:
public void startSearchServices() throws Exception{ UUID uuids[] = {new UUID(0x0100)}; // "0100" L2CAP int attridset[] = {0x0100}; // SERVICE_NAME_ATTRID = 0x0100; this.services.clear(); System.out.println("start search services for " + devices.size() + " devices"); for( int i=0; i<devices.size(); i++ ) { RemoteDevice rd = devices.elementAt(i); System.out.println(" search services for " + rd.getBluetoothAddress()); agent.searchServices(attridset, uuids, rd, this); synchronized(this) { while(!serviceSearchCompleted) wait(); serviceSearchCompleted=false; } Les périphériques découverts: Vector<RemoteDevice> devices = new Vector<RemoteDevice>(); Les services découverts: Vector<ServiceRecord> services = new Vector<ServiceRecord>();

75 Les services en clair … // tous les services, <HostDevice,nom du service, URL> for(int i=0; i< services.size(); i++){ str.append("<"); str.append(services.elementAt(i).getHostDevice().getBluetoothAddress()); try{ DataElement nameElement = (DataElement)services.elementAt(i).getAttributeValue(SERVICE_NAME_ATTRID); str.append(","); if ( nameElement != null ) str.append((String)nameElement.getValue()); else str.append("_"); str.append(services.elementAt(i).getConnectionURL( ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false)); }catch(Exception e){} str.append(">\n"); } return str.toString();

76 Lire les résultats retournés
Comment ? Quelle Structure ? À faire 0x4: DATSEQ { UUID f9b34fb } UUID f9b34fb U_INT_1 0x10 0x1: UUID a0b0c0d0e0f088 UUID f9b34fb 0x0: U_INT_4 0x10100

77 Comment ? suite public void serviceSearchCompleted( int transID, int respCode ) { System.out.println("service search complete"); synchronized(this) { try { serviceSearchCompleted=true; this.notifyAll(); } catch(Exception e) {} } public void servicesDiscovered( int transID, ServiceRecord[] rec){ if(rec!=null && rec.length>0){ for( int i=0; i<rec.length; i++ ) { services.addElement(rec[i]);

78 http://www.bluecove.org/bluecove/apidocs/ voir UUID
Base UUID Value (Used in promoting 16-bit and 32-bit UUIDs to 128-bit UUIDs) 0x F9B34FB 128-bit SDP 0x bit RFCOMM 0x bit OBEX 0x bit HTTP 0x000C bit L2CAP 0x bit BNEP 0x000F bit Serial Port x bit ServiceDiscoveryServerServiceClassID 0x bit BrowseGroupDescriptorServiceClassID 0x bit PublicBrowseGroup x bit OBEX Object Push Profile 0x bit OBEX File Transfer Profile 0x bit Personal Area Networking User 0x bit Network Access Point x bit Group Network x bit

79 Autre exemple Qui aux alentours possède ce service ?
Object push, c’est un service au protocole OBEX final UUID OBEX_OBJECT_PUSH = new UUID(0x1105); final UUID OBEX_FILE_TRANSFER = new UUID(0x1106); final int SERVICE_NAME_ATTRID = 0x0100; public void startSearchServices() throws Exception{ UUID uuids[] = {OBEX_OBJECT_PUSH}; int attridset[] = {SERVICE_NAME_ATTRID}; for(int i=0;i<devices.size();i++){ RemoteDevice rd = devices.elementAt(i); agent.searchServices(attridset, uuids, rd, this); synchronized(this) { while(!serviceSearchCompleted) wait(); serviceSearchCompleted=false; }

80 Exemple : Remote Control
A l’origine un exemple sur le web sourceforge.net/projects/blurc Défilement distant de diapositives PowerPoint (par exemple) Contrôle distant du clavier Ajouts d’évènements dans la file « du système » Usage de java.awt.Robot le blog de Federico Paparoni BTFree ici Une librairie qui peut être utile

81 Mise en œuvre « Prise de contrôle distant »
Choix d’un protocole de communication Plusieurs mobiles en même temps la connexion reste ouverte Envoi de next\n vers le serveur, (son interprétation ->) Envoi de previous\n vers le serveur, (son interprétation <-) Etc…

82 Démonstration Côté serveur Un client sur PC pour les tests
Usage de java.awt.Robot Un client sur PC pour les tests Avec microemulator Télécharger ces fichiers Puis >run_microemulateur Sur votre mobile installez cette MIDlette BTClientVNC.jar

83 Démonstration suite Pas de clé BT sur PC, pas de téléphones … le néant… Utilisation du WTK et de l’émulateur Bluetooth intégré Le « serveur » est une midlette Le source du serveur perfectible Il ne vous plus qu’à développer le client ! Serait-ce une question de tp …

84 Un schéma / résumé

85 En résumé Le client et son agent

86 OBEX http://developers.sun.com/mobility/apis/articles/bluetoothobex/
BNEP Bluetooth Network Encapsulation Protocol AVC(D)TP Audio/Video Control(Distribution) Transport Protocol HCI Host Controller Interface

87 OBEX

88 OBEX Client/Server Les clients OBEX Le Serveur
CONNECT, GET, PUT … import javax.obex.ClientSession; import javax.obex.HeaderSet; import javax.obex.Operation; import javax.obex.ResponseCodes; Le Serveur UUID uuid = new UUID("8841", true); String url = "btgoep://localhost:" + uuid + ";name=FTP;authenticate=false;master=false;encrypt=false"; import javax.obex.ServerRequestHandler; import javax.obex.SessionNotifier;

89 OBEX : les UUID Object Push Profile OPP 0x1105
File Transfer Profile FTP 0x1106 Synchronization Profile SYP 0x1104 Basic Imaging Profile BIP 0x111A Phone Book Access Profile PBAP 0x1130 Basic Printing Profile BPP 0x1122 Lire le Quick Tutorial 0x1105 Ou F9B34FB en version longue …

90 Une session Client, ici un envoi d’un fichier
Recherche du « bon service » ici serverURL Puis établissement d’une connexion au protocole OBEX public boolean obexPut(String serverURL) { ClientSession clientSession clientSession = (ClientSession) Connector.open(serverURL); HeaderSet hsConnectReply = clientSession.connect(clientSession.createHeaderSet()); if (hsConnectReply.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) { System.out.println("Connect Error " + hsConnectReply.getResponseCode()); } HeaderSet hsOperation = clientSession.createHeaderSet(); hsOperation.setHeader(HeaderSet.NAME, fileName); String type = ObexTypes.getObexFileType(fileName); hsOperation.setHeader(HeaderSet.LENGTH, new Long(data.length)); Operation po = clientSession.put(hsOperation); // envoi du fichier  analyse po.getResponseCode() po.close(); HeaderSet hsDisconnect = clientSession.disconnect(null); //  hsDisconnect.getResponseCode() == ResponseCodes.OBEX_HTTP_OK

91 ObexTypes.getObexFileType, apparenté mimes
public static class ObexTypes { private static Hashtable<String,String> types = new Hashtable<String,String>(); static { types.put("jpg", "image/jpeg"); types.put("jpeg", "image/jpeg"); types.put("gif", "image/gif"); types.put("mp3", "audio/mpeg"); types.put("txt", "text/plain"); types.put("jar", "application/java-archive"); } static String getFileExtension(String fileName) { int extEnd = fileName.lastIndexOf('.'); if (extEnd == -1) { return ""; } else { return fileName.substring(extEnd + 1).toLowerCase(); static String getObexFileType(String fileName) { return (String) types.get(getFileExtension(fileName));

92 Le service Inscription du service A chaque client
SessionNotifier serverConnection = (SessionNotifier) Connector.open("btgoep://localhost:"+ serverUUID + ";name=ObexPutServer2"); A chaque client Une requête/un thread Connection conn = serverConnection.acceptAndOpen(new RequestHandler()); Traitement de la reqûete, PUT,GET, … : -> RequestHandler

93 Le service : RequestHandler
private class RequestHandler extends ServerRequestHandler { public int onPut(Operation op) { try { HeaderSet hs = op.getReceivedHeaders(); String name = (String) hs.getHeader(HeaderSet.NAME); InputStream is = op.openInputStream(); StringBuffer buf = new StringBuffer(); int data; while ((data = is.read()) != -1) { buf.append((char) data); } op.close(); synchronized(lock){notify();} return ResponseCodes.OBEX_HTTP_OK; } catch (IOException e) { e.printStackTrace(); return ResponseCodes.OBEX_HTTP_UNAVAILABLE; }}

94 Un client OBEX du serveur au complet
private static class ClientObex extends Thread{ private Connection conn; private SessionNotifier serverConnection; private Object lock; private class RequestHandler extends ServerRequestHandler {…} public ClientObex(SessionNotifier serverConnection) throws IOException{ this.serverConnection = serverConnection; this.lock = new Object(); this.conn = serverConnection.acceptAndOpen(new RequestHandler()); this.setPriority(10); this.start(); } public void run(){ synchronized(lock){ try{ wait(); conn.close(); }catch(Exception e){} }}}

95 Applications, c.f. bluecove
Extraites des exemples joints avec bluecove

96 Démonstration BTFileUpload
Envoi d’un fichier sur tous les mobiles ici présents … 1) Recherche de tous les périphériques BT Autoriser vos portables 2) Sélection de tous les périphériques possédant ce service OBEX Object push 0x1105

97 Un petit outil très contagieux
Diffusion, mise à jour, déploiement Hypothèse : Une Midlet capable de diffuser une Midlet capable de diffuser une … Usage du service OBEX Push Object prédéfini Comment ? Une archive contenue dans le .jar de la midlette est envoyée à tous ses voisins Le voisin reçoit une archive soit une midlette qui contient une archive … Viable ? TTL déguisé Fonctionne quelque soit le mobile ?

98 Petit outil de diffusion suite
La Midlette BTFileUpLoad Contient une archive BTFileUpLoad.jar qui contient à son tour …

99 Petit Outil en démonstration
Préambule Ok Avec le micro-émulateur ! Sony Ericsson, S500i Motorola K1, envoi ok, réception incorrecte… La Midlette est là

100 Démo du WTK Voir obexdemo
Et le sous répertoire j2seObexDemo… Et surtout

101 Démo microemulator/ pile bluecove
server Installées ici

102 Le patron/observateur/Observé-MVC
HTTP Observateurs/Observé modele 2,mise à jour) Contrôle Vue Vue 1,notification) Vue vue1 0,init)

103 MVC HTTP+BT modele Contrôle Vue Vue Vue vue1 HTTP/BT 2,mise à jour)
Observateurs/Observé Midlettes BTProxyHTTP BTServerHTTP modele 2,mise à jour) Contrôle Vue Vue 1,notification) Vue vue1 0,init)

104 Patrons Observateur + Fabrique
ObservableServer addObserver, notifyObservers comme services Web/HTTP ObserverServer Update comme service Web ObserversHTTPList La liste des observateurs ConnectionFactory Une fabrique de Connexion Deux connexions concrètes Bluetooth et HTTP (dépend de l’url choisie)

105 Un exemple avec Httpunit
public void test_notifyBTObservers(){ try{ new Thread(new Runnable(){ // création de l’observable public void run(){ ObservableServer.main(new String[]{"8226"}); }}).start(); WebConversation conversation = new WebConversation(); WebRequest request = null; // inscription d’un observateur request = new GetMethodWebRequest("http://localhost:8226/addObserver/?uuid= A0B0C0D0E0F088"); WebResponse response = conversation.getResponse( request ); assertTrue(" pas de réponse ???", response.getText().length() > 0); assertTrue(" la réponse doit doit ici retournée true ???", response.getText().contains("true")); // une première notification request = new GetMethodWebRequest("http://localhost:8226/notifyObservers/?temperature=300&capteur=DS1921" ); response = conversation.getResponse( request ); // une seconde notification request = new GetMethodWebRequest("http://localhost:8226/notifyObservers/?temperature=200&capteur=DS1922" ); }finally{ ObservableServer.stopServer(); }

106 Une démonstration … Démonstration en ligne : Traces côté Observable
Traces côté Observable BlueCove version on winsock Request: GET /notifyObservers/?temperature=200&capteur=DS1922 HTTP/1.1 Request: GET /addObserver/?uuid= A0B0C0D0E0F088 HTTP/1.1 addObserver : A0B0C0D0E0F088 Request: GET /notifyObservers/?temperature=300&capteur=DS1921 HTTP/1.1 Côté Mobile, bluetooth

107 Petite conclusion Observateur/Observé sur le web Mobiles
Contrôles/ Vue Modèle ? / liaison web ? En quelques lignes Abstraction des distances À terminer

108 Conclusion plus grande ?
Bluetooth Mobile/java Motorola K1, Sony Ericsson À tester : Clé USB ou intégré sur PC bluecove API jsr82 Cette présentation : impasse sur l2cap ? Dans une prochaine mouture

109 Conclusion http://www.bluecove.org/
à vérifier sur d’autres périphériques

110 Annexes UbiqMuseum Réseaux ad’hoc broadcast Télécommandes…

111 UbiqMuseum comme projet

112 UbiqMuseum Tout visiteur reçoit une MIDlet de visite
MIDLet cliente et/ou MIDLet serveur … Chaque pièce du musée est équipé d’un PC/BT/Wifi Serveur / Client … PC relié entre eux voir Java Messaging Service (JMS) Mode connecté < 8 périphériques simultanés Mode de type Session Côté client RFComm OBEX

113 UbiqMuseum Discussion

114 Annexe javawebStart Un certificat > keytool -genkey -alias jmd -keypass PASSWORD -keystore jmdstore -storepass PASSWORD jar  cvf MiniBrowser.jar  webBrowser/*.class jarsigner -keystore jmdstore MiniBrowser.jar jmd <jnlp spec="1.0+" codebase="http://jfod.cnam.fr/SEJA/jnlp/" href="MiniBrowser.jnlp"> <information> <title>MiniBrowser</title> <vendor>SEJA Cnam</vendor> <description>MiniBrowser</description> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.5+"/> <jar href="MiniBrowser.jar"/> <jar href="bluecove jar"/> </resources> <application-desc main-class="webBrowser.MiniBrowser"/> </jnlp>

115 Annexe : MIDlet javax.bluetooth.*
JSR82 javax.bluetooth

116 Device Management Device Management
LocalDevice() appelé par l’application cliente setDiscoverable() updateRecord() getBluetoothAddress() getProperty() RemoteDevice() informations du fournisseur authenticate() authorize() isEncrypted()

117 Résumé Communication JSR 82 supports a low-level data transfer (Logic Link Control & Adaptation) and a stream communication interface (RFCOMM) L2CAP interface not commonly used Need significant effort from user to handle the packets, fragmentation etc., Stream communication API is used extensively in MIDP development btspp://hostname:[CN | UUID];parameters - btspp indique le protocole RFCOMM (StreamConnection) - hostname soit localhost, ou l’adresse Bluetooth - CN est le numéro de port - UUID l’identifiant du service - parameters authenticate, authorize, and encrypt information - Eg: btspp://hostname;authenticate=true;authorize=true;encrypt=true

118 Annexe Klings

119 BTBrowserMIDlet de klings
Mise en œuvre, développement WTK Avec le microemulateur* Pile bluecove et avetana Les sources et exécutables *java -cp ./microemulator.jar;./bluecove jar;. org.microemu.app.Main BTBrowserMIDlet

120 BTBrowser, avec un autre émulateur
java -cp ./me4se jar;./bluecove jar;. org.me4se.MIDletRunner BTBrowserMIDlet


Télécharger ppt "Bluetooth orienté java : JSR82 + Android"

Présentations similaires


Annonces Google