mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-20 07:16:03 +00:00
10_CUL_HM:restrict statusrequest repetition - 3
git-svn-id: https://svn.fhem.de/fhem/trunk@8846 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
52f80cd14d
commit
1f749e0b0d
@ -9,6 +9,9 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
use HMConfig;
|
use HMConfig;
|
||||||
|
|
||||||
|
eval "use Crypt::Rijndael";
|
||||||
|
my $cryptFunc = ($@)?0:1;
|
||||||
|
|
||||||
# ========================import constants=====================================
|
# ========================import constants=====================================
|
||||||
|
|
||||||
my $culHmModel =\%HMConfig::culHmModel;
|
my $culHmModel =\%HMConfig::culHmModel;
|
||||||
@ -1180,6 +1183,9 @@ sub CUL_HM_Parse($$) {#########################################################
|
|||||||
elsif($parse eq "NACK"){
|
elsif($parse eq "NACK"){
|
||||||
push @evtEt,[$shash,1,"state:NACK"];
|
push @evtEt,[$shash,1,"state:NACK"];
|
||||||
}
|
}
|
||||||
|
elsif($parse eq "AES"){
|
||||||
|
;# nothing todo
|
||||||
|
}
|
||||||
elsif($mTp eq "12") {#$lcm eq "09A112" Another fhem request (HAVE_DATA)
|
elsif($mTp eq "12") {#$lcm eq "09A112" Another fhem request (HAVE_DATA)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
@ -2566,6 +2572,15 @@ sub CUL_HM_parseCommon(@){#####################################################
|
|||||||
return "done";
|
return "done";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (defined($shash->{helper}{AESreqAck})) {
|
||||||
|
if ($shash->{helper}{AESreqAck} eq substr($p, -1 * length($shash->{helper}{AESreqAck}))) {
|
||||||
|
push @evtEt,[$shash,1,"aesCommToDev:ok"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
push @evtEt,[$shash,1,"aesCommToDev:fail"];
|
||||||
|
}
|
||||||
|
delete $shash->{helper}{AESreqAck};
|
||||||
|
}
|
||||||
|
|
||||||
if ($subType =~ m/^8/){#NACK
|
if ($subType =~ m/^8/){#NACK
|
||||||
#82 : peer not accepted - list full (VD)
|
#82 : peer not accepted - list full (VD)
|
||||||
@ -2599,12 +2614,49 @@ sub CUL_HM_parseCommon(@){#####################################################
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif($subType eq "04"){ #ACK-AES, interim########
|
elsif($subType eq "04"){ #ACK-AES, ###############
|
||||||
my (undef,$key,$aesKeyNbr) = unpack'A2A12A2',$p;
|
my (undef,$challenge,$aesKeyNbr) = unpack'A2A12A2',$p;
|
||||||
push @evtEt,[$shash,1,"aesKeyNbr:".$aesKeyNbr] if (defined $aesKeyNbr);# if ($msgStat =~ m/AESKey/)
|
push @evtEt,[$shash,1,"aesKeyNbr:".$aesKeyNbr] if (defined $aesKeyNbr);# if ($msgStat =~ m/AESKey/)
|
||||||
#push @evtEt,[$shash,1,"aesCommToDev:".substr($msgStat,7)];#elsif($msgStat =~ m/AESCom/){# AES communication to central
|
|
||||||
#$success = ""; #result not final, another response should come
|
if ($shash->{IODev}->{TYPE} eq "CUL" && #IO is CUL
|
||||||
$reply = "done";
|
defined($aesKeyNbr)) {
|
||||||
|
if ($cryptFunc == 1 && #AES is available
|
||||||
|
$shash->{helper}{prt}{rspWait}{cmd}){ #There is a previously executed command
|
||||||
|
my (undef, %keys) = CUL_HM_getKeys($shash);
|
||||||
|
|
||||||
|
my $kNo = hex($aesKeyNbr) / 2;
|
||||||
|
Log3 $shash,5,"CUL_HM $shash->{NAME} signing request for $shash->{helper}{prt}{rspWait}{cmd} challenge: "
|
||||||
|
.$challenge." kNo: ".$kNo;
|
||||||
|
|
||||||
|
if (!defined($keys{$kNo})) {
|
||||||
|
Log3 $shash,1,"CUL_HM $shash->{NAME} unknown key for index $kNo, define it in the VCCU!";
|
||||||
|
$reply = "done";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my $key = $keys{$kNo} ^ pack("H12", $challenge);
|
||||||
|
my $cipher = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_ECB());
|
||||||
|
my($s,$us) = gettimeofday();
|
||||||
|
my $respRaw = pack("NnH20", $s, $us, substr($shash->{helper}{prt}{rspWait}{cmd}, 4, 20));
|
||||||
|
my $response = $cipher->encrypt($respRaw);
|
||||||
|
$shash->{helper}{AESreqAck} = uc(unpack("H*", substr($response,0,4)));
|
||||||
|
Log3 $shash,5,"CUL_HM $shash->{NAME} signing response: ".unpack("H*", $respRaw)
|
||||||
|
." should send $shash->{helper}{AESreqAck} to authenticate";
|
||||||
|
$response = $response ^ pack("H*", substr($shash->{helper}{prt}{rspWait}{cmd}, 24));
|
||||||
|
$response = $cipher->encrypt(substr($response, 0, 16));
|
||||||
|
|
||||||
|
CUL_HM_SndCmd($shash, $mNo.$mFlg.'03'.CUL_HM_IoId($shash).$src.unpack("H*", $response));
|
||||||
|
|
||||||
|
$reply = "AES";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ($cryptFunc != 1){ #AES is not available
|
||||||
|
Log3 $shash,1,"CUL_HM ".$shash->{NAME}." need Crypt::Rijndael to answer signing request with CUL";
|
||||||
|
$reply = "done";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$reply = "done";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{ #ACK
|
else{ #ACK
|
||||||
$success = "yes";
|
$success = "yes";
|
||||||
@ -2872,6 +2924,7 @@ sub CUL_HM_parseCommon(@){#####################################################
|
|||||||
@{$modules{CUL_HM}{helper}{qReqStat}} = grep { $_ ne $shash->{NAME} }
|
@{$modules{CUL_HM}{helper}{qReqStat}} = grep { $_ ne $shash->{NAME} }
|
||||||
@{$modules{CUL_HM}{helper}{qReqStat}};
|
@{$modules{CUL_HM}{helper}{qReqStat}};
|
||||||
|
|
||||||
|
CUL_HM_unQEntity($shash->{NAME},"qReqStat");
|
||||||
if ($pendType eq "StatusReq"){#it is the answer to our request
|
if ($pendType eq "StatusReq"){#it is the answer to our request
|
||||||
my $chnSrc = $src.$shash->{helper}{prt}{rspWait}{forChn};
|
my $chnSrc = $src.$shash->{helper}{prt}{rspWait}{forChn};
|
||||||
my $chnhash = $modules{CUL_HM}{defptr}{$chnSrc};
|
my $chnhash = $modules{CUL_HM}{defptr}{$chnSrc};
|
||||||
@ -3429,6 +3482,7 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
|
|||||||
$_ = "$cmd:".join(",",@vArr);
|
$_ = "$cmd:".join(",",@vArr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@arr1 = ("--") if (!scalar @arr1);
|
||||||
my $usg = "Unknown argument $cmd, choose one of ".join(" ",sort @arr1);
|
my $usg = "Unknown argument $cmd, choose one of ".join(" ",sort @arr1);
|
||||||
$usg =~ s/ pct/ pct:slider,0,1,100/;
|
$usg =~ s/ pct/ pct:slider,0,1,100/;
|
||||||
$usg =~ s/ virtual/ virtual:slider,1,1,50/;
|
$usg =~ s/ virtual/ virtual:slider,1,1,50/;
|
||||||
@ -4997,10 +5051,45 @@ sub CUL_HM_Set($@) {#+++++++++++++++++ set command+++++++++++++++++++++++++++++
|
|||||||
my $oldKeyIdx = ReadingsVal($name, "aesKeyNbr", "00");
|
my $oldKeyIdx = ReadingsVal($name, "aesKeyNbr", "00");
|
||||||
return "current key unknown" if (!defined $oldKeyIdx || $oldKeyIdx eq "");
|
return "current key unknown" if (!defined $oldKeyIdx || $oldKeyIdx eq "");
|
||||||
|
|
||||||
CUL_HM_PushCmdStack($hash,'++'.$flag.'04'.$id.$dst.'01'.
|
my ($key1,$key2);
|
||||||
sprintf("%02X",$oldKeyIdx));
|
|
||||||
CUL_HM_PushCmdStack($hash,'++'.$flag.'04'.$id.$dst.'01'.
|
if ($hash->{IODev}->{TYPE} eq "CUL") {
|
||||||
sprintf("%02X",($oldKeyIdx+1)));
|
return "$cmd needs Crypt::Rijndael for updating keys with CUL"
|
||||||
|
if ($cryptFunc != 1);
|
||||||
|
|
||||||
|
my ($newKeyIdx, %keys) = CUL_HM_getKeys($hash);
|
||||||
|
my $oldKey = $keys{hex($oldKeyIdx)/2};
|
||||||
|
|
||||||
|
return "$cmd requires VCCU with hmKeys" if ($newKeyIdx == 0);
|
||||||
|
return "$cmd needs old key with index ".(hex($oldKeyIdx)/2) if (!defined($oldKey));
|
||||||
|
|
||||||
|
my $newKey = $keys{$newKeyIdx};
|
||||||
|
my $payload1 = pack("CCa8nN",1 #changekey?
|
||||||
|
,$newKeyIdx*2 #index for first part of key
|
||||||
|
,substr($newKey, 0, 8) #first 8 bytes of new key
|
||||||
|
,rand(0xffff) #random
|
||||||
|
,0x7e296fa5); #magic
|
||||||
|
my $payload2 = pack("CCa8nN",1 #changekey?
|
||||||
|
,($newKeyIdx*2)+1 #index for second part of key
|
||||||
|
,substr($newKey, 8, 8) #second 8 bytes of new key
|
||||||
|
,rand(0xffff) #random
|
||||||
|
,0x7e296fa5); #magic
|
||||||
|
|
||||||
|
my $cipher = Crypt::Rijndael->new($oldKey, Crypt::Rijndael::MODE_ECB());
|
||||||
|
Log3 $name,2,"CUL_HM $name assignHmKey index ".(hex($oldKeyIdx)/2)." to ".$newKeyIdx
|
||||||
|
." Key1: ".unpack("H*", $payload1)
|
||||||
|
." Key2: ".unpack("H*", $payload2);
|
||||||
|
|
||||||
|
$key1 = unpack("H*", $cipher->encrypt($payload1));
|
||||||
|
$key2 = unpack("H*", $cipher->encrypt($payload2));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$key1 = sprintf("%02X",$oldKeyIdx);
|
||||||
|
$key2 = sprintf("%02X",($oldKeyIdx+1));
|
||||||
|
}
|
||||||
|
CUL_HM_PushCmdStack($hash,'++'.$flag.'04'.$id.$dst.'01'.$key1);
|
||||||
|
CUL_HM_PushCmdStack($hash,'++'.$flag.'04'.$id.$dst.'01'.$key2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else{
|
else{
|
||||||
@ -6272,6 +6361,24 @@ sub CUL_HM_getAssChnNames($) { #in: name out:list of assotiated chan and device
|
|||||||
}
|
}
|
||||||
return sort(@chnN);
|
return sort(@chnN);
|
||||||
}
|
}
|
||||||
|
sub CUL_HM_getKeys($) { #in: device-hash out:highest index, hash with keys
|
||||||
|
my ($hash) = @_;
|
||||||
|
my $highestIdx = 0;
|
||||||
|
my %keys = ();
|
||||||
|
$keys{0} = pack("H*", "A4E375C6B09FD185F27C4E96FC273AE4"); #index 0: eQ-3 default
|
||||||
|
if (defined($hash->{IODev}->{owner_CCU})) {
|
||||||
|
my $vccu = $hash->{IODev}->{owner_CCU};
|
||||||
|
foreach my $i (1..3){
|
||||||
|
my ($kNo,$k) = split(":",AttrVal($vccu,"hmKey".($i== 1?"":$i),""));
|
||||||
|
if (defined($k)) {
|
||||||
|
$keys{hex($kNo)} = pack("H*", $k);
|
||||||
|
$highestIdx = hex($kNo) if (hex($kNo) > $highestIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ($highestIdx, %keys);
|
||||||
|
}
|
||||||
|
|
||||||
#+++++++++++++++++ Conversions names, hashes, ids++++++++++++++++++++++++++++++
|
#+++++++++++++++++ Conversions names, hashes, ids++++++++++++++++++++++++++++++
|
||||||
#Performance opti: subroutines may consume up to 5 times the performance
|
#Performance opti: subroutines may consume up to 5 times the performance
|
||||||
#
|
#
|
||||||
@ -7574,7 +7681,7 @@ sub CUL_HM_readStateTo($){#staterequest not working
|
|||||||
my ($eN) = @_;
|
my ($eN) = @_;
|
||||||
$eN = substr($eN,6) if ($eN =~ m/^sUpdt:/);
|
$eN = substr($eN,6) if ($eN =~ m/^sUpdt:/);
|
||||||
CUL_HM_UpdtReadSingle($defs{$eN},"state","unreachable",1);
|
CUL_HM_UpdtReadSingle($defs{$eN},"state","unreachable",1);
|
||||||
CUL_HM_stateUpdatDly($eN,1800);
|
CUL_HM_stateUpdatDly($eN,1800 );
|
||||||
}
|
}
|
||||||
sub CUL_HM_procQs($){#process non-wakeup queues
|
sub CUL_HM_procQs($){#process non-wakeup queues
|
||||||
# --- verify send is possible
|
# --- verify send is possible
|
||||||
|
Loading…
x
Reference in New Issue
Block a user