From 71f43a6a2c45ec9e65b15fd37bb66eca18f6e059 Mon Sep 17 00:00:00 2001 From: ntruchsess Date: Mon, 21 Oct 2013 23:25:54 +0000 Subject: [PATCH] Merge branch 'dev' (make sure the FRM IODev is allways the main FRM-device when connecting by tcp) git-svn-id: https://svn.fhem.de/fhem/trunk@4095 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/10_FRM.pm | 93 ++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/fhem/FHEM/10_FRM.pm b/fhem/FHEM/10_FRM.pm index 97eef2fb9..41828f502 100755 --- a/fhem/FHEM/10_FRM.pm +++ b/fhem/FHEM/10_FRM.pm @@ -97,15 +97,18 @@ sub FRM_Undef($) { if (defined $hash->{DeviceName}) { DevIo_Disconnected($hash); }; - my $device = $hash->{FirmataDevice}; - if (defined $device) { - if (defined $device->{io}) { - delete $hash->{FirmataDevice}->{io}->{handle} if defined $hash->{FirmataDevice}->{io}->{handle}; - delete $hash->{FirmataDevice}->{io}; + + foreach my $d ( sort keys %main::defs ) { # close and dispose open tcp-connection (if any) to free open filedescriptors + if ( defined( my $dev = $main::defs{$d} )) { + if ( defined( $main::defs{$d}{SNAME} ) + && $main::defs{$d}{SNAME} eq $hash->{NAME}) { + FRM_Tcp_Connection_Close($main::defs{$d}); + } } - delete $device->{protocol} if defined $device->{protocol}; - delete $hash->{FirmataDevice}; } + + FRM_FirmataDevice_Close($hash); + return undef; } @@ -168,6 +171,16 @@ sub FRM_Read($) { return if(!$chash); $chash->{DeviceName}=$hash->{PORT}; # required for DevIo_CloseDev and FRM_Ready $chash->{TCPDev}=$chash->{CD}; + + # dispose preexisting connections + foreach my $e ( sort keys %main::defs ) { + if ( defined( my $dev = $main::defs{$e} )) { + if ( $dev != $chash && defined( $dev->{SNAME} ) && ( $dev->{SNAME} eq $chash->{SNAME} )) { + FRM_Tcp_Connection_Close($dev); + } + } + } + FRM_FirmataDevice_Close($hash); FRM_DoInit($chash); return; } @@ -180,13 +193,8 @@ sub FRM_Ready($) { my ($hash) = @_; my $name = $hash->{NAME}; if ($name=~/^^FRM:.+:\d+$/) { # this is a closed tcp-connection, remove it - TcpServer_Close($hash); - delete $main::defs{$hash->{SNAME}}{FirmataDevice} if (defined $hash->{SNAME} && defined $main::defs{$hash->{SNAME}}{FirmataDevice}); - my $dev = $hash->{DeviceName}; - delete $main::readyfnlist{"$name.$dev"}; - delete $main::attr{$name}; - delete $main::defs{$name}; - return undef; + FRM_Tcp_Connection_Close($hash); + FRM_FirmataDevice_Close($hash); } return DevIo_OpenDev($hash, 1, "FRM_DoInit") if($hash->{STATE} eq "disconnected"); @@ -199,6 +207,32 @@ sub FRM_Ready($) { return ($InBytes && $InBytes>0); } +sub FRM_Tcp_Connection_Close($) { + my $hash = shift; + TcpServer_Close($hash); + my $dev = $hash->{DeviceName}; + my $name = $hash->{NAME}; + if (defined $name) { + delete $main::readyfnlist{"$name.$dev"} if (defined $dev); + delete $main::attr{$name}; + delete $main::defs{$name}; + } + return undef; +} + +sub FRM_FirmataDevice_Close($) { + my $hash = shift; + my $device = $hash->{FirmataDevice}; + if (defined $device) { + if (defined $device->{io}) { + delete $hash->{FirmataDevice}->{io}->{handle} if defined $hash->{FirmataDevice}->{io}->{handle}; + delete $hash->{FirmataDevice}->{io}; + } + delete $device->{protocol} if defined $device->{protocol}; + delete $hash->{FirmataDevice}; + } +} + sub FRM_Attr(@) { my ($command,$name,$attribute,$value) = @_; if ($command eq "set") { @@ -252,7 +286,7 @@ sub FRM_DoInit($) { my $name = $hash->{SNAME}; #is this a serversocket-connection? my $shash = defined $name ? $main::defs{$name} : $hash; - $name = $hash->{NAME} if (!defined $name); + $name = $hash->{NAME};# if (!defined $name); my $firmata_io = Firmata_IO->new($hash); my $device = Device::Firmata::Platform->attach($firmata_io) or return 1; @@ -373,18 +407,20 @@ FRM_Init_Pin_Client($$$) { return $u unless defined $args and int(@$args) > 0; my $pin = @$args[0]; - foreach my $d ( sort keys %main::defs ) { - if ( defined( $main::defs{$d} ) - && defined( $main::defs{$d}{IODev} ) - && defined( $main::defs{$d}{PIN} ) - && $main::defs{$d}{IODev} == $hash->{IODev} - && $main::defs{$d}{PIN} == $pin ) { - die "Device $main::defs{$d}{NAME} allready defined for pin $pin"; - } - } - $hash->{PIN} = $pin; - eval { - FRM_Client_FirmataDevice($hash)->pin_mode($pin,$mode); + foreach my $d ( sort keys %main::defs ) { + if ( defined( my $dev = $main::defs{$d} )) { + if ( $dev != $hash + && defined( $dev->{IODev} ) + && defined( $dev->{PIN} ) + && $dev->{IODev} == $hash->{IODev} + && $dev->{PIN} == $pin ) { + die "Device $main::defs{$d}{NAME} allready defined for pin $pin"; + } + } + } + $hash->{PIN} = $pin; + eval { + FRM_Client_FirmataDevice($hash)->pin_mode($pin,$mode); }; if ($@) { main::Log(2,"FRM_Init error setting pin_mode: ".$@); @@ -403,6 +439,9 @@ FRM_Client_Define($$) $hash->{STATE}="defined"; AssignIoPort($hash); + if ( defined($hash->{IODev}) && defined($hash->{IODev}->{SNAME})) { + $hash->{IODev} = $main::defs{$hash->{IODev}->{SNAME}}; + } eval { FRM_Init_Client($hash,[@a[2..scalar(@a)-1]]); };