Implementierung der ZWAVE Command Class SECURITY (0x98, AES Verschlüsselung)

Begonnen von A.Harrenberg, 27 Juni 2015, 21:25:37

Vorheriges Thema - Nächstes Thema

rudolfkoenig

Ich versuchs anders/fokussierter:
1. ja, ReadAnswerFn ist schuld

2. ja, ich meinte telnet/FHEMWEB, fuer dich irrelevant, fuer mich Arbeit (irgendwannmal).

3. timer: genau das habe ich gemeint.

4. Du sollst bitte secNonce und secSupported (auch?) als set anlegen, und die 3 Aufrufe von get aus set aendern. Da bei den Aufrufen das Rueckgabewert nicht ausgewertet wird, ist es egal, ob es set oder get ist, und da man mit set nicht auf eine Antwort wartet, blockiert auch nichts mehr. FHEM2FHEM:RAW muesste damit auch funktionieren.

5. Das Loesen des "get" Problems im ZWave_Cmd hat leider einen Haken: ich weiss nicht, wie man es ohne eine deutliche Interface-Aenderung (d.h. einfuehren von Callbacks oder Umsteigen auf Multithreading) loesen kann.
Dein Vorschlag wird z.Zt. schon umgesetzt. Was Du und die aktuelle Implementierung aber ignorieren: die anderen Filedeskriptoren (FHEMWEB/telnet/andere Inputs wie Homematic/etc) werden nicht geprueft, genausowenig werden Timer abgearbeitet, etc. Das alles passiert im Haupt-Select, aber ReadAnswerFn macht seinen eigenen eingeschraenkten select auf, was zwar bequem aber eigentlich falsch ist. Solange es selten verwendet wird, faellt es nicht auf, aber wenn man Security aktiviert, ist es staendig in Benutzung.

6. get wird auch jetzt mit einem regexp gestartet, der id beinhaltet. Wir sollten noch die Klasse hinzufuegen.

A.Harrenberg

Hi Rudi,
Zitat von: rudolfkoenig am 14 Januar 2016, 09:54:25
Ich versuchs anders/fokussierter:
danke ,-)

Ich arbeite das am WE mal ab, vor allem Punkt 5 wird 'ne Weile brauchen bis ich das drumherum verstanden habe (Wir brauchen mal ein "BootCamp" mit Dir...) .-)

Zitat von: rudolfkoenig am 14 Januar 2016, 09:54:25
6. get wird auch jetzt mit einem regexp gestartet, der id beinhaltet. Wir sollten noch die Klasse hinzufuegen.
Ist das nicht genau anders herum? Die Klasse ist drin, aber die BefehlsID nicht?

Danke,
Andreas.
FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

A.Harrenberg

Hi Rudi,
Zitat von: rudolfkoenig am 14 Januar 2016, 09:54:25
4. Du sollst bitte secNonce und secSupported (auch?) als set anlegen, und die 3 Aufrufe von get aus set aendern. Da bei den Aufrufen das Rueckgabewert nicht ausgewertet wird, ist es egal, ob es set oder get ist, und da man mit set nicht auf eine Antwort wartet, blockiert auch nichts mehr. FHEM2FHEM:RAW muesste damit auch funktionieren.
so ganz habe ich das Endziel der Umbauarbeiten noch nicht verstanden aber ich habe mal die get-Befehle aus SECURITY ausgebaut und durch entsprechende SET ersetzt. Ich habe dabei die Namen etwas geändert, dafür aber auch die Doku angepasst ,-)

Patch ist angehängt...

Gruß,
Andreas.
FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

rudolfkoenig

Eingecheckt.

Ab jetzt duerfte ZWave auch im Security Modus nicht die Ursache fuer irgendwelche Haenger sein.

krikan

Könntet Ihr das bitte für mich (einfacher) übersetzen. Trifft das:
SECURITY hat damit das Problem der gelegentlichen Störungen bei der Kommunikation zwischen Gateway und Endgerät in einer Kette von Funktelegrammen für einen FHEM-Befehl verloren?
Danke und Gruß, Christian

rudolfkoenig

Nein, innerhalb des ZWave-Welts sollte sich nichts aendern.
Es sollte aber nicht mehr passieren, dass wg. ZWave-Security HomeMatic Probleme kriegt.

A.Harrenberg

Hi Christian,
Zitat von: krikan am 15 Januar 2016, 10:05:32
SECURITY hat damit das Problem der gelegentlichen Störungen bei der Kommunikation zwischen Gateway und Endgerät in einer Kette von Funktelegrammen für einen FHEM-Befehl verloren?
also durch das "secStart/secEnd" ist das Problem aber auch schon deutlich verringert worden. Von FHEM sollte dadurch jetzt kein weiterer Befehl mehr in einer laufenden SECURITY-Kommunikation gesendet werden.

Die Erkennung und Behandlung von eingehenden Paketen während der Kommunikation ist aber noch nicht wirklich implementiert. Falls eine Nachricht verlorengeht wird momentan wenigstens durch ein Timer das "secEnd" ausgelöst und damit der komplette DeadLock verhindert wird.

Für das Problem das dann evtl. eine Nachricht im Security Stack liegenbleibt und damit der Ablauf auch durcheinander kommt wollte ich mir demnächst mal auch so eine Lösung mit einem Timer überlegen.

Gruß,
Andreas.
FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

A.Harrenberg

Hallo Rudi,
Zitat von: rudolfkoenig am 14 Januar 2016, 09:54:25
5. Das Loesen des "get" Problems im ZWave_Cmd hat leider einen Haken: ich weiss nicht, wie man es ohne eine deutliche Interface-Aenderung (d.h. einfuehren von Callbacks oder Umsteigen auf Multithreading) loesen kann.
Dein Vorschlag wird z.Zt. schon umgesetzt. Was Du und die aktuelle Implementierung aber ignorieren: die anderen Filedeskriptoren (FHEMWEB/telnet/andere Inputs wie Homematic/etc) werden nicht geprueft, genausowenig werden Timer abgearbeitet, etc. Das alles passiert im Haupt-Select, aber ReadAnswerFn macht seinen eigenen eingeschraenkten select auf, was zwar bequem aber eigentlich falsch ist. Solange es selten verwendet wird, faellt es nicht auf, aber wenn man Security aktiviert, ist es staendig in Benutzung.
so nochmal eine Verständnisfrage.
Ist jetzt das select in ReadAnswerFn das eigentliche Problem oder (was ist eher vermute) das jegliches Warten den "return" zur aufrufenden Funktion verzögert und das durch Singlethread dann während der Wartezeit nichts anderes ausgeführt wird?
(Wobei ich bisher nicht wirklich verstanden habe was mit "select" wirklich im Hintergrund gemacht wird...)

Das mit dem %zwave_parseHook muss ich mir auch noch genauer anschauen. Der einzige Vorteil den ich momentan sehe ist das man dort auch Funktionen spezifizieren könnte die man nicht in  bei %zwave_class in PARSE angegeben hat. Ansonsten kann man doch auch einfach die Antwort normal parsen, oder?
Allerdings kann ich nicht erkennen wie man bei dem zwave_parseHook Parameter übergibt (für z.B. die Nachricht)???

Ich muss mir das für das AssociationRequest noch mal anschauen und nachvollziehen, vielleicht eignet sich das ja auch dazu das umständliche Konstrukt zum Einleiten der SECURITY-Inklusion besser zu lösen.

Gruß,
Andreas.
FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

rudolfkoenig

Zitat(Wobei ich bisher nicht wirklich verstanden habe was mit "select" wirklich im Hintergrund gemacht wird...)
Siehe "man select". Du musst das select Konzept verstehen, sonst verstehst das Problem (bzw. FHEM) nicht.
Problem ist nicht das select per se, sondern dass man SingleThreaded ist, auf das Ergebnis warten muss, und in diesem(!) Select man nur auf die betroffene ZWave Dongle aufpasst, und alle anderen FileDescriptoren ausser acht laesst.

zwave_parseHook ist vergleichbar mit der bei SECURITY verwendeten Methode (Funktionsaufruf bei Nachricht bestimmter Klasse). Der Aufruf ist aber temporaer, und kann auf einzelne Geraete oder andere Antwortparameter filtern, damit u.U. flexibler. Parameter kann man mit einem direkten sub
$zwave_parseHook{"$hash->{nodeIdHex}:..85"} = sub($h) { Funktion($h, meineParameter) }
uebergeben, oder indem man die im $hash zwischenspeichert. In diesem Fall ist $h und $hash gleich, in dem Sinne das vor dem Aufruf der sub das gleiche $hash ausgewaehlt wird.

Man koennte ein Grossteil (aber nicht alles) von Security auf parseHook umbauen, ob das danach besser/eleganter ist, kann ich jetzt nicht sagen.

A.Harrenberg

Hi Rudi,
Zitat von: rudolfkoenig am 19 Januar 2016, 07:15:26
Siehe "man select". Du musst das select Konzept verstehen, sonst verstehst das Problem (bzw. FHEM) nicht.
so grundlegend habe ich ja schon verstanden das man dort per Bitmaske die FileDeskriptoren definiert die man dann auf lesen oder schreiben überwacht.

Zitat von: rudolfkoenig am 19 Januar 2016, 07:15:26
Problem ist nicht das select per se, sondern dass man SingleThreaded ist, auf das Ergebnis warten muss, und in diesem(!) Select man nur auf die betroffene ZWave Dongle aufpasst, und alle anderen FileDescriptoren ausser acht laesst.
Ok, so langsam verstehe ich das ganze etwas besser... Wie machen das denn die anderen Systeme (z.B. Homematic), dort gibt es doch auch Get-Befehle die auf Rückgaben der Devices angewiesen sind. (Und dort scheint mir die "Antwortzeit" vom System sogar noch länger zu sein als bei ZWave).
Ist dort eine asynchrone Verarbeitung implementiert?

Zitat von: rudolfkoenig am 19 Januar 2016, 07:15:26
zwave_parseHook ist vergleichbar mit der bei SECURITY verwendeten Methode (Funktionsaufruf bei Nachricht bestimmter Klasse). Der Aufruf ist aber temporaer, und kann auf einzelne Geraete oder andere Antwortparameter filtern, damit u.U. flexibler. Parameter kann man mit einem direkten sub
$zwave_parseHook{"$hash->{nodeIdHex}:..85"} = sub($h) { Funktion($h, meineParameter) }
uebergeben, oder indem man die im $hash zwischenspeichert. In diesem Fall ist $h und $hash gleich, in dem Sinne das vor dem Aufruf der sub das gleiche $hash ausgewaehlt wird.

Man koennte ein Grossteil (aber nicht alles) von Security auf parseHook umbauen, ob das danach besser/eleganter ist, kann ich jetzt nicht sagen.
Danke für die Erklärung, dann lag ich ja nicht ganz so falsch. Ich werde mir das noch etwas genauer ansehen und dann wahrscheinlich mal einige der Sonderbehandlungen während der Inklusion damit umbauen, das ist dann deutlich eleganter und aufgeräumter. Kann sein das ich dafür kleine "Spezialfunktionen" brauche, dafür würden dann aber die Abfragen auf die Sonderfälle in den normalen Routinen entfallen.

Gruß,
Andreas.
FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

rudolfkoenig

Wenn ich das richtig sehe, gibt es keine HM get Befehle, die eine Kommunikation mit dem Stick oder gar mit den Endgeraeten ausloesen, es sind "nur" Befehle, die bereits vorhandene Informationen anders aufbereiten. Das ist eigentlich auch die richtige Vorgehensweise.

A.Harrenberg

Hi Rudi,

was machen denn dann die GET-REG Befehle?
An irgendeiner Stelle muss da doch auch mal was gelesen werden? Muss mir das bei meinen Geräten mal ansehen.

Gruß,
Andreas.
FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

A.Harrenberg

Hi Rudi,

ich versuche gerade das mit dem zwave_parseHook nachzuvollziehen...

Der "interessante" Teil in ZWave_Parse ist ja hier:

    my $matched = 0;
    foreach my $k (keys %{$ptr}) {
      if($arg =~ m/^$k/) {
        my $val = $ptr->{$k};
        my @val = ($val);
        #Log3 $ioName, 1, "Parse: $val";
        @val = eval $val if(index($val, '$') >= 0);
        push @event, @val if(defined($val[0]));
        $matched++;
      }
    }

    foreach my $h (keys %zwave_parseHook) {
      if("$id:$arg" =~ m/$h/) {
        my $fn = $zwave_parseHook{$h};
        delete $zwave_parseHook{$h};
        $fn->($hash, $arg);
      }
    }

Dazu hätte ich mal ein paar Fragen...

Auch wenn die Nachricht im oberen Teil geparst werden konnte wird dennoch der untere Teil abgearbeitet, oder?

In der Konstellation sollte man also nur Sachen in zwave_parseHook eintragen die NICHT in der %zwave_class enthalten sind, da diese dann zweifach abgearbeitet werden, oder?

Spricht was dagegen die Reihenfolge der beiden Blöcke zu tauschen und den Block mit dem "normalen" Parsen nur zu durchlaufen falls in zwave_parseHook nichts passendes gefunden wurde?
Dadurch könnte man temporäre "Ausnahmen" für die normalen Parsefunktionen definieren. Ich könnte das dann (eventuell, ist bisher nur eine Idee) z.B. für ZWave_secNonceReceived nutzen. Da gibt es einen Sonderfall während der Inklusion der dann aus der normalen Funktion raus könnte und in eine spezielle Funktion gepackt werden könnte die dann nur durch das setzen in zwave_parseHook während der Inklusion gestartet werden kann.

Gruß,
Andreas.

FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

A.Harrenberg

Hi,

ich denke ich habe gerade durch ausprobieren und testen mit associationRequestAll herausbekommen das Du zwave_parseHook genau andersherum einsetzt wie ich das vorhatte...

Du lässt erst parsen und DANACH machst Du was besonderes, richtig?

Gruß,
Andreas.
FB 7360, Homematic und ZWave
Support for ZWave-SECURITY

rudolfkoenig

Ich habe kein Problem, die Aufrufraihenfolge zu aendern, ich will es nur nicht "sinnlos" machen. Vorschlag: Reihenfolge der beiden Bloecke tauschen. Falls die zwave_parseHook Funktion != 0 zurueckliefert, dann wird die (jetzt darauffolgende) Schleife mit den Regexps aus zwave_class _nicht_ ausgefuehrt.

Fuer associationRequestAll sollte die Reihenfolge egal sein.