2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 23:06:37 +00:00

SONOS: Change SubProcess-checking routine. Change logging.

git-svn-id: https://svn.fhem.de/fhem/trunk@15823 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
Reinerlein 2018-01-07 22:42:45 +00:00
parent 6cec652fc3
commit 4bd8f000f8
3 changed files with 65 additions and 28 deletions

View File

@ -1,6 +1,6 @@
######################################################################################## ########################################################################################
# #
# SONOS.pm (c) by Reiner Leins, December 2017 # SONOS.pm (c) by Reiner Leins, January 2018
# rleins at lmsoft dot de # rleins at lmsoft dot de
# #
# $Id$ # $Id$
@ -51,6 +51,10 @@
# Changelog (last 4 entries only, see Wiki for complete changelog) # Changelog (last 4 entries only, see Wiki for complete changelog)
# #
# SVN-History: # SVN-History:
# 07.01.2018
# Der Initialwert von LastProcessAnswer (wird beim Start auf 0 gesetzt) wird nun korrekt berücksichtigt
# Bei ignoredIPs und bei usedOnlyIPs kann jetzt für jedes Komma-Getrennte Element auch ein regulärer Ausdruck stehen. Wird mit // umschlossen, und darf keine Doppelpunkte enthalten.
# Logausgabe im UPnP-Modul, welche Devices mit welchen Header-Angaben nun akzeptiert wurden (Ausgabe auf Level 5)
# 23.12.2017 # 23.12.2017
# Subscriptions-Refresh umgebaut. # Subscriptions-Refresh umgebaut.
# Devicenamen mit Punkt (.) funktionieren nun. # Devicenamen mit Punkt (.) funktionieren nun.
@ -66,8 +70,6 @@
# 14.07.2017 # 14.07.2017
# Änderung in der ControlPoint.pm: Es wurden zuviele Suchantworten berücksichtigt. # Änderung in der ControlPoint.pm: Es wurden zuviele Suchantworten berücksichtigt.
# Bei einem Modify wird von Fhem nur die DefFn aufgerufen (und nicht vorher UndefFn). Dadurch blieben Reste, die aber vor einer Definition aufgeräumt werden müssen. Resultat war eine 100%-CPU-Last. # Bei einem Modify wird von Fhem nur die DefFn aufgerufen (und nicht vorher UndefFn). Dadurch blieben Reste, die aber vor einer Definition aufgeräumt werden müssen. Resultat war eine 100%-CPU-Last.
# 09.07.2017
# BulkUpdate: Beginn und Ende sind nun sicher davor einen vom SubProzess gestarteten BulkUpdate vorzeitig zu beenden.
# #
######################################################################################## ########################################################################################
# #
@ -133,8 +135,8 @@ no if $] >= 5.017011, warnings => 'experimental::smartmatch';
# IP-Adressen, die vom UPnP-Modul ignoriert werden sollen. # IP-Adressen, die vom UPnP-Modul ignoriert werden sollen.
# Diese können über ein Attribut gesetzt werden. # Diese können über ein Attribut gesetzt werden.
######################################################## ########################################################
my %ignoredIPs = (); my @ignoredIPs = ();
my %usedonlyIPs = (); my @usedonlyIPs = ();
my $reusePort = 0; my $reusePort = 0;
@ -1943,7 +1945,7 @@ sub SONOS_IsSubprocessAliveChecker() {
SONOS_DoWork('undef', 'refreshProcessAnswer') if ($lastProcessAnswer < time() - $hash->{INTERVAL}); SONOS_DoWork('undef', 'refreshProcessAnswer') if ($lastProcessAnswer < time() - $hash->{INTERVAL});
# Wenn die letzte Antwort zu lange her ist, dann den SubProzess neustarten... # Wenn die letzte Antwort zu lange her ist, dann den SubProzess neustarten...
if ($lastProcessAnswer < time() - (4 * $hash->{INTERVAL})) { if (($lastProcessAnswer != 0) && ($lastProcessAnswer < time() - (4 * $hash->{INTERVAL}))) {
# Verbindung beenden, damit der SubProzess die Chance hat neu initialisiert zu werden... # Verbindung beenden, damit der SubProzess die Chance hat neu initialisiert zu werden...
SONOS_Log $hash->{UDN}, 2, 'LastProcessAnswer way too old (Lastanswer: '.$lastProcessAnswer.' ~ '.SONOS_GetTimeString($lastProcessAnswer).')... try to restart the process and connection...'; SONOS_Log $hash->{UDN}, 2, 'LastProcessAnswer way too old (Lastanswer: '.$lastProcessAnswer.' ~ '.SONOS_GetTimeString($lastProcessAnswer).')... try to restart the process and connection...';
@ -2390,7 +2392,7 @@ sub SONOS_Discover() {
$SONOS_RestartControlPoint = 0; $SONOS_RestartControlPoint = 0;
eval { eval {
$SONOS_Controlpoint = UPnP::ControlPoint->new(SearchPort => 0, SubscriptionPort => 0, SubscriptionURL => '/fhemmodule', MaxWait => 30, UsedOnlyIP => \%usedonlyIPs, IgnoreIP => \%ignoredIPs, ReusePort => $reusePort); $SONOS_Controlpoint = UPnP::ControlPoint->new(SearchPort => 0, SubscriptionPort => 0, SubscriptionURL => '/fhemmodule', MaxWait => 30, LogLevel => $SONOS_Client_LogLevel, UsedOnlyIP => \@usedonlyIPs, IgnoreIP => \@ignoredIPs, ReusePort => $reusePort);
$SONOS_Search = $SONOS_Controlpoint->searchByType('urn:schemas-upnp-org:device:ZonePlayer:1', \&SONOS_Discover_Callback); $SONOS_Search = $SONOS_Controlpoint->searchByType('urn:schemas-upnp-org:device:ZonePlayer:1', \&SONOS_Discover_Callback);
#$SONOS_Controlpoint->handle; #$SONOS_Controlpoint->handle;
@ -5001,7 +5003,7 @@ sub SONOS_RestoreOldPlaystate() {
SONOS_Log undef, 1, 'Restore-Thread gestartet. Warte auf Arbeit...'; SONOS_Log undef, 1, 'Restore-Thread gestartet. Warte auf Arbeit...';
my $runEndlessLoop = 1; my $runEndlessLoop = 1;
my $controlPoint = UPnP::ControlPoint->new(SearchPort => 0, SubscriptionPort => 0, SubscriptionURL => '/fhemmodule', MaxWait => 20, UsedOnlyIP => \%usedonlyIPs, IgnoreIP => \%ignoredIPs, ReusePort => $reusePort); my $controlPoint = UPnP::ControlPoint->new(SearchPort => 0, SubscriptionPort => 0, SubscriptionURL => '/fhemmodule', MaxWait => 20, LogLevel => $SONOS_Client_LogLevel, UsedOnlyIP => \@usedonlyIPs, IgnoreIP => \@ignoredIPs, ReusePort => $reusePort);
$SIG{'PIPE'} = 'IGNORE'; $SIG{'PIPE'} = 'IGNORE';
$SIG{'CHLD'} = 'IGNORE'; $SIG{'CHLD'} = 'IGNORE';
@ -10067,17 +10069,11 @@ sub SONOS_Client_ConsumeMessage($$) {
$SONOS_Client_LogfileName = $3; $SONOS_Client_LogfileName = $3;
$SONOS_Client_Data{pingType} = $4; $SONOS_Client_Data{pingType} = $4;
my @usedonlyIPs = split(/,/, $5); @usedonlyIPs = split(/,/, $5);
$SONOS_Client_Data{usedonlyIPs} = shared_clone(\@usedonlyIPs); $SONOS_Client_Data{usedonlyIPs} = shared_clone(\@usedonlyIPs);
for my $elem (@usedonlyIPs) {
$usedonlyIPs{SONOS_Trim($elem)} = 1;
}
my @ignoredIPs = split(/,/, $6); @ignoredIPs = split(/,/, $6);
$SONOS_Client_Data{ignoredIPs} = shared_clone(\@ignoredIPs); $SONOS_Client_Data{ignoredIPs} = shared_clone(\@ignoredIPs);
for my $elem (@ignoredIPs) {
$ignoredIPs{SONOS_Trim($elem)} = 1;
}
$reusePort = $7; $reusePort = $7;

View File

@ -1,6 +1,6 @@
######################################################################################## ########################################################################################
# #
# SONOSPLAYER.pm (c) by Reiner Leins, December 2017 # SONOSPLAYER.pm (c) by Reiner Leins, January 2018
# rleins at lmsoft dot de # rleins at lmsoft dot de
# #
# $Id$ # $Id$

View File

@ -48,8 +48,47 @@ use constant DEFAULT_SSDP_SEARCH_PORT => 8008;
use constant DEFAULT_SUBSCRIPTION_PORT => 8058; use constant DEFAULT_SUBSCRIPTION_PORT => 8058;
use constant DEFAULT_SUBSCRIPTION_URL => '/eventSub'; use constant DEFAULT_SUBSCRIPTION_URL => '/eventSub';
our %IGNOREIP; our @IGNOREIP;
our %USEDONLYIP; our @USEDONLYIP;
our $LogLevel;
sub isIgnoreIP($) {
my($ip) = @_;
foreach my $elem (@IGNOREIP) {
if ($elem =~ m/^\/(.*)\/$/) {
if ($ip =~ m/^$1$/) {
return 1;
}
} else {
if ($ip eq $elem) {
return 1;
}
}
}
return 0;
}
sub isUsedOnlyIP($) {
my($ip) = @_;
return 1 if (!scalar(@USEDONLYIP));
foreach my $elem (@USEDONLYIP) {
if ($elem =~ m/^\/(.*)\/$/) {
if ($ip =~ m/^$1$/) {
return 1;
}
} else {
if ($ip eq $elem) {
return 1;
}
}
}
return 0;
}
sub new { sub new {
my($self, %args) = @_; my($self, %args) = @_;
@ -60,8 +99,9 @@ sub new {
my $searchPort = defined($args{SearchPort}) ? $args{SearchPort} : DEFAULT_SSDP_SEARCH_PORT; my $searchPort = defined($args{SearchPort}) ? $args{SearchPort} : DEFAULT_SSDP_SEARCH_PORT;
my $subscriptionPort = defined($args{SubscriptionPort}) ? $args{SubscriptionPort} : DEFAULT_SUBSCRIPTION_PORT; my $subscriptionPort = defined($args{SubscriptionPort}) ? $args{SubscriptionPort} : DEFAULT_SUBSCRIPTION_PORT;
my $maxWait = $args{MaxWait} || 3; my $maxWait = $args{MaxWait} || 3;
%IGNOREIP = %{$args{IgnoreIP}}; @IGNOREIP = @{$args{IgnoreIP}};
%USEDONLYIP = %{$args{UsedOnlyIP}}; @USEDONLYIP = @{$args{UsedOnlyIP}};
$LogLevel = $args{LogLevel} || 0;
my $reuseport = $args{ReusePort}; my $reuseport = $args{ReusePort};
$reuseport = 0 if (!defined($reuseport)); $reuseport = 0 if (!defined($reuseport));
@ -187,8 +227,8 @@ sub handleOnce {
} }
elsif ($socket == $self->{_subscriptionSocket}) { elsif ($socket == $self->{_subscriptionSocket}) {
if (my $connect = $socket->accept()) { if (my $connect = $socket->accept()) {
return if (scalar(%USEDONLYIP) && (!$USEDONLYIP{$connect->peerhost()})); return if (!isUsedOnlyIP($connect->peerhost()));
return if ($IGNOREIP{$connect->peerhost()}); return if (isIgnoreIP($connect->peerhost()));
$self->_receiveSubscriptionNotification($connect); $self->_receiveSubscriptionNotification($connect);
} }
} }
@ -391,8 +431,8 @@ sub _receiveSearchResponse {
my $peer = recv($socket, $buf, 2048, 0); my $peer = recv($socket, $buf, 2048, 0);
my @peerdata = unpack_sockaddr_in($peer); my @peerdata = unpack_sockaddr_in($peer);
return if (scalar(%USEDONLYIP) && (!$USEDONLYIP{inet_ntoa($peerdata[1])})); return if (!isUsedOnlyIP(inet_ntoa($peerdata[1])));
return if ($IGNOREIP{inet_ntoa($peerdata[1])}); return if (isIgnoreIP(inet_ntoa($peerdata[1])));
if ($buf !~ /\015?\012\015?\012/) { if ($buf !~ /\015?\012\015?\012/) {
return; return;
@ -409,6 +449,7 @@ sub _receiveSearchResponse {
foreach my $searchkey (keys %{$self->{_activeSearches}}) { foreach my $searchkey (keys %{$self->{_activeSearches}}) {
my $search = $self->{_activeSearches}->{$searchkey}; my $search = $self->{_activeSearches}->{$searchkey};
if ($search->{_type} && $buf =~ $search->{_type}) { if ($search->{_type} && $buf =~ $search->{_type}) {
print 'xxxx.xx.xx xx:xx:xx 5: ControlPoint: Accepted Search-Response: "'.$buf.'"'."\n" if ($LogLevel >= 5);
$found = 1; $found = 1;
last; last;
} }
@ -426,7 +467,7 @@ sub _receiveSearchResponse {
} }
if (! $found) { if (! $found) {
#print "Unknown response: " . Dumper($buf); #ALW uncomment print 'xxxx.xx.xx xx:xx:xx 5: ControlPoint: Unknown Search-Response: "'.$buf.'"'."\n" if ($LogLevel >= 5);
return; return;
} }
@ -454,8 +495,8 @@ sub _receiveSSDPEvent {
my @peerdata = unpack_sockaddr_in($peer); my @peerdata = unpack_sockaddr_in($peer);
return if (!@peerdata); return if (!@peerdata);
return if (scalar(%USEDONLYIP) && (!$USEDONLYIP{inet_ntoa($peerdata[1])})); return if (!isUsedOnlyIP(inet_ntoa($peerdata[1])));
return if ($IGNOREIP{inet_ntoa($peerdata[1])}); return if (isIgnoreIP(inet_ntoa($peerdata[1])));
if ($buf !~ /\015?\012\015?\012/) { if ($buf !~ /\015?\012\015?\012/) {
return; return;