Die Architektur der Software musste auf die besonderen Gegebenheiten des Wireless LANs der HTW-Aalen abgestimmt werden. Ursprünglich war geplant den Eee PC (verwendeter Client) als eigenständigen Sender einzusetzen, der seine GPS-Daten zur Verfügung stellt. Dies sollte entweder direkt über den Austausch per Wireless LAN stattfinden oder indem ein Server-Dienst die Daten im Internet direkt zum Abruf bereithält. In beiden Fällen müsste die Position beim Eee PC angefordert werden. Dazu wäre ein direkter Verbindungsaufbau über die IP-Adresse erforderlich gewesen. Leider ist diese nach aussen nicht sichtbar, so dass keine Möglichkeit besteht den Eee PC aktiv zu konnektieren. Der Eee PC kann also nicht als Server fungieren.
Um diesen Sachverhalt zu klären waren bereits umfangreiche Tests notwendig. Die Rücksprache mit Herrn Zimmermann vom Rechenzentrum der HTW-Aalen ergab, dass es nicht möglich wäre, Server-Dienste im Wireless LAN zu betreiben. Als Gründe nannte er den Aufwand der Administration, da die IP des PCs im Wireless LAN nicht zwingend statisch ist. Sie wird zwar auf Basis des OpenVPN-Benutzer-Logins zugeordnet, so dass sie meistens statisch ist. Das kann aber nicht garantiert werden. Die Administration der Firewall erfordert aber statische IPs. Generell können Server-Dienste nicht erlaubt werden, da es sich um ein Funknetz handelt. Das ist für mich nachvollziehbar, da hier die Sicherheit eine noch grössere Rolle spielt als in einem Kabel-LAN. Die Bandbreite ist in einem Wireless LAN nicht so hoch, so dass der Datenverkehr möglichst gering gehalten werden sollte. Der Zugang ins Internet erfolgt verschlüsselt über VPN. Dazu verwendet man OpenVPN oder eine ähnliche Software.
Als Server-Dienst sollte gpsd (http://gpsd.berlios.de/) verwendet werden. Dies ist ein Open Source Programm, das die GPS-Daten direkt vom angeschlossenen USB-GPS-Empfänger einliesst und im Internet unter dem Port 2947 zur Verfügung stellt. Der Port ist voreingestellt und kann beim Aufruf mit dem Parameter -S auf einen beliebigen geändert werden. Im Internet findet man unter http://gpsd.mainframe.cx/ einen gpsd-Test-Server. Lokal auf dem Eee PC kann ich zu dem gpsd-Server verbinden. Diese Methode nutze ich um auf die GPS-Maus zuzugreifen. Beim Test des direkten Zugriffs über /dev/ttyUSB0 gab es große Schwierigkeiten an die GPS-Daten zu kommen. Erst durch mehrere Aufrufe von gpsd und xgps gelang es mir den Datenfluss in Gang zu bekommen. Deshalb entschied ich mich für den Umweg über gpsd, da damit der Datenzugriff ohne Probleme funktioniert.
Der Multimedia-Server der HTW-Aalen (http://multimedia.informatik.htw-aalen.de/) hostet die PHP-Skripte, die für die Kommunikation mit dem Eee PC notwendig sind. Dies ist die einzigste Möglichkeit um an die GPS-Daten des Eee PC zu gelangen. Dazu ruft ein eigens dafür entwickeltes C-Programm client_sendNewPositions das PHP-Skript client_saveNewPosition.php auf und übergibt Daten an die Parameter num, status, lat, lng und login. Das C-Programm ruft in einer Schleife das PHP-Skript auf, so dass stets die aktuelle Position des Eee PCs verfügbar ist. Die Server-IP, die Intervallzeit zwischen den Aufrufen und die Anzahl der Wiederholungen kann per Parameter frei bestimmt werden. Die Intervallzeit sollte dabei nicht zu kurz gewählt werden, damit das Funknetz und der Multimedia-Server nicht zu stark belastet werden. Dies ist aufgrund der Ungenauigkeit vom GPS (10-15 m) und der langsamen Positionsänderung (zu Fuss) auch überflüssig. Minimale Positionsänderungen sind mit GPS nicht exakt erfassbar. Änderungen die über die GPS-Ungenauigkeit von 10-15 m hinausgehen machen dann erst Sinn. Bei der Übertragung muss auf die Synchronisation von Server und Client geachtet werden. Aktualisiert der Client die Position zu häufig gehen beim Server Positionen verloren (Redundanz). Aktualisiert der Client zu langsam entsteht ein Informationsflussabbruch, der von meiner Software dann als Verbindungsfehler zu interpretieren ist. Ich habe ermittelt, dass der Intervall auf dem Eee PC ca. 6 Sekunden geringer sein sollte als auf dem Server. Das liegt daran, dass die Daten auf dem Server gespeichert werden und so sofort für ihn verfügbar sind, während der Client die Daten über das Internet übertragen muss. Da es sich um ein Funknetz handelt, sind die Übertragungszeiten noch höher als sonst. Die Aktualisierungsgeschwindigkeit kann beim Server (Kontrollzentrum) ebenfalls eingestellt werden. Es sind verschiedene Intervallzeiten zur Auswahl vorgegeben.
Bei der Software-Architektur habe ich insbesondere auf eine einfache Schnittstelle geachtet. Diese ist durch ein allgemein verwendbares PHP-Skript gegeben. Das Skript wird über die übliche GET-Methode aufgerufen, dabei werden die genannten Parameter übergeben. So kann im Prinzip jedes mobile Endgerät als Client eingesetzt werden, das Zugriff auf das Internet hat und einen GPS-Empfänger besitzt. Denkbar wäre zum Beispiel ein aktuelles Smartphone. Neuere Modelle besitzen bereits standardmässig einen GPS-Empfänger. Als Programmiersprache wird Java verwendet. Es gibt für Handys eine spezielle Ausgabe, sie nennt sich Java ME. Ich habe damit bereits ein einfaches Programm für mein Sony Ericsson T610 entwickelt. Dies ist anfangs nicht ganz einfach, da das Programm speziell auf das verwendete Handy angepasst werden muss. Je nach Handytyp sind mehr oder weniger Funktionen verfügbar. Java ME ist vom Funktionsumfang stark eingeschränkt im Vergleich zum normalen Java. Das verwendete Protokoll http ist aber meist verfügbar. Als Übertragungsstandard eignet sich bei Handys GPRS, da es schnell genug ist und meist volumenbasiert abgerechnet wird. Ansonsten gibt es auf dem Markt auch Datenflatrates für Handys. Eine andere Möglichkeit ist einfach das Handy oder ein UMTS-Modul an den Eee PC anzuschließen. Dabei wären keine Änderungen am C-Programm notwendig, da es keine Rolle spielt wie der Eee PC ins Internet kommt. Sobald ein Zugriff auf das Internet möglich ist, kann die Software die GPS-Daten übertragen.
Ein weiterer Aspekt bei meiner Software ist die Sicherheit. Da das PHP-Skript im frei verfügbaren Internet läuft kann im Prinzip jeder darauf zugreifen der seine Adresse (URL) kennt. Dies gilt es zu verhindern, da dadurch der Server unnötig belastet würde und fremde (ungültige) Positionen empfangen werden könnten. Eine Möglichkeit ist es nur bestimmte IP-Adressen zu erlauben. Der Nachteil ist die aufwendige Administration (zum Beispiel bei dynamischen IPs) und daraus resultierend der Verlust der Flexibilität. Deswegen ist ein Session-basierender Loginbereich besser geeignet. Er ist von IP-Adressen unabhängig. Ein Benutzername und Passwort reichen aus. Der Nachteil ist, dass Sessions nur eine bestimmte Zeitdauer gültig sind und dann verworfen werden. Deswegen ist ein erneuter Login in regelmässigen Zeitintervallen notwendig. Beim Client besteht das Problem, dass das C-Programm eigenständig in der Konsole läuft und so eine explizite Übergabe der aktuellen Session-ID notwendig wird. Dies kann per Übergabeparameter oder über eine Textdatei gelöst werden. Ich habe mich für letzteres entschieden. Nach dem Login steht die Session-ID als Textdatei zum Download bereit. Sie wird im Programmverzeichnis gespeichert. Das C-Programm liesst sie dann automatisch ein und verwendet sie beim Aufruf des PHP-Skriptes. Einfacher wäre es natürlich ein festes Passwort beim Aufruf zu übertragen und auszuwerten. Dies ist sicherheitstechnisch aber bedenklich und zu unterlassen.
Da das Speichern der Textdatei zu aufwendig ist, entschied ich mich doch für eine andere Lösung. Der Benutzername und das Passwort werden als weitere Parameter dem C-Programm übergeben. Die Strings werden durch einen Doppelpunkt verbunden und mit dem base64-Algorithmus enkodiert. Das PHP-Skript erhält das Resultat als zusätzlichen Parameter login. Diese Lösung ist ein Kompromiss zwischen Sicherheit und Benutzerfreundlichkeit der Software.
Das Kontrollzentrum stellt die Wegstrecke des Clienten in Google-Maps dar. Die meisten
Programmdateien befinden sich in dem Unterverzeichnis gps. Das Hauptprogramm wird mit der
server.php gestartet. Beim ersten Aufruf werden Benutzername und Passwort abgefragt über das
Skript login.php. Dabei wird eine Session angelegt. Wie bei jeder Datei wird config.inc.php
eingebunden, die Benutzerdaten und Pfade von Textdateien enthält. So müssen diese Änderungen nur
zentral in einer Datei erfolgen und nicht in vielen verschiedenen. Die config.inc.php bindet die
root.inc.php ein, die das Root-Verzeichnis enthält. Es ist dynamisch und wird je nach
verwendetem Server gesetzt. Es wird noch die apikey.inc.php benötigt, sie enthält den
Google-Maps Key. Er ist auch variabel je nach verwendetem Server. Ein bestimmter Key ist
nur für die registrierte Domaine gültig. Falls das Software-System also auf einem anderen
Server mit neuer Domain installiert werden soll, muss zuerst ein neuer Google-Maps Key
registriert werden und in apikey.inc.php ergänzt werden. Für das Bildschirmlayout wird das
Stylesheet screen.css verwendet, für das Drucklayout wird das leicht angepasste Stylesheet
print.css genutzt. Danach werden einige JavaScript-Funktionen importiert. Zuerst die von
Google-Maps verfügbare Funktionsbibliothek danach noch zwei eigene server_map_functions.js
und
google_ajax.js. Sie enthalten Funktionen zur Darstellung von Google Maps und zum Beispiel zur
Aktualisierung der Karte im Hintergrund mit Ajax. Weitere Funktionen steuern den Timer zur
Aktualisierung der Karte.
In der JavaScript-Datei server_map_functions.js werden verschiedene globale Variablen definiert. Die Funktion drawBurren() zeichnet das neue HTW-Gelände im Burren als Rechteck ein. Die Funktion init() zeichnet das Google Maps Fenster an der dafür vorgesehenen Position. Im Browser muss also JavaScript aktiviert sein, es ist Voraussetzung für Google Maps und allen weiteren Funktionen wie zum Beispiel Ajax.
Die andere JavaScript-Bibliothek google_ajax.js enthält weitere Funktionen, die hauptsächlich der
indirekten Kommunikation mit dem Clienten dienen. Die Funktion addMarker(,,) fügt einen
Markierungspunkt in der Karte hinzu. Er wird beim Start der Wegstrecke benötigt. Falls eine
zurückliegende Position bekannt ist wird diese mit der aktuellen Position durch eine Gerade
verbunden. Die Funktion autoZoom() sorgt dafür, dass immer die gesamte Wegstrecke auf der Karte zu
sehen ist. Falls es erst eine Position gibt wird diese zentriert in Google-Maps dargestellt. Die Funktion
loading() wird für Ajax benötigt. Sie zeigt eine Ladeanimation an beziehungsweise blendet sie wieder
aus. Damit wird dem Benutzer angezeigt, dass Daten im Hintergrund nachgeladen werden. Es wird so
sichergestellt, dass er sich einen Augenblick gedulded und nicht an eine Fehlfunktion der Software
denkt. Eine weitere Funktion timestamp() wird ebenfalls für Ajax benötigt. Sie erzeugt einen
Zeitstempel, der eindeutig ist und beim Aufruf der PHP-Dateien angehängt wird. Damit wird
das Caching des Microsoft Internet Explorers verhindert, das zu fehlerhaften Ergebnissen
führen kann. Die Funktion server_updateMap() aktualisiert die Karte mit den Daten vom
Clienten, dazu ruft sie die PHP-Datei server_getNewPosition.php auf. Die Ausgabe wird
entschlüsselt und den unterschiedlichen Variablen zugewiesen. client_updateMap() ist die
entsprechende Funktion für die Karte auf dem Clienten, die client_getNewPosition.php aufruft.
sendMessage() versendet indirekt eine Nachricht an den Clienten, dafür ist das PHP-Skript
server_sendMessage.php zuständig. Die Nachricht wird dabei nur in einer Textdatei abgelegt, der
Client muss in bestimmten Zeitabständen die Daten abrufen. getMessage() ruft beim Clienten die
Datei
client_getMessage.php auf, die wiederum die Textdatei einliest und ausgibt. Die
JavaScript-Funktion getTransferStatus() wird ebenfalls beim Clienten aufgerufen, sie ermittelt mit
dem PHP-Skript client_getTransferStatus.php ob die übertragenen GPS-Positionen
gelesen wurden. Dabei wird eine laufende Index-Nummer angezeigt. Falls die Nummern
nicht fortlaufend sondern lückenhaft sind sollte die Intervallzeit im C-Programm erhöht
werden.
Der Client wurde für den Asus Eee PC optimiert. Er wird mit client.php aufgerufen. Der Benutzer muss sich zuerst einmal einloggen über das Skript login.php. Danach wird Google Maps mit der aktuellen Standortposition angezeigt. Darunter stehen die Nachricht vom Kontrollzentrum und der Status der übertragenen GPS-Daten. Es werden die gleichen Dateien eingebunden bis auf die server_map_functions.js. Sie wird ersetzt durch die client_map_functions.js.
Das PHP-Skript client_saveNewPosition.php wird vom C/Java-Programm auf dem Clienten aufgerufen. Es bindet die Konfigurationsdatei config.inc.php ein. Die Benutzeranmeldung erfolgt hier nicht über ein Login-Formular, da es automatisch und nicht manuell aufgerufen wird. Die Anmeldedaten werden per GET-Methode beim Aufruf angehängt. Die Daten liegen in base64-kodierter Form vor. Die zwei Strings wurden vor der Kodierungen mit einem Doppelpunkt verbunden. Die Parameter werden auf Vollständigkeit und Richtigkeit überprüft. Der Passwortschutz kann in der Konfigurationsdatei abgeschaltet werden. Dies ist sinnvoll um das Skript manuell im Browser aufzurufen und die Funktion zu testen. Die GPS-Daten können optional geloggt werden in der Textdatei server_gpsLog.log. So gehen keine Daten vom Clienten verloren und können auch zu einem späteren Zeitpunkt eingesehen werden. Jeweils die aktuelle GPS-Information des Clienten wird in der Textdatei client_NewPosition.txt gespeichert. Natürlich sind diese Dateinamen in der Konfigurationsdatei config.inc.php jederzeit änderbar. Allerdings ist bei einem Linux-Server zu beachten, dass die entsprechenden Textdateien im richtigen Verzeichnis manuell angelegt werden. Das PHP-Skript hat dafür meistens nicht genügend Rechte. Ausserdem benötigen die Textdateien Schreibrechte. Diese können über das Eigenschaften-Menü vergeben werden oder über den Linux-Befehl chmod 666 <Datei>. Eine weitere Textdatei server_TransferStatus.txt wird bei der korrekten Übermittlung der Position geändert. Dort wird gespeichert, dass die aktuelle Position (gekennzeichnet durch eine Index-Nummer) gespeichert, auf Google Maps aber noch nicht eingezeichnet wurde.
Das Skript server_getNewPosition.php wird wie oben beschrieben per Ajax im Hintergrund aufgerufen. Es bindet server_access.inc.php ein, das sicherstellt, dass der Benutzer eingeloggt ist und die IP sich nicht verändert hat. Danach wird noch die Konfigurationsdatei config.inc.php geladen. Die Textdatei client_NewPosition.txt wird geöffnet und die Daten eingelesen. Die unterschiedlichen Daten werden verschiedenen Variablen zugewiesen. Die Textdatei server_TransferStatus.txt wird nun überschrieben. Es wird gespeichert, dass die Position gelesen wurde. Danach wird die server_NewPosition.txt geändert, falls der Status nicht zehn ist. Falls der alte Status kleiner als drei ist wird er auf drei gesetzt ansonsten um eins erhöht. Siehe auch Tabelle 3.1. Danach werden die Daten aus der Textdatei einfach ausgegeben. Mit Hilfe von JavaScript werden diese dann weiterverarbeitet.
Das PHP-Skript client_getNewPosition.php wird auf dem Clienten aufgerufen. Es liest ebenfalls die Textdatei client_NewPosition.txt aus. Allerdings werden keine Änderungen an den Daten vorgenommen.
Zustand | Erklärung |
(client_NewPosition.txt) | |
0 | Die aktuelle GPS-Position hat sich verändert |
1 | Die aktuelle GPS-Position hat sich nicht verändert (keine Bewegung) |
2 | Der Client hat keinen GPS-Empfang |
oder es ist ein Fehler beim Client aufgetreten | |
3-9 | Es wurden keine neuen Daten vom Clienten erhalten |
(zum Beispiel kein WLAN verfügbar) | |
10 | Der Client hat ein Netzwerkproblem |
(zum Beispiel kein WLAN verfügbar) | |
Die PHP-Datei server_sendMessage.php wird ebenfalls vom Kontrollzentrum ausgelöst. Es stellt die Nachricht vom Kontrollzentrum an den Clienten zum Abruf bereit, indem es die Nachricht in der Textdatei server_Message.txt abspeichert. Die Daten werden hier per POST-Methode übermittelt, da die GET-Methode zur Übertragung längerer Texte ungeeignet ist.
Die PHP-Datei client_getMessage.php wird vom Eee PC aus aufgerufen. Die Textdatei server_Message.txt wird zum lesen/schreiben geöffnet. Falls die Nachricht den Status null hat wird er auf eins geändert. Siehe auch Tabelle 3.2. Die Daten werden schliesslich noch ausgegeben und anschliessend von JavaScript-Funktionen erfasst.
Die PHP-Datei mobile_getMessage.php wird vom Mobiltelefon aus aufgerufen. Die Benutzerdaten werden per Parameter übergeben.
Zustand | Erklärung |
(server_Message.txt) | |
0 | Die Nachricht wurde noch nicht vom Client empfangen |
1 | Die Nachricht wurde auf dem Client angezeigt |
Das PHP-Skript client_getTransferStatus.php wird auf dem Clienten aufgerufen und liest die Textdatei server_TransferStatus.txt aus. Damit wird auf dem Clienten angezeigt ob die übertragenen Daten im Kontrollzentrum richtig verarbeitet und angezeigt werden. Siehe auch Tabelle 3.3.
Zustand | Erklärung |
(server_TransferStatus.txt) | |
0 | Das GPS-Datum ist neu und wurde noch nicht |
in die Google-Maps Karte eingezeichnet | |
1 | Das GPS-Datum wurde in die Google-Maps Karte eingezeichent |
2 | Der aufgetretene Fehler wurde vom Kontrollzentrum erfasst |
Dateiname | Funktion | Parameter | Methode |
client_saveNewPosition.php | -speichert eine neue GPS-Position | -num | GET |
des Clienten | -status | ||
-optionale Logfunktion | -lat | ||
-lng | |||
-login | |||
server_getNewPosition.php | -liest die aktuelle GPS-Position aus | - | GET |
-markiert die Position als gelesen | |||
-ändert server_TransferStatus.txt | |||
client_getNewPosition.php | -liest die GPS-Position für den Clienten | - | GET |
server_sendMessage.php | -sendet eine Nachricht an den Clienten | -num | POST |
-msg | |||
client_getMessage.php | -liest eine Nachricht beim Eee PC | - | GET |
mobile_getMessage.php | -liest eine Nachricht fürs Mobiltelefon | -login | GET |
client_getTransferStatus.php | -zeigt den Status der Übertragung | - | GET |
beim Clienten an | |||
server.php | -Startseite des Kontrollzentrums | -login | GET/POST |
-passwort | |||
-logout | |||
client.php | -Startseite des Clienten | -login | GET/POST |
-passwort | |||
login.php | -Login-Formular für Server und Client | -action | GET |
config.inc.php | -Konfigurationsdatei für Benutzer- | - | - |
Einstellungen | |||
root.inc.php | -Root-Pfad des Servers | - | - |
server_access.inc.php | -Zugriffsschutz für Server-Files | - | - |
client_access.inc.php | -Zugriffsschutz für Client-Files | - | - |
apikey.inc.php | -Google-Maps Key für den Server | - | - |