Skip to content

Commit

Permalink
verify 1st Revolt checksum byte
Browse files Browse the repository at this point in the history
To avoid wrong reads and especially invalid autocreates for Revolt NC-546x
energy cost meters, add verification of the 1st Revolt checksum byte.
Check based on (old) analysis from mehf, see Forum #14292. There's
another checksum(?) byte which I didn't understand yet.

Also increase minimum length of messages to assure we received the checksum
byte. In general, this patch might slightly decrease probability of receiving
far devices, but I think avoiding erronous reads is more important.

NOTE: For a patch for the svn.fhem.de version of SIGNALduino, see
https://forum.fhem.de/index.php/topic,58397.msg1151053.html#msg1151053.
  • Loading branch information
gernot-h committed Apr 23, 2021
1 parent a725963 commit 484f11a
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
4 changes: 2 additions & 2 deletions FHEM/lib/SD_ProtocolData.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1316,9 +1316,9 @@ package lib::SD_ProtocolData;
preamble => 'r',
clientmodule => 'Revolt',
modulematch => '^r[A-Fa-f0-9]{22}',
length_min => '84',
length_min => '96',
length_max => '120',
postDemodulation => sub { my $self=shift; my ($name, @bit_msg) = @_; my @new_bitmsg = splice @bit_msg, 0,88; return 1,@new_bitmsg; },
postDemodulation => \&lib::SD_Protocols::postDemo_Revolt,
},
"46" => ## Tedsen Fernbedienungen u.a. für Berner Garagentorantrieb GA401 und Geiger Antriebstechnik Rolladensteuerung
# https://github.com/RFD-FHEM/RFFHEM/issues/91
Expand Down
36 changes: 36 additions & 0 deletions FHEM/lib/SD_Protocols.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,42 @@ sub postDemo_EM {
return 0, undef;
}

############################# package lib::SD_Protocols, test exists
=item postDemo_Revolt()
This function checks the bit sequence. On an error in the CRC, it issues an output.
Input: $object,$name,@bit_msg
Output:
(returncode = 0 on success, prepared message or undef)
=cut

sub postDemo_Revolt {
my $self = shift // carp 'Not called within an object';
my $name = shift // carp 'no $name provided';
my @bit_msg = @_;

my $protolength = scalar @bit_msg;
my $sum = 0;

my $checksum = oct( '0b' . ( join "", @bit_msg[ 88 .. 95 ] ) );
$self->_logging( qq[lib/postDemo_Revolt, length=$protolength], 5 );
for ( my $b = 0 ; $b < 88 ; $b += 8 ) {
# build sum over first 11 bytes
$sum += oct( '0b' . ( join "", @bit_msg[ $b .. $b + 7 ] ) );
}
$sum = $sum & 0xFF;

if ($sum != $checksum) {
my $dmsg = lib::SD_Protocols::binStr2hexStr( join "", @bit_msg[ 0 .. 95 ] );
$self->_logging(qq[lib/postDemo_Revolt, ERROR checksum mismatch, $sum != $checksum in msg $dmsg], 3 );
return 0, undef;
}
my @new_bitmsg = splice @bit_msg, 0,88;
return 1, @new_bitmsg;
}

############################# package lib::SD_Protocols, test exists
=item postDemo_FS20()
Expand Down
38 changes: 38 additions & 0 deletions t/SD_Protocols/02_postDemo_Revolt.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/usr/bin/env perl

use strict;
use warnings;

use Test2::V0;
use lib::SD_Protocols;
use Test2::Tools::Compare qw{ is };

my $Protocols =
new lib::SD_Protocols( filetype => 'json', filename => './t/SD_Protocols/test_protocolData.json' );
my $target='some_device_name';

plan(4);

my $output;
my $rcode;

subtest 'Test CRC OK' => sub {
plan(2);
# MU;P0=143;P1=-218;P2=11620;P3=-332;P5=264;D=01230151515101015151015101515101510151515101015101010101010101010101010101010101010101015151010151010101010101010101010101010101010101010101010101010151015101010151010101015151015101510101010101510151015151010150;CP=0;R=0;
my @bits=qw(0 1 1 1 0 0 1 1 0 1 0 1 1 0 1 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 0 0 1);

($rcode,@bits)=lib::SD_Protocols::postDemo_Revolt($Protocols,$target,@bits);
is($rcode,1,'check returncode for postDemo_Revolt, CRC OK');
is(join("",@bits),'0111001101011010111001000000000000000000001100100000000000000000000000000101000100001101','check result postDemo_Revolt, CRC OK');
};


subtest 'Test CRC ERROR' => sub {
plan(2);
# MU;P1=10300;P2=-348;P3=112;P4=-254;P5=233;D=1234543434343434343434343434343434343434343434343434343454345454343454345434343454343454345434343454545434343434345454343434343434343434343434343454345454343454345434343454343454345434343454545434343434345450;CP=3;R=0;
my @bits=qw(0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1);

($rcode,$output)=lib::SD_Protocols::postDemo_Revolt($Protocols,$target,@bits);
is($rcode,0,'check returncode for postDemo_Revolt, CRC ERROR');
is($output,undef,'check result postDemo_Revolt, CRC ERROR');
};

0 comments on commit 484f11a

Please sign in to comment.