From fa90f66bde2831c96338654fabf51c9222b031f0 Mon Sep 17 00:00:00 2001 From: rudolfkoenig Date: Sun, 27 Dec 2015 12:18:13 +0000 Subject: [PATCH] 00_ZWCUL.pm: better 100k support git-svn-id: https://svn.fhem.de/fhem/trunk@10274 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/00_ZWCUL.pm | 38 +++++++++++++++++++++++++------------- fhem/FHEM/00_ZWDongle.pm | 4 ++-- fhem/FHEM/ZWLib.pm | 14 +++++++++++++- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/fhem/FHEM/00_ZWCUL.pm b/fhem/FHEM/00_ZWCUL.pm index 33671c2f8..d1692ab9a 100755 --- a/fhem/FHEM/00_ZWCUL.pm +++ b/fhem/FHEM/00_ZWCUL.pm @@ -3,13 +3,16 @@ package main; # TODO -# implement resend in firmware -# fix remotes -# implement inclusion/exclusion -# implement neighborUpdate: 010404010c0001 010604000c0040 010700 0105 -# implement static routing -# implement/understand explorer frames -# check security +# 9.6k, needed by inclusion +# always verify checksum in firmware +# inclusion/exclusion +# resend in firmware +# send anomaly on remotes +# neighborUpdate Class: 010404010c0001 010604000c0040 010700 0105 +# static routing +# explorer frames +# implement security +# multicast use strict; use warnings; @@ -222,18 +225,23 @@ ZWCUL_Write($$$) my ($t,$l,$p) = ($1,$2,$3); my $th = $modules{ZWave}{defptr}{"$fn $t"}; if(!$th) { - Log 1, "ZWCUL: no device found for $fn $t"; + Log3 $hash, 1, "ZWCUL: no device found for $fn $t"; return; } # Do not send wakeupNoMoreInformation in monitor mode return if($p eq "8408" && $hash->{monitor}); - $th->{sentIdx} = ($th->{sentIdx}++ % 16); + $th->{sentIdx} = 0 if(!$th->{sentIdx} || $th->{sentIdx} == 15); + $th->{sentIdx}++; + + my $s100 = (AttrVal($hash->{NAME}, "dataRate", "40k") eq "100k"); + $msg = sprintf("%s%s41%02x%02x%s%s", $fn, $hash->{nodeIdHex}, $th->{sentIdx}, - length($p)/2+10, $th->{nodeIdHex}, $p); - $msg .= zwlib_checkSum($msg); + length($p)/2+($s100 ? 11 : 10), $th->{nodeIdHex}, $p); + $msg .= ($s100 ? zwlib_checkSum_16($msg) : zwlib_checkSum_8($msg)); + ZWCUL_SimpleWrite($hash, "zs".$msg); } } @@ -290,6 +298,10 @@ ZWCUL_Parse($$$$$) my $me = $hash->{NAME}; my $s100 = (AttrVal($me, "dataRate", "40k") eq "100k"); + if($rmsg =~ m/^za(..)$/) { + Log3 $hash, 5, "$me sent ACK to $1"; + return; + } my ($H, $S, $F, $f, $sn, $L, $T, $P, $C); if($s100 && $rmsg =~ '^z(........)(..)(..)(.)(.)(..)(..)(.*)(....)$') { @@ -299,7 +311,7 @@ ZWCUL_Parse($$$$$) ($H,$S,$F,$f,$sn,$L,$T,$P,$C) = ($1,$2,$3,$4,$5,$6,$7,$8,$9); } else { - Log 1, "ERROR: Unknown packet $rmsg"; + Log3 $hash, 1, "ERROR: Unknown packet $rmsg"; return; } @@ -368,7 +380,7 @@ ZWCUL_ReadAnswer($$$) my ($hash, $arg, $regexp) = @_; Log3 $hash, 4, "ZWCUL_ReadAnswer arg:$arg regexp:".($regexp ? $regexp:""); my $transform; - if($regexp =~ m/^\^000400(..)..(..)/) { + if($regexp && $regexp =~ m/^\^000400(..)..(..)/) { $regexp = "^z........$1........$2"; $transform = 1; } diff --git a/fhem/FHEM/00_ZWDongle.pm b/fhem/FHEM/00_ZWDongle.pm index 68e15f888..a40c6c57b 100755 --- a/fhem/FHEM/00_ZWDongle.pm +++ b/fhem/FHEM/00_ZWDongle.pm @@ -389,7 +389,7 @@ ZWDongle_Write($$$) # assemble complete message $msg = sprintf("%02x%s", length($msg)/2+1, $msg); - $msg = "01$msg" . zwlib_checkSum($msg); + $msg = "01$msg" . zwlib_checkSum_8($msg); push @{$hash->{SendStack}}, $msg; ZWDongle_ProcessSendStack($hash); @@ -535,7 +535,7 @@ ZWDongle_Read($@) my $rcs = substr($data, $l+2, 2); # Received Checksum $data = substr($data, $l+4); - my $ccs = zwlib_checkSum("$len$msg"); # Computed Checksum + my $ccs = zwlib_checkSum_8("$len$msg"); # Computed Checksum if($rcs ne $ccs) { Log3 $name, 1, "$name: wrong checksum: received $rcs, computed $ccs for $len$msg"; diff --git a/fhem/FHEM/ZWLib.pm b/fhem/FHEM/ZWLib.pm index 6a10964e2..691cc72d8 100644 --- a/fhem/FHEM/ZWLib.pm +++ b/fhem/FHEM/ZWLib.pm @@ -166,7 +166,7 @@ zwlib_parseNeighborList($$) ##################################### sub -zwlib_checkSum($) +zwlib_checkSum_8($) { my ($data) = @_; my $cs = 0xff; @@ -174,5 +174,17 @@ zwlib_checkSum($) return sprintf("%02x", $cs); } +sub +zwlib_checkSum_16($) # CRC16-CCITT (Polynom: 1021) +{ + my ($data) = @_; + my $crc = 0x1d0f; + for my $c (split("", pack('H*', $data))) { + my $x = ($crc>>8) ^ ord($c); + $x ^= $x>>4; + $crc = (($crc<<8) ^ ($x<<12) ^ ($x<<5) ^ $x) & 0xffff; + } + return sprintf("%04x", $crc); +} 1;