1. Préparation
2. Un peu de théorie sur bluetooth
3. Le code commenté
4. Le projet eclipse avec toutes les dépendances
Cette partie a pour but de voir le minimum necessaire sur la spécification bluetooth pour pouvoir comprendre les apis logiciels que nous mettons en oeuvre dans ce tutoriel. Ce résumé à ma sauce s'appuie sur :
Le dernier article est très complet et je vous conseille de l'approfondir pour étudier l'utilisation du JSR 82.
Le stack bleutooth
Ce sont les couches logicielles qui nous interesse et ne parlerons pas des couches matérielles.
L2CAP
L2CAP (Logical Link Control & Adaptation Protocol) fournit les services de multiplexage des protocoles de niveau supérieur et la segmentation et le réassemblage des paquets ainsi que le transport des informations de qualité de service. Les protocoles de haut niveau peuvent ainsi transmettre et recevoir des paquets jusqu'à 64 Ko. Elle autorise un contrôle de flux par canal de communication.
La couche L2CAP utilise des canaux logiques.
Dans le java bluetooth stack cette couche est représenté par l'interface L2CAPConnection. Comme elle respecte le CLDC Generic Connection Framework (
http://www.oracle.com/technetwork/systems/index-155711.html) elle est accompagnée de L2CAPConnectionNotifier qui permet de créer des connections de type server.
En pratique on ne travaillera pas directement avec L2CAPConnection mais plustôt avec l'interface StreamConnection et StreamConnectionServer qui respecte les mêmes contrats. En effet travailler L2CAPConnection nous oblige à limiter la taille de nos paquets et à gérer le réassemblage de paquets. Néanmoins voici un exemple d'utilisation de des interfaces.
//coté client
//.....
L2CAPConnection conn = (L2CAPConnection)
//on suppose que le server écoute sur le port 1003 on verra qu'en fait les services
//sont découverts dynamiquement.
Connector.open("btl2cap://0050CD00321B:1003;ReceiveMTU=512;TransmitMTU=512");
PrintStream out = new PrintStream(conn.openOutputStream());
//...
//coté serveur
//.....
L2CAPConnectionNotifier service = (L2CAPConnectionNotifier)
Connector.open("btl2cap://localhost:0050CD00321B;ReceiveMTU=512;TransmitMTU=512");
L2CAPConnection conn = (L2CAPConnection) service.acceptAndOpen();
InputStream is = conn.openInputStream();
Comme nous le disions précédemment "Elle autorise un contrôle de flux par canal de communication" c'est pourquoi on trouve dans ces deux urls les parametres ReceiveMTU et TransmitMTU :
/**
* ReceiveMTU
* specifies the maximum payload size this connection can accept, and
* TransmitMTU specifies the maximum payload size this connection can
* send
*/
RFCOMM
Il est exigé d'un stack bluetooth qu'au dessus de sa couche L2CAP un protocole série soit émulé : RFCOMM (Radio frequency communication).
Cette exigence connu aussi sous Serial Port Profile (SPP) existe car beaucoup de processus savent communiquer avec ce protocole plutôt qu'avec L2CAP.
Par exemple pour les tests sur un PC on peut utiliser Hyper Terminal pour voir les données arrivant sur le port émulé COM.
Je ne présente pas d'exemple d'utilisation avec RFCOMM car je pense que c'est la même chose que pour L2CAP. On trouve deux classes : BluetoothRFCommConnection et BluetoothRFCommConnectionNotifier qui implémentent respectivement StreamConnection et StreamConnectionNotifier que nous allons étudier plus en détail.
Je n'ai néanmoins pas approfondi cette partie et toute remarque est bienvenue.
SDP
Service Discovery protocole, qui permet de découvrir les autres devices à portée du client. Le code du précédent article présente ce processus et est déjà abondemment commenté.
TCS
Telephony Control Protocol, est un protocole obsolète orienté donnée binaire, je n'ai pas cherché à l'étudier, si vous pouvez apporter plus de précision sur son rôle c'est avec plaisir que je lirai vos commentaires.
OBEX
Obex est un protocole permettant l'échange d'objet, nous n'allons pas l'étudier dans ce tutoriel, mais vous trouverez deux exemples de codes :
Client Obex : http://bluecove.org/apidocs/overview-summary.html#OBEXPutClient
Server Obex : http://bluecove.org/apidocs/overview-summary.html#OBEXPutServer
Les profils
Un profil correspond à une spécification fonctionnelle d'un usage particulier. Les profils peuvent également correspondre à différents types de périphériques.
Les profils ont pour but d'assurer une interopérabilité entre tous les appareils Bluetooth.
Ils définissent :
la manière d'implémenter un usage défini
les protocoles spécifiques à utiliser
les contraintes et les intervalles de valeurs de ces protocoles.
On a vu un de ces profils SPP (Serial Port Profile), lorsqu'un insdustriel souhaite obtenir la certification Bluetooth il doit valider une certaine quantités de ces profils.
La notion de client et de serveur.
Il faut bien différencier la notion de client et de serveur, un serveur publie un service et un client le consomme. Un device peut à la fois être client et serveur, aucun stack ne met de limite à être soit uniquement client soit uniquement serveur.
Voici un diagramme d'activité qui illustre ce que nos deux codes (code client et code serveur) vont faire.
Le code client.
Il va commencer par découvrir les devices bluetooth autour de lui : Un casque bluetooth, un téléphone, un autre ordinateur, etc.
C'est la phase d'inquiry, il va envoyer des ondes tout autour de lui pour dire qu'il cherche à découvrir les autres devices. Si les autres devices ont décidé de se rendre découvrable alors ils répondront à ce message d'inquiry pour dire qu'ils sont présents. Cela permet au client d'acquerir les adresses physiques des devices autour de lui et lui permet de les mettre dans son cache.
Enfin une fois qu'il aura découvert ces devices il va demander s'il existe un service spécifique sur le devices auquel il s'adresse. Si la réponse est positive alors la communication va avoir lieu.
Le code serveur
Il publie un service en ajoutant donc une entrée (Un service record) dans le SDB (Service Data Base) puis il se met en attente d'une requète entrante.
Et La sécurité et l'appairage des appareils ?
Cette partie n'est pas de la responsabilité des codes serveur ou client. C'est le statck sous-jacent qui doit s'occuper de l'appairage et de l'authentification des appareils entre eux.
Au mieux les codes peuvent exiger que l'échange n'ai lieu que si les appareils se sont authentifiés et/ou que l'échange soit cryptés, mais ce n'est pas eux qui géreront cette partie.