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.