mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-20 13:26:02 +00:00
DevIo.pm: DevIo_SimpleReadWithTimeout and DevIo_Expect from Boris
git-svn-id: https://svn.fhem.de/fhem/trunk@5236 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
fdb28cbdf3
commit
7f4bc2024a
@ -2,13 +2,15 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
package main;
|
package main;
|
||||||
|
|
||||||
sub DevIo_SimpleRead($);
|
|
||||||
sub DevIo_TimeoutRead($$);
|
|
||||||
sub DevIo_SimpleWrite($$$);
|
|
||||||
sub DevIo_OpenDev($$$);
|
|
||||||
sub DevIo_CloseDev($@);
|
sub DevIo_CloseDev($@);
|
||||||
sub DevIo_Disconnected($);
|
sub DevIo_Disconnected($);
|
||||||
|
sub DevIo_Expect($$$);
|
||||||
|
sub DevIo_OpenDev($$$);
|
||||||
sub DevIo_SetHwHandshake($);
|
sub DevIo_SetHwHandshake($);
|
||||||
|
sub DevIo_SimpleRead($);
|
||||||
|
sub DevIo_SimpleReadWithTimeout($$);
|
||||||
|
sub DevIo_SimpleWrite($$$);
|
||||||
|
sub DevIo_TimeoutRead($$);
|
||||||
|
|
||||||
########################
|
########################
|
||||||
sub
|
sub
|
||||||
@ -53,7 +55,25 @@ DevIo_SimpleRead($)
|
|||||||
}
|
}
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Read until you get the timeout. Use it with care
|
# wait at most timeout seconds until the file handle gets ready
|
||||||
|
# for reading; returns undef on timeout
|
||||||
|
# NOTE1: FHEM can be blocked for $timeout seconds!
|
||||||
|
# NOTE2: This works on Windows only for TCP connections
|
||||||
|
sub
|
||||||
|
DevIo_SimpleReadWithTimeout($$)
|
||||||
|
{
|
||||||
|
my ($hash, $timeout) = @_;
|
||||||
|
|
||||||
|
my $rin = "";
|
||||||
|
vec($rin, $hash->{FD}, 1) = 1;
|
||||||
|
my $nfound = select($rin, undef, undef, $timeout);
|
||||||
|
return DevIo_DoSimpleRead($hash) if($nfound> 0);
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Read until you get the timeout. Use it with care since it waits _at least_
|
||||||
|
# timeout seconds, and it works on Windows only for TCP/IP connections
|
||||||
sub
|
sub
|
||||||
DevIo_TimeoutRead($$)
|
DevIo_TimeoutRead($$)
|
||||||
{
|
{
|
||||||
@ -72,7 +92,6 @@ DevIo_TimeoutRead($$)
|
|||||||
return $answer;
|
return $answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# Input is HEX, with header and CRC
|
# Input is HEX, with header and CRC
|
||||||
sub
|
sub
|
||||||
@ -91,6 +110,51 @@ DevIo_SimpleWrite($$$)
|
|||||||
select(undef, undef, undef, 0.001);
|
select(undef, undef, undef, 0.001);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Write something, then read something
|
||||||
|
# reopen device if timeout occurs and write again, then read again
|
||||||
|
sub
|
||||||
|
DevIo_Expect($$$)
|
||||||
|
{
|
||||||
|
my ($hash, $msg, $timeout) = @_;
|
||||||
|
my $name= $hash->{NAME};
|
||||||
|
|
||||||
|
my $state= $hash->{STATE};
|
||||||
|
if($state ne "opened") {
|
||||||
|
Log3 $name, 2, "Attempt to write to $state device.";
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
# write something
|
||||||
|
return undef unless defined(DevIo_SimpleWrite($hash, $msg, 0));
|
||||||
|
# read answer
|
||||||
|
my $answer= DevIo_SimpleReadWithTimeout($hash, $timeout);
|
||||||
|
return $answer unless($answer eq "");
|
||||||
|
# the device has failed to deliver a result
|
||||||
|
$hash->{STATE}= "failed";
|
||||||
|
DoTrigger($name, "FAILED");
|
||||||
|
# reopen device
|
||||||
|
# unclear how to know whether the following succeeded
|
||||||
|
Log3 $name, 2, "$name: first attempt to read timed out, trying to close and open the device.";
|
||||||
|
# The next two lines are required to avoid a deadlock when the remote end closes the connection
|
||||||
|
# upon DevIo_OpenDev, as e.g. netcat -l <port> does.
|
||||||
|
DevIo_CloseDev($hash);
|
||||||
|
sleep(5) if($hash->{USBDEV});
|
||||||
|
DevIo_OpenDev($hash, 0, undef); # where to get the initfn from?
|
||||||
|
# write something again
|
||||||
|
return undef unless defined(DevIo_SimpleWrite($hash, $msg, 0));
|
||||||
|
# read answer again
|
||||||
|
$answer= DevIo_SimpleReadWithTimeout($hash, $timeout);
|
||||||
|
# success
|
||||||
|
if($answer ne "") {
|
||||||
|
$hash->{STATE}= "opened";
|
||||||
|
DoTrigger($name, "CONNECTED");
|
||||||
|
return $answer;
|
||||||
|
}
|
||||||
|
# ultimate failure
|
||||||
|
Log3 $name, 2, "$name: second attempt to read timed out, this is an unrecoverable error.";
|
||||||
|
DoTrigger($name, "DISCONNECTED");
|
||||||
|
return undef; # undef means ultimate failure
|
||||||
|
}
|
||||||
|
|
||||||
########################
|
########################
|
||||||
sub
|
sub
|
||||||
|
Loading…
x
Reference in New Issue
Block a user