Praktikum: Spezifikation

Transcrição

Praktikum: Spezifikation
1
Seminar zum Programmierprojekt (TI) Sommersemester 2007
(Lehrstuhl für Technische Informatik)
Ausgabe: 24. Mai 2007
Aufgabe C5: Anleitung
Einführung in die BT-Server-Programmierung mit JavaSE
Allgemeines
Mit Aufgabe 5 beginnen Sie die Implementierungsphase des SW-Programmierprojekts. Im
Raum C220 stehen drei so genannte „Praktikumsrechner“ für Sie bereit. Für die Studierenden
unseres SW-Projekts ist ein Zugang zu C220 beantragt worden. Auf dem Praktikumsrechner
2 ist Java2SE und eclipse installiert. Sie müssen für diese Aufgabe den Bluetooth-Dongle in
einen USB-Port einstecken. Sie lernen in Aufgabe 5 die Grundstruktur eines BT-Servers kennen.
JAVA Bluetooth-Programmierung im HOST
In dieser Programmieraufgabe sollen die Grundlagen der Bluetooth-Programmierung erlernt
werden. Als Ziel für den gesamten Aufgabenblock C5 bis C7 sei die Programmierung eines
Servers im Host gesetzt, der selbst drei Dienste anbietet, nämlich den Dienst "TelefonDienst", der auf Anfrage eine Telefonnummer (z.B. des Sekretariats der TI), den "Gebäudeplan-Dienst", der einen Gebäudeplan an das anfragende Gerät schickt und den „Quiz-Dienst“:
ein kleines Frage- und Antwort-Spiel. Zusätzlich soll ein Dienst "SendServices" als Antwort
auf eine Dienstanfrage eines entfernten Gerätes die im Host registrierten Dienste an das anfragende Gerät zurückgeben. In dieser Aufgabe wird zunächst das Serverframework programmiert, das die Dienste im Host registriert, eine DeviceDiscovery, also Suche nach entfernten Geräten durchführt und eine Dienstanfrage beantwortet. Gefundene BT-Geräte sollen
im Serverprogramm in einer Liste ausgegeben werden. Das Handling der Clientverbindungen
sei auf die nächsten Aufgaben (C6 und C7) verschoben.
Für die Programmierung soll die Java BT Implementierung von Benhui Bluecove sowie das
Java J2SE Development Kit und die J2SE Runtime Environment 5.0 Update 10 oder höher
verwendet werden. Als Entwicklungsumgebung bietet sich Eclipse an. Hier muss ein neues
Java-Projekt angelegt werden. Es muss die Benhui Bluecove Bibliothek ins Projekt eingebunden werden (über RechteMaustaste auf Projekt -> BuildPath -> Configure Build Path ->
Add External Jars).
Das Gegenstück zu dem hier zu entwickelnden Hostprogramm ist das Clientprogramm der
Gruppe B. Sie müssen sich mit der Gruppe B absprechen, wenn Sie ihr Programm testen wollen.
Initialisierung des Servers
2
Um einen Dienst im Server zu registrieren, ist zunächst die Initialisierung des lokalen Bluetoothgerätes nötig, d.h. der angeschlossene BT-Dongle muss über die JavaAPI initialisiert
werden. Ein Aufruf von
LocalDevice localDevice = getLocalDevice()
aus dem javax.bluetooth.*-Paket erledigt dies. Zusätzlich muss ein StreamConnectionNotifier-Objekt angelegt werden, welche ähnlich wie ein Server-Socket eingehende Verbindung
akzeptiert. Die Initialisierung des StreamConnectionNotifiers geschieht über folgenden Aufruf:
StreamConnectionNotifier serverconn = (StreamConnectionNotifier) Connector.open(url);
Die Connector-Klasse aus javax.microedition.io.Connector öffnet eine Verbindung und gibt
ein Connection- Objekt zurück, welches in die entsprechende Verbindungsart gecastet werden kann (hier also StreamConnectionNotifier). Der url-Parameterstring muss dem URLFormat aus RFC 2396 entsprechen. Er hat die allgemeine Form wie folgt:
{scheme}:[{target}][{params}]
•
{Scheme}: Name des Protkolls, z.B. btspp oder http
•
{target}: Eine Netzwerkadresse, für den lokalen Host "localhost:1", für entfernte Geräte eine BT-Adresse
•
[{params}]: Weitere Parameter der Form ";x=Y", z.B. ";app-name=HostNode"
Hinter der {target}-Netzwerkadresse wird die PSM angegeben, um einen speziellen Dienst
im Server anzusprechen. PSM 1 (genauer 0x0001) enspricht z.B. dem ServiceDiscoveryProtocol. Auf diese Weise kann später mittels der UUIDs für die Serverdienste ein Dienst gezielt
ausgewählt werden (eine PSM entspricht letztlich einer UUID, da die 16- bzw. 32-Bit-PSM
intern in eine 128-Bit UUID umgewandelt wird (siehe BluetoothAPI:UUID für eine Beschreibung der UUID-Klasse).
Die UUIDs für die Serverdienste müssen angelegt und im ServiceRecord des Hosts abgelegt
werden. Damit sind die Services im ServiceRecord der localDevice registriert und können bei
einer ServiceDiscovery durch ein entferntes Gerät gefunden werden. Eine Beschreibung des
Service Discovery Protokolls findet sich in der Bluetooth Core Specification v2.0.
Device Discovery
Nach der Dienstregistrierung sollen entfernte Geräte im Suchbereich entdeckt und eine Liste
der gefundenen Geräte ausgegeben werden. Dazu kann die BT-API wie folgt verwendet werden: Die Discovery sollte als eigener Thread aufgerufen werden, da die Synchronisation und
evtl. Ausnahmebehandlungen dadurch gut umzusetzen sind.
Der Discovery-Thread implementiert das Interface DiscoveryListener, welches folgende Methoden deklariert:
•
public void deviceDiscovered(RemoteDevice rd, DeviceClass dc);
•
public void inquiryCompleted(int complete);
3
•
public void servicesDiscovered(int id, ServiceRecord[] sr);
•
public void serviceSearchCompleted(int arg0, int complete);
Als Parameter für den DiscoveryThread wird ein DiscoveryAgent-Objekt , erhalten mit
DiscoveryAgent da = localDevice.getDiscoveryAgent();
übergeben. Dieses bietet einen Methodenaufruf
da.startInquiry(DisoveryAgent.GIAC, new DiscoveryListener());,
welcher die DeviceDiscovery startet. Hierbei wird die Methode deviceDiscovered(rd, dc)
aufgerufen, wenn ein Gerät gefunden wurde (hier kann dann also das Gerät in eine Liste bekannter Geräte aufgenommen werden). Wenn die Suche beendet ist, wird die Methode inquiryCompleted(int complete) aufgerufen (hier bietet sich die Ausgabe aller gefundenen Geräte
an, bevor der Thread beendet ist).
Es existieren einige Tutorials von SUN im Netz, die recht gut sind. Zu finden sind diese unter:
•
Tutorial 1
•
Tutorial 2
Außerdem zu empfehlen ist die Homepage von Benhui, auf der Beispielprogramme und viele
nützliche Informationen sowie ein Diskussionsforum zu finden sind.
Akzeptieren einer Client Verbindung
In dieser Aufgabe geht es darum, eingehende Clientverbindungen zu verarbeiten. Die
Dienstauswahl geschieht hier vereinfacht über den Austausch von Strings, die im Host geparst werden. Das Mobiltelefon (MT) schickt zuerst einen String, der im Pflichtenheft definiert ist, an den Host. Im Host soll dies erkannt werden und die registrierten Dienste ebenfalls
als String zurückgeschickt werden (siehe Pflichtenheft). Dieser String kann vom MT wiederum erkannt werden, welches dann die einzelnen Dienste zur Auswahl freigibt. Das Handling
der angebotenen Dienste wird in den folgenden Aufgaben durchgeführt. Hier soll zunächst
nur die Dienst-Antwort auf die Dienstanfrage des Client implementiert werden.
Akzeptieren einer Clientverbindung wird durch
StreamConnection clientconn = serverconn.acceptAndOpen()
ausgeführt. Dadurch wird ein StreamConnection Objekt erstellt, über das verschiedene
Schreib- und Leseoperationen durchgeführt werden können
Dienstanfrage: „Service Discovery“
Für die Service Discovery sendet in diesem Projekt das Mobiltelefon einfach einen String
"<SendServices String>" an den Server. Dieser parst den String und schickt seinerseits einen
String mit der Liste der angebotenen Dienste (also "Telefon-Service, Gebäudeplan-Service,
Quiz-Service-String") zurück. Falsche Anfragen vom Handy sollten mit einer Fehlermeldung
beantwortet werden.
4
Benutzen Sie für Input und Output über Bluetooth die Funktionen writeUTF(String s) und
readUTF(). Sie müssen zunächst ein DataInputStream Objekt für die eingehende Anfrage erzeugen:
DataInputStream in = clientconn.openDataInputStream();,
bevor sie mit
String s = in.readUTF()
den eingehenden String lesen können. Analog läuft das Schreiben auf den DataOutputStream
ab:
DataOutputStream out = clientconn.openDataOutputStream();
out.write("ihreantwort");
Der folgende Lückencode für den Server hilft Ihnen beim Einstieg in die Codierung.