From 0945297d89fb261aeb716a24d9de37e0a0334c31 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 1 Dec 2002 11:25:22 +0100 Subject: Added the 'sky' plugin --- HISTORY | 2 + PLUGINS/src/sky/COPYING | 340 ++++++++++++++++++++++++++++++++++++++ PLUGINS/src/sky/HISTORY | 6 + PLUGINS/src/sky/Makefile | 82 +++++++++ PLUGINS/src/sky/README | 45 +++++ PLUGINS/src/sky/channels.conf.sky | 4 + PLUGINS/src/sky/getskyepg.pl | 200 ++++++++++++++++++++++ PLUGINS/src/sky/lircd.conf.sky | 299 +++++++++++++++++++++++++++++++++ PLUGINS/src/sky/sky.c | 243 +++++++++++++++++++++++++++ 9 files changed, 1221 insertions(+) create mode 100644 PLUGINS/src/sky/COPYING create mode 100644 PLUGINS/src/sky/HISTORY create mode 100644 PLUGINS/src/sky/Makefile create mode 100644 PLUGINS/src/sky/README create mode 100644 PLUGINS/src/sky/channels.conf.sky create mode 100755 PLUGINS/src/sky/getskyepg.pl create mode 100644 PLUGINS/src/sky/lircd.conf.sky create mode 100644 PLUGINS/src/sky/sky.c diff --git a/HISTORY b/HISTORY index cd8fdc72..6f9a0250 100644 --- a/HISTORY +++ b/HISTORY @@ -1834,3 +1834,5 @@ Video Disk Recorder Revision History housekeeping (suggested by Emil Naepflein). - Macros in 'keymacros.conf' can now use "@plugin" to directly access the main menu function of a given plugin (see man vdr(5) for details). +- The new plugin 'sky' can be used to integrate a Sky Digibox into the VDR system, + using a Kfir MPEG2 encoder card (see PLUGINS/src/sky/README for details). diff --git a/PLUGINS/src/sky/COPYING b/PLUGINS/src/sky/COPYING new file mode 100644 index 00000000..5b6e7c66 --- /dev/null +++ b/PLUGINS/src/sky/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/PLUGINS/src/sky/HISTORY b/PLUGINS/src/sky/HISTORY new file mode 100644 index 00000000..8be01f15 --- /dev/null +++ b/PLUGINS/src/sky/HISTORY @@ -0,0 +1,6 @@ +VDR Plugin 'sky' Revision History +--------------------------------- + +2002-12-01: Version 0.0.1 + +- Initial revision. diff --git a/PLUGINS/src/sky/Makefile b/PLUGINS/src/sky/Makefile new file mode 100644 index 00000000..4e1eb2f0 --- /dev/null +++ b/PLUGINS/src/sky/Makefile @@ -0,0 +1,82 @@ +# +# Makefile for a Video Disk Recorder plugin +# +# $Id: Makefile 1.1 2002/12/01 11:00:00 kls Exp $ + +# The official name of this plugin. +# This name will be used in the '-P...' option of VDR to load the plugin. +# By default the main source file also carries this name. +# +PLUGIN = sky + +### The version number of this plugin (taken from the main source file): + +VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g') + +### The C++ compiler and options: + +CXX = g++ +CXXFLAGS = -O2 -Wall -Woverloaded-virtual + +### The directory environment: + +DVBDIR = ../../../../DVB +VDRDIR = ../../.. +LIBDIR = ../../lib +TMPDIR = /tmp + +### Allow user defined options to overwrite defaults: + +-include $(VDRDIR)/Make.config + +### The version number of VDR (taken from VDR's "config.h"): + +VDRVERSION = $(shell grep 'define VDRVERSION ' $(VDRDIR)/config.h | awk '{ print $$3 }' | sed -e 's/"//g') + +### The name of the distribution archive: + +ARCHIVE = $(PLUGIN)-$(VERSION) +PACKAGE = vdr-$(ARCHIVE) + +### Includes and Defines (add further entries here): + +INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include + +DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' + +### The object files (add further files here): + +OBJS = $(PLUGIN).o + +### Implicit rules: + +%.o: %.c + $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = g++ -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +all: libvdr-$(PLUGIN).so + +libvdr-$(PLUGIN).so: $(OBJS) + $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ + @cp $@ $(LIBDIR)/$@.$(VDRVERSION) + +dist: clean + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @mkdir $(TMPDIR)/$(ARCHIVE) + @cp -a * $(TMPDIR)/$(ARCHIVE) + @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE) + @-rm -rf $(TMPDIR)/$(ARCHIVE) + @echo Distribution package created as $(PACKAGE).tgz + +clean: + @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ diff --git a/PLUGINS/src/sky/README b/PLUGINS/src/sky/README new file mode 100644 index 00000000..e3832791 --- /dev/null +++ b/PLUGINS/src/sky/README @@ -0,0 +1,45 @@ +This is a "plugin" for the Video Disk Recorder (VDR). + +Written by: Klaus Schmidinger + +Project's homepage: www.cadsoft.de/vdr + +Latest version available at: www.cadsoft.de/vdr + +See the file COPYING for license information. + +Description: + +The 'sky' plugin implements a new device for VDR, which is based on the +MPEG2 encoder card described at linuxtv.org/mpeg2/kfir.xml. It +allows you to connect the analog a/v output of your Sky Digibox to VDR, +so that you can enjoy the full recording flexibility of VDR with your +Sky subscription. Note that this is NOT something that does anything +illegal, like decrypting the Sky programme without a subscription. You +will need a Sky Digibox and a valid subscription in order to use this +plugin. + +The Digibox is remotely controlled through VDR via LIRC (see lirc.org). +The file lircd.conf.sky contains the remote control codes necessary to +control the Digibox. + +In order to access the Sky channels VDR needs to know the channel number +under which each channel is stored in the Sky Digibox. These numbers are +used as 'frequency' parameters in the channels.conf definitions of the Sky +channels (see the file 'channels.conf.sky'). Since these numbers are always +less than 1000, they can be easily distinguished from normal satellite +transponder frequencies. The VPID is 160 and the APID is 80 for all Sky +channels. These are just fake PIDs, since the Kfir card always uses these +fixed PIDs. The 'Ca' parameter of the Sky channels is set to 301, which +is defined as "Videoguard, Sky Digital" in VDR's 'ca.conf' file. Again, please +note that VDR doesn't do any decrypting here, this is just to mark these +channels as "conditionally accessible" and have a way of setting the CICAM +value for the Kfir device in VDR's Setup menu. + +The Sky EPG is available on the Internet at http://www.ananova.com. +The Perl script getskyepg.pl extracts the EPG data from these pages +and sends it to VDR via an SVDRP connection. The channel numbers Sky +uses to generate the EPG pages are stored as the 'sid' parameter in +the channels.conf definitions of the Sky channels. You can keep your +EPG data up-to-date by entering a call to getskyepg.pl into your +/etc/crontab. Call 'getskyepg.pl -h' for a list of options. diff --git a/PLUGINS/src/sky/channels.conf.sky b/PLUGINS/src/sky/channels.conf.sky new file mode 100644 index 00000000..f4a437be --- /dev/null +++ b/PLUGINS/src/sky/channels.conf.sky @@ -0,0 +1,4 @@ +Sky One:106:h:S28.2E:0:160:80:0:301:222 +itv2:226:h:S28.2E:0:160:80:0:301:451 +sci-fi:130:h:S28.2E:0:160:80:0:301:161 +Paramount Comedy:127:h:S28.2E:0:160:80:0:301:185 diff --git a/PLUGINS/src/sky/getskyepg.pl b/PLUGINS/src/sky/getskyepg.pl new file mode 100755 index 00000000..511d2f2c --- /dev/null +++ b/PLUGINS/src/sky/getskyepg.pl @@ -0,0 +1,200 @@ +#!/usr/bin/perl + +# getskyepg.pl: Get EPG data from Sky's web pages +# +# Connects to a running VDR instance via SVDRP, gets the channel data +# for the Sky channels and connects to Sky's web pages to extract the +# EPG data for these channels. The result is sent to VDR via SVDRP. +# +# See the README file for copyright information and how to reach the author. +# +# $Id: getskyepg.pl 1.1 2002/12/01 11:00:00 kls Exp $ + +use Getopt::Std; +use Time::Local; + +$Usage = qq{ +Usage: $0 [options] + +Options: -d hostname destination hostname (default: localhost) + -p port SVDRP port number (default: 2001) + -S source channel source (default: S28.2E) + -D days days to get EPG for (1..7, default: 2) +}; + +die $Usage if (!getopts("d:D:hp:S:") || $opt_h); + +$Dest = $opt_d || "localhost"; +$Port = $opt_p || 2001; +$Source = $opt_S || "S28.2E"; +$Days = $opt_D || 2; + +$SkyWebPage = "www.ananova.com/tv/frontpage.html"; +$WGET = "/usr/bin/wget -q -O-"; +$LOGGER = "/usr/bin/logger -t SKYEPG"; + +$DST = 0; ##XXX TODO find out whether DST is active! +$SecsInDay = 86400; + +$MaxFrequency = 1000; +$idxName = 0; +$idxFrequency = 1; +$idxSource = 3; +$idxSid = 9; + +Error("days out of range: $Days") unless (1 <= $Days && $Days <= 7); + +sub Log +{ + system("$LOGGER '@_'"); +} + +sub Error +{ + Log(@_); + die "$0: @_\n"; +} + +sub GetChannels +{ + SVDRPsend("LSTC"); + my @channels = (); + for (SVDRPreceive(250)) { + my @a = split(':', substr($_, 4)); + if ($a[$idxSource] eq $Source && $a[$idxFrequency] < $MaxFrequency) { + push(@channels, [@a]); + } + } + return @channels; +} + +sub GetPage +{ + my $channel = shift; + my $day = shift; + my $url = "$SkyWebPage?c=$channel&day=day$day"; + Log("reading $url"); + my @page = split("\n", `$WGET '$url'`); + Log("received " . ($#page + 1) . " lines"); + return @page; +} + +# In order to get the duration we need to buffer the last event: +$Id = ""; +$Time = 0; +$Title = ""; +$Episode = ""; +$Descr = ""; + +sub GetEpgData +{ + my ($channel, $channelID) = @_; + my $numEvents = 0; + SVDRPsend("C $channelID"); + $Time = 0; + for $day (1 .. $Days) { + my $dt = 0; + my $ap = ""; + my @page = GetPage($channel, $day); + for $line (@page) { + if ($line =~ /^<\/tr>(.*?)<\/b>.*?(.*?)<\/b> *(.*?<\/i>)? *(.*?) *<\/small>/); + my ($h, $m, $a) = ($time =~ /([0-9]+)\.([0-9]+)(.)m/); + # handle am/pm: + $dt = $SecsInDay if ($ap eq "p" && $a eq "a"); + $ap = $a; + $h += 12 if ($a eq "p" && $h < 12); + $h -= 12 if ($a eq "a" && $h == 12); + # convert to time_t: + my @gmt = gmtime; + $gmt[0] = 0; # seconds + $gmt[1] = $m; # minutes + $gmt[2] = $h; # hours + $time = timegm(@gmt) + ($day - 1) * $SecsInDay + $dt + $DST; + # create EPG data: + if ($Time) { + $duration = $time - $Time; + SVDRPsend("E $Id $Time $duration"); + SVDRPsend("T $Title"); + SVDRPsend("S $Episode"); + SVDRPsend("D $Descr"); + SVDRPsend("e"); + $numEvents++; + } + # buffer the last event: + $Id = $time / 60 % 0xFFFF; # this gives us unique ids for every minute of over 6 weeks + $Time = $time; + ($Title = $title) =~ s/<[^>]+>//g; + ($Episode = $episode) =~ s/<[^>]+>//g; + ($Descr = $descr) =~ s/<[^>]+>//g; + } + } + } + SVDRPsend("c"); + Log("generated $numEvents EPG events"); +} + +sub ProcessEpg +{ + Log("getting Sky channel definitions"); + my @channels = GetChannels(); + Error("no Sky channels found") unless @channels; + Log("found " . ($#channels + 1) . " channels"); + for (@channels) { + my $channel = @$_[$idxSid]; + my $channelID = "@$_[$idxSource]-0-@$_[$idxFrequency]-$channel"; + Log("processing channel @$_[0]"); + SVDRPsend("PUTE"); + SVDRPreceive(354); + GetEpgData($channel, $channelID); + SVDRPsend("."); + SVDRPreceive(250); + } + Log("done"); +} + +#--------------------------------------------------------------------------- +# TODO: make this a Perl module??? What about Error()??? + +use Socket; + +$Timeout = 300; # max. seconds to wait for response + +$SIG{ALRM} = sub { Error("timeout"); }; +alarm($Timeout); + +$iaddr = inet_aton($Dest) || Error("no host: $Dest"); +$paddr = sockaddr_in($Port, $iaddr); + +$proto = getprotobyname('tcp'); +socket(SOCK, PF_INET, SOCK_STREAM, $proto) || Error("socket: $!"); +connect(SOCK, $paddr) || Error("connect: $!"); +select(SOCK); $| = 1; +SVDRPreceive(220); +ProcessEpg(); +SVDRPsend("QUIT"); + +sub SVDRPsend +{ + my $s = shift; + print SOCK "$s\r\n"; +} + +sub SVDRPreceive +{ + my $expect = shift | 0; + my @a = (); + while () { + s/\s*$//; # 'chomp' wouldn't work with "\r\n" + push(@a, $_); + if (substr($_, 3, 1) ne "-") { + my $code = substr($_, 0, 3); + Error("expected SVDRP code $expect, but received $code") if ($code != $expect); + last; + } + } + return @a; +} + +#--------------------------------------------------------------------------- diff --git a/PLUGINS/src/sky/lircd.conf.sky b/PLUGINS/src/sky/lircd.conf.sky new file mode 100644 index 00000000..191dcb56 --- /dev/null +++ b/PLUGINS/src/sky/lircd.conf.sky @@ -0,0 +1,299 @@ +# Copyright (C) 1999 Christoph Bartelmus +# +# You may only use this file if you make it available to others, +# i.e. if you send it to +# +# this config file was automatically generated +# using lirc-0.6.4-CVS(serial) on Mon Jul 9 08:14:04 2001 +# +# contributed by Steve Davies +# +# brand: sky +# model no. of remote control: +# supported devices: 34000 20 +# +# + +begin remote + + name SKY + flags CONST_LENGTH|RAW_CODES + eps 30 + aeps 100 + ptrail 0 + repeat 0 0 + gap 149692 + frequency 36000 + duty_cycle 50 + + begin raw_codes + + name 0 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 + + name 1 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 888 + + name 2 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 888 888 + 444 + + name 3 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 888 444 + 444 + + name 4 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 888 888 444 444 + 444 + + name 5 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 888 888 888 + + name 6 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 888 444 444 888 + 444 + + name 7 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 888 444 444 444 + 444 + + name 8 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 888 888 444 444 444 444 + 444 + + name 9 + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 888 888 444 444 888 + + name RED + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 444 444 888 888 444 444 888 888 + + name GREEN + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 444 444 888 888 444 444 444 444 888 444 + + name YELLOW + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 444 444 888 888 444 444 444 444 444 444 + + name BLUE + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 444 444 444 444 888 444 444 444 444 444 444 + 444 + + name TEXT + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 888 444 444 444 444 444 444 888 444 444 + 444 + + name BACKUP + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 888 888 444 444 444 444 444 444 444 444 888 444 444 + + name HELP + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 888 888 444 444 444 444 444 444 444 444 444 444 888 + + name CURSOR-LEFT + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 888 888 444 444 888 888 888 444 + + name CURSOR-DOWN + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 888 888 444 444 888 444 444 888 + + name CURSOR-RIGHT + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 888 888 444 444 888 888 444 444 + + name CURSOR-UP + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 888 888 444 444 888 444 444 444 444 444 + + name SELECT + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 888 888 888 444 444 444 444 888 444 444 444 + + name CHANNEL-DOWN + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 888 888 444 444 444 444 444 444 888 + + name CHANNEL-UP + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 888 888 444 444 444 444 444 444 444 444 + 444 + + name I + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 888 444 444 888 444 444 888 888 888 444 444 + + name ONOFF + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 888 444 444 888 444 444 + 444 + + name SKY + 2664 888 444 444 444 444 444 888 444 888 888 444 444 444 444 444 + 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 444 + 444 444 888 888 444 444 444 444 444 444 444 444 444 444 444 444 + 444 + + name TV + 2830 724 583 333 553 339 + 548 791 543 795 977 357 + 527 364 524 367 524 368 + 522 369 521 370 520 371 + 519 372 519 372 519 372 + 518 372 518 374 963 818 + 516 376 510 381 509 382 + 954 828 508 407 481 + + name SKY + 2829 726 580 336 551 340 + 547 791 540 798 977 366 + 519 364 523 367 521 370 + 521 370 520 371 520 371 + 520 371 519 372 518 373 + 517 374 517 374 957 825 + 512 379 512 380 513 377 + 511 381 506 410 477 413 + 483 + + name MUTE + 2567 429 751 447 743 456 + 1335 464 734 466 1325 496 + 697 504 693 506 1284 513 + 681 518 681 517 679 520 + 678 26288 2533 462 734 489 + 705 470 1323 501 695 503 + 1287 511 683 516 683 518 + 1277 522 676 521 678 521 + 675 523 675 26286 2533 465 + 731 491 702 499 1293 504 + 692 507 1280 518 683 516 + 679 524 1272 522 675 529 + 670 523 682 517 675 26286 + 2532 465 729 493 702 473 + 1318 506 688 509 1282 517 + 680 519 677 524 1274 523 + 676 + + name VOLUME-UP + 2568 430 766 433 1342 456 + 734 489 708 466 1326 497 + 699 505 686 508 1286 512 + 688 510 683 516 682 516 + 681 26284 2540 481 711 488 + 1301 498 703 495 695 504 + 1284 516 682 516 684 515 + 1276 522 675 523 675 524 + 674 524 675 26286 2532 490 + 709 489 1300 500 689 509 + 695 517 1270 516 683 520 + 675 519 1274 529 668 525 + 675 524 673 526 672 26288 + 2532 466 731 491 1300 499 + 695 503 692 509 1277 520 + 681 518 679 519 1278 520 + 675 + + name VOLUME-DOWN + 2562 434 1348 451 1332 465 + 733 489 704 496 1296 504 + 690 507 694 511 1281 511 + 683 523 677 515 679 520 + 680 25687 2533 464 1330 491 + 1295 505 693 506 689 510 + 1293 505 684 516 678 520 + 1276 523 677 520 675 524 + 673 526 674 25686 2531 467 + 1324 498 1292 506 691 509 + 683 515 1280 518 678 521 + 675 523 1273 525 674 527 + 672 525 673 527 671 25685 + 2531 467 1320 501 1288 511 + 687 511 688 512 1282 516 + 678 521 675 524 1273 + + name TVGUIDE + 2834 720 586 330 554 338 + 548 794 539 796 975 360 + 528 363 521 371 519 371 + 520 371 519 375 514 374 + 517 374 516 375 513 379 + 511 380 510 381 949 387 + 500 836 505 387 945 391 + 493 868 469 422 468 + + name BOXOFFICE + 2833 745 564 329 555 338 + 548 790 545 793 982 352 + 529 362 526 365 522 370 + 519 371 519 372 519 372 + 518 373 517 374 513 378 + 515 376 507 384 506 385 + 945 390 496 396 498 392 + 496 419 468 847 936 + + name SERVICES + 2829 725 585 330 555 338 + 548 798 537 794 979 356 + 528 368 522 363 523 369 + 521 370 521 370 520 370 + 520 371 520 371 520 371 + 519 372 519 372 518 373 + 964 371 517 375 513 377 + 511 404 489 402 485 828 + 514 + + name INTERACTIVE + 2829 726 591 324 553 340 + 550 788 542 796 981 354 + 532 359 522 369 522 369 + 520 372 518 373 518 373 + 516 375 515 375 513 379 + 515 375 510 381 948 389 + 498 392 504 412 470 867 + 916 866 913 + + end raw_codes + +end remote diff --git a/PLUGINS/src/sky/sky.c b/PLUGINS/src/sky/sky.c new file mode 100644 index 00000000..627a9451 --- /dev/null +++ b/PLUGINS/src/sky/sky.c @@ -0,0 +1,243 @@ +/* + * sky.c: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: sky.c 1.1 2002/12/01 11:00:00 kls Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include + +static const char *VERSION = "0.0.1"; +static const char *DESCRIPTION = "Sky Digibox interface"; + +// --- cDigiboxDevice -------------------------------------------------------- + +class cDigiboxDevice : public cDevice { +private: + int source; + int digiboxChannelNumber; + int fd_dvr; + cTSBuffer *tsBuffer; + int fd_lirc; + void LircSend(const char *s); + void LircSend(int n); +protected: + virtual bool SetPid(cPidHandle *Handle, int Type, bool On); + virtual bool OpenDvr(void); + virtual void CloseDvr(void); + virtual bool GetTSPacket(uchar *&Data); +public: + cDigiboxDevice(void); + virtual ~cDigiboxDevice(); + virtual bool ProvidesSource(int Source) const; + virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsSetChannel = NULL) const; + virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); + }; + +cDigiboxDevice::cDigiboxDevice(void) +{ + source = cSource::FromString("S28.2E");//XXX parameter??? + digiboxChannelNumber = 0; + fd_dvr = -1; + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + strn0cpy(addr.sun_path, "/dev/lircd", sizeof(addr.sun_path));//XXX parameter??? + fd_lirc = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd_lirc >= 0) { + if (connect(fd_lirc, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + LOG_ERROR; + close(fd_lirc); + } + } + else + LOG_ERROR; +} + +cDigiboxDevice::~cDigiboxDevice() +{ + if (fd_lirc >= 0) + close(fd_lirc); +} + +void cDigiboxDevice::LircSend(const char *s) +{ + const char *c = "SEND_ONCE SKY %s\n"; + char buf[100]; + sprintf(buf, c, s); + dsyslog(buf);//XXX + if (write(fd_lirc, buf, strlen(buf)) < 0) + LOG_ERROR;//XXX _STR + delay_ms(200); +} + +void cDigiboxDevice::LircSend(int n) +{ + char buf[10]; + snprintf(buf, sizeof(buf), "%d", n); + char *p = buf; + while (*p) { + char q[10]; + sprintf(q, "%c", *p); + LircSend(q); + p++; + } +} + +bool cDigiboxDevice::SetPid(cPidHandle *Handle, int Type, bool On) +{ + dsyslog("SetPid %d %d", Handle->pid, On); + return true; +} + +bool cDigiboxDevice::OpenDvr(void) +{ + CloseDvr(); + fd_dvr = open("/dev/video2", O_RDONLY | O_NONBLOCK);//XXX parameter??? + if (fd_dvr >= 0) + tsBuffer = new cTSBuffer(fd_dvr, KILOBYTE(256), CardIndex() + 1); + return fd_dvr >= 0; +} + +void cDigiboxDevice::CloseDvr(void) +{ + if (fd_dvr >= 0) { + close(fd_dvr); + fd_dvr = -1; + delete tsBuffer; + tsBuffer = NULL; + } +} + +bool cDigiboxDevice::GetTSPacket(uchar *&Data) +{ + if (tsBuffer) { + int r = tsBuffer->Read(); + if (r >= 0) { + Data = tsBuffer->Get(); + return true; + } + else if (FATALERRNO) { + LOG_ERROR; + return false; + } + return true; + } + return false; +} + +bool cDigiboxDevice::ProvidesSource(int Source) const +{ + return source == Source; +} + +bool cDigiboxDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const +{ + bool result = false; + bool hasPriority = Priority < 0 || Priority > this->Priority(); + bool needsDetachReceivers = true; + + if (ProvidesSource(Channel->Source()) && ProvidesCa(Channel->Ca())) { + if (Receiving()) { + if (digiboxChannelNumber == Channel->Frequency()) { + needsDetachReceivers = false; + result = true; + } + else + result = hasPriority; + } + else + result = hasPriority; + } + if (NeedsDetachReceivers) + *NeedsDetachReceivers = needsDetachReceivers; + return result; +} + +bool cDigiboxDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) +{ + if (fd_lirc >= 0 && !Receiving()) { // if we are receiving the channel is already set! + digiboxChannelNumber = Channel->Frequency(); + //XXX only when recording??? -> faster channel switching! + LircSend("SKY"); // makes sure the Digibox is "on" + //XXX lircprint(fd_lirc, "BACKUP"); + //XXX lircprint(fd_lirc, "BACKUP"); + //XXX lircprint(fd_lirc, "BACKUP"); + LircSend(digiboxChannelNumber); + } +return true; +} + +// --- cPluginSky ------------------------------------------------------------ + +class cPluginSky : public cPlugin { +private: + // Add any member variables or functions you may need here. +public: + cPluginSky(void); + virtual ~cPluginSky(); + virtual const char *Version(void) { return VERSION; } + virtual const char *Description(void) { return DESCRIPTION; } + virtual const char *CommandLineHelp(void); + virtual bool ProcessArgs(int argc, char *argv[]); + virtual bool Start(void); + virtual void Housekeeping(void); + virtual cMenuSetupPage *SetupMenu(void); + virtual bool SetupParse(const char *Name, const char *Value); + }; + +cPluginSky::cPluginSky(void) +{ + // Initialize any member variables here. + // DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL + // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! +} + +cPluginSky::~cPluginSky() +{ + // Clean up after yourself! +} + +const char *cPluginSky::CommandLineHelp(void) +{ + // Return a string that describes all known command line options. + return NULL; +} + +bool cPluginSky::ProcessArgs(int argc, char *argv[]) +{ + // Implement command line argument processing here if applicable. + return true; +} + +bool cPluginSky::Start(void) +{ + // Start any background activities the plugin shall perform. + new cDigiboxDevice; + return true; +} + +void cPluginSky::Housekeeping(void) +{ + // Perform any cleanup or other regular tasks. +} + +cMenuSetupPage *cPluginSky::SetupMenu(void) +{ + // Return a setup menu in case the plugin supports one. + return NULL; +} + +bool cPluginSky::SetupParse(const char *Name, const char *Value) +{ + // Parse your own setup parameters and store their values. + return false; +} + +VDRPLUGINCREATOR(cPluginSky); // Don't touch this! -- cgit v1.2.3