-
Notifications
You must be signed in to change notification settings - Fork 0
/
Hausbus%2FAnwendungs-Programmierung.mw
53 lines (45 loc) · 3.58 KB
/
Hausbus%2FAnwendungs-Programmierung.mw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Anwendungen, die Zugriff auf das Hausbus-Netz (auf Ethernet-Ebene) haben, können Pakete an den Bus schicken, indem sie diese an die entsprechenden IPv6-Adressen schicken. Weiterhin können Anwendungen bestimmte Pakete aus dem Bus empfangen, indem sie auf den jeweiligen Multicast-Adressen lauschen.
== Übersicht ==
Im Hausbus verwenden wir Unique Local Addresses aus dem Bereich fd1a:56e6:97e9:0:b5:ff:fe00:01.
=== Pakete senden ===
* Wie in [[Hausbus/Adressen]] angesprochen hat jedes Gerät am Bus seine eigene Adresse (zwischen 1 und 29, einschließlich). Diese Adresse bildet die letzte Stelle einer IPv6-Adresse, z.B. ''fd1a:56e6:97e9:0:b5:ff:fe00:'''01'''''.
* Der Hausbus läuft auf Port 41999, UDP.
=== Pakete empfangen ===
* Auf gesendete Pakete gibt es keine direkte Antwort. Stattdessen werden Pakete aus dem Hausbus grundsätzlich an bestimmte IPv6-Multicast-Gruppen geschickt. Die Adresse setzt sich diesmal aus der Gruppennummer (von 50 bis 100 einschließlich) zusammen: ''ff05::b5:ff:fe00:'''32''''' ist die erste Gruppe (0x32 entspricht 50).
* Nachdem man einen neuen UDP-Socket auf Port 41999 erstellt hat, muss man mit ''setsockopt'' und dem ''IPV6_JOIN_GROUP''-Parameter dem Kernel mitteilen, dass man an der Multicast-Gruppe ''ff05::b5:ff:fe00:'''32''''' (z.B.) Interesse hat.
* Sofern dieser Aufruf erfolgreich war, sollte die Datei /proc/net/igmp6 einen neuen Eintrag nach folgendem Schema enthalten:
2 eth0 ff050000000000000000000000b50001 1 00000004 0
* Auf dem UDP-Socket empfängt man nun die Pakete aus dem Hausbus. Die Absenderadresse entspricht hierbei den Adressen, die wir auch im Abschnitt „Pakete senden” benutzt haben (z.B. ''fd1a:56e6:97e9:0:b5:ff:fe00:01'').
== Ruby ==
Für Ruby gibt es bereits eine Hausbus-API ([http://github.com/raumzeitlabor/hausbus/tree/master/application/ Github]), die alles nötige abstrahiert. Die Benutzung funktioniert so:
#!/usr/bin/ruby1.9.1
require 'bus'
bus = Hausbus.new
bus.set_interface "eth0"
bus.join_group 50, do |msg, sender|
puts "Status: #{msg}"
exit 0
end
puts "Requesting pinpad status..."
bus.send 1, "get_status"
bus.run
Falls jemand Implementationen für andere Sprachen schreiben will kann er sich gerne an ''bus.rb'' orientieren, der Sourcecode sollte hinreichend klar sein.
== Debugging ==
Zum Debuggen ist es hilfreich, ''Wireshark'' zu benutzen und sich die Pakete anzusehen. Wer lieber auf Konsole arbeitet (in diesem Fall nicht wirklich besser als Wireshark):
$ sudo tcpdump -i eth1 -A -s 2048 -v -n
Weiterhin kann man die grundlegende Verbindung zum Hausbus kontrollieren, indem man den Busmaster pingt:
$ ping6 -n fe80::b5:ff:fe00:00%eth1
PING fe80::b5:ff:fe00:00%eth1(fe80::b5:ff:fe00:0) 56 data bytes
64 bytes from fe80::b5:ff:fe00:0: icmp_seq=1 ttl=255 time=21.0 ms
64 bytes from fe80::b5:ff:fe00:0: icmp_seq=2 ttl=255 time=4.09 ms
64 bytes from fe80::b5:ff:fe00:0: icmp_seq=3 ttl=255 time=6.98 ms
64 bytes from fe80::b5:ff:fe00:0: icmp_seq=4 ttl=255 time=9.95 ms
64 bytes from fe80::b5:ff:fe00:0: icmp_seq=5 ttl=255 time=2.97 ms
^C
--- fe80::b5:ff:fe00:00%eth1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4005ms
rtt min/avg/max/mdev = 2.975/9.009/21.043/6.486 ms
Sollte der Busmaster nicht auf pings antworten, kann man überprüfen, ob wenigstens die Neighbor Discovery (das IPv6-Äquivalent zu ARP) klappt:
$ ip -6 neighbor show
fe80::b5:ff:fe00:0 dev eth1 lladdr 02:b5:00:00:00:00 REACHABLE
Falls hier INCOMPLETE oder FAILED steht, antwortet der Busmaster nicht auf die Neighbor Discovery-Pakete (oder der Kernel verwirft die Antworten, was man mit Wireshark prüfen sollte).