MAX: refactor Send code

git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@2728 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
mgehre 2013-02-15 03:19:57 +00:00
parent 9e464d2de7
commit a789235962
3 changed files with 40 additions and 34 deletions

View File

@ -743,17 +743,24 @@ MAXLAN_RequestConfiguration($$)
sub sub
MAXLAN_Send(@) MAXLAN_Send(@)
{ {
my ($hash, $cmd, $dst, $payload, $flags, $groupId, $msgcnt) = @_; my ($hash, $cmd, $dst, $payload, %opts) = @_;
$flags = "00" if(!$flags); my $flags = "00";
$groupId = "00" if(!defined($groupId)); my $groupId = "00";
my $callbackParam = undef;
$flags = $opts{flags} if(exists($opts{flags}));
$groupId = $opts{groupId} if(exists($opts{groupId}));
Log 2, "MAXLAN_Send: MAXLAN does not support src" if(exists($opts{src}));
$callbackParam = $opts{callbackParam} if(exists($opts{callbackParam}));
if(defined($msgcnt)) {
Log 2, "MAXLAN_Send: MAXLAN does not support msgcnt";
}
$payload = pack("H*","00".$flags.$msgCmd2Id{$cmd}."000000".$dst.$groupId.$payload); $payload = pack("H*","00".$flags.$msgCmd2Id{$cmd}."000000".$dst.$groupId.$payload);
my $ret = MAXLAN_Write($hash,"s:".encode_base64($payload,""), "S:"); my $ret = MAXLAN_Write($hash,"s:".encode_base64($payload,""), "S:");
#TODO: actually check return value
if(defined($opts{callbackParam})) {
Dispatch($hash, "MAX,1,Ack$cmd,$dst,$opts{callbackParam}", {RAWMSG => ""});
}
#Reschedule a poll in the near future after the cube will #Reschedule a poll in the near future after the cube will
#have gotten an answer #have gotten an answer
RemoveInternalTimer($hash); RemoveInternalTimer($hash);

View File

@ -343,7 +343,7 @@ MAX_Set($@)
if($hash->{type} eq "ShutterContact") { if($hash->{type} eq "ShutterContact") {
return "Invalid number of arguments" if(@args != 2); return "Invalid number of arguments" if(@args != 2);
my $state = $args[1] ? "12" : "10"; my $state = $args[1] ? "12" : "10";
return ($hash->{IODev}{Send})->($hash->{IODev},"ShutterContactState",$dest,$state,"06",undef,undef,$hash->{addr}); return ($hash->{IODev}{Send})->($hash->{IODev},"ShutterContactState",$dest,$state, flags => "06", src => $hash->{addr});
} elsif($hash->{type} eq "WallMountedThermostat") { } elsif($hash->{type} eq "WallMountedThermostat") {
return "Invalid number of arguments" if(@args != 3); return "Invalid number of arguments" if(@args != 3);
@ -358,7 +358,7 @@ MAX_Set($@)
$arg2 &= 0xFF; #only take the lower 8 bits $arg2 &= 0xFF; #only take the lower 8 bits
return ($hash->{IODev}{Send})->($hash->{IODev},"WallThermostatControl",$dest, return ($hash->{IODev}{Send})->($hash->{IODev},"WallThermostatControl",$dest,
sprintf("%02x%02x",$arg1,$arg2),"04",undef,undef,$hash->{addr}); sprintf("%02x%02x",$arg1,$arg2),flags => "04", src => $hash->{addr});
} else { } else {
return "fake does not work for device type $hash->{type}"; return "fake does not work for device type $hash->{type}";
} }

View File

@ -8,10 +8,8 @@ use warnings;
use MaxCommon; use MaxCommon;
use POSIX; use POSIX;
sub CUL_MAX_Send(@);
sub CUL_MAX_BroadcastTime(@); sub CUL_MAX_BroadcastTime(@);
sub CUL_MAX_Set($@); sub CUL_MAX_Set($@);
sub CUL_MAX_SendAck($$$);
sub CUL_MAX_SendTimeInformation(@); sub CUL_MAX_SendTimeInformation(@);
sub CUL_MAX_GetTimeInformationPayload(); sub CUL_MAX_GetTimeInformationPayload();
sub CUL_MAX_Send(@); sub CUL_MAX_Send(@);
@ -181,7 +179,7 @@ CUL_MAX_Parse($$)
return $shash->{NAME} if(!@{$shash->{sendQueue}}); #we are not waiting for any Ack return $shash->{NAME} if(!@{$shash->{sendQueue}}); #we are not waiting for any Ack
my $packet = $shash->{sendQueue}[0]; my $packet = $shash->{sendQueue}[0];
if($packet->{dest} eq $src and $packet->{cnt} == hex($msgcnt)) { if($packet->{dst} eq $src and $packet->{cnt} == hex($msgcnt)) {
Log $ll5, "Got matching ack"; Log $ll5, "Got matching ack";
$packet->{sent} = 2; $packet->{sent} = 2;
return $shash->{NAME}; return $shash->{NAME};
@ -243,33 +241,28 @@ CUL_MAX_Parse($$)
return $shash->{NAME}; return $shash->{NAME};
} }
sub
CUL_MAX_SendAck($$$)
{
my ($hash,$msgcnt,$dst) = @_;
return CUL_MAX_Send($hash, "Ack", $dst, "00", "00", "00", $msgcnt);
}
#All inputs are hex strings, $cmd is one from %msgCmd2Id #All inputs are hex strings, $cmd is one from %msgCmd2Id
sub sub
CUL_MAX_Send(@) CUL_MAX_Send(@)
{ {
# $cmd is one of # $cmd is one of
my ($hash, $cmd, $dst, $payload, $flags, $groupId, $msgcnt, $src) = @_; my ($hash, $cmd, $dst, $payload, %opts) = @_;
CUL_MAX_Check($hash); CUL_MAX_Check($hash);
$flags = "00" if(!$flags); my $flags = "00";
$groupId = "00" if(!defined($groupId)); my $groupId = "00";
$src = $hash->{addr} if(!defined($src)); my $src = $hash->{addr};
my $callbackParam = undef;
if(!defined($msgcnt)) { $flags = $opts{flags} if(exists($opts{flags}));
my $dhash = CUL_MAX_DeviceHash($dst); $groupId = $opts{groupId} if(exists($opts{groupId}));
#replace message counter if not already set $src = $opts{src} if(exists($opts{src}));
$dhash->{READINGS}{msgcnt}{VAL} += 1; $callbackParam = $opts{callbackParam} if(exists($opts{callbackParam}));
$dhash->{READINGS}{msgcnt}{VAL} &= 0xFF;
$msgcnt = sprintf("%02x",$dhash->{READINGS}{msgcnt}{VAL}); my $dhash = CUL_MAX_DeviceHash($dst);
} $dhash->{READINGS}{msgcnt}{VAL} += 1;
$dhash->{READINGS}{msgcnt}{VAL} &= 0xFF;
my $msgcnt = sprintf("%02x",$dhash->{READINGS}{msgcnt}{VAL});
my $packet = $msgcnt . $flags . $msgCmd2Id{$cmd} . $src . $dst . $groupId . $payload; my $packet = $msgcnt . $flags . $msgCmd2Id{$cmd} . $src . $dst . $groupId . $payload;
@ -280,10 +273,13 @@ CUL_MAX_Send(@)
my $timeout = gettimeofday()+$ackTimeout; my $timeout = gettimeofday()+$ackTimeout;
my $aref = $hash->{sendQueue}; my $aref = $hash->{sendQueue};
push(@{$aref}, { "packet" => $packet, push(@{$aref}, { "packet" => $packet,
"dest" => $dst, "dst" => $dst,
"cnt" => hex($msgcnt), "cnt" => hex($msgcnt),
"time" => $timeout, "time" => $timeout,
"sent" => "0" }); "sent" => "0",
"cmd" => $cmd,
"callbackParam" => $callbackParam,
});
#Call CUL_MAX_SendQueueHandler if we just enqueued the only packet #Call CUL_MAX_SendQueueHandler if we just enqueued the only packet
#otherwise it is already in the InternalTimer list #otherwise it is already in the InternalTimer list
@ -339,7 +335,7 @@ CUL_MAX_SendQueueHandler($)
} elsif( $packet->{sent} == 1 ) { #Already sent it, got no Ack } elsif( $packet->{sent} == 1 ) { #Already sent it, got no Ack
if( $packet->{sentTime} + $ackTimeout < gettimeofday() ) { if( $packet->{sentTime} + $ackTimeout < gettimeofday() ) {
# ackTimeout exceeded # ackTimeout exceeded
Log 2, "CUL_MAX_SendQueueHandler: Missing ack from $packet->{dest} for $packet->{packet}"; Log 2, "CUL_MAX_SendQueueHandler: Missing ack from $packet->{dst} for $packet->{packet}";
splice @{$hash->{sendQueue}}, 0, 1; #Remove from array splice @{$hash->{sendQueue}}, 0, 1; #Remove from array
readingsSingleUpdate($hash, "packetsLost", ReadingsVal($hash->{NAME}, "packetsLost", 0) + 1, 1); readingsSingleUpdate($hash, "packetsLost", ReadingsVal($hash->{NAME}, "packetsLost", 0) + 1, 1);
} else { } else {
@ -348,6 +344,9 @@ CUL_MAX_SendQueueHandler($)
} }
} elsif( $packet->{sent} == 2 ) { #Got ack } elsif( $packet->{sent} == 2 ) { #Got ack
if(defined($packet->{callbackParam})) {
Dispatch($hash, "MAX,1,Ack$packet->{cmd},$packet->{dst},$packet->{callbackParam}", {RAWMSG => ""});
}
splice @{$hash->{sendQueue}}, 0, 1; #Remove from array splice @{$hash->{sendQueue}}, 0, 1; #Remove from array
} }
@ -371,7 +370,7 @@ CUL_MAX_SendTimeInformation(@)
my ($hash,$addr,$payload) = @_; my ($hash,$addr,$payload) = @_;
$payload = CUL_MAX_GetTimeInformationPayload() if(!defined($payload)); $payload = CUL_MAX_GetTimeInformationPayload() if(!defined($payload));
Log GetLogLevel($hash->{NAME}, 5), "broadcast time to $addr"; Log GetLogLevel($hash->{NAME}, 5), "broadcast time to $addr";
CUL_MAX_Send($hash, "TimeInformation", $addr, $payload, "04"); CUL_MAX_Send($hash, "TimeInformation", $addr, $payload, flags => "04");
} }
sub sub