Hacking Havag
Ihr kennt vielleicht die Havag (Hallesche Verkehrs-AG)? Das ist das Verkehrsunternehmen in Halle, befördert uns zu maximalen Preisen bei dürftiger Qualität. Wie auch immer.
Das Unternehmen bietet seinen Kunden ein Widget an, mit dem man vom Wohnzimmer das Eintreffen der Bahnen an der nächstgelegenen Haltestelle monitoren kann. Das ganze nennt sich mobile@home (siehe Bild 1) und ist in Java geschrieben. Ist eigentlich eine feine Sache, man muss nicht mehr nach Bauchgefühl das Haus verlassen, wenn ja doch gerade keine Bahn kommt. Das Fenster nervt jedoch tierisch. Ich hab seit langen auf meinem Schedule einen Eintrag, der mich daran erinnert eine bessere Lösung zu finden. Heute Nacht hab ich mich nun endlich an die Arbeit gemacht.
Das Problem ist wie üblich eine geschlossene Software, keine Dokumentation für jemanden wie mich. Ja es ist Java, also wäre es ein Leichtes die Binaries zu dekompilieren, deren Projekt besteht jedoch aus >1000 Klassen (öhm overhead!) und über den rechtlichen Aspekt bin ich mir da auch nicht sicher.
Aber was wird das Tool wohl machen? Es wird einen zentralen Server nach den nächsten Stopps an einer von mir gewählten Haltestelle fragen. Der Server wird dann sicherlich mit den jeweiligen Bahnen antworten.
Soweit Client und Server kein kryptisches Protokoll sprechen kann ich also einfach den Netzwerkverkehr der über meine Interfaces geht mitschneiden und nachbauen. Also fix den Sniffer meines Vertrauens und das tolle Tool gestartet. Schnell wurde klar um welchen Server es sich handelt: 83.221.237.42
auf Port 20010
. Und die Sache war auch schon so gut wie gegessen als ich folgende Pakete an mir vorbei rauschen sah:
An der Feuerwache
ist die Haltestelle, für die meine Anfrage raus ging, und ein POST
-connect mit den Daten ...d....c..m..getDeparturesForStopS..An der Feuerwachez
sieht stark nach dem aus, was ich gesucht habe. Kurz darauf kommt auch gleich die Antwort S..9S..Soltauer Stra..eS..2011.08.09.03:46:00S..2011.08.09.03:46:00S..true[..]
, und tatsächlich fährt eine Linie 9 in kürze zur Soltauer Straße
. Dedüm!!
Der Rest ist simpel. Nur noch mit ‘nem Hexeditor (ich empfehle hexcurse) in die Pakete hinein geschaut um zu sehen was genau übermittelt werden muss (die .
zwischen den Daten stehen für Zeichen, die in meinem Terminal nicht für mich sichtbar dargestellt werden können. Deren Hexadezimal-Code gibt aber Aufschluss über ihren Wert). Mit ein wenig Trial&Error ist die Geschichte vom Tisch.
Natürlich ist meine Alternative zu dem Widget für jedermann verfügbar:
Als Argument einfach die gewünschte Haltestelle angeben:
Das Protokoll
Vielleicht hat ja jemand Lust weitere Tools zu schreiben, die die “Serverschnittstelle” der Havag benutzen. Daher hier eine kurze Dokumentation des inoffiziellen Protokolls, das mit dem Server gesprochen werden kann.
Eine Anfrage an den Server muss via HTTP-POST an 83.221.237.42:20010/init/rtpi
geschehen und die folgenden Inhalte liefern:
Hierbei ist xAB
das Zeichen für den Hexwert AB
, LEN
ist die Länge der darauf folgenden Zeichenkette. Um den Server nach den nächsten Stopps am Rennbahnkreuz zu fragen sendet man als Kommando ein c
, als Funktion ein m
, und die Funktion heißt getDeparturesForStop
. Als Argument wird dann die Haltestelle erwartet. Die Anfrage in HalbHex sieht also wie folgt aus:
und komplett Hexadezimal-kodiert:
Als Antwort bekommt man die Abfahrtszeiten in den nächsten 60 min. Die Antwort beginnt mit einer Zeichenkette die ich nicht verstehe und vorerst nur verwerfe. Ein Eintrag für eine Bahn startet mit den Hexadezimalwerten x56x74x00x07x5Cx5Bx73x74x72x69x6Ex67x6Cx00x00x00x0D
. Darauf folgen die einzelnen Informationen zu dieser Bahn. Eine einzelne Information ist wie folgt kodiert:
LEN
gibt hier wieder die Länge der folgenden Information an, die Information selbst ist ASCII Klartext. Ein Bahneintrag wird abgeschlossen mit einem x7a
(z). Folgende Daten werden übermittelt:
Das boolsche N
gibt an, ob es sich um eine Niederflur-Straßenbahn handelt. Die mit ???
gekennzeichneten Felder verstehe ich (noch) nicht. Vielleicht etwas wie Wagennummer/Typ, ob es eine Verspätung gibt etc. Kann man sicher auch herausbekommen, da sie aber für mich vorerst nicht wichtig sind habe ich mich nicht weiter darum gekümmert.
Meine Beschreibungen sind natürlich alles andere als komplett, für die Korrektheit kann ich auch nicht garantieren. Vielleicht gehört das x00 vor der Längen-Kodierung auch mit zur Längenangabe und ist bei den kurzen Zeichenketten nur immer 0? Wer weiß, in der Praxis funktioniert mein Gehacktes aber (mindestens für mich) ;-)
Update:
Wird getDeparturesForStop
ohne Argumente gesendet, bekommt man eine Antwort mit allen Verfügbaren Stopps. (via @michas)
Damit ist also der Weg für coole neue Apps geebnet. Vielleicht hat ja jemand von euch eines dieser Smartphones (oder es findet sich ein Sponsor der mir eines zur Verfügung stellt)?
Übrigens flogen auch hin und wieder Pakete mit Inhalten wie diesem vorbei: Apache Tomcat/5.5.17 - Error report
. Spricht nicht gerade für das Widget. :-P
- analyzed (15) ,
- apache (15) ,
- crazy (8) ,
- debug (4) ,
- explained (43) ,
- hacked (25) ,
- halle (7) ,
- java (22) ,
- media (61) ,
- network (81) ,
- programming (75) ,
- simplification (16) ,
- trick (61)
Leave a comment
There are multiple options to leave a comment:
- send me an email
- submit a comment through the feedback page (anonymously via TOR)
- Fork this repo at GitHub, add your comment to the _data/comments directory and send me a pull request
- Fill the following form and Staticman will automagically create a pull request for you:
10 comments
[…] das Eintreffen der Bahnen a …
Bookmark: Zum Originalbeitrag: Hacking Havag […]
Klasse!
Genau sowas fehlte mir wirklich – weil ich von Perl und Java keine Ahnung habe (als LINUXer!).
Genial. Die Befreiung einer Quelle > “openHavag”.
Weiter so und Gruss.
Soweit ich informiert bin, ist das Widget keine HAVAG-Eigenentwicklung und das Protokoll teil des “MOBILE-STOPinfo” von der INIT AG. Mehr Infos dazu gibt es u.U. auf deren Webseite: www.initag.de (Direktlink auf die Referenz der HAVAG: http://www.initag.de/share/projects/de/Halle.pdf)…
Vielleicht findet man so auch andere “MOBILE-STOPinfo-Hacker” oder kann über die Firma eine Protokollbeschreibung erhalten, obwohl zweiteres doch eher unwahrscheinlich ist - schließlich werden die ihre Lösungen für viel Geld verticken!
Hallo, super töölchen, sowas hat mit noch gefehlt in
~/bin/
:DVllt. schreibst du noch dazu – für den perl-noob, dass
libwww-perl
benötigt wird :)Gruß
Achso, ja, natürlich:
aptitude install libwww-perl
Gestern hat es mich mal gepackt und ich habe ein wenig mit deinen Script rumprobiert. Die Abfahrtszeiten herauszubekommen war recht schnell erledigt. Doch wie die Haltestellen intern codiert sind…das war gar nicht so leicht herauszubekommen. Es ging trotzdem:
Anstatt
getDeparturesForStop z
ohne Argumente zu schicken, muss mangetStopCodes z
ohne Argumente schicken.Hex Code: 63:00:01:6d:00:0c:67:65:74:53:74:6f:70:43:6f:64:65:73:7a
Das fertig angepasste Perl Skript findet man hier: http://www.jimtim.de/download/public/index.php?dir=Havag%2F . In den denselben Ordner befindet sich ein Skript mit allen Haltestellencodes.
Das Skript ist nicht wirklich gut programmiert…tut aber seinen Dienst. :-D
Danke nochmal an den Verfasser für den Denkanstoß
Habe es nun endlich mal geschafft, eine erste Beta einer App für iOS, die auf diesem Protokoll-Reengineering basiert, umzusetzen. Man kann sich alle (aktuellen) Haltestellen listen lassen, in der Liste nach einer bestimmten Haltestelle suchen und sich dann die derzeitigen Fahrten dieser Haltestelle im Detail anzeigen lassen.
Jmd. Interesse an einem Beta-Test? :)
Ahoi.
Saubere Arbeit! Schicke Analyse! Wir haben da mal eben eine Implementierung in Ruby gestrickt. Das Ganze findet ihr hier: https://bitbucket.org/terminal21/ruby_on_havag
Wenn alles funzt wird das ein schönes Dashing-Widget (http://shopify.github.io/dashing/) für den Hackspace.
Wir haben da mal noch ein wenig rumgeforscht. Das Protokoll unter der ganzen Nummer nennt sich ‘Hessian’ (https://de.wikipedia.org/wiki/Hessian_(Webprotokoll)).
Es gibt ein paar angegammelte Bibliotheken, z.B.
HessianPy
für Python. Damit wird der ganze Eiertanz deutlich trivialer: