CUNO disconnect

Begonnen von doubh, 21 April 2015, 16:28:49

Vorheriges Thema - Nächstes Thema

doubh

Hallo,

ich verwende FHEM-5.6 und u.a. einen CUNO (für HomeMatic und 1-Wire Multisensoren) mit FW1.46 (getestet auch 1.61 & 1.63), der über eine WLAN-Bridge im Netzwerk hängt.
Da die Entfernung der WLAN-Bridge relativ groß ist, werden nicht 100% der Pakete erfolgreich übertragen; <1% geht verloren und verursacht Probleme!


Es kommt bei mir sehr häufig vor, dass FHEM meldet, dass der CUNO disconnected ist.
Meistens klappt ein automatischer Reconnect/Reopen, aber in ca. 10-20% der Fälle nicht. Es ist dann weiterhin ein Ping zum CUNO möglich, aber es kann eine neue Verbindung zu Port 2323 aufgebaut werden - weder von FHEM noch von Putty!
Der Timeout für Antworten in 00_CUL.pm/00_OWX.pm ist nur 3 Sekunden und ich dachte dies ist zu kurz. Allerdings hat eine testweise Erhöhung auf 12s keine Besserung gebracht.

Wenn keine Verbindung zu Port 2323 möglich ist, obwohl FHEM disconnected anzeigt, hat der CUNO intern die TCP-Verbindung weiterhin mit dem Status CONNECTED und nimmt daher keine neue Verbindung von außen an. Der CUNO hat nicht erkannt, dass die Verbindung (wg der Timeouts) von FHEM getrennt wurde - woher auch, er hat das Paket von FHEM nicht empfangen und selbst kann er die tote TCP-Verbindung nur erkennen, wenn er aktiv Daten versendet (was bei mir nur sehr selten der Fall ist).
Wenn ich also eine Aktion auslöse, auf die der CUNO aktiv Daten versenden will (z.B. durch Drücken ein HM Taste), erkennt er, dass die TCP-Verbindung tot ist, beendet sie daraufhin intern und nimmt wieder neue Verbindungen auf Port 2323 an.
Solange der CUNO keine Daten selbst versenden will, ist er somit im Netzwerk "tot".


Eine Frage zu FHEM stellt sich mir:
Wenn über die TCP-Verbindung ein Paket zum CUNO gesendet wird und dieses Paket wird nicht zugestellt (bei mir wg der WLAN-Verbindung), werden dann automatische Sendewiederholungen durchgeführt?
Wenn ja, wer steuert diese und deren Anzahl?


Als Lösung für dieses (generelle) Problem, würde ich gerne
A) ggf. Sendewiederholen in FHEM einfügen und
B) eine TCP Keepalive Funktion in die culfw integrieren.

Leider muss die Keepalive Funktion im culfw uIP TCP/IP Stack auf Applikationebene implementiert werden, da der uIP Stack von sich aus diese Funktion nicht unterstützt.
Welche Daten bzw. welches Kommando könnte vom CUNO periodisch als Keepalive gesendet werden, ohne das FHEM darauf reagiert oder gestört wird?


Oder hat Jmd andere Ideen???


Generell denke ich, dass das Handling der TCP-Verbindung auf beiden Seiten nicht mit verlorenen Paketen klarkommt...
...wobei wir beim nächsten Thema wären:

Der uIP Stack in der culfw erkennt zwar, wenn ein Paket neu gesendet werden muss, allerdings ist bei diesem Stack lt. Beschreibung die Applikation zuständig, die alten Daten für den Resend zur Verfügung zu stellen.
Aktuell überschreibt die culfw nach jedem Sendevorgang die Daten, sodass sie für einen Resend nicht mehr zur Verfügung stehen und falsche Daten oder Mülldaten(!!!) beim Resend gesendet werden.

Ich würde daher noch eine Änderung für die culfw Vorschlagen:
A) Gesendete Daten immer für einen Resend in einem separaten Puffer vorhalten (läuft bei mir seit sehr langer Zeit perfekt).



Danke schon jetzt für eure Antworten und Anmerkungen.

rudolfkoenig

ZitatWenn ja, wer steuert diese und deren Anzahl?
Das regelt TCP/IP, da muesste auch die Anzahl der Wiederholungen und Abstand zwischen den einzelnen Schritten stehen.

ZitatWelche Daten bzw. welches Kommando könnte vom CUNO periodisch als Keepalive gesendet werden, ohne das FHEM darauf reagiert oder gestört wird?

Sowas gibts mWn nicht. Man koennte aber sowas einfuehren.

ZitatA) Gesendete Daten immer für einen Resend in einem separaten Puffer vorhalten (läuft bei mir seit sehr langer Zeit perfekt).
Ich koennte das einchecken, falls ich das als Patch bekomme. Testen kann ich es leider nicht.


Ich wuerde zunaechst an der WLAN-Bridge Einstellungen experimentieren.

doubh

Zitat von: rudolfkoenig am 21 April 2015, 17:01:42
Ich wuerde zunaechst an der WLAN-Bridge Einstellungen experimentieren.
Das habe ich schon optimiert. Aber egal wie gut das WLAN auch ist, ein Paket könnte immer verloren gehen und sollte nicht zu einem Fehler beim CUNO/FHEM führen...

Zitat von: rudolfkoenig am 21 April 2015, 17:01:42
Sowas gibts mWn nicht. Man koennte aber sowas einfuehren.
Ich koennte das einchecken, falls ich das als Patch bekomme. Testen kann ich es leider nicht.
Welches Kommando kann denn verwendet werden ohne den FHEM zu stören? Ich würde es einbauen...
Wie knapp ist der RAM bei culfw?
Patch kann ich einfach erstellen. Wie soll ich ich ihn dir zusenden?

rudolfkoenig

Zitatein Paket könnte immer verloren gehen und sollte nicht zu einem Fehler beim CUNO/FHEM führen...
Beim Verlust von einem Paket erzeugt TCP/IP auch keinen Verbindungsaubbruch, dazu muss schon mehr passieren.

ZitatWelches Kommando kann denn verwendet werden ohne den FHEM zu stören? Ich würde es einbauen...
Noch alle, das muesste man einbauen. Ich schlage mal vor den Versionstring, d.h. du koenntest version("") aufrufen.

ZitatWie knapp ist der RAM bei culfw?
Je nach CPU modell bzw. culfw Variante extrem bis geht so. Auf dem CUNO sollte noch ertraeglich sein.

ZitatPatch kann ich einfach erstellen. Wie soll ich ich ihn dir zusenden?
Hier im Thread anhaengen.

doubh

Hallo Rudolf,

du hast Recht, das TCP/IP Protokoll ist natürlich so designed, dass der Verlust eines einzelnen Paketes nicht zu einem Verbindungsabbruch führt, aber der Retransmit-Fehler in der culfw führt dazu, dass u.U. kein Retransmit durchgeführt wird.

siehe Datei tcplink.c, Zeile 163 (ich verwenden SVN Rev 303):
Dort wird uip_rexmit() überprüft und ggf. senddata() aufgerufen. Sind aber keine NEUEN Daten im Puffer (s->offset==0), wird innerhalb der Funktion senddata() die Funktion uip_send() NICHT aufgerufen.
-> so wie ich es verstehe, gibt es dann keinen Resend und in 00_CUL.pm wird DevIo_Disconnected() aufgerufen, wenn keine Antwort kommt.

Indirekt kann ein verlorenes Paket zu einen Verbindungsabbruch führen...oder?


Bei meinem Setup kommt es aber in der Tat vor, dass die WiFi Verbindung einige Sekunden tot ist.
Der kurze Timeout von 3 Sekunden in 00_CUL.pm und 00_OWX.pm trennt dann die Verbindung. Innerhalb der 3 Sekunden macht Linux ein paar Resends. Das anschließende TCP FIN Paket kommt nicht beim CUNO an (WLAN länger als 3 Sekunden tot) und CUNOs interner Verbindungszustand bleibt bei ESTABLISHED/CONNECTED.


Meine Lösungsansätze wären dafür:
A) Retransmit für CUNO/CUNO2 implementiere und
B) einfaches Keepalive im CUNO implementieren, damit der CUNO tote Verbindungen erkennen kann.

Rudolf, was meinst du?
Danke derweil für deine Einschätzung.

rudolfkoenig

Dein Vorschlag ist sinnvoll. Falls du die culfw patches hier bereitstellst, dann check ich sie ein, und ich modifiziere CUL.pm, damit unbestellte V Nachrichten ignoriert werden.

Mitch

Sehr interessant, ich "kämpfe" sein ein paar Wochen mit (fast) dem gleichen Problem.
Bei mir ist nur der Aufbau ein kleines bisschen anders: FHEM <-> Gigabitswitch <-> DLAN <-> DLAN <-> Gigabitswitch <-> CUNO

Lief alles immer perfekt, nur seit ein paar Wochen immer Disconnect, Reconnect, teilweise bleibt FHEM bei einem Disconnect, obwohl der CUNO verfügbar ist.
Das führt soweit, dass FHEM auch "andere" Probleme verursacht. Habe den CUNO jetzt abgeklemmt und FHEm funktioniert wieder ohne Probleme.

Was mich wundert, es wurde am Netz/DLAN nichts geändert.

Wäre schön, wenn Du hier einen Patch zur Verfügung stellen kannst, mit dem ich nochmal testen kann.
So wie es jetzt ist, kann ich meinen CUNO nicht mehr benutzen.

Was mich schon wundert, wover die Disconnects überhaupt kommen. Das DLAN ist stabil und bringt knapp 100MBit, was für den CUNO eigentlich locker reichen sollte.
Es hängt an diesem Netzwerkteil zwar noch ein TV, Sat und Streamer, allerdings sind die fast immer aus.
FHEM im Proxmox Container

doubh

Ich werde versuchen am WE die Änderungen zu testen und füge dann einen Patch hier ein...

doubh

Hallo Rudolf,

anbei findest du die Patches für die culfw (basierend auf SVN r516) mit den Änderungen für
A) das quasi TCP-Keepalive sowie
B) den korrigierten TCP Retransmissions.

Die Patches betreffen nur Devices, bei denen HAS_ETHERNET definiert ist.
Die aktuellste SVN Revision 516 ist mit den Patches für CUN, CUNO & CUNO2 kompilierbar. Getestet habe ich selbst aber nur mit der CUNO2 Hardware.

Der Keepalive Timeout ist im Boardfile einstellbar und verwendet wie besprochen das Cmd 'V' (version) als Keepalive Paket.

Beste Grüße.

rudolfkoenig

Ich werde fruehestens Ende dieser Woche dazukommen, sie zu integrieren.
Wuerde mich freuen, wenn die Patches von jemanden mit einem CUNO getestet werden koennten.

rudolfkoenig

Habe die Patches eingebaut, und mit Version 1.64 eingecheckt.

Weiterhin habe ich 00_CUL.pm so erweitert, dass unbestellte V* Nachrichten ignoriert werden. Leider konnte ich es nicht testen, deswegen wuerde mich eine Rueckmeldung interessieren.

doubh

Ich habe ein Update gemacht und deine Änderungen an 00_CUL.pm gesehen.
Nach einem Neustart haben unbestellte 'V' Nachrichten kein "CUNO UNKNOWNCODE" Event mehr verursacht.

Allerdings musste ich mehrmals neustarten, da das OWX Device (define owCUNO OWX CUNO) nicht initialisiert werden konnte.
Das OWX Device frägt die Version mit 'V' ab und entscheidet dann anhang der Antwort, welches Device verwendet wird (00_OWX.pm, Zeile 204).
Ich kann nicht beurteilen, ob das in Zusammenhang steht...!?

Beim OWX gibts kein reopen/reinit, sodass der Server jedesmal neu gestartet werden muss, wenn die Initialisierung fehlschlägt.


Im culfw SVN sind nur die Patches der board.h Dateien eingefügt. Die tcplink.c/h sind unchanged und enthalten den Keepalive Patch nicht.

rudolfkoenig

Danke fuer den Hinweis, habe die Fehlenden Dateien eingecheckt. Habe gestern wohl im falschen Verzeichnis (Devices) das svn commit . abgesetzt.

Wg. dem OWX kann ich leider nicht helfen (hab kein CUNO), ich vermute das Problem haengt aber nicht mit der letzten Modifikationen zusammen: wenn ich die vom Code abgesetzte Versionpruefung manuell auf einem CUL absetze:
fhem> { CUL_SimpleWrite($defs{CUL}, "V");; my ($a,$b) = OWX_ReadAnswer_CCC($defs{CUL});;return "$a/$b" }
/V 1.64 CUL868

dann funktioniert es.

doubh

Hab den Fehler im 00_OWX.pm gefunden und ein neues Thema erstellt:
http://forum.fhem.de/index.php/topic,37224.0.html