summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Reimer <manuel.reimer@gmx.de>2019-07-20 08:06:19 (GMT)
committerManuel Reimer <manuel.reimer@gmx.de>2019-07-20 08:06:19 (GMT)
commit8d73a7c7e7cb4026f4c3b35308686701d925bef2 (patch)
treefa41a324ff26b8c030ff9ce1d687cfae01c52e83
parente87f3a99008b2324f805c5f43134ecbe50c7559f (diff)
downloadvdrpbd-8d73a7c7e7cb4026f4c3b35308686701d925bef2.tar.gz
vdrpbd-8d73a7c7e7cb4026f4c3b35308686701d925bef2.tar.bz2
Add Kodi support
-rwxr-xr-xvdrpbd76
-rw-r--r--vdrpbd.conf5
-rw-r--r--vdrpbd.conf.pod4
3 files changed, 60 insertions, 25 deletions
diff --git a/vdrpbd b/vdrpbd
index cbd7a65..5d2b035 100755
--- a/vdrpbd
+++ b/vdrpbd
@@ -23,7 +23,7 @@ use threads;
use Thread::Queue;
use Sys::Syslog qw(:standard :macros);
use Fcntl qw(LOCK_EX LOCK_NB LOCK_UN);
-use Socket;
+use IO::Socket::IP;
use FileHandle;
use constant {EVIOCGRAB => 0x40044590, EV_KEY => 1, KEY_POWER => 116};
my $HAVE_DBUS = eval {require Net::DBus;};
@@ -35,7 +35,8 @@ my $CFGFILE = '/etc/vdrpbd.conf';
my $FHPID;
my %CONF = (
ER_COUNT => 4, # Number of keypresses and ...
- ER_TIME => 3 # ... timerange in seconds for emergency reboot
+ ER_TIME => 3, # ... timerange in seconds for emergency reboot
+ TARGET => 'svdrp' # Target to send the power button event to
);
my $KEYQUEUE = Thread::Queue->new();
@@ -53,7 +54,11 @@ my $KEYQUEUE = Thread::Queue->new();
# Read config
ParseConfig();
- if ($CONF{USE_DBUS} && !$HAVE_DBUS) {
+ $CONF{TARGET} = 'dbus' if ($CONF{USE_DBUS}); # Legacy "USE_DBUS" option
+ if ($CONF{TARGET} !~ /^(svdrp|dbus|kodi)$/) {
+ die("Invalid value for TARGET in $CFGFILE!\n");
+ }
+ if ($CONF{TARGET} eq 'dbus' && !$HAVE_DBUS) {
die("DBus support requested but no Net::DBus module present!\n");
}
if ($CONF{ER_COUNT} !~ /^[0-9]+$/ || $CONF{ER_COUNT} < 2) {
@@ -113,10 +118,18 @@ my $KEYQUEUE = Thread::Queue->new();
Cleanup();
}
-# Worker thread. Tries to forward enqueued keypresses to VDR.
+# Worker thread. Tries to forward enqueued keypresses to VDR/Kodi.
sub KeyProcessor {
while ($KEYQUEUE->dequeue()) {
- $CONF{USE_DBUS} ? SendDBus() : SendSVDRP();
+ if ($CONF{TARGET} eq 'dbus') {
+ SendDBus();
+ }
+ elsif ($CONF{TARGET} eq 'kodi') {
+ SendKodi();
+ }
+ else {
+ SendSVDRP();
+ }
}
}
@@ -192,27 +205,38 @@ sub GetButtonDevice {
return "/dev/input/$event";
}
-sub SendSVDRP {
+# Establishes local TCP connection.
+# Parameters:
+# aPort: Port to connect to
+# Return values:
+# Connected socket on success
+# undef on error
+sub ConnectTCP {
my $timeout = 15; # Socket timeout in seconds
- my $port = getservbyname('svdrp', 'tcp') || 6419;
-
- # Prepare socket and connect to VDR
- my $sh;
- unless (socket($sh, PF_INET, SOCK_STREAM, getprotobyname('tcp'))) {
- warn("svdrp: $!");
- return;
- }
- setsockopt($sh, SOL_SOCKET, SO_SNDTIMEO, pack('L!L!', $timeout, 0) ) or
- warn("svdrp: $!");
- setsockopt($sh, SOL_SOCKET, SO_RCVTIMEO, pack('L!L!', $timeout, 0) ) or
- warn("svdrp: $!");
- unless(connect($sh, sockaddr_in($port, INADDR_LOOPBACK))) {
- warn("svdrp: $!");
+ my ($aPort) = @_;
+
+ my $sock = IO::Socket::IP->new(
+ PeerHost => 'localhost',
+ PeerPort => $aPort,
+ Type => SOCK_STREAM,
+ Timeout => $timeout
+ );
+
+ # Connection failed
+ if (!$sock) {
+ warn("ConnectTCP: $!");
return;
}
+ $sock->autoflush(1);
+ return $sock;
+}
+
+sub SendSVDRP {
+ my $port = getservbyname('svdrp', 'tcp') || 6419;
+ my $sh = ConnectTCP($port) or return;
+
# Send power button event
- $sh->autoflush(1);
print $sh "HITK POWER\nQUIT\n"; # Send full command sequence at once!
my @reply = <$sh>;
if ($!) { # Read timed out
@@ -228,6 +252,12 @@ sub SendSVDRP {
}
}
+sub SendKodi {
+ my $sock = ConnectTCP(9090);
+ print $sock '{"jsonrpc":"2.0","method":"System.Shutdown","id":1}';
+ # TODO: Do some "error tracking" here (read back feedback from Kodi?)
+}
+
# This one requires the "dbus2vdr-plugin" to be installed.
sub SendDBus {
eval {
@@ -280,6 +310,10 @@ B<vdrpbd> is a ACPI power button handling daemon, which has been created with a
The usual downside of this is, that a hanging VDR process makes the power button useless for shutting down the system cleanly. You either have to do a shutdown via remote access or, if available, via terminal on your TV. To address this issue, B<vdrpbd> has a "emergency reboot" feature. If you press the power button four times within three seconds, then the daemon triggers a system reboot to bring your system back to a working state in a clean, easy and fast way.
+=head1 KODI SUPPORT
+
+B<vdrpbd> supports Kodi as frontend for Linux HTPC systems. This doesn't require you to use VDR as PVR backend or any PVR backend at all. To have the power button sent to Kodi, just set B<TARGET> in vdrpbd.conf to B<kodi>.
+
=head2 Command Switches
Switches include:
diff --git a/vdrpbd.conf b/vdrpbd.conf
index 87bacdf..a7c7463 100644
--- a/vdrpbd.conf
+++ b/vdrpbd.conf
@@ -4,5 +4,6 @@
# ... time range in seconds to trigger emergency reboot
#ER_TIME=3
-# Set this to 1 if you want to dbus2vdr plugin to send the power button event
-#USE_DBUS=0
+# Set this to "dbus" to send power button event via dbus2vdr plugin
+# Set this to "kodi" to send power button event to Kodi via TCP
+#TARGET=svdrp
diff --git a/vdrpbd.conf.pod b/vdrpbd.conf.pod
index c2b24a3..dd3c1f3 100644
--- a/vdrpbd.conf.pod
+++ b/vdrpbd.conf.pod
@@ -23,11 +23,11 @@ These two variables customize the key sequence that has to be pressed to trigger
=back
- USE_DBUS=0
+ TARGET=svdrp
=over 5
-If you set this to 1, then the power button event is sent to VDR using "dbus" and not using SVDRP. This requires the dbus2vdr plugin to be loaded in VDR and the "Net::DBus" Perl module has to exist on your system.
+This allows you to define the target for the power button event. Default is B<svdrp> for sending to a running VDR daemon using the SVDRP protocol. Set to B<dbus> to send to VDR via dbus. This requires the dbus2vdr plugin to be loaded in VDR and the "Net::DBus" Perl module has to exist on your system. Set to B<kodi> to send to a running Kodi process via TCP.
=back