netBiDiB

BiDiB - Bidirektionaler Bus - Logo

Inhaltsverzeichnis

1. Allgemeines

Das Protokoll BiDiB dient zur Kontrolle einer Modellbahnanlage. Es ermöglicht die Ansteuerung von Loks, Zubehör und sichere Übertragung von Rückmelderinformationen aus der Modellbahnanlage an den steuernden Rechner.

BiDiB kann über verschiedene Übertragungsmedien transportiert werden, dabei wird das Framing und die Sicherung der Nachrichten gewährleistet.

Eine Erläuterung der hier verwendeten Begriffe und der Protokollgrundzüge findet sich im allgemeinen Teil der Protokollbeschreibung, gleiches gilt auch für die Hinweise zur Benutzung und zur Lizenz.

Im folgenden ist der Transport über eine Netzwerkverbindung beschrieben, verwendet wird der TCP/IP-Stack.

Hinweis: Datenübertragung über ein öffentliches Netzwerk beinhaltet die Gefahr der Manipulation der übertragenen Daten. Die unverschlüsselte Datenübertragung zur Modellbahn darf daher nur in einer lokalen, geschützten Umgebung erfolgen. Eine Fernsteuerung der Modellbahn mittels netBiDiB über das Internet ist grob fahrlässig.

1.1. Zielsetzung

Übliche Modelleisenbahn-Bussyssteme wie CAN, BiDiBus, Xpressnet® oder Loconet® sind als Feldbus für die robuste Verkabelung innerhalb der Anlage geeignet. Für einen direkten Anschluss an moderne Endnutzergeräte fehlt diesen jedoch die notwendige Hardwareschnittstelle. Eine Verbindung zu aktueller Computertechnik erfolgt häufig über USB-Adapter und beschränkt sich damit auf stationäre PCs, eine Verwendung von Mobilgeräten (Smartphones, Tablets, Laptops) oder weit entfernten Computern ist nur über Umwege möglich.

Daher entstand die folgende Einbettung des BiDiB-Protokolls in den universellen und allgegenwärtigen IP-Stack. Sie ermöglicht es, die vielerorts bestehende Heimnetzwerk-Infrastruktur zur einfachen Anbindung der Modelleisenbahnansteuerung zu nutzen. Die Netzverbindung kann dabei ein Segment der Baumstruktur eines BiDiB-Systems bilden.

  • Plug & Play ohne Konfiguration
  • Zuverlässige und fehlerfreie Übertragung
  • Uneingeschränkte Übertragungsrate

1.2. Revisionsstand

Dieses Dokument beschreibt Revision 0.2 von netBiDiB, Stand 13. Januar 2021.

Revisionsgeschichte
0.22020-12-?? Keepalive, Konkretisierung Logon/Logoff, neu: Anmeldeaufforderung, Statusinformationen BIDIB_LINK_NODE_(UN)AVAILABLE
0.12017-12-13 Initiale Veröffentlichung

1.3. Glossar

In diesem Dokument werden folgende Bezeichnungen verwendet:

Internet Protocol (IP): Ein Protokoll zur Vermittlung von Datenpaketen in und zwischen Netzwerken. Es kann dabei verschiedene Verbindungen wie Ethernet oder WLAN nutzen.
IP-Adresse: Eine 32- (bei IPv4) oder 128-Bit-Zahl (bei IPv6) zur Identifikation und Verortung eines Rechners.
Port: Eine 16-Bit-Zahl, mit der sich mehrere Verbindungen oder Dienste unterscheiden lassen, die dasselbe Transportprotokoll verwenden.
Transmission Control Protocol (TCP): Ein zuverlässiges, verbindungsorientiertes, paketvermitteltes Transportprotokoll für einen Datenstrom.
User Datagram Protokoll (UDP): Ein minimales, verbindungsloses Transportprotokoll für einzelne Datenpakete.
Server: Der Kommunikationsteilnehmer bei TCP, welcher Verbindungen annimmt.
Client: Der Kommunikationsteilnehmer bei TCP, welcher aktiv Verbindungen öffnet.
netBiDiB-Teilnehmer: Eine physische oder logische Instanz (d.h. eine Baugruppe oder ein laufendes Programm), die als Server oder Client einem netBiDiB-System teilnehmen kann.
Host: Die zentrale Instanz eines BiDiB-Systems, welche die Kontrolle über verbundene Knoten ausübt - i.d.R. ein PC-Programm.
Knoten (Node): Ein Teilnehmer im BiDiB-System, i.d.R. eine Hardware-Baugruppe.
Businterface (Interface): Die Stelle im Bus, an der sich die Knoten anmelden.
Descriptor: Eine Informationsstruktur zur Identifikation und Beschreibung eines Teilnehmers, bestehend mindestens aus einer Unique-ID, einem Produktnamen sowie einem vom Anwender gewählten Namen.

2. Netzwerk

2.1. Architektur

Die Kommunikation zwischen zwei Teilnehmern ist verbindungsorientiert. Eine Busebene mit mehreren BiDiB-Knoten wird durch eine zentrale Instanz gebildet, an der sich die Knoten anmelden: Das (Bus-)Interface (kann auch im Hostprogramm integriert sein), welches zu jedem Knoten eine eigene Verbindung aufrecht erhält.

Gleichzeitig kann ein Knoten mit mehreren Interface-Teilnehmern verbunden sein, ist aber höchstens an einem von diesen angemeldet.

Teilnehmer werden in zwei Gruppen unterschieden:

  • Server akzeptieren eingehende Verbindungen. Sie verkünden anderen Teilnehmern ihre Anwesenheit im Netzwerk.
  • Clients öffnen von sich aus Verbindungen zu einem oder mehreren Servern.

Diese Klassifizierung ist nur für den Verbindungsaufbau nach dem Client-Server-Modell entscheidend und impliziert nicht die Rolle des Teilnehmers in einem BiDiB-System. Diese wird erst mit der Anmeldung des Knotens beim Interface festgelegt, bei der die beiden ein gerichtetes Kontrollverhältnis eingehen.

Um Interoperabilität zu garantieren, ist jedoch festgelegt, dass

  • ein Teilnehmer mit Interface-Rolle (z.B. ein Hostprogramm) als Client agiert und
  • ein Teilnehmer mit Knotenrolle als Server agiert.

Darüber hinaus darf ein Teilnehmer auf demselben Port sowohl als Client als auch als Server agieren. Dies ermöglicht es beiden Seiten in P2P-Manier, eine TCP-Verbindung zu beginnen und bei Nichtgebrauch zu beenden.

Ein Programm, das mehrere unabhängige Teilnehmer in verschiedenen Rollen implementiert, soll unterschiedliche Ports dafür verwenden.

2.2. Verbindungsaufbau

Prinzipiell gliedert sich eine netBiDiB-Verbindung in folgende Teilaspekte:

  1. Discovery: Finden und Erkennen von netBiDiB-Teilnehmern

    Discovery dient dazu, BiDiB-Knoten zu entdecken und deren BiDiB-Fähigkeiten, Netzwerkadresse und Port für die folgenden Vorgänge zu erfahren. Wegen der dabei nötigen Broadcast-Nachrichten im Netzwerk wird hierfür UDP benutzt. Discovery hilft bei einer anwenderfreundlichen Ausgestaltung des Verbindungsaufbaus.

  2. Linkaufbau: Öffnen der Verbindung

    Mit der Aufnahme der TCP-Verbindung wird ein Kommunikationskanal zwischen zwei netBiDiB-Teilnehmern geöffnet. Zu Beginn werden die Identitäten der beteiligten Teilnehmer ausgetauscht, der Client wird dadurch auch für den Server sichtbar.

    Eine solche Verbindung mit identifiziertem Gegenüber nennen wir Link.

    Der Link kann durch das Schließen der Verbindung aufgelöst werden.

  3. Pairing: Miteinander-Vertraut-Machen von Teilnehmern

    Dies dient dazu, BiDiB-Hostprogramme (bzw. allgemein Interfaces) und BiDiB-Knoten bekannt zu machen und ungewollte Verbindungen mit nicht autorisierten Teilnehmern zu verhindern. Beim Pairing werden andere netBiDiB-Teilnehmer im Netzwerk als prinzipiell mögliche Partner bestimmt und gespeichert. Ein gegenseitiges Vertrautmachen sagt noch nichts über das tatsächliche Kontrollverhältnis aus, ein netBiDiB-Teilnehmer kann mit vielen anderen Teilnehmern zugleich vertraut sein.

    Einen Link, dessen zwei Teilnehmer einander vertrauen, nennen wir paired.

    Der Pairing-Vorgang ist nur einmalig bei der Erstinbetriebnahme erforderlich.

  4. Kontrolle: Anmelden zur Steuerung

    Der Aufbau einer Steuerverbindung zwischen zwei Teilnehmern wird als Logon bezeichnet. Voraussetzung hierfür ist ein (irgendwann vorher) durchgeführtes, erfolgreiches Pairing. Nach erfolgtem Logon kann der Host den Knoten kontrollieren – beginnend mit der BiDiB-Nachricht MSG_SYS_GET_MAGIC.

    Ein Kontrollverhältnis zweier Teilnehmer kann von jeder der beiden Seiten aufgelöst werden, dies ist unabhängig vom Link.

2.3. Teilnehmer

Ein netBiDiB-Teilnehmer muss folgende Bedingungen erfüllen, um als standardkonform zu gelten:

  • Unterstützung des im folgenden beschriebenen Protokolls zum Etablieren eines Links und des Knoten-Logon
  • Eigene Identifikation als netBiDiB-Teilnehmer mittels UID, Produktname und Teilnehmername
  • Merken des Vertrauens zu mindestens einem anderem Teilnehmer
  • Anzeige des Status der Verbindung bzw. eines Pairingvorgangs
  • Interaktionsmöglichkeit zum Auslösen/Akzeptieren/Ablehnen eines Pairings
  • Interaktionsmöglichkeit zum Auflösen der Kontrollverbindung (oder mehr)
  • Interaktionsmöglichkeit zum Entzug des Vertrauens zu einzelnen (oder allen) gemerkten Teilnehmern

Ein als Client agierender Teilnehmer muss darüber hinaus über eine Möglichkeit verfügen, mindestens eine Verbindung zu öffnen. Der Hostname bzw. die IP-Adresse und der Port des Servers müssen dabei frei wählbar sein. Eine zusätzliche Möglichkeit zur Auswahl der mittels Discovery gefundenen Server ist optional aber wünschenswert.

Ein Teilnehmer mit graphischer Benutzeroberfläche muss bei der Anzeige anderer Teilnehmer deren Produktname und Teilnehmername verwenden.

Als Interaktionsmöglichkeit genügt, gerade an Teilnehmern ohne graphische Oberfläche, ein einzelner Knopf. Ein kurzer Knopfdruck soll hier ein Pairing auslösen bzw. akzeptieren und gleichzeitig eine eventuell bestehende Kontrollverbindung beenden. Ein langer Knopfdruck soll allen gespeicherten Teilnehmern das Vertrauen entziehen.

3. Protokoll

3.1. Discovery

Discovery ist eine Komfortfunktion, die das automatische Einbinden eines Netzwerkknotens ohne vorausgehende Konfiguration ermöglicht. Wo dies nicht funktioniert, ist die manuelle Eingabe von Netzwerkinterface, IP-Adresse und Port nötig.

Ein Client beginnt mit dem Discovery automatisch beim Programmstart oder wenn eine neue Verbindung eingerichtet werden soll. Erkennt ein Client einen netBiDiB-Server, mit dem er schon vertraut ist, soll er automatisch zu diesem eine Verbindung aufbauen, jedoch ohne bereits die Knoten-Anmeldung durchzuführen. Zu unbekannten Servern soll nur dann eine Verbindung aufgebaut werden, wenn der Anwender dies wünscht.

Ein netBiDiB-Server kann über verschiedene Service-Discovery-Protokolle im Netz bekanntgemacht werden, auch mittels mehrerer Protokolle gleichzeitig. Empfohlen wird die Verwendung von DND-SD über mDNS.

3.1.1. DNS Service Discovery

Ein netBiDiB-Server kann im Domain Name System (RFC 1034) gefunden werden. Das DNS Service Discovery (RFC 6763) ermöglicht das Auffinden aller Services in einer Domäne, die das netBiDiB-Protokoll unterstützen, diesem ist der Service Name bidib zugewiesen. Als Service Type wird daher _bidib._tcp verwendet.

Jede Service-Instanz im DNS repräsentiert einen netBiDiB-Teilnehmer. Ihr ist ein Resource Record vom Typ SRV zugeordnet, der auf den Hostnamen und Port des Teilnehmers verweist (RFC 2782), sowie ein Resource Record vom Typ TXT, der weitere Eigenschaften des Services als Schlüssel-Wert-Paare enthält. Für netBiDiB-Teilnehmer sind im speziellen die folgenden Schlüssel definiert:

  • uid: ein 7 Byte langer Binärwert mit der Unique-ID des Teilnehmers
  • prod: String-Wert ist der Produktname des Teilnehmers, vgl. DESCRIPTOR_PROD_STRING
  • user: String-Wert ist der Teilnehmername, vgl. DESCRIPTOR_USER_STRING
  • node: boolsches Attribut. Das Vorhandensein (mit keinem, leeren oder beliebigen Wert) bedeutet, dass der Teilnehmer die Knoten-Rolle einnimmt und auf eine Anmeldeaufforderung reagieren wird.
  • interface: boolsches Attribut. Das Vorhandensein (mit keinem, leeren oder beliebigen Wert) bedeutet, dass der Teilnehmer die Interface-Rolle einnimmt und Anmeldungen eines Knotens akzeptieren kann.
  • bidib (veraltet): der Wert "node" hat dieselbe Bedeutung wie ein vorhandener node-Schlüssel, der Wert "interface" hat dieselbe Bedeutung wie ein vorhandener interface-Schlüssel.

Um das Auffinden von Teilnehmern anhand ihrer Rolle zu erleichtern, werden zwei Subtypen für _bidib._tcp verwendet: _node._sub._bidib._tcp und _interface._sub._bidib._tcp. Teilnehmer, die das jeweilige boolsche Attribut gesetzt haben, werden auch unter dem entsprechenden Subtyp angekündigt.

Im lokalen Netzwerk geschieht die Ankündigung von und das Suchen nach entsprechenden Resource Records in der Domäne .local. über Multicast DNS (RFC 6762). Dieses unterstützt nicht nur einmalige Anfragen, sondern auch kontinuierlich mitlaufende Verfolgung, ohne dabei auf Polling zurückzugreifen.

Als Beispiel verfügt ein netBiDiB-Knoten, der mit dem Service Instance Name <Dienstname> auf dem Host <Hostname> im lokalen Netzwerk läuft, über folgende DNS-Resource-Records:

  _services._dns-sd._udp.local.   PTR    _bidib._tcp.local.                shared   TTL=75min (4500s)
             _bidib._tcp.local.   PTR    <Dienstname>._bidib._tcp.local.   shared   TTL=75min (4500s)
  _node._sub._bidib._tcp.local.   PTR    <Dienstname>._bidib._tcp.local.   shared   TTL=75min (4500s)
<Dienstname>._bidib._tcp.local.   SRV    <Hostname>.local.:<BiDiB-Port>    unique   TTL=75min (4500s)
<Dienstname>._bidib._tcp.local.   TXT    node,uid=…,user=…,prod=…          unique   TTL=75min (4500s)
              <Hostname>.local.   A      <IPv4-Adresse>                    unique   TTL=2min (120s)
              <Hostname>.local.   AAAA   <IPv6-Adresse>                    unique   TTL=2min (120s)

In der Darstellung soll dem Teilnehmernamen der Vorrang gegenüber dem Instanznamen gegeben werden. Sie sind nicht notwendigerweise gleich, nur der Instanzname muss im DNS eindeutig sein.

3.1.2. BiDiB-eigenes DIY Discovery

Dieser Teil ist experimentell und veraltet.

Für Fälle, in denen kein Standard-Discovery-Protokoll zum Einsatz kommen kann, wurde speziell für netBiDiB ein eigenes Discovery-Protokoll mit proprietärer Übertragung selbst entworfen. Sein Einsatz wird nicht empfohlen.

3.1.2.1. UDP-Transport

Das User Datagram Protocol (siehe RFC 768) ist ein minimales, verbindungsloses Netzwerkprotokoll zur Übertragung einzelner Datentelegramme. Diese sogenannten Datagramme enthalten Quellport und Zielport zur Identifikation des verantwortlichen Dienstes, ein Längenfeld, eine Prüfsumme und die Nutzdaten. Die Datagramme werden in Pakete des Internet Protocol eingebettet, die u.a. Quell- und Zieladresse vorgeben.

DATAGRAM ::= SOURCE_PORT  DEST_PORT  LENGTH  CHECKSUM  UDP_DATA
SOURCE_PORT ::= 0x0000 | 0xC000 … 0xFFFF
DEST_PORT ::= 0xC000 … 0xFFFF
LENGTH ::= 0x0008 … 0xFFFF
CHECKSUM ::= 0x0000 … 0xFFFF

Der Inhalt eines UDP-Datagramms für BiDiB ist prinzipiell wie folgt aufgebaut:

UDP_DATA ::= EMITTER  MESSAGE_SEQ
MESSAGE_SEQ ::= ε | MESSAGE  MESSAGE_SEQ
EMITTER ::= EMITTER_LENGTH  0x00  0x00  MSG_LOCAL_PROTOCOL_SIGNATURE  'B'  'i'  'D'  'i'  'B'  EMITTER_SUFFIX
EMITTER_LENGTH ::= 0x08 | … | 0x7F
EMITTER_SUFFIX ::= ε | ANY_BYTE  EMITTER_SUFFIX

Die erste Nachricht im Datagramm muss eine MSG_LOCAL_PROTOCOL_SIGNATURE sein, die einen String mit dem Präfix "BiDiB" als Inhalt hat. Ungenügende Pakete müssen verworfen werden.

Für die Pakete bei BiDiB-Discovery gelten folgende Bestimmungen:

  • Es ist seitens des Netzwerkes nicht garantiert, dass UDP-Pakete in der Sendereihenfolge beim Empfänger eintreffen, obwohl dies (speziell bei einem lokalen Netz) in aller Regel der Fall ist. Daher müssen alle Nachrichten eines Discovery-Broadcasts zusammen in nur einem Datagramm gesendet werden.
  • Es soll ein dynamischer Quellport verwendet werden, unter dem das sendende Programm Antworten empfangen kann. Für AVAILABLE-Broadcasts, die nicht beantwortet werden, kann auch 0 verwendet werden.
  • Nachrichten im Discovery sind lokale Nachrichten, sie verwenden daher keine Sequenznummern (MNUM wird als 0 übertragen).

Für Broadcast-Pakete bei BiDiB-Discovery gilt darüber hinaus:

  • Es wird der Zielport 62875 verwendet. Dieser liegt in der Dynamic Ports Range, er ist nicht offiziell reserviert!
  • Es sollen die Zieladressen 224.0.0.1 (IPv4: all-hosts multicast group), 255.255.255.255 (IPv4: limited broadcast) bzw. ff02::1 (IPv6: link-local all nodes address) verwendet werden.

Um Broadcasts von BiDiB-Discovery zu empfangen, muss die Socket-Option SO_REUSEADDR verwendet werden, um auch anderen Anwendungen auf demselben Rechner den Empfang zu ermöglichen.

3.1.2.2. Ablauf

Um netBiDiB-Server im Netz zu finden, sendet ein Client Discover-Datagramme mit folgendem Inhalt als Broadcast über BiDiB-UDP:

MSG_LOCAL_PROTOCOL_SIGNATURE "BiDiB…"
MSG_LOCAL_DISCOVER

Ein Server kündigt seinen Dienst mit Announcement-Datagrammen über BiDiB-UDP an. Sie sollen beim Start des Servers und regelmäßig in einem Intervall von etwa 5 Sekunden als Broadcast gesendet werden. Auch beim Empfang eines BiDiB-Datagramms mit einer MSG_LOCAL_DISCOVER wird ein Announcement-Datagramm als Unicast an den Absender (Quell-IP-Adresse und -Port) gesendet.

Der Inhalt der Datagramme besteht aus mindestens einer Nachricht mit der UID des Servers, gefolgt mindestens von einer Nachricht mit Verbindungsmöglichkeiten:

MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB…"
MSG_LOCAL_LINK  DESCRIPTOR_UID  0x…
[ MSG_LOCAL_LINK  DESCRIPTOR_P_VERSION  0  7
  MSG_LOCAL_LINK  DESCRIPTOR_PROD_STRING  "Typ"
  MSG_LOCAL_LINK  DESCRIPTOR_USER_STRING  "Name" ]
MSG_LOCAL_ANNOUNCE  SERVER_TCP_NODE  tcp_port
[…]

Das Senden des kompletten Descriptors ist optional.

3.2. Verbindung

3.2.1. TCP-Transport

Das Transmission Control Protocol (siehe RFC 793 und weitere) überträgt einen bidirektionalen, byte-orientierten, zuverlässigen Datenstrom zwischen zwei Endpunkten. Es garantiert die korrekte Auslieferung der Daten in der vorgegebenen Reihenfolge und eignet sich daher auch zur Übertragung über störungsempfindliche Kanäle wie WLAN. Darüber hinaus wird es von Firewalls in Standardkonfiguration seltener behindert als UDP. BiDiB verwendet TCP für die Übertragung von Steuernachrichten zwischen Knoten.

Die Endpunkte werden jeweils durch IP-Adresse und Portnummer identifiziert. Für BiDiB werden Portnummern aus dem Bereich der dynamischen Ports verwendet (49152-65535), diese werden vom Betriebssystem dynamisch an Programme vergeben werden. Der serverseitige Port soll auch vom Anwender einstellbar sein, als Default wird 62875 genutzt.

Der Datenstrom ist wie folgt aufgebaut:

TCP_STREAM ::= EMITTER  MESSAGE_SEQ
MESSAGE_SEQ ::= ε | MESSAGE  MESSAGE_SEQ
EMITTER ::= EMITTER_LENGTH  0x00  0x00  MSG_LOCAL_PROTOCOL_SIGNATURE  'B'  'i'  'D'  'i'  'B'  EMITTER_SUFFIX
EMITTER_LENGTH ::= 0x08 | … | 0x7F
EMITTER_SUFFIX ::= ε | ANY_BYTE  EMITTER_SUFFIX

Der Datenstrom besteht aus einer Folge von BiDiB-Nachrichten. Diese unterscheiden sich in lokale Nachrichten und normale, an den angemeldeten Knoten bzw. Host gerichtete Nachrichten. Normale Nachrichten werden vom Knoten erst dann interpretiert, wenn er erfolgreich angemeldet ist.

EMITTER bezeichnet die erste Nachricht und muss zwingend eine MSG_LOCAL_PROTOCOL_SIGNATURE sein, die einen String mit dem Präfix "BiDiB" als Inhalt hat. Dies ermöglicht die Erkennung eines versehentlichen, protokollfremden Datenstroms. Scheitert die Prüfung, wird die Verbindung unmittelbar geschlossen. MSG_LOCAL_PROTOCOL_SIGNATURE darf (und soll) auch während der Übertragung wiederholt werden um die TCP-Pakete zu kennzeichnen.

Bei der Datenübertragung ist das maximal mögliche Antwortvolumen von 48 Bytes je Zielknoten zu beachten und fallweise der Datenstrom pro Zielknoten zu drosseln. Für Nachrichten an den angemeldeten Knoten (Adresse 0) sowie für den Upstream wird die TCP-Flusskontrolle zur Beschränkung genutzt.

Um eine möglichst geringe Latenz zu erreichen, sollen Teilnehmer die Socket-Option TCP_NODELAY setzen.

Verbindungsabbrüche (halb-offene Verbindungen) werden bei TCP anhand des Ausbleibens von ACKs erkannt. Hierzu soll TCP-Keepalive mit einem angemessenen Timeout eingesetzt werden. Wo dies von der verwendeten TCP-Implementierung nicht unterstützt wird, können statt der Keepalive-Pakete regelmäßige MSG_LOCAL_PROTOCOL_SIGNATURE gesendet werden.

3.2.2. Linkaufbau

Ein Client ermöglicht dem Anwender, zu beliebigen Adressen und Ports eine TCP-Verbindung aufzunehmen. Unterstützt ein Client Discovery, öffnet er automatisch Verbindungen zu bekannten Servern, sobald diese sichtbar werden.

Jeder Teilnehmer verfügt über einen Descriptor, der neben der Unique-ID zur Identifikation vor allem den Produktnamen und den individuellen Teilnehmernamen zur anwenderfreundlichen Darstellung enthält sowie weitere nützliche Details zur Auswahl eines Links. Ein Host soll als Produktnamen den Programmnamen und als Teilnehmername einen vom Anwender wählbaren Namen verwenden, beispielsweise den Dateinamen der Anlagendatei oder den Computernamen. Für die Unique-ID soll ein Host eine Seriennummer zufällig generieren und in der Anlagendatei hinterlegen, Klassenbits hat er nicht gesetzt.

Nach dem Öffnen der TCP-Verbindung beginnen beide Teilnehmer mit dem Senden ihres Deskriptors:

MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB"
MSG_LOCAL_LINK  DESCRIPTOR_UID  0x...
MSG_LOCAL_LINK  DESCRIPTOR_P_VERSION  0  7
MSG_LOCAL_LINK  DESCRIPTOR_PROD_STRING  "Typ"
MSG_LOCAL_LINK  DESCRIPTOR_USER_STRING  "Name"

Den Empfang der DESCRIPTOR_UID quittiert das Gegenüber mit MSG_LOCAL_LINK und einem Status, ob ihm die Unique-ID bereits vertraut ist (STATUS_PAIRED) oder nicht (STATUS_UNPAIRED).

Sobald beide Seiten den Pairing-Status empfangen haben, ist der Link aufgebaut. Haben beide Seiten STATUS_PAIRED gesendet, gilt der Link als paired und eine Knotenanmeldung kann erfolgen.

3.2.3. Pairing

Sind die beiden Teilnehmer nicht miteinander vertraut, so muss ein explizites Pairing durch den Anwender durchgeführt werden. Dieser bestätigt dabei an beiden Teilnehmern, dass der Link legitim ist. Erst danach wird die Kontrollausübung erlaubt.

Eine solche Bestätigung des Vertrauens kann prinzipiell auf beliebigem Wege erfolgen, z.B. durch Hinzufügen eines Konfigurationseintrages. Um das Pairing nutzerfreundlich zu gestalten, sieht BiDiB jedoch auch einen Handschlag im Protokoll vor. Damit ist es möglich, durch einen einfachen Knopfdruck auch ohne graphische Oberfläche die Bestätigung durchzuführen.

Der Handschlag ist symmetrisch aufgebaut. Er kann von jedem der Teilnehmer mit einem PAIRING_REQUEST initiiert werden. Beim Empfang eines Antrags von einem noch nicht vertrauten Gegenüber zeigt der Teilnehmer dies an, wartet dann eine Zeit lang auf die Annahme durch den Anwender und sendet selbst einen PAIRING_REQUEST sobald eine explizite Bestätigung erfolgt.

Jeder Antrag wird mit einem Pairing-Status zur Zustimmung (STATUS_PAIRED) oder Ablehnung (STATUS_UNPAIRED) beantwortet, entweder nach der Anwenderinteraktion oder einem Timeout, optional auch sofort bei bereits bestehendem Vertrauen.

Werden auf einem Link innerhalb einer gewissen Zeitspanne zwei PAIRING_REQUESTs ausgetauscht, senden beide Teilnehmer STATUS_PAIRED und das Pairing war erfolgreich. Beim Empfang der STATUS_PAIRED speichern beide Teilnehmer den neuen Partner als vertrauenswürdig, sodass das Pairing beim nächsten Verbindungsaufbau nicht erneut durchgeführt werden muss. Der Link gilt nun als paired und ein Logon kann erfolgen.

Durch das Senden von MSG_LOCAL_LINK STATUS_UNPAIRED kann das Vertrauen jederzeit wieder entzogen werden. Eine Steuerung ist dann nicht mehr möglich.

3.2.4. Anmeldung

Auf einem paired Link kann sich der Knoten nun beim Businterface anmelden. Ist er jedoch bereits bei einem anderen Interface angemeldet, teilt er dies dem hinzugekommenen Businterface per MSG_LOCAL_LOGOFF mit. Stehen mehrere Möglichkeiten zur Auswahl, entscheidet sich der Knoten für eine davon.

Insbesondere nach dem Starten des Knotens soll hier nach dem initialen Announcement ein wenig gewartet werden, um allen interessierten Clients einen Linkaufbau zu ermöglichen. Der Knoten soll dasjenige Interface bevorzugen, bei dem er zuletzt (für längere Zeit) angemeldet war, ein Anlagenbetrieb kann so mit demselben Hostprogramm fortgesetzt werden, das bereits bei Betriebsschluss aktiv war. Ebenfalls bevorzugt werden sollen Links, auf denen zuletzt ein PAIRING_REQUEST empfangen wurde.

Der Knoten sendet zur Anmeldung MSG_LOCAL_LOGON mit seiner Unique-ID. Das Interface kann den Logon akzeptieren (MSG_LOCAL_LOGON_ACK) oder verweigern (MSG_LOCAL_LOGON_REJECTED), in letzterem Falle soll der Knoten evtl. bestehende andere Links durchprobieren.

Wurde der Logon akzeptiert, ist der Knoten nun angemeldet und lässt sich kontrollieren. Das Interface kann den Knoten nun in seine Nodetabelle eintragen (und eventuell mittels MSG_NODE_NEW zu seinem Host melden), der Host kann nun mit MSG_SYS_GET_MAGIC und dem typischen Protokollstart beginnen.

Die Anmeldung kann von beiden Seiten jederzeit zurückgenommen werden, vom Interface mittels MSG_LOCAL_LOGON_REJECTED und - in Ausnahmefällen - vom Knoten mittels MSG_LOCAL_LOGOFF. Eine solche Abmeldung kann durch den Anwender ausgelöst werden, etwa um den Knoten für andere Programme freizugeben. Auch ein Auflösen des Pairings oder der Abbau der TCP-Verbindung bedeuten unmittelbar eine Abmeldung.

Auch von einem Businterface aus, bei dem der Knoten nicht angemeldet ist, kann der Anwender jederzeit versuchen nun die Kontrolle zu übernehmen. Dazu wird mit einem erneuten STATUS_PAIRED eine Anmeldeaufforderung zum Knoten gesendet. Ist der Knoten bei keinem Businterface (mehr) angemeldet - nach einer Freigabe mit MSG_LOCAL_LOGON_REJECTED oder weil beim initialen Linkaufbau kein Interface die Anmeldung akzeptiert hat - so wird er eine Anmeldung durchführen.

Bestehen paired Links zu mehreren Businterfaces, so können auch diese den Anwender über den Zustand des Knotens in Kenntnis setzen. Dazu sendet der Knoten bei einem LOGOFF bzw. LOGON_ACK den jeweils anderen Interfaces ein NODE_AVAILABLE bzw. NODE_UNAVAILABLE. Dies ist vor allem relevant, wenn der Knoten selbst keine Anzeige hat.

3.3. Beispiele

Eine typische Startsequenz sieht beispielhaft folgendermaßen aus (die beiden Teilnehmer sind bereits miteinander vertraut):

  Host (Client) 0x0D 933C8A6C                                             Knoten (Server) 0x0D 0278456B
Discovery:
MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB"                              UDP>
MSG_LOCAL_DISCOVER                                                 UDP>
                                                                        <UDP  MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB"
                                                                        <UDP  MSG_LOCAL_LINK  DESCRIPTOR_UID  0xC000 0D 0278456B
                                                                        <UDP  MSG_LOCAL_ANNOUNCE  SERVER_TCP_NODE  0xF5  0x9B
Verbindung (auf Port 0xF59B / 62875):
                                                               SYN TCP>
                                                                        <TCP SYN/ACK
                                                               ACK TCP>
Beide Teilnehmer senden EMITTER als erste Nachricht
MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB"                              TCP> <TCP  MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB"
und beginnen (unabhängig voneinander), die Teile ihres Descriptors zu senden (in beliebiger Reihenfolge):
MSG_LOCAL_LINK  DESCRIPTOR_UID  0x00000D933C8A6C                   TCP> <TCP  MSG_LOCAL_LINK  DESCRIPTOR_PROD_STRING  18  "Raspi-Ethernet-Hub"
                                                                        <TCP  MSG_LOCAL_LINK  DESCRIPTOR_USER_STRING  18  "Messeanlage-Master"
                                                                        <TCP  MSG_LOCAL_LINK  DESCRIPTOR_P_VERSION  0  6
                                                                        <TCP  MSG_LOCAL_LINK  DESCRIPTOR_UID  0xC0000D0278456B
Der Empfang der UIDs etabliert den Link und wird jeweils mit dem Pairing-Status bestätigt:
MSG_LOCAL_LINK  STATUS_PAIRED  0x00000D933C8A6C  0xC0000D0278456B  TCP>
                                                                        <TCP  MSG_LOCAL_LINK  STATUS_PAIRED  0xC0000D0278456B 0x00000D933C8A6C
(der Host sendet hier weiter seinen Descriptor)
MSG_LOCAL_LINK  DESCRIPTOR_P_VERSION  0  7                         TCP>
MSG_LOCAL_LINK  DESCRIPTOR_PROD_STRING  6  "Wizard"                TCP>
MSG_LOCAL_LINK  DESCRIPTOR_USER_STRING  7  "Richard"               TCP>
Der Knoten meldet sich nun an:
                                                                        <TCP  MSG_LOCAL_LOGON  0xC0000D0278456B
MSG_LOCAL_LOGON_ACK  0x00  0xC0000D0278456B                        TCP>
MSG_SYS_GET_MAGIC                                                  TCP>
                                                                        <TCP  MSG_SYS_MAGIC  0xAFFE
MSG_SYS_GET_P_VERSION                                              TCP>
MSG_NODETAB_GETALL                                                 TCP>
MSG_FEATURE_GETALL                                                 TCP>

Beachtenswert ist die unterschiedliche Reihenfolge und das Durcheinander bei den MSG_LOCAL_LINK im Beispiel. Die einzige Einschränkung ist, dass erst nach dem Senden der eigenen und dem Empfang der fremden UID der Pairing-Status (STATUS_PAIRED bzw. STATUS_UNPAIRED) gesendet wird. Descriptorteile außer der UID können auch jederzeit auf einem bereits aufgebauten Link gesendet werden, etwa wenn sich der Name des Teilnehmers ändert.

Sind die Teilnehmer nicht miteinander vertraut, so ist ein Pairing durch den Anwender nötig und die Verbindung beginnt beispielsweise wie folgt:

  Host (Client) 0x0D 933C8A6C                                             Knoten (Server) 0x0D 0278456B
                                                                 SYN TCP>
                                                                          <TCP SYN/ACK
                                                                 ACK TCP>
Beide Teilnehmer beginnen:
MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB"                                TCP> <TCP  MSG_LOCAL_PROTOCOL_SIGNATURE  "BiDiB"
MSG_LOCAL_LINK  DESCRIPTOR_UID  0x00000D933C8A6C                     TCP> <TCP  MSG_LOCAL_LINK  DESCRIPTOR_PROD_STRING  18 "Raspi-Ethernet-Hub"
MSG_LOCAL_LINK  DESCRIPTOR_PROD_STRING  6  "Wizard"                  TCP> <TCP  MSG_LOCAL_LINK  DESCRIPTOR_USER_STRING  18 "Messeanlage-Master"
                                                                          <TCP  MSG_LOCAL_LINK  DESCRIPTOR_P_VERSION  0  6
                                                                          <TCP  MSG_LOCAL_LINK  DESCRIPTOR_UID  0xC0000D0278456B
Der Empfang der UIDs etabliert den Link und wird jeweils mit dem Pairing-Status bestätigt:
MSG_LOCAL_LINK  STATUS_UNPAIRED  0x00000D933C8A6C  0xC0000D0278456B  TCP>
MSG_LOCAL_LINK  DESCRIPTOR_P_VERSION  0  7                           TCP>
MSG_LOCAL_LINK  DESCRIPTOR_USER_STRING  7  "Richard"                 TCP> <TCP  MSG_LOCAL_LINK  STATUS_UNPAIRED  0xC0000D0278456B 0x00000D933C8A6C
Der Link ist nun unpaired (es genügt dazu auch UNPAIRED von nur einer Seite).

[Anwender löst Pairing am Host aus]
MSG_LOCAL_LINK  PAIRING_REQUEST  0x00000D933C8A6C  0xC0000D0278456B  TCP>
Der Knoten signalisiert den eingegangenen Request und wartet.                                                                  [Timeout im Knoten]
                                                                          <TCP  MSG_LOCAL_LINK  STATUS_UNPAIRED  0xC0000D0278456B 0x00000D933C8A6C
Der Request wurde nicht im gegebenen Zeitraum akzeptiert, der Link ist weiter unpaired.
[Anwender löst Pairing am Host aus] (erneut)
MSG_LOCAL_LINK  PAIRING_REQUEST  0x00000D933C8A6C  0xC0000D0278456B  TCP>
                                                                                                             [Anwender löst Pairing am Knoten aus]
                                                                          <TCP  MSG_LOCAL_LINK  PAIRING_REQUEST  0xC0000D0278456B 0x00000D933C8A6C
Nach einem ausgelösten Pairing werden die empfangenen Pairing-Requests jeweils akzeptiert:
MSG_LOCAL_LINK  STATUS_PAIRED  0x00000D933C8A6C  0xC0000D0278456B    TCP> <TCP  MSG_LOCAL_LINK  STATUS_PAIRED  0xC0000D0278456B 0x00000D933C8A6C
Der Link ist nun paired und der Knoten meldet sich an:
                                                                          <TCP  MSG_LOCAL_LOGON  0xC0000D0278456B
MSG_LOCAL_LOGON_ACK  0x00  0xC0000D0278456B                          TCP>
MSG_SYS_GET_MAGIC                                                    TCP>

Die Reihenfolge der beiden Nachrichten bei der Annahme des Pairings ist beliebig. Genauso denkbar ist:

                                                                         …
MSG_LOCAL_LINK  PAIRING_REQUEST  0x00000D933C8A6C  0xC0000D0278456B  TCP>
                                                                          <TCP  MSG_LOCAL_LINK  STATUS_PAIRED  0xC0000D0278456B 0x00000D933C8A6C
                                                                          <TCP  MSG_LOCAL_LINK  PAIRING_REQUEST  0xC0000D0278456B 0x00000D933C8A6C
MSG_LOCAL_LINK  STATUS_PAIRED  0x00000D933C8A6C  0xC0000D0278456B    TCP>

Die Annahme des Pairings kann sogar vor dem zweiten PAIRING_REQUEST erfolgen, wenn ein Teilnehmer den anderen bereits kennt. Für das Pairing mit Teilnehmern ohne graphische Anzeige und Auswahlmöglichkeit einer bestimmten Verbindung ist jedoch der zweite, ebenfalls vom Anwender ausgelöste, PAIRING_REQUEST weiter nötig.

4. Lokale Nachrichten

Lokale Nachrichten dienen zum Aushandeln der Transportverbindung. Sie sind vom Aufbau identisch zu normalen BiDiB-Nachrichten, werden aber nicht an andere Busteilnehmer weitergeroutet. Lokale Nachrichten werden nicht in das Sequencing einbezogen. Ihr MSG_ADDR_STACK ist leer, MSG_ADDR und MSG_NUM sind mit 0x00 kodiert.

  • MSG_LOCAL_PROTOCOL_SIGNATURE:

    Mit dieser Nachricht wird die Art des Datenstromes angekündigt. Der Dateninhalt ist eine Bytefolge, die mit den 5 ASCII-Zeichen 'B' 'i' 'D' 'i' 'B' beginnen muss.

    Weitere Zeichen hinter 'BiDiB' sind möglich und erwünscht, um den Absender für Debuggingzwecke zu kennzeichnen. Diese weiteren Zeichen haben sonst keine Bedeutung und dürfen nicht ausgewertet werden.

    Die Nachricht hat keine Antwort zur Folge, der Empfänger muss aber den String 'BiDiB' abprüfen. Sollte die Prüfung scheitern, wird die TCP-Verbindung geschlossen, es handelt sich offensichtlich um protokollfremde Daten.

  • MSG_LOCAL_LINK:

    Mit dieser Nachricht wird ein Link hergestellt und bestätigt sowie dessen Status geändert. Es folgen ein OPCODE und davon abhängig zusätzliche Daten. Sie kann von beiden Seiten der Verbindung und zu jeder Zeit gesendet werden.

    Kodierung des Opcode für Linkverwaltung
    WertNameBedeutung
    0xFF BIDIB_LINK_DESCRIPTOR_UID Der Sender baut von seiner Seite den Link (fallweise neu) auf.
    Es folgt die Unique-ID des Senders (7 Byte).
    Der Empfänger antwortet mit STATUS_PAIRED oder STATUS_UNPAIRED.
    0x00 BIDIB_LINK_DESCRIPTOR_PROD_STRING Der Sender verkündet seinen Produktnamen, entsprechend String 0 im Namespace 0 (siehe MSG_STRING).
    Es folgt ein Byte SIZE (0…24) und dementsprechend viele CHARs.
    0x01 BIDIB_LINK_DESCRIPTOR_USER_STRING Der Sender verkündet seinen Teilnehmernamen, entsprechend String 1 im Namespace 0 (siehe MSG_STRING, "Knotenname des Anwenders").
    Es folgt ein Byte SIZE (0…24) und dementsprechend viele CHARs.
    0x80 BIDIB_LINK_DESCRIPTOR_P_VERSION Der Sender verkündet seine unterstützte Protokollversion.
    Es folgen 2 Bytes, Kodierung wie MSG_SYS_P_VERSION.
    0x81 BIDIB_LINK_NODE_UNAVAILABLE Der Sender verkündet, dass er als Knoten bereits an einem anderen Interface angemeldet ist.
    Es folgen 2 oder mehr Bytes, PROD_STRING_SIZE PROD_STRING[SIZE] USER_STRING_SIZE USER_STRING[SIZE], mit den Werten aus dem Descriptor des Interfaces welches gerade die Kontrolle über den Knoten hat.
    Die Nachricht erfolgt im abgemeldeten Zustand und dient einzig der Information des Anwenders, um ihm einen Überblick über den Systemstatus zu verschaffen. Es ist keine Garantie, dass eine erneute Anmeldeaufforderung negativ beantwortet wird.
    0x82 BIDIB_LINK_NODE_AVAILABLE Der Sender verkündet, dass er als Knoten derzeit an keinem Interface (mehr) angemeldet ist.
    Es folgt kein Byte.
    Dies dient einzig der Information des Anwenders über den Status des Knoten. Es ist keine Garantie, dass eine Anmeldeaufforderung positiv beantwortet wird.
    0xFC BIDIB_LINK_PAIRING_REQUEST Der Sender initiiert ein Pairing beziehungsweise entgegnet den Antrag. Vorraussetzung ist ein bereits aufgebauter Link (d.h. ausgetauschte UIDs). Eine Nachricht mit diesem Opcode darf nur infolge einer expliziten Anwenderinteraktion erfolgen. Nach einer Entgegnung des Antrags (Handschlag durch zwei PAIRING_REQUESTs) innerhalb einer in der Nachricht enthaltenen maximalen Wartezeit setzen die beiden Teilnehmer ihr Vertrauen zueinander.
    Es folgen 15 Byte mit der Unique-ID des Senders und der Unique-ID des beabsichtigten Empfängers, sowie die Wartezeit in Sekunden. Die Seite, die das Pairing beginnt, legt die Wartezeit fest.
    Der Empfänger antwortet (eventuell verzögert) mit STATUS_PAIRED oder STATUS_UNPAIRED.
    0xFD BIDIB_LINK_STATUS_UNPAIRED Der Sender gibt an, dem Empfänger nicht zu vertrauen; er verweigert das Vertrauen oder zieht es zurück.
    Es folgen 14 Byte mit der Unique-ID des Senders und der Unique-ID des beabsichtigten Empfängers.
    Sender und Empfänger setzen ihren Linkstatus auf unpaired. Eine Überprüfung der Unique-IDs ist dazu nicht nötig.
    0xFE BIDIB_LINK_STATUS_PAIRED Der Sender gibt an, dem Empfänger zu vertrauen; er spricht das Vertrauen aus. Vorraussetzung ist ein bereits aufgebauter Link (d.h. ausgetauschte UIDs).
    Es folgen 14 Byte mit der Unique-ID des Senders und der Unique-ID des beabsichtigten Empfängers.
    Der Empfänger merkt sich den Partner und setzt seinen Linkstatus auf paired, wenn er dem Sender ebenfalls vertraut. Eine Überprüfung der Unique-IDs ist möglich aber optional.
    Erhält ein Knoten auf einem paired Link ein STATUS_PAIRED, so stellt dies eine Anmeldeaufforderung seitens des Interfaces dar. Der Knoten startet eine Anmeldung mit MSG_LOCAL_LOGON, oder weist die Aufforderung mit MSG_LOCAL_LOGFF zurück, wenn er bereits an einem anderen Interface angemeldet ist.
  • MSG_LOCAL_LOGON:

    Mit dieser Nachricht wird die Anmeldung durch den Knoten eingeleitet, er möchte sich vom Host kontrollieren lassen und wird nun auch nicht-lokale Nachrichten akzeptieren. Vorraussetzung ist ein paired Link. Es folgen 7 Byte:

    MSG_LOCAL_LOGON Parameter
    ParameterBeschreibung
    UID[7] Die Unique-ID des Knotens.

    Hinweis: Die Klassenbits der anzumeldenden Unique-ID müssen dabei nicht unbedingt mit denen der beim Linkaufbau verwendeten Unique-ID übereinstimmen.

    Das Businterface antwortet mit MSG_LOCAL_LOGON_ACK oder MSG_LOCAL_LOGON_REJECTED.

    Erhält der Knoten kein MSG_LOCAL_LOGON_ACK, so muss er die Anmeldung mit MSG_LOCAL_LOGOFF abbrechen bevor er sich an anderen verbundenen Interfaces anmelden kann.

    Empfängt ein Knoten ein irrtümliches MSG_LOCAL_LOGON eines anderen Knoten, soll er mit MSG_LOCAL_LOGON_REJECTED antworten.

  • MSG_LOCAL_LOGON_ACK:

    Mit dieser Nachricht wird ein LOGON durch das Interface bestätigt. Der Host kann nun mit MSG_SYS_MAGIC und dem Einlesen des Knotens beginnen, der Knoten darf nun nicht-lokale Nachrichten senden. Vorraussetzung ist ein paired Link. Es folgen 8 Byte:

    MSG_LOCAL_LOGON_ACK Parameter
    ParameterBeschreibung
    NODE Die lokale BiDiB-Adresse, unter der das Interface den Knoten eingebucht hat, oder 0 falls das Interface (z. B. im Host) keine eigene Busebene darstellt.
    UID[7] Die Unique-ID des Knotens, wie in der MSG_LOCAL_LOGON.

    Anmerkung: NODE wird dabei nicht für das Routing benötigt, das erledigt das Interface anhand der TCP-Verbindung. Sie ist nur für Debugging im Knoten bestimmt.

    Nur wenn die empfangene Unique-ID identisch zu der internen Unique-ID des Knotens ist, ist die Anmeldung gültig.

    Haben weitere Interfaces mit dem Knoten einen paired Link aufgebaut, so soll ihnen jeweils MSG_LOCAL_LINK mit BIDIB_LINK_NODE_UNAVAILABLE und den Namen aus dem Descriptor des bestätigenden Interfaces gesendet werden.

  • MSG_LOCAL_LOGON_REJECTED:

    Mit dieser Nachricht wird ein LOGON durch das Interface abgelehnt beziehungsweise ein bestehende Kontrollverhältnis wieder aufgelöst. Das Interface sendet fortan nur noch lokale Nachrichten. Es folgen 7 Byte:

    MSG_LOCAL_LOGON_REJECTED Parameter
    ParameterBeschreibung
    UID[7] Die Unique-ID des betroffenen Knotens.

    Der Knoten quittiert dies mit MSG_LOCAL_LOGOFF. Haben weitere Interfaces mit dem Knoten einen paired Link aufgebaut, so soll ihnen jeweils eine MSG_LOCAL_LINK mit BIDIB_LINK_NODE_AVAILABLE gesendet werden.

  • MSG_LOCAL_LOGOFF:

    Mit dieser Nachricht meldet sich ein Knoten vom Interface ab und unterliegt damit nicht mehr der Kontrolle durch den Host. Er sendet und interpretiert danach nur noch lokale Nachrichten. Ebenso wird die Nachricht verwendet, um Anmeldeaufforderungen (STATUS_PAIRED) des Interfaces abzuweisen. Es folgen 7 Byte:

    MSG_LOCAL_LOGOFF Parameter
    ParameterBeschreibung
    UID[7] Die Unique-ID des Knotens.
  • MSG_LOCAL_DISCOVER:

    Diese Nachricht wurde nur in UDP-Datagrammen verwendet und ist veraltet.

    Mit dieser Nachricht bittet ein Client alle Server im Netz, ihre Dienste anzukündigen. Es folgen keine Daten.

    Ein Server antwortet mit MSG_LOCAL_LINK DESCRIPTOR_UID und einer oder mehreren MSG_LOCAL_ANNOUNCE.

  • MSG_LOCAL_ANNOUNCE:

    Diese Nachricht wurde nur in UDP-Datagrammen verwendet und ist veraltet.

    Mit dieser Nachricht kündigt ein Server allen Clients im Netz seine Dienste an. Es folgen ein OPCODE und davon abhängig zusätzliche Daten:

    Kodierung des Opcode für Serverdienste
    WertNameBedeutung
    0x00 BIDIB_ANNOUNCEMENT_SERVER_TCP_NODE Der Teilnehmer stellt einen Knoten als BiDiB-TCP-Server bereit. Es folgen 2 Byte (TCP_PORTH und TCP_PORTL, in Network Byte Order!) mit der Portnummer des Servers. Die IP-Adresse des Servers ist die Senderadresse des UDP-Pakets.
  • MSG_LOCAL_SYNC:

    Diese Nachricht wird regelmäßig vom Interface zur Synchronisation der BiDiB-Systemzeit gesendet. Die Nachricht kodiert den Zeitpunkt des Absendens einmal als BiDiB-Systemzeitstempel und einmal als Zeitstempel mit der Systemzeit des Computers, auf dem das Interface läuft. Die netBiDiB-Teilnehmer synchronisieren ihre Uhren über das Network Time Protocol (NTP, siehe RFC 5905), mit der MSG_LOCAL_SYNC gibt das Interface dann nur noch den Offset zwischen UTC und BiDiB Systemzeit vor.

    MSG_LOCAL_SYNC Parameter
    ParameterBeschreibung
    TIMEL BiDiB Systemzeitstempel, 16 bit little endian.
    TIMEH
    UTC[8] Millisekunden seit dem 1. Januar 1970 00:00:00 UTC (Unix Epoch), 64 bit little endian.

    Mit der Referenz auf eine NTP-synchronisierte Uhr wird der negative Einfluss der variablen Netzwerklatenz und TCP-Flusskontrolle vermieden. Dennoch soll ein Knoten die Nachricht verwerfen, wenn seine Systemuhrzeit um mehr als eine Sekunde von dem übertragenen Wert abweicht.

    Sollte ein Knoten über keine NTP-Synchronisierung verfügen, so muss er den BiDiB-Systemzeitstempel bestmöglich interpretieren, z.B. durch Berücksichtigung der typischen Netzwerklatenz (die in der Regel in einem lokalen Netzwerk im Bereich unter 5 ms liegt).