mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Modified channel handling; full DiSEqC support
This commit is contained in:
		| @@ -185,6 +185,7 @@ Wolfgang Henselmann-Weiss <Wolfgang_Henselmann@betaresearch.de> | ||||
|  | ||||
| Uwe Scheffler <UweScheffler@t-online.de> | ||||
|  for his help in keeping 'channels.conf.cable' up to date | ||||
|  for helping to test new DVB-T handling | ||||
|  | ||||
| Matjaz Thaler <matjaz.thaler@guest.arnes.si> | ||||
|  for improving AC3 decoding when replaying DVDs | ||||
| @@ -407,3 +408,10 @@ Jeremy Hall <jhall@UU.NET> | ||||
|  | ||||
| Oliver Endriss <o.endriss@gmx.de> | ||||
|  for fixing a missing Flush() call in the remote control learning procedure | ||||
|  for helping to test and debug the new channel source and DiSEqC handling | ||||
|  | ||||
| Reinhard Walter Buchner <rw.buchner@freenet.de> | ||||
|  for adding some satellites to 'sources.conf' | ||||
|  | ||||
| Lauri Tischler <lauri.tischler@efore.fi> | ||||
|  for helping to test and debug the new channel source and DiSEqC handling | ||||
|   | ||||
							
								
								
									
										33
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -1536,7 +1536,38 @@ Video Disk Recorder Revision History | ||||
| - Avoiding restarts due to 'panic level' when switching channels on the primary | ||||
|   device during EPG scan. | ||||
|  | ||||
| 2002-09-30: Version 1.1.12 | ||||
| 2002-10-06: Version 1.1.12 | ||||
|  | ||||
| - Fixed a missing Flush() call in the remote control learning procedure (thanks | ||||
|   to Oliver Endriss). | ||||
| - Modified channel handling to cover all parameters necessary for DVB-C and DVB-T | ||||
|   (see man vdr(5) for the meaning of the additional parameters stored in the field | ||||
|   previously named 'polarisation'). Thanks to Uwe Scheffler for testing. | ||||
|   If you have a system with different kinds of DVB cards, like DVB-T and DVB-C, | ||||
|   for instance, there is no more need to distinguish the channels through the | ||||
|   'Ca' parameter in order to assign them to the various DVB cards. This is now | ||||
|   taken care of by the "source" parameter. So a channel marked as "terrestrial", | ||||
|   for example, will only be received on DVB-T cards. | ||||
|   Note that the cChannel class has been moved into a separate file (channels.[ch]), | ||||
|   and that all data members have been made private and are now only accessible | ||||
|   through member functions. You may have to change any plugin code that accesses | ||||
|   cChannel data accordingly. | ||||
| - The new configuration file 'sources.conf' contains the various signal sources | ||||
|   (satellites, cable and terrestrial) which are used in 'channels.conf' and | ||||
|   'diseqc.conf' (thanks to Reinhard Walter Buchner for adding some satellites to | ||||
|   'sources.conf' and Oliver Endriss and Lauri Tischler for testing and debugging). | ||||
| - The 'diseqc' parameter in the channel definitions has been redefined to hold the | ||||
|   "source" of the given channel (which can be either a satellite, cable or terrestrial). | ||||
|   For compatibility with channels.conf files from older versions, numeric values in | ||||
|   this parameter will be tolerated, but they have no meaning. If you want to use | ||||
|   DiSEqC you will need to replace these old values with the proper source identifiers | ||||
|   defined in the new configuration file 'sources.conf'. See how this is done in the | ||||
|   'channels.conf' file that comes with the VDR package. | ||||
| - The new configuration file 'diseqc.conf' can be used to set up the individual | ||||
|   diseqc configuration (see man vdr(5) for a description of the file format). | ||||
| - The "Edit channel" menu has a new entry "Source:" in which the source of this | ||||
|   channel can be selected (either a satellite, cable or terrestrial). The set of | ||||
|   parameters at the end of this menu will change according to the type of source. | ||||
| - The "Use DiSEqC" parameter in the "Setup/LNB" menu has been moved to the beginning | ||||
|   of the list and disables the rest of the parameters when set to "yes", since these | ||||
|   are now only meaningful if DiSEqC is _not_ used. | ||||
|   | ||||
							
								
								
									
										11
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Makefile
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
| # See the main source file 'vdr.c' for copyright information and | ||||
| # how to reach the author. | ||||
| # | ||||
| # $Id: Makefile 1.47 2002/09/28 14:12:43 kls Exp $ | ||||
| # $Id: Makefile 1.48 2002/10/04 14:29:14 kls Exp $ | ||||
|  | ||||
| .DELETE_ON_ERROR: | ||||
|  | ||||
| @@ -32,10 +32,11 @@ endif | ||||
|  | ||||
| DTVLIB   = $(DTVDIR)/libdtv.a | ||||
|  | ||||
| OBJS = audio.o config.o cutter.o device.o dvbdevice.o dvbosd.o dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o\ | ||||
|        interface.o keys.o lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o receiver.o\ | ||||
|        recorder.o recording.o remote.o remux.o ringbuffer.o spu.o status.o svdrp.o thread.o\ | ||||
|        tools.o transfer.o vdr.o videodir.o | ||||
| OBJS = audio.o channels.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbosd.o\ | ||||
|        dvbplayer.o dvbspu.o eit.o eitscan.o font.o i18n.o interface.o keys.o\ | ||||
|        lirc.o menu.o menuitems.o osdbase.o osd.o player.o plugin.o rcu.o\ | ||||
|        receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sources.o\ | ||||
|        spu.o status.o svdrp.o thread.o tools.o transfer.o vdr.o videodir.o | ||||
|  | ||||
| OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1 | ||||
| FIXFONT = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1 | ||||
|   | ||||
							
								
								
									
										31
									
								
								PLUGINS.html
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								PLUGINS.html
									
									
									
									
									
								
							| @@ -21,18 +21,18 @@ VDR program and present itself to the user. | ||||
| The <i>inside</i> interface provides the plugin code access to VDR's internal data | ||||
| structures and allows it to hook itself into specific areas to perform special actions. | ||||
| <p> | ||||
| <!--X1.1.7--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| Important modifications introduced in version 1.1.7 are marked like this. | ||||
| <!--X1.1.7--></td></tr></table> | ||||
| <!--X1.1.8--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| Important modifications introduced in version 1.1.8 are marked like this. | ||||
| <!--X1.1.8--></td></tr></table> | ||||
| <!--X1.1.9--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| Important modifications introduced in version 1.1.9 are marked like this. | ||||
| <!--X1.1.9--></td></tr></table> | ||||
| <!--X1.1.11--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| Important modifications introduced in version 1.1.11 are marked like this. | ||||
| <!--X1.1.11--></td></tr></table> | ||||
| <!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| Important modifications introduced in version 1.1.12 are marked like this. | ||||
| <!--X1.1.12--></td></tr></table> | ||||
|  | ||||
| <a name="Part I - The Outside Interface"><hr><center><h1>Part I - The Outside Interface</h1></center> | ||||
|  | ||||
| @@ -957,7 +957,6 @@ stream. There are no prerequisites regarding the length or alignment of an | ||||
| individual block of data. The sum of all blocks must simply result in the | ||||
| desired video data stream, and it must be delivered fast enough so that the | ||||
| DVB device doesn't run out of data. | ||||
| <!--X1.1.7--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| To avoid busy loops the player should call its member function | ||||
|  | ||||
| <p><table><tr><td bgcolor=#F0F0F0><pre><br> | ||||
| @@ -965,7 +964,6 @@ bool DevicePoll(cPoller &Poller, int TimeoutMs = 0); | ||||
| </pre></td></tr></table><p> | ||||
|  | ||||
| to determine whether the device is ready for further data. | ||||
| <!--X1.1.7--></td></tr></table> | ||||
| <p> | ||||
| TODO: PlayAudio()??? | ||||
| <p> | ||||
| @@ -1184,14 +1182,17 @@ the <tt>cDvbDevice</tt>, which is used to access the DVB PCI cards. | ||||
| If the new device can receive, it most likely needs to provide a way of | ||||
| selecting which channel it shall tune to: | ||||
|  | ||||
| <!--X1.1.9--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <p><table><tr><td bgcolor=#F0F0F0><pre><br> | ||||
| <!--X1.1.12--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| virtual bool ProvidesSource(int Source) const; | ||||
| <!--X1.1.12--></td></tr></table> | ||||
| virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL); | ||||
| virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); | ||||
| </pre></td></tr></table><p> | ||||
|  | ||||
| These functions will be called with the desired channel and shall return whether | ||||
| this device can provide the requested channel and whether tuning to it was successful, | ||||
| These functions will be called with the desired source or channel and shall return whether | ||||
| this device can provide the requested source or channel and whether tuning to it was successful, | ||||
| repectively. | ||||
| <!--X1.1.9--></td></tr></table> | ||||
| <p> | ||||
| @@ -1203,7 +1204,7 @@ A device that can be used for recording must implement the functions | ||||
| virtual bool SetPid(cPidHandle *Handle, int Type, bool On); | ||||
| virtual bool OpenDvr(void); | ||||
| virtual void CloseDvr(void); | ||||
| <!--X1.1.9--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.1.9--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| virtual bool GetTSPacket(uchar *&Data); | ||||
| <!--X1.1.9--></td></tr></table> | ||||
| </pre></td></tr></table><p> | ||||
| @@ -1227,7 +1228,6 @@ to indicate this to VDR. | ||||
| <p> | ||||
| The functions to implement replaying capabilites are | ||||
|  | ||||
| <!--X1.1.7--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <p><table><tr><td bgcolor=#F0F0F0><pre><br> | ||||
| virtual bool HasDecoder(void) const; | ||||
| virtual bool SetPlayMode(ePlayMode PlayMode); | ||||
| @@ -1240,7 +1240,6 @@ virtual void StillPicture(const uchar *Data, int Length); | ||||
| virtual bool Poll(cPoller &Poller, int TimeoutMs = 0); | ||||
| virtual int PlayVideo(const uchar *Data, int Length); | ||||
| </pre></td></tr></table><p> | ||||
| <!--X1.1.7--></td></tr></table> | ||||
|  | ||||
| In addition, the following functions may be implemented to provide further | ||||
| functionality: | ||||
| @@ -1251,7 +1250,7 @@ virtual void SetVideoFormat(bool VideoFormat16_9); | ||||
| virtual void SetVolumeDevice(int Volume); | ||||
| </pre></td></tr></table><p> | ||||
|  | ||||
| <!--X1.1.8--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.1.8--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <p> | ||||
| <b>On Screen Display</b> | ||||
| <p> | ||||
| @@ -1292,7 +1291,7 @@ shut down (delete) all devices when the program terminates. It is therefore | ||||
| important that the devices are created on the heap, using the <tt>new</tt> | ||||
| operator! | ||||
|  | ||||
| <!--X1.1.11--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.1.11--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <hr><h2>Remote Control</h2> | ||||
|  | ||||
| <center><i><b>The joy of zapping!</b></i></center><p> | ||||
|   | ||||
							
								
								
									
										433
									
								
								channels.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										433
									
								
								channels.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,433 @@ | ||||
| /* | ||||
|  * channels.c: Channel handling | ||||
|  * | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: channels.c 1.1 2002/10/05 13:22:28 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "channels.h" | ||||
| #ifdef NEWSTRUCT | ||||
| #include <linux/dvb/frontend.h> | ||||
| #else | ||||
| #include <ost/frontend.h> | ||||
| #endif | ||||
| #include <ctype.h> | ||||
|  | ||||
| // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d' | ||||
| // format characters in order to allow any number of blanks after a numeric | ||||
| // value! | ||||
|  | ||||
| // -- Channel Parameter Maps ------------------------------------------------- | ||||
|  | ||||
| const tChannelParameterMap InversionValues[] = { | ||||
|   {   0, INVERSION_OFF }, | ||||
|   {   1, INVERSION_ON }, | ||||
|   { 999, INVERSION_AUTO }, | ||||
|   { -1 } | ||||
|   }; | ||||
|  | ||||
| const tChannelParameterMap BandwidthValues[] = { | ||||
|   {   6, BANDWIDTH_6_MHZ }, | ||||
|   {   7, BANDWIDTH_7_MHZ }, | ||||
|   {   8, BANDWIDTH_8_MHZ }, | ||||
| #ifdef NEWSTRUCT | ||||
|   { 999, BANDWIDTH_AUTO }, | ||||
| #endif | ||||
|   { -1 } | ||||
|   }; | ||||
|  | ||||
| const tChannelParameterMap CoderateValues[] = { | ||||
|   {   0, FEC_NONE }, | ||||
|   {  12, FEC_1_2 }, | ||||
|   {  23, FEC_2_3 }, | ||||
|   {  34, FEC_3_4 }, | ||||
| #ifdef NEWSTRUCT | ||||
|   {  45, FEC_4_5 }, | ||||
| #endif | ||||
|   {  56, FEC_5_6 }, | ||||
| #ifdef NEWSTRUCT | ||||
|   {  67, FEC_6_7 }, | ||||
| #endif | ||||
|   {  78, FEC_7_8 }, | ||||
| #ifdef NEWSTRUCT | ||||
|   {  89, FEC_8_9 }, | ||||
| #endif | ||||
|   { 999, FEC_AUTO }, | ||||
|   { -1 } | ||||
|   }; | ||||
|  | ||||
| const tChannelParameterMap ModulationValues[] = { | ||||
|   {   0, QPSK }, | ||||
|   {  16, QAM_16 }, | ||||
|   {  32, QAM_32 }, | ||||
|   {  64, QAM_64 }, | ||||
|   { 128, QAM_128 }, | ||||
|   { 256, QAM_256 }, | ||||
| #ifdef NEWSTRUCT | ||||
|   { 999, QAM_AUTO }, | ||||
| #endif | ||||
|   { -1 } | ||||
|   }; | ||||
|  | ||||
| const tChannelParameterMap TransmissionValues[] = { | ||||
|   {   2, TRANSMISSION_MODE_2K }, | ||||
|   {   8, TRANSMISSION_MODE_8K }, | ||||
| #ifdef NEWSTRUCT | ||||
|   { 999, TRANSMISSION_MODE_AUTO }, | ||||
| #endif | ||||
|   { -1 } | ||||
|   }; | ||||
|  | ||||
| const tChannelParameterMap GuardValues[] = { | ||||
|   {   4, GUARD_INTERVAL_1_4 }, | ||||
|   {   8, GUARD_INTERVAL_1_8 }, | ||||
|   {  16, GUARD_INTERVAL_1_16 }, | ||||
|   {  32, GUARD_INTERVAL_1_32 }, | ||||
| #ifdef NEWSTRUCT | ||||
|   { 999, GUARD_INTERVAL_AUTO }, | ||||
| #endif | ||||
|   { -1 } | ||||
|   }; | ||||
|  | ||||
| const tChannelParameterMap HierarchyValues[] = { | ||||
|   {   0, HIERARCHY_NONE }, | ||||
|   {   1, HIERARCHY_1 }, | ||||
|   {   2, HIERARCHY_2 }, | ||||
|   {   4, HIERARCHY_4 }, | ||||
| #ifdef NEWSTRUCT | ||||
|   { 999, HIERARCHY_AUTO }, | ||||
| #endif | ||||
|   { -1 } | ||||
|   }; | ||||
|  | ||||
| int UserIndex(int Value, const tChannelParameterMap *Map) | ||||
| { | ||||
|   const tChannelParameterMap *map = Map; | ||||
|   while (map && map->userValue != -1) { | ||||
|         if (map->userValue == Value) | ||||
|            return map - Map; | ||||
|         map++; | ||||
|         } | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| int DriverIndex(int Value, const tChannelParameterMap *Map) | ||||
| { | ||||
|   const tChannelParameterMap *map = Map; | ||||
|   while (map && map->userValue != -1) { | ||||
|         if (map->driverValue == Value) | ||||
|            return map - Map; | ||||
|         map++; | ||||
|         } | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| int MapToUser(int Value, const tChannelParameterMap *Map) | ||||
| { | ||||
|   int n = DriverIndex(Value, Map); | ||||
|   if (n >= 0) | ||||
|      return Map[n].userValue; | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| int MapToDriver(int Value, const tChannelParameterMap *Map) | ||||
| { | ||||
|   int n = UserIndex(Value, Map); | ||||
|   if (n >= 0) | ||||
|      return Map[n].driverValue; | ||||
|   return -1; | ||||
| } | ||||
|  | ||||
| // -- cChannel --------------------------------------------------------------- | ||||
|  | ||||
| char *cChannel::buffer = NULL; | ||||
|  | ||||
| cChannel::cChannel(void) | ||||
| { | ||||
|   *name = 0; | ||||
|   frequency    = 0; | ||||
|   source       = 0; | ||||
|   srate        = 0; | ||||
|   vpid         = 0; | ||||
|   apid1        = 0; | ||||
|   apid2        = 0; | ||||
|   dpid1        = 0; | ||||
|   dpid2        = 0; | ||||
|   tpid         = 0; | ||||
|   ca           = 0; | ||||
|   sid          = 0; | ||||
|   groupSep     = false; | ||||
|   //XXX | ||||
|   polarization = 'v'; | ||||
|   inversion    = INVERSION_AUTO; | ||||
|   bandwidth    = BANDWIDTH_8_MHZ; | ||||
|   coderateH    = FEC_AUTO;//XXX FEC_2_3 | ||||
|   coderateL    = FEC_1_2;//XXX | ||||
|   modulation   = QAM_64; | ||||
|   transmission = TRANSMISSION_MODE_2K; | ||||
|   guard        = GUARD_INTERVAL_1_32; | ||||
|   hierarchy    = HIERARCHY_NONE; | ||||
| } | ||||
|  | ||||
| cChannel::cChannel(const cChannel *Channel) | ||||
| { | ||||
|   strcpy(name,   Channel ? Channel->name         : "Pro7"); | ||||
|   frequency    = Channel ? Channel->frequency    : 12480; | ||||
|   source       = Channel ? Channel->source       : 0; | ||||
|   srate        = Channel ? Channel->srate        : 27500; | ||||
|   vpid         = Channel ? Channel->vpid         : 255; | ||||
|   apid1        = Channel ? Channel->apid1        : 256; | ||||
|   apid2        = Channel ? Channel->apid2        : 0; | ||||
|   dpid1        = Channel ? Channel->dpid1        : 257; | ||||
|   dpid2        = Channel ? Channel->dpid2        : 0; | ||||
|   tpid         = Channel ? Channel->tpid         : 32; | ||||
|   ca           = Channel ? Channel->ca           : 0; | ||||
|   sid          = Channel ? Channel->sid          : 0; | ||||
|   groupSep     = Channel ? Channel->groupSep     : false; | ||||
|   //XXX | ||||
|   polarization = Channel ? Channel->polarization : 'v'; | ||||
|   inversion    = Channel ? Channel->inversion    : INVERSION_AUTO; | ||||
|   bandwidth    = Channel ? Channel->bandwidth    : BANDWIDTH_8_MHZ; | ||||
|   coderateH    = Channel ? Channel->coderateH    : FEC_AUTO;//XXX FEC_2_3 | ||||
|   coderateL    = Channel ? Channel->coderateL    : FEC_1_2;//XXX | ||||
|   modulation   = Channel ? Channel->modulation   : QAM_64; | ||||
|   transmission = Channel ? Channel->transmission : TRANSMISSION_MODE_2K; | ||||
|   guard        = Channel ? Channel->guard        : GUARD_INTERVAL_1_32; | ||||
|   hierarchy    = Channel ? Channel->hierarchy    : HIERARCHY_NONE; | ||||
| } | ||||
|  | ||||
| static int PrintParameter(char *p, char Name, int Value) | ||||
| { | ||||
|   return Value > 0 && Value != 999 ? sprintf(p, "%c%d", Name, Value) : 0; | ||||
| } | ||||
|  | ||||
| const char *cChannel::ParametersToString(void) | ||||
| { | ||||
|   char type = *cSource::ToString(source); | ||||
| #define ST(s) if (strchr(s, type)) | ||||
|   static char buffer[64]; | ||||
|   char *q = buffer; | ||||
|   *q = 0; | ||||
|   ST(" S ")  q += sprintf(q, "%c", polarization); | ||||
|   ST("CST")  q += PrintParameter(q, 'I', MapToUser(inversion, InversionValues)); | ||||
|   ST("CST")  q += PrintParameter(q, 'C', MapToUser(coderateH, CoderateValues)); | ||||
|   ST("  T")  q += PrintParameter(q, 'D', MapToUser(coderateL, CoderateValues)); | ||||
|   ST("C T")  q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues)); | ||||
|   ST("  T")  q += PrintParameter(q, 'B', MapToUser(bandwidth, BandwidthValues)); | ||||
|   ST("  T")  q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues)); | ||||
|   ST("  T")  q += PrintParameter(q, 'G', MapToUser(guard, GuardValues)); | ||||
|   ST("  T")  q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues)); | ||||
|   return buffer; | ||||
| } | ||||
|  | ||||
| static const char *ParseParameter(const char *s, int &Value, const tChannelParameterMap *Map) | ||||
| { | ||||
|   if (*++s) { | ||||
|      char *p = NULL; | ||||
|      errno = 0; | ||||
|      int n = strtol(s, &p, 10); | ||||
|      if (!errno && p != s) { | ||||
|         Value = MapToDriver(n, Map); | ||||
|         if (Value >= 0) | ||||
|            return p; | ||||
|         } | ||||
|      } | ||||
|   esyslog("ERROR: illegal value for parameter '%c'", *(s - 1)); | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| bool cChannel::StringToParameters(const char *s) | ||||
| { | ||||
|   while (s && *s) { | ||||
|         switch (toupper(*s)) { | ||||
|           case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break; | ||||
|           case 'C': s = ParseParameter(s, coderateH, CoderateValues); break; | ||||
|           case 'D': s = ParseParameter(s, coderateL, CoderateValues); break; | ||||
|           case 'G': s = ParseParameter(s, guard, GuardValues); break; | ||||
|           case 'H': polarization = *s++; break; | ||||
|           case 'I': s = ParseParameter(s, inversion, InversionValues); break; | ||||
|           // 'L' reserved for possible circular polarization | ||||
|           case 'M': s = ParseParameter(s, modulation, ModulationValues); break; | ||||
|           // 'R' reserved for possible circular polarization | ||||
|           case 'T': s = ParseParameter(s, transmission, TransmissionValues); break; | ||||
|           case 'V': polarization = *s++; break; | ||||
|           case 'Y': s = ParseParameter(s, hierarchy, HierarchyValues); break; | ||||
|           default: esyslog("ERROR: unknown parameter key '%c'", *s); | ||||
|                    return false; | ||||
|           } | ||||
|         } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| const char *cChannel::ToText(cChannel *Channel) | ||||
| { | ||||
|   char buf[MaxChannelName * 2]; | ||||
|   char *s = Channel->name; | ||||
|   if (strchr(s, ':')) { | ||||
|      s = strcpy(buf, s); | ||||
|      strreplace(s, ':', '|'); | ||||
|      } | ||||
|   free(buffer); | ||||
|   if (Channel->groupSep) | ||||
|      asprintf(&buffer, ":%s\n", s); | ||||
|   else { | ||||
|      char apidbuf[32]; | ||||
|      char *q = apidbuf; | ||||
|      q += snprintf(q, sizeof(apidbuf), "%d", Channel->apid1); | ||||
|      if (Channel->apid2) | ||||
|         q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->apid2); | ||||
|      if (Channel->dpid1 || Channel->dpid2) | ||||
|         q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ";%d", Channel->dpid1); | ||||
|      if (Channel->dpid2) | ||||
|         q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->dpid2); | ||||
|      *q = 0; | ||||
|      asprintf(&buffer, "%s:%d:%s:%s:%d:%d:%s:%d:%d:%d\n", s, Channel->frequency, Channel->ParametersToString(), cSource::ToString(Channel->source), Channel->srate, Channel->vpid, apidbuf, Channel->tpid, Channel->ca, Channel->sid); | ||||
|      } | ||||
|   return buffer; | ||||
| } | ||||
|  | ||||
| const char *cChannel::ToText(void) | ||||
| { | ||||
|   return ToText(this); | ||||
| } | ||||
|  | ||||
| bool cChannel::Parse(const char *s) | ||||
| { | ||||
|   if (*s == ':') { | ||||
|      if (*++s) { | ||||
|         strn0cpy(name, s, MaxChannelName); | ||||
|         groupSep = true; | ||||
|         number = 0; | ||||
|         } | ||||
|      else | ||||
|         return false; | ||||
|      } | ||||
|   else { | ||||
|      groupSep = false; | ||||
|      char *namebuf = NULL; | ||||
|      char *sourcebuf = NULL; | ||||
|      char *parambuf = NULL; | ||||
|      char *apidbuf = NULL; | ||||
|      int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%d :%a[^:]:%d :%d :%d ", &namebuf, &frequency, ¶mbuf, &sourcebuf, &srate, &vpid, &apidbuf, &tpid, &ca, &sid); | ||||
|      if (fields >= 9) { | ||||
|         if (fields == 9) { | ||||
|            // allow reading of old format | ||||
|            sid = ca; | ||||
|            ca = tpid; | ||||
|            tpid = 0; | ||||
|            } | ||||
|         apid1 = apid2 = 0; | ||||
|         dpid1 = dpid2 = 0; | ||||
|         bool ok = false; | ||||
|         if (parambuf && sourcebuf && apidbuf) { | ||||
|            ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0; | ||||
|            char *p = strchr(apidbuf, ';'); | ||||
|            if (p) | ||||
|               *p++ = 0; | ||||
|            sscanf(apidbuf, "%d ,%d ", &apid1, &apid2); | ||||
|            if (p) | ||||
|               sscanf(p, "%d ,%d ", &dpid1, &dpid2); | ||||
|            } | ||||
|         strn0cpy(name, namebuf, MaxChannelName); | ||||
|         free(parambuf); | ||||
|         free(sourcebuf); | ||||
|         free(apidbuf); | ||||
|         free(namebuf); | ||||
|         return ok; | ||||
|         } | ||||
|      else | ||||
|         return false; | ||||
|      } | ||||
|   strreplace(name, '|', ':'); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool cChannel::Save(FILE *f) | ||||
| { | ||||
|   return fprintf(f, ToText()) > 0; | ||||
| } | ||||
|  | ||||
| // -- cChannels -------------------------------------------------------------- | ||||
|  | ||||
| cChannels Channels; | ||||
|  | ||||
| bool cChannels::Load(const char *FileName, bool AllowComments) | ||||
| { | ||||
|   if (cConfig<cChannel>::Load(FileName, AllowComments)) { | ||||
|      ReNumber(); | ||||
|      return true; | ||||
|      } | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| int cChannels::GetNextGroup(int Idx) | ||||
| { | ||||
|   cChannel *channel = Get(++Idx); | ||||
|   while (channel && !channel->GroupSep()) | ||||
|         channel = Get(++Idx); | ||||
|   return channel ? Idx : -1; | ||||
| } | ||||
|  | ||||
| int cChannels::GetPrevGroup(int Idx) | ||||
| { | ||||
|   cChannel *channel = Get(--Idx); | ||||
|   while (channel && !channel->GroupSep()) | ||||
|         channel = Get(--Idx); | ||||
|   return channel ? Idx : -1; | ||||
| } | ||||
|  | ||||
| int cChannels::GetNextNormal(int Idx) | ||||
| { | ||||
|   cChannel *channel = Get(++Idx); | ||||
|   while (channel && channel->GroupSep()) | ||||
|         channel = Get(++Idx); | ||||
|   return channel ? Idx : -1; | ||||
| } | ||||
|  | ||||
| void cChannels::ReNumber( void ) | ||||
| { | ||||
|   int Number = 0; | ||||
|   cChannel *ch = (cChannel *)First(); | ||||
|   while (ch) { | ||||
|         if (!ch->GroupSep()) | ||||
|            ch->SetNumber(++Number); | ||||
|         ch = (cChannel *)ch->Next(); | ||||
|         } | ||||
|   maxNumber = Number; | ||||
| } | ||||
|  | ||||
| cChannel *cChannels::GetByNumber(int Number) | ||||
| { | ||||
|   cChannel *channel = (cChannel *)First(); | ||||
|   while (channel) { | ||||
|         if (!channel->GroupSep() && channel->Number() == Number) | ||||
|            return channel; | ||||
|         channel = (cChannel *)channel->Next(); | ||||
|         } | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| cChannel *cChannels::GetByServiceID(unsigned short ServiceId) | ||||
| { | ||||
|   cChannel *channel = (cChannel *)First(); | ||||
|   while (channel) { | ||||
|         if (!channel->GroupSep() && channel->Sid() == ServiceId) | ||||
|            return channel; | ||||
|         channel = (cChannel *)channel->Next(); | ||||
|         } | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| bool cChannels::SwitchTo(int Number) | ||||
| { | ||||
|   cChannel *channel = GetByNumber(Number); | ||||
|   return channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true); | ||||
| } | ||||
|  | ||||
| const char *cChannels::GetChannelNameByNumber(int Number) | ||||
| { | ||||
|   cChannel *channel = GetByNumber(Number); | ||||
|   return channel ? channel->Name() : NULL; | ||||
| } | ||||
							
								
								
									
										124
									
								
								channels.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								channels.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| /* | ||||
|  * channels.h: Channel handling | ||||
|  * | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: channels.h 1.1 2002/10/05 13:53:15 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __CHANNELS_H | ||||
| #define __CHANNELS_H | ||||
|  | ||||
| #include "config.h" | ||||
| #include "sources.h" | ||||
| #include "tools.h" | ||||
|  | ||||
| #define ISTRANSPONDER(f1, f2)  (abs((f1) - (f2)) < 4) //XXX | ||||
|  | ||||
| struct tChannelParameterMap { | ||||
|   int userValue; | ||||
|   int driverValue; | ||||
|   }; | ||||
|  | ||||
| //XXX into cChannel??? | ||||
| int MapToUser(int Value, const tChannelParameterMap *Map); | ||||
| int MapToDriver(int Value, const tChannelParameterMap *Map); | ||||
| int UserIndex(int Value, const tChannelParameterMap *Map); | ||||
| int DriverIndex(int Value, const tChannelParameterMap *Map); | ||||
|  | ||||
| extern const tChannelParameterMap InversionValues[]; | ||||
| extern const tChannelParameterMap BandwidthValues[]; | ||||
| extern const tChannelParameterMap CoderateValues[]; | ||||
| extern const tChannelParameterMap ModulationValues[]; | ||||
| extern const tChannelParameterMap TransmissionValues[]; | ||||
| extern const tChannelParameterMap GuardValues[]; | ||||
| extern const tChannelParameterMap HierarchyValues[]; | ||||
|  | ||||
| class cChannel : public cListObject { | ||||
|   friend class cMenuEditChannel; | ||||
| private: | ||||
|   static char *buffer; | ||||
|   static const char *ToText(cChannel *Channel); | ||||
|   enum { MaxChannelName = 32 }; // 31 chars + terminating 0! | ||||
|   char name[MaxChannelName]; | ||||
|   int frequency; // MHz | ||||
|   int source; | ||||
|   int srate; | ||||
|   int vpid; | ||||
|   int apid1, apid2; | ||||
|   int dpid1, dpid2; | ||||
|   int tpid; | ||||
|   int ca; | ||||
|   int sid; | ||||
|   int number;    // Sequence number assigned on load | ||||
|   bool groupSep; | ||||
|   //XXX | ||||
|   char polarization; | ||||
|   int inversion; | ||||
|   int bandwidth; | ||||
|   int coderateH; | ||||
|   int coderateL; | ||||
|   int modulation; | ||||
|   int transmission; | ||||
|   int guard; | ||||
|   int hierarchy; | ||||
|   const char *ParametersToString(void); | ||||
|   bool StringToParameters(const char *s); | ||||
| public: | ||||
|   cChannel(void); | ||||
|   cChannel(const cChannel *Channel); | ||||
|   const char *ToText(void); | ||||
|   bool Parse(const char *s); | ||||
|   bool Save(FILE *f); | ||||
|   const char *Name(void) const { return name; } | ||||
|   int Frequency(void) const { return frequency; } | ||||
|   int Source(void) const { return source; } | ||||
|   int Srate(void) const { return srate; } | ||||
|   int Vpid(void) const { return vpid; } | ||||
|   int Apid1(void) const { return apid1; } | ||||
|   int Apid2(void) const { return apid2; } | ||||
|   int Dpid1(void) const { return dpid1; } | ||||
|   int Dpid2(void) const { return dpid2; } | ||||
|   int Tpid(void) const { return tpid; } | ||||
|   int Ca(void) const { return ca; } | ||||
|   int Sid(void) const { return sid; } | ||||
|   int Number(void) const { return number; } | ||||
|   void SetNumber(int Number) { number = Number; } | ||||
|   bool GroupSep(void) const { return groupSep; } | ||||
|   //XXX | ||||
|   char Polarization(void) const { return polarization; } | ||||
|   int Inversion(void) const { return inversion; } | ||||
|   int Bandwidth(void) const { return bandwidth; } | ||||
|   int CoderateH(void) const { return coderateH; } | ||||
|   int CoderateL(void) const { return coderateL; } | ||||
|   int Modulation(void) const { return modulation; } | ||||
|   int Transmission(void) const { return transmission; } | ||||
|   int Guard(void) const { return guard; } | ||||
|   int Hierarchy(void) const { return hierarchy; } | ||||
|   //XXX | ||||
|   bool IsCable(void) { return (source & cSource::st_Mask) == cSource::stCable; } | ||||
|   bool IsSat(void) { return (source & cSource::st_Mask) == cSource::stSat; } | ||||
|   bool IsTerr(void) { return (source & cSource::st_Mask) == cSource::stTerr; } | ||||
|   }; | ||||
|  | ||||
| class cChannels : public cConfig<cChannel> { | ||||
| protected: | ||||
|   int maxNumber; | ||||
| public: | ||||
|   cChannels(void) { maxNumber = 0; } | ||||
|   virtual bool Load(const char *FileName, bool AllowComments = false); | ||||
|   int GetNextGroup(int Idx);   // Get next channel group | ||||
|   int GetPrevGroup(int Idx);   // Get previous channel group | ||||
|   int GetNextNormal(int Idx);  // Get next normal channel (not group) | ||||
|   void ReNumber(void);         // Recalculate 'number' based on channel type | ||||
|   cChannel *GetByNumber(int Number); | ||||
|   cChannel *GetByServiceID(unsigned short ServiceId); | ||||
|   const char *GetChannelNameByNumber(int Number); | ||||
|   bool SwitchTo(int Number); | ||||
|   int MaxNumber(void) { return maxNumber; } | ||||
|   }; | ||||
|  | ||||
| extern cChannels Channels; | ||||
|  | ||||
| #endif //__CHANNELS_H | ||||
							
								
								
									
										202
									
								
								config.c
									
									
									
									
									
								
							
							
						
						
									
										202
									
								
								config.c
									
									
									
									
									
								
							| @@ -4,12 +4,13 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: config.c 1.106 2002/09/28 09:43:41 kls Exp $ | ||||
|  * $Id: config.c 1.107 2002/10/03 10:06:55 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "config.h" | ||||
| #include <ctype.h> | ||||
| #include <stdlib.h> | ||||
| #include "channels.h" //XXX timers! | ||||
| #include "i18n.h" | ||||
| #include "interface.h" | ||||
| #include "plugin.h" | ||||
| @@ -19,116 +20,6 @@ | ||||
| // format characters in order to allow any number of blanks after a numeric | ||||
| // value! | ||||
|  | ||||
| // -- cChannel --------------------------------------------------------------- | ||||
|  | ||||
| char *cChannel::buffer = NULL; | ||||
|  | ||||
| cChannel::cChannel(void) | ||||
| { | ||||
|   *name = 0; | ||||
| } | ||||
|  | ||||
| cChannel::cChannel(const cChannel *Channel) | ||||
| { | ||||
|   strcpy(name,   Channel ? Channel->name         : "Pro7"); | ||||
|   frequency    = Channel ? Channel->frequency    : 12480; | ||||
|   polarization = Channel ? Channel->polarization : 'v'; | ||||
|   diseqc       = Channel ? Channel->diseqc       : 0; | ||||
|   srate        = Channel ? Channel->srate        : 27500; | ||||
|   vpid         = Channel ? Channel->vpid         : 255; | ||||
|   apid1        = Channel ? Channel->apid1        : 256; | ||||
|   apid2        = Channel ? Channel->apid2        : 0; | ||||
|   dpid1        = Channel ? Channel->dpid1        : 257; | ||||
|   dpid2        = Channel ? Channel->dpid2        : 0; | ||||
|   tpid         = Channel ? Channel->tpid         : 32; | ||||
|   ca           = Channel ? Channel->ca           : 0; | ||||
|   pnr          = Channel ? Channel->pnr          : 0; | ||||
|   groupSep     = Channel ? Channel->groupSep     : false; | ||||
| } | ||||
|  | ||||
| const char *cChannel::ToText(cChannel *Channel) | ||||
| { | ||||
|   char buf[MaxChannelName * 2]; | ||||
|   char *s = Channel->name; | ||||
|   if (strchr(s, ':')) { | ||||
|      s = strcpy(buf, s); | ||||
|      strreplace(s, ':', '|'); | ||||
|      } | ||||
|   free(buffer); | ||||
|   if (Channel->groupSep) | ||||
|      asprintf(&buffer, ":%s\n", s); | ||||
|   else { | ||||
|      char apidbuf[32]; | ||||
|      char *q = apidbuf; | ||||
|      q += snprintf(q, sizeof(apidbuf), "%d", Channel->apid1); | ||||
|      if (Channel->apid2) | ||||
|         q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->apid2); | ||||
|      if (Channel->dpid1 || Channel->dpid2) | ||||
|         q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ";%d", Channel->dpid1); | ||||
|      if (Channel->dpid2) | ||||
|         q += snprintf(q, sizeof(apidbuf) - (q - apidbuf), ",%d", Channel->dpid2); | ||||
|      *q = 0; | ||||
|      asprintf(&buffer, "%s:%d:%c:%d:%d:%d:%s:%d:%d:%d\n", s, Channel->frequency, Channel->polarization, Channel->diseqc, Channel->srate, Channel->vpid, apidbuf, Channel->tpid, Channel->ca, Channel->pnr); | ||||
|      } | ||||
|   return buffer; | ||||
| } | ||||
|  | ||||
| const char *cChannel::ToText(void) | ||||
| { | ||||
|   return ToText(this); | ||||
| } | ||||
|  | ||||
| bool cChannel::Parse(const char *s) | ||||
| { | ||||
|   char *buffer = NULL; | ||||
|   if (*s == ':') { | ||||
|      if (*++s) { | ||||
|         strn0cpy(name, s, MaxChannelName); | ||||
|         groupSep = true; | ||||
|         number = 0; | ||||
|         } | ||||
|      else | ||||
|         return false; | ||||
|      } | ||||
|   else { | ||||
|      groupSep = false; | ||||
|      char *apidbuf = NULL; | ||||
|      int fields = sscanf(s, "%a[^:]:%d :%c:%d :%d :%d :%a[^:]:%d :%d :%d ", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apidbuf, &tpid, &ca, &pnr); | ||||
|      apid1 = apid2 = 0; | ||||
|      dpid1 = dpid2 = 0; | ||||
|      if (apidbuf) { | ||||
|         char *p = strchr(apidbuf, ';'); | ||||
|         if (p) | ||||
|            *p++ = 0; | ||||
|         sscanf(apidbuf, "%d ,%d ", &apid1, &apid2); | ||||
|         if (p) | ||||
|            sscanf(p, "%d ,%d ", &dpid1, &dpid2); | ||||
|         free(apidbuf); | ||||
|         } | ||||
|      else | ||||
|         return false; | ||||
|      if (fields >= 9) { | ||||
|         if (fields == 9) { | ||||
|            // allow reading of old format | ||||
|            pnr = ca; | ||||
|            ca = tpid; | ||||
|            tpid = 0; | ||||
|            } | ||||
|         strn0cpy(name, buffer, MaxChannelName); | ||||
|         free(buffer); | ||||
|         } | ||||
|      else | ||||
|         return false; | ||||
|      } | ||||
|   strreplace(name, '|', ':'); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool cChannel::Save(FILE *f) | ||||
| { | ||||
|   return fprintf(f, ToText()) > 0; | ||||
| } | ||||
|  | ||||
| // -- cTimer ----------------------------------------------------------------- | ||||
|  | ||||
| char *cTimer::buffer = NULL; | ||||
| @@ -139,7 +30,7 @@ cTimer::cTimer(bool Instant) | ||||
|   recording = pending = false; | ||||
|   active = Instant ? taActInst : taInactive; | ||||
|   cChannel *ch = Channels.GetByNumber(cDevice::CurrentChannel()); | ||||
|   channel = ch ? ch->number : 0; | ||||
|   channel = ch ? ch->Number() : 0; | ||||
|   time_t t = time(NULL); | ||||
|   struct tm tm_r; | ||||
|   struct tm *now = localtime_r(&t, &tm_r); | ||||
| @@ -156,7 +47,7 @@ cTimer::cTimer(bool Instant) | ||||
|   firstday = 0; | ||||
|   summary = NULL; | ||||
|   if (Instant && ch) | ||||
|      snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : ch->name); | ||||
|      snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", *Setup.NameInstantRecord ? Setup.NameInstantRecord : ch->Name()); | ||||
| } | ||||
|  | ||||
| cTimer::cTimer(const cEventInfo *EventInfo) | ||||
| @@ -165,7 +56,7 @@ cTimer::cTimer(const cEventInfo *EventInfo) | ||||
|   recording = pending = false; | ||||
|   active = true; | ||||
|   cChannel *ch = Channels.GetByServiceID(EventInfo->GetServiceID()); | ||||
|   channel = ch ? ch->number : 0; | ||||
|   channel = ch ? ch->Number() : 0; | ||||
|   time_t tstart = EventInfo->GetTime(); | ||||
|   time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60; | ||||
|   tstart -= Setup.MarginStart * 60; | ||||
| @@ -573,89 +464,6 @@ bool cCaDefinition::Parse(const char *s) | ||||
|  | ||||
| cCommands Commands; | ||||
|  | ||||
| // -- cChannels -------------------------------------------------------------- | ||||
|  | ||||
| cChannels Channels; | ||||
|  | ||||
| bool cChannels::Load(const char *FileName, bool AllowComments) | ||||
| { | ||||
|   if (cConfig<cChannel>::Load(FileName, AllowComments)) { | ||||
|      ReNumber(); | ||||
|      return true; | ||||
|      } | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| int cChannels::GetNextGroup(int Idx) | ||||
| { | ||||
|   cChannel *channel = Get(++Idx); | ||||
|   while (channel && !channel->groupSep) | ||||
|         channel = Get(++Idx); | ||||
|   return channel ? Idx : -1; | ||||
| } | ||||
|  | ||||
| int cChannels::GetPrevGroup(int Idx) | ||||
| { | ||||
|   cChannel *channel = Get(--Idx); | ||||
|   while (channel && !channel->groupSep) | ||||
|         channel = Get(--Idx); | ||||
|   return channel ? Idx : -1; | ||||
| } | ||||
|  | ||||
| int cChannels::GetNextNormal(int Idx) | ||||
| { | ||||
|   cChannel *channel = Get(++Idx); | ||||
|   while (channel && channel->groupSep) | ||||
|         channel = Get(++Idx); | ||||
|   return channel ? Idx : -1; | ||||
| } | ||||
|  | ||||
| void cChannels::ReNumber( void ) | ||||
| { | ||||
|   int Number = 0; | ||||
|   cChannel *ch = (cChannel *)First(); | ||||
|   while (ch) { | ||||
|         if (!ch->groupSep) | ||||
|            ch->number = ++Number; | ||||
|         ch = (cChannel *)ch->Next(); | ||||
|         } | ||||
|   maxNumber = Number; | ||||
| } | ||||
|  | ||||
| cChannel *cChannels::GetByNumber(int Number) | ||||
| { | ||||
|   cChannel *channel = (cChannel *)First(); | ||||
|   while (channel) { | ||||
|         if (!channel->groupSep && channel->number == Number) | ||||
|            return channel; | ||||
|         channel = (cChannel *)channel->Next(); | ||||
|         } | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| cChannel *cChannels::GetByServiceID(unsigned short ServiceId) | ||||
| { | ||||
|   cChannel *channel = (cChannel *)First(); | ||||
|   while (channel) { | ||||
|         if (!channel->groupSep && channel->pnr == ServiceId) | ||||
|            return channel; | ||||
|         channel = (cChannel *)channel->Next(); | ||||
|         } | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| bool cChannels::SwitchTo(int Number) | ||||
| { | ||||
|   cChannel *channel = GetByNumber(Number); | ||||
|   return channel && cDevice::PrimaryDevice()->SwitchChannel(channel, true); | ||||
| } | ||||
|  | ||||
| const char *cChannels::GetChannelNameByNumber(int Number) | ||||
| { | ||||
|   cChannel *channel = GetByNumber(Number); | ||||
|   return channel ? channel->name : NULL; | ||||
| } | ||||
|  | ||||
| // -- cTimers ---------------------------------------------------------------- | ||||
|  | ||||
| cTimers Timers; | ||||
|   | ||||
							
								
								
									
										50
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								config.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: config.h 1.130 2002/09/30 15:57:23 kls Exp $ | ||||
|  * $Id: config.h 1.131 2002/10/05 09:58:58 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __CONFIG_H | ||||
| @@ -32,34 +32,6 @@ | ||||
|  | ||||
| #define MaxFileName 256 | ||||
|  | ||||
| #define ISTRANSPONDER(f1, f2)  (abs((f1) - (f2)) < 4) | ||||
|  | ||||
| class cChannel : public cListObject { | ||||
| private: | ||||
|   static char *buffer; | ||||
|   static const char *ToText(cChannel *Channel); | ||||
| public: | ||||
|   enum { MaxChannelName = 32 }; // 31 chars + terminating 0! | ||||
|   char name[MaxChannelName]; | ||||
|   int frequency; // MHz | ||||
|   char polarization; | ||||
|   int diseqc; | ||||
|   int srate; | ||||
|   int vpid; | ||||
|   int apid1, apid2; | ||||
|   int dpid1, dpid2; | ||||
|   int tpid; | ||||
|   int ca; | ||||
|   int pnr; | ||||
|   int number;    // Sequence number assigned on load | ||||
|   bool groupSep; | ||||
|   cChannel(void); | ||||
|   cChannel(const cChannel *Channel); | ||||
|   const char *ToText(void); | ||||
|   bool Parse(const char *s); | ||||
|   bool Save(FILE *f); | ||||
|   }; | ||||
|  | ||||
| enum eTimerActive { taInactive = 0, | ||||
|                     taActive   = 1, | ||||
|                     taInstant  = 2, | ||||
| @@ -193,7 +165,7 @@ public: | ||||
|                    if (l->Parse(buffer)) | ||||
|                       Add(l); | ||||
|                    else { | ||||
|                       esyslog("error in %s, line %d\n", fileName, line); | ||||
|                       esyslog("ERROR: error in %s, line %d\n", fileName, line); | ||||
|                       delete l; | ||||
|                       result = false; | ||||
|                       break; | ||||
| @@ -229,23 +201,6 @@ public: | ||||
|   } | ||||
|   }; | ||||
|  | ||||
| class cChannels : public cConfig<cChannel> { | ||||
| protected: | ||||
|   int maxNumber; | ||||
| public: | ||||
|   cChannels(void) { maxNumber = 0; } | ||||
|   virtual bool Load(const char *FileName, bool AllowComments = false); | ||||
|   int GetNextGroup(int Idx);   // Get next channel group | ||||
|   int GetPrevGroup(int Idx);   // Get previous channel group | ||||
|   int GetNextNormal(int Idx);  // Get next normal channel (not group) | ||||
|   void ReNumber(void);         // Recalculate 'number' based on channel type | ||||
|   cChannel *GetByNumber(int Number); | ||||
|   cChannel *GetByServiceID(unsigned short ServiceId); | ||||
|   const char *GetChannelNameByNumber(int Number); | ||||
|   bool SwitchTo(int Number); | ||||
|   int MaxNumber(void) { return maxNumber; } | ||||
|   }; | ||||
|  | ||||
| class cTimers : public cConfig<cTimer> { | ||||
| public: | ||||
|   cTimer *GetTimer(cTimer *Timer); | ||||
| @@ -265,7 +220,6 @@ public: | ||||
|   const cCaDefinition *Get(int Number); | ||||
|   }; | ||||
|  | ||||
| extern cChannels Channels; | ||||
| extern cTimers Timers; | ||||
| extern cCommands Commands; | ||||
| extern cSVDRPhosts SVDRPhosts; | ||||
|   | ||||
							
								
								
									
										20
									
								
								device.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								device.c
									
									
									
									
									
								
							| @@ -4,13 +4,14 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: device.c 1.22 2002/09/28 12:20:22 kls Exp $ | ||||
|  * $Id: device.c 1.23 2002/10/05 15:18:39 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "device.h" | ||||
| #include <errno.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <sys/mman.h> | ||||
| #include "channels.h" | ||||
| #include "eit.h" | ||||
| #include "i18n.h" | ||||
| #include "player.h" | ||||
| @@ -143,7 +144,7 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool *NeedsDe | ||||
|             || !d->Receiving() // ...the one we have is not receiving... | ||||
|                && (device[i]->Priority() < d->Priority() // ...this one has an even lower Priority, or... | ||||
|                   || device[i]->Priority() == d->Priority() // ...same Priority... | ||||
|                      && device[i]->ProvidesCa(Channel->ca) < d->ProvidesCa(Channel->ca) // ...but this one provides fewer Ca values | ||||
|                      && device[i]->ProvidesCa(Channel->Ca()) < d->ProvidesCa(Channel->Ca()) // ...but this one provides fewer Ca values | ||||
|                   ) | ||||
|             ) | ||||
|          ) { | ||||
| @@ -275,6 +276,11 @@ bool cDevice::SetPid(cPidHandle *Handle, int Type, bool On) | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| bool cDevice::ProvidesSource(int Source) const | ||||
| { | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| bool cDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const | ||||
| { | ||||
|   return false; | ||||
| @@ -283,7 +289,7 @@ bool cDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Needs | ||||
| bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) | ||||
| { | ||||
|   if (LiveView) | ||||
|      isyslog("switching to channel %d", Channel->number); | ||||
|      isyslog("switching to channel %d", Channel->Number()); | ||||
|   for (int i = 3; i--;) { | ||||
|       switch (SetChannel(Channel, LiveView)) { | ||||
|         case scrOk:           return true; | ||||
| @@ -344,7 +350,7 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) | ||||
|      if (CaDevice) { | ||||
|         cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel | ||||
|         if (CaDevice->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()! | ||||
|            cControl::Launch(new cTransferControl(CaDevice, Channel->vpid, Channel->apid1, 0, 0, 0));//XXX+ | ||||
|            cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apid1(), 0, 0, 0));//XXX+ | ||||
|         else | ||||
|            Result = scrNoTransfer; | ||||
|         } | ||||
| @@ -359,10 +365,10 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) | ||||
|  | ||||
|   if (Result == scrOk) { | ||||
|      if (LiveView && IsPrimaryDevice()) { | ||||
|         cSIProcessor::SetCurrentServiceID(Channel->pnr); | ||||
|         currentChannel = Channel->number; | ||||
|         cSIProcessor::SetCurrentServiceID(Channel->Sid()); | ||||
|         currentChannel = Channel->Number(); | ||||
|         } | ||||
|      cStatus::MsgChannelSwitch(this, Channel->number); // only report status if channel switch successfull | ||||
|      cStatus::MsgChannelSwitch(this, Channel->Number()); // only report status if channel switch successfull | ||||
|      } | ||||
|  | ||||
|   return Result; | ||||
|   | ||||
							
								
								
									
										4
									
								
								device.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								device.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: device.h 1.20 2002/09/28 12:20:34 kls Exp $ | ||||
|  * $Id: device.h 1.21 2002/10/05 15:18:13 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __DEVICE_H | ||||
| @@ -139,6 +139,8 @@ public: | ||||
| protected: | ||||
|   static int currentChannel; | ||||
| public: | ||||
|   virtual bool ProvidesSource(int Source) const; | ||||
|          // Returns true if this device can provide the given source. | ||||
|   virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const; | ||||
|          // Returns true if this device can provide the given channel. | ||||
|          // In case the device has cReceivers attached to it or it is the primary | ||||
|   | ||||
							
								
								
									
										136
									
								
								diseqc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								diseqc.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| /* | ||||
|  * diseqc.c: DiSEqC handling | ||||
|  * | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: diseqc.c 1.1 2002/10/05 13:54:32 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "diseqc.h" | ||||
| #include <ctype.h> | ||||
| #include "sources.h" | ||||
|  | ||||
| // -- cDiseqc ---------------------------------------------------------------- | ||||
|  | ||||
| cDiseqc::cDiseqc(void) | ||||
| { | ||||
|   commands = NULL; | ||||
|   currentAction = NULL;; | ||||
|   parsing = false; | ||||
|   numCodes = 0; | ||||
| } | ||||
|  | ||||
| cDiseqc::~cDiseqc() | ||||
| { | ||||
|   free(commands); | ||||
| } | ||||
|  | ||||
| bool cDiseqc::Parse(const char *s) | ||||
| { | ||||
|   bool result = false; | ||||
|   char *sourcebuf = NULL; | ||||
|   int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands); | ||||
|   if (fields == 4) | ||||
|      commands = NULL; //XXX Apparently sscanf() doesn't work correctly if the last %a argument results in an empty string | ||||
|   if (4 <= fields && fields <= 5) { | ||||
|      source = cSource::FromString(sourcebuf); | ||||
|      if (Sources.Get(source)) { | ||||
|         polarization = toupper(polarization); | ||||
|         if (polarization == 'V' || polarization == 'H') { | ||||
|            parsing = true; | ||||
|            bool Start = true; | ||||
|            while (Execute(Start) != daNone) | ||||
|                  Start = false; | ||||
|            parsing = false; | ||||
|            result = !commands || currentAction && !*currentAction; | ||||
|            } | ||||
|         else | ||||
|            esyslog("ERROR: unknown polarization '%c'", polarization); | ||||
|         } | ||||
|      else | ||||
|         esyslog("ERROR: unknown source '%s'", sourcebuf); | ||||
|      } | ||||
|   free(sourcebuf); | ||||
|   return result; | ||||
| } | ||||
|  | ||||
| char *cDiseqc::Wait(char *s) | ||||
| { | ||||
|   char *p = NULL; | ||||
|   errno = 0; | ||||
|   int n = strtol(s, &p, 10); | ||||
|   if (!errno && p != s && n >= 0) { | ||||
|      if (!parsing) | ||||
|         usleep(n * 1000); | ||||
|      return p; | ||||
|      } | ||||
|   esyslog("ERROR: illegal value for wait time in '%s'", s - 1); | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| char *cDiseqc::Codes(char *s) | ||||
| { | ||||
|   char *e = strchr(s, ']'); | ||||
|   if (e) { | ||||
|      numCodes = 0; | ||||
|      char *t = s; | ||||
|      char *p = s; | ||||
|      while (t < e) { | ||||
|            if (numCodes < MaxDiseqcCodes) { | ||||
|               errno = 0; | ||||
|               int n = strtol(t, &p, 16); | ||||
|               if (!errno && p != t && 0 <= n && n <= 255) { | ||||
|                  codes[numCodes++] = n; | ||||
|                  t = skipspace(p); | ||||
|                  } | ||||
|               else { | ||||
|                  esyslog("ERROR: illegal code at '%s'", t); | ||||
|                  return NULL; | ||||
|                  } | ||||
|               } | ||||
|            else { | ||||
|               esyslog("ERROR: too many codes in code sequence '%s'", s - 1); | ||||
|               return NULL; | ||||
|               } | ||||
|            } | ||||
|      return e + 1; | ||||
|      } | ||||
|   else | ||||
|      esyslog("ERROR: missing closing ']' in code sequence '%s'", s - 1); | ||||
|   return NULL; | ||||
| } | ||||
|  | ||||
| cDiseqc::eDiseqcActions cDiseqc::Execute(bool Start) | ||||
| { | ||||
|   if (Start) | ||||
|      currentAction = commands; | ||||
|   while (currentAction && *currentAction) { | ||||
|         switch (*currentAction++) { | ||||
|           case ' ': break; | ||||
|           case 't': return daToneOff; | ||||
|           case 'T': return daToneOn; | ||||
|           case 'v': return daVoltage13; | ||||
|           case 'V': return daVoltage18; | ||||
|           case 'A': return daMiniA; | ||||
|           case 'B': return daMiniB; | ||||
|           case 'W': currentAction = Wait(currentAction); break; | ||||
|           case '[': currentAction = Codes(currentAction); return currentAction ? daCodes : daNone; | ||||
|           default: return daNone; | ||||
|           } | ||||
|         } | ||||
|   return daNone; | ||||
| } | ||||
|  | ||||
| // -- cDiseqcs --------------------------------------------------------------- | ||||
|  | ||||
| cDiseqcs Diseqcs; | ||||
|  | ||||
| cDiseqc *cDiseqcs::Get(int Source, int Frequency, char Polarization) | ||||
| { | ||||
|   for (cDiseqc *p = First(); p; p = Next(p)) { | ||||
|       if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) | ||||
|         return p; | ||||
|       } | ||||
|   return NULL; | ||||
| } | ||||
							
								
								
									
										30
									
								
								diseqc.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								diseqc.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| # DiSEqC configuration for VDR | ||||
| # | ||||
| # Format: | ||||
| # | ||||
| # satellite slof polarization lof command... | ||||
| # | ||||
| # satellite:      one of the 'S' codes defined in sources.conf | ||||
| # slof:           switch frequency of LNB; the first entry with | ||||
| #                 an slof greater than the actual transponder | ||||
| #                 frequency will be used | ||||
| # polarization:   V = vertical, H = horizontal | ||||
| # lof:            the local oscillator frequency to subtract from | ||||
| #                 the actual transponder frequency | ||||
| # command: | ||||
| #   t         tone off | ||||
| #   T         tone on | ||||
| #   v         voltage low (13V) | ||||
| #   V         voltage high (18V) | ||||
| #   A         mini A | ||||
| #   B         mini B | ||||
| #   Wnn       wait nn milliseconds (nn may be any positive integer number) | ||||
| #   [xx ...]  hex code sequence (max. 6) | ||||
| # | ||||
| # The 'command...' part is optional. | ||||
|  | ||||
| S19.2E  11700 V  9750  t v W15 [E0 10 38 F0] W15 A W15 t | ||||
| S19.2E  99999 V 10600  t v W15 [E0 10 38 F1] W15 A W15 T | ||||
| S19.2E  11700 H  9750  t V W15 [E0 10 38 F2] W15 A W15 t | ||||
| S19.2E  99999 H 10600  t V W15 [E0 10 38 F3] W15 A W15 T | ||||
|  | ||||
							
								
								
									
										60
									
								
								diseqc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								diseqc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| /* | ||||
|  * diseqc.h: DiSEqC handling | ||||
|  * | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: diseqc.h 1.1 2002/10/05 13:02:52 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __DISEQC_H | ||||
| #define __DISEQC_H | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| class cDiseqc : public cListObject { | ||||
| public: | ||||
|   enum eDiseqcActions { | ||||
|     daNone, | ||||
|     daToneOff, | ||||
|     daToneOn, | ||||
|     daVoltage13, | ||||
|     daVoltage18, | ||||
|     daMiniA, | ||||
|     daMiniB, | ||||
|     daCodes, | ||||
|     }; | ||||
|   enum { MaxDiseqcCodes = 6 }; | ||||
| private: | ||||
|   int source; | ||||
|   int slof; | ||||
|   char polarization; | ||||
|   int lof; | ||||
|   char *commands; | ||||
|   char *currentAction; | ||||
|   bool parsing; | ||||
|   uchar codes[MaxDiseqcCodes]; | ||||
|   int numCodes; | ||||
|   char *Wait(char *s); | ||||
|   char *Codes(char *s); | ||||
| public: | ||||
|   cDiseqc(void); | ||||
|   ~cDiseqc(); | ||||
|   bool Parse(const char *s); | ||||
|   eDiseqcActions Execute(bool Start = false); | ||||
|   int Source(void) const { return source; } | ||||
|   int Slof(void) const { return slof; } | ||||
|   char Polarization(void) const { return polarization; } | ||||
|   int Lof(void) const { return lof; } | ||||
|   const char *Commands(void) const { return commands; } | ||||
|   uchar *Codes(int &NumCodes) { NumCodes = numCodes; return numCodes ? codes : NULL; } | ||||
|   }; | ||||
|  | ||||
| class cDiseqcs : public cConfig<cDiseqc> { | ||||
| public: | ||||
|   cDiseqc *Get(int Source, int Frequency, char Polarization); | ||||
|   }; | ||||
|  | ||||
| extern cDiseqcs Diseqcs; | ||||
|  | ||||
| #endif //__DISEQC_H | ||||
							
								
								
									
										278
									
								
								dvbdevice.c
									
									
									
									
									
								
							
							
						
						
									
										278
									
								
								dvbdevice.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: dvbdevice.c 1.21 2002/09/29 13:53:26 kls Exp $ | ||||
|  * $Id: dvbdevice.c 1.22 2002/10/06 09:07:45 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "dvbdevice.h" | ||||
| @@ -31,6 +31,8 @@ extern "C" { | ||||
| #endif | ||||
| #include <sys/ioctl.h> | ||||
| #include <sys/mman.h> | ||||
| #include "channels.h" | ||||
| #include "diseqc.h" | ||||
| #include "dvbosd.h" | ||||
| #include "player.h" | ||||
| #include "receiver.h" | ||||
| @@ -124,7 +126,9 @@ cDvbDevice::cDvbDevice(int n) | ||||
|   else | ||||
|      esyslog("ERROR: can't open DVB device %d", n); | ||||
|  | ||||
|   frequency = 0; | ||||
|   source = -1; | ||||
|   frequency = -1; | ||||
|   diseqcCommands = NULL; | ||||
| } | ||||
|  | ||||
| cDvbDevice::~cDvbDevice() | ||||
| @@ -344,18 +348,33 @@ bool cDvbDevice::SetPid(cPidHandle *Handle, int Type, bool On) | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool cDvbDevice::IsTunedTo(const cChannel *Channel) const | ||||
| { | ||||
|   return source == Channel->Source() && frequency == Channel->Frequency(); | ||||
| } | ||||
|  | ||||
| bool cDvbDevice::ProvidesSource(int Source) const | ||||
| { | ||||
|   int type = Source & cSource::st_Mask; | ||||
|   return type == cSource::stNone | ||||
|       || type == cSource::stCable && frontendType == FE_QAM | ||||
|       || type == cSource::stSat   && frontendType == FE_QPSK | ||||
|       || type == cSource::stTerr  && frontendType == FE_OFDM; | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const | ||||
| { | ||||
|   bool result = false; | ||||
|   bool hasPriority = Priority < 0 || Priority > this->Priority(); | ||||
|   bool needsDetachReceivers = true; | ||||
|  | ||||
|   if (ProvidesCa(Channel->ca)) { | ||||
|   if (ProvidesSource(Channel->Source()) && ProvidesCa(Channel->Ca())) { | ||||
|      if (Receiving()) { | ||||
|         if (frequency == Channel->frequency) { | ||||
|         if (IsTunedTo(Channel)) { | ||||
|            needsDetachReceivers = false; | ||||
|            if (!HasPid(Channel->vpid)) { | ||||
|               if (Channel->ca > CACONFBASE) { | ||||
|            if (!HasPid(Channel->Vpid())) { | ||||
|               if (Channel->Ca() > CACONFBASE) { | ||||
|                  needsDetachReceivers = true; | ||||
|                  result = hasPriority; | ||||
|                  } | ||||
| @@ -394,24 +413,24 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) | ||||
|      LiveView = true; | ||||
| #endif | ||||
|  | ||||
|   bool DoTune = frequency != Channel->frequency; // TODO will be changed when DiSEqC handling is revised | ||||
|   bool DoTune = !IsTunedTo(Channel); | ||||
|  | ||||
|   bool TurnOffLivePIDs = HasDecoder() | ||||
|                          && (DoTune | ||||
|                             || Channel->ca > CACONFBASE && pidHandles[ptVideo].pid != Channel->vpid // CA channels can only be decrypted in "live" mode | ||||
|                             || Channel->Ca() > CACONFBASE && pidHandles[ptVideo].pid != Channel->Vpid() // CA channels can only be decrypted in "live" mode | ||||
|                             || IsPrimaryDevice() | ||||
|                                && (LiveView // for a new live view the old PIDs need to be turned off | ||||
|                                   || pidHandles[ptVideo].pid == Channel->vpid // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER | ||||
|                                   || pidHandles[ptVideo].pid == Channel->Vpid() // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER | ||||
|                                   ) | ||||
|                             ); | ||||
|  | ||||
|   bool StartTransferMode = IsPrimaryDevice() && !DoTune | ||||
|                            && (LiveView && HasPid(Channel->vpid) && pidHandles[ptVideo].pid != Channel->vpid // the PID is already set as DMX_PES_OTHER | ||||
|                               || !LiveView && pidHandles[ptVideo].pid == Channel->vpid // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER | ||||
|                            && (LiveView && HasPid(Channel->Vpid()) && pidHandles[ptVideo].pid != Channel->Vpid() // the PID is already set as DMX_PES_OTHER | ||||
|                               || !LiveView && pidHandles[ptVideo].pid == Channel->Vpid() // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER | ||||
|                               ); | ||||
|  | ||||
|   bool TurnOnLivePIDs = HasDecoder() && !StartTransferMode | ||||
|                         && (Channel->ca > CACONFBASE // CA channels can only be decrypted in "live" mode | ||||
|                         && (Channel->Ca() > CACONFBASE // CA channels can only be decrypted in "live" mode | ||||
|                            || LiveView | ||||
|                            ); | ||||
|  | ||||
| @@ -452,67 +471,127 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) | ||||
|      switch (frontendType) { | ||||
|        case FE_QPSK: { // DVB-S | ||||
|  | ||||
|             // Frequency offsets: | ||||
|             unsigned int frequency = Channel->Frequency(); | ||||
|  | ||||
|             unsigned int freq = Channel->frequency; | ||||
|             int tone = SEC_TONE_OFF; | ||||
|             if (Setup.DiSEqC) { | ||||
|                cDiseqc *diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); | ||||
|                if (diseqc) { | ||||
|                   if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) { | ||||
| #ifndef NEWSTRUCT | ||||
|                      int SecTone = SEC_TONE_OFF; | ||||
|                      int SecVolt = SEC_VOLTAGE_13; | ||||
| #endif | ||||
|                      cDiseqc::eDiseqcActions da; | ||||
|                      for (bool Start = true; (da = diseqc->Execute(Start)) != cDiseqc::daNone; Start = false) { | ||||
|                          switch (da) { | ||||
| #ifdef NEWSTRUCT | ||||
|                            case cDiseqc::daNone:      break; | ||||
|                            case cDiseqc::daToneOff:   CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; | ||||
|                            case cDiseqc::daToneOn:    CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break; | ||||
|                            case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break; | ||||
|                            case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; | ||||
|                            case cDiseqc::daMiniA:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; | ||||
|                            case cDiseqc::daMiniB:     CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; | ||||
|                            case cDiseqc::daCodes: { | ||||
|                                 int n = 0; | ||||
|                                 uchar *codes = diseqc->Codes(n); | ||||
|                                 if (codes) { | ||||
|                                    struct dvb_diseqc_master_cmd cmd; | ||||
|                                    memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg)))); | ||||
|                                    cmd.msg_len = n; | ||||
|                                    CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); | ||||
|                                    } | ||||
|                                 } | ||||
|                                 break; | ||||
| #else | ||||
|                            // This may not work very good with the old driver. | ||||
|                            // Let's try to emulate the NEWSTRUCT driver's behaviour as good as possible... | ||||
|                            case cDiseqc::daNone:      break; | ||||
|                            case cDiseqc::daToneOff:   CHECK(ioctl(fd_sec, SEC_SET_TONE, SecTone = SEC_TONE_OFF)); break; | ||||
|                            case cDiseqc::daToneOn:    CHECK(ioctl(fd_sec, SEC_SET_TONE, SecTone = SEC_TONE_ON)); break; | ||||
|                            case cDiseqc::daVoltage13: CHECK(ioctl(fd_sec, SEC_SET_VOLTAGE, SecVolt = SEC_VOLTAGE_13)); break; | ||||
|                            case cDiseqc::daVoltage18: CHECK(ioctl(fd_sec, SEC_SET_VOLTAGE, SecVolt = SEC_VOLTAGE_18)); break; | ||||
|                            case cDiseqc::daMiniA: | ||||
|                            case cDiseqc::daMiniB: { | ||||
|                                 secCmdSequence scmds; | ||||
|                                 memset(&scmds, 0, sizeof(scmds)); | ||||
|                                 scmds.voltage = SecVolt; | ||||
|                                 scmds.miniCommand = (da == cDiseqc::daMiniA) ? SEC_MINI_A : SEC_MINI_B; | ||||
|                                 scmds.continuousTone = SecTone; | ||||
|                                 CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds)); | ||||
|                                 } | ||||
|                                 break; | ||||
|                            case cDiseqc::daCodes: { | ||||
|                                 int n = 0; | ||||
|                                 uchar *codes = diseqc->Codes(n); | ||||
|                                 if (codes && n >= 3 && codes[0] == 0xE0) { | ||||
|                                    secCommand scmd; | ||||
|                                    memset(&scmd, 0, sizeof(scmd)); | ||||
|                                    scmd.type = SEC_CMDTYPE_DISEQC; | ||||
|                                    scmd.u.diseqc.addr = codes[1]; | ||||
|                                    scmd.u.diseqc.cmd = codes[2]; | ||||
|                                    scmd.u.diseqc.numParams = n - 3; | ||||
|                                    memcpy(scmd.u.diseqc.params, &codes[3], min(n - 3, int(sizeof(scmd.u.diseqc.params)))); | ||||
|     | ||||
|                                    secCmdSequence scmds; | ||||
|                                    memset(&scmds, 0, sizeof(scmds)); | ||||
|                                    scmds.voltage = SecVolt; | ||||
|                                    scmds.miniCommand = SEC_MINI_NONE; | ||||
|                                    scmds.continuousTone = SecTone; | ||||
|                                    scmds.numCommands = 1; | ||||
|                                    scmds.commands = &scmd; | ||||
|  | ||||
|             if (freq < (unsigned int)Setup.LnbSLOF) { | ||||
|                freq -= Setup.LnbFrequLo; | ||||
|                tone = SEC_TONE_OFF; | ||||
|                                    CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds)); | ||||
|                                    } | ||||
|                                 } | ||||
|                                 break; | ||||
| #endif | ||||
|                            } | ||||
|                          } | ||||
|                      diseqcCommands = diseqc->Commands(); | ||||
|                      } | ||||
|                   frequency -= diseqc->Lof(); | ||||
|                   } | ||||
|                else { | ||||
|                   esyslog("ERROR: no DiSEqC parameters found for channel %d", Channel->Number()); | ||||
|                   return false; | ||||
|                   } | ||||
|                } | ||||
|             else { | ||||
|                freq -= Setup.LnbFrequHi; | ||||
|                tone = SEC_TONE_ON; | ||||
|                } | ||||
|                int tone = SEC_TONE_OFF; | ||||
|  | ||||
|                if (frequency < (unsigned int)Setup.LnbSLOF) { | ||||
|                   frequency -= Setup.LnbFrequLo; | ||||
|                   tone = SEC_TONE_OFF; | ||||
|                   } | ||||
|                else { | ||||
|                   frequency -= Setup.LnbFrequHi; | ||||
|                   tone = SEC_TONE_ON; | ||||
|                   } | ||||
|                int volt = (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18; | ||||
| #ifdef NEWSTRUCT | ||||
|             Frontend.frequency = freq * 1000UL; | ||||
|             Frontend.inversion = INVERSION_AUTO; | ||||
|             Frontend.u.qpsk.symbol_rate = Channel->srate * 1000UL; | ||||
|             Frontend.u.qpsk.fec_inner = FEC_AUTO; | ||||
|                CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt)); | ||||
|                CHECK(ioctl(fd_frontend, FE_SET_TONE, tone)); | ||||
| #else | ||||
|             Frontend.Frequency = freq * 1000UL; | ||||
|             Frontend.Inversion = INVERSION_AUTO; | ||||
|             Frontend.u.qpsk.SymbolRate = Channel->srate * 1000UL; | ||||
|             Frontend.u.qpsk.FEC_inner = FEC_AUTO; | ||||
|                secCmdSequence scmds; | ||||
|                memset(&scmds, 0, sizeof(scmds)); | ||||
|                scmds.voltage = volt; | ||||
|                scmds.miniCommand = SEC_MINI_NONE; | ||||
|                scmds.continuousTone = tone; | ||||
|                CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds)); | ||||
| #endif | ||||
|  | ||||
|             int volt = (Channel->polarization == 'v' || Channel->polarization == 'V') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18; | ||||
|  | ||||
|             // DiSEqC: | ||||
|                } | ||||
|  | ||||
| #ifdef NEWSTRUCT | ||||
|             struct dvb_diseqc_master_cmd cmd = { {0xE0, 0x10, 0x38, 0xF0, 0x00, 0x00}, 4}; | ||||
|             cmd.msg[3] = 0xF0 | (((Channel->diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0)); | ||||
|  | ||||
|             if (Setup.DiSEqC) | ||||
|                CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); | ||||
|             CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt)); | ||||
|             if (Setup.DiSEqC) { | ||||
|                usleep(15 * 1000); | ||||
|                CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); | ||||
|                usleep(15 * 1000); | ||||
|                CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, (Channel->diseqc / 4) % 2 ? SEC_MINI_B : SEC_MINI_A)); | ||||
|                usleep(15 * 1000); | ||||
|                } | ||||
|             CHECK(ioctl(fd_frontend, FE_SET_TONE, tone)); | ||||
|             Frontend.frequency = frequency * 1000UL; | ||||
|             Frontend.inversion = SpectralInversion(Channel->Inversion()); | ||||
|             Frontend.u.qpsk.symbol_rate = Channel->Srate() * 1000UL; | ||||
|             Frontend.u.qpsk.fec_inner = CodeRate(Channel->CoderateH()); | ||||
| #else | ||||
|             secCommand scmd; | ||||
|             scmd.type = 0; | ||||
|             scmd.u.diseqc.addr = 0x10; | ||||
|             scmd.u.diseqc.cmd = 0x38; | ||||
|             scmd.u.diseqc.numParams = 1; | ||||
|             scmd.u.diseqc.params[0] = 0xF0 | ((Channel->diseqc * 4) & 0x0F) | (tone == SEC_TONE_ON ? 1 : 0) | (volt == SEC_VOLTAGE_18 ? 2 : 0); | ||||
|  | ||||
|             secCmdSequence scmds; | ||||
|             scmds.voltage = volt; | ||||
|             scmds.miniCommand = SEC_MINI_NONE; | ||||
|             scmds.continuousTone = tone; | ||||
|             scmds.numCommands = Setup.DiSEqC ? 1 : 0; | ||||
|             scmds.commands = &scmd; | ||||
|  | ||||
|             CHECK(ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds)); | ||||
|             Frontend.Frequency = frequency * 1000UL; | ||||
|             Frontend.Inversion = SpectralInversion(Channel->Inversion()); | ||||
|             Frontend.u.qpsk.SymbolRate = Channel->Srate() * 1000UL; | ||||
|             Frontend.u.qpsk.FEC_inner = CodeRate(Channel->CoderateH()); | ||||
| #endif | ||||
|             } | ||||
|             break; | ||||
| @@ -521,17 +600,17 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) | ||||
|             // Frequency and symbol rate: | ||||
|  | ||||
| #ifdef NEWSTRUCT | ||||
|             Frontend.frequency = Channel->frequency * 1000000UL; | ||||
|             Frontend.inversion = INVERSION_AUTO; | ||||
|             Frontend.u.qam.symbol_rate = Channel->srate * 1000UL; | ||||
|             Frontend.u.qam.fec_inner = FEC_AUTO; | ||||
|             Frontend.u.qam.modulation = QAM_64; | ||||
|             Frontend.frequency = Channel->Frequency() * 1000000UL; | ||||
|             Frontend.inversion = SpectralInversion(Channel->Inversion()); | ||||
|             Frontend.u.qam.symbol_rate = Channel->Srate() * 1000UL; | ||||
|             Frontend.u.qam.fec_inner = CodeRate(Channel->CoderateH()); | ||||
|             Frontend.u.qam.modulation = Modulation(Channel->Modulation()); | ||||
| #else | ||||
|             Frontend.Frequency = Channel->frequency * 1000000UL; | ||||
|             Frontend.Inversion = INVERSION_AUTO; | ||||
|             Frontend.u.qam.SymbolRate = Channel->srate * 1000UL; | ||||
|             Frontend.u.qam.FEC_inner = FEC_AUTO; | ||||
|             Frontend.u.qam.QAM = QAM_64; | ||||
|             Frontend.Frequency = Channel->Frequency() * 1000000UL; | ||||
|             Frontend.Inversion = SpectralInversion(Channel->Inversion()); | ||||
|             Frontend.u.qam.SymbolRate = Channel->Srate() * 1000UL; | ||||
|             Frontend.u.qam.FEC_inner = CodeRate(Channel->CoderateH()); | ||||
|             Frontend.u.qam.QAM = Modulation(Channel->Modulation()); | ||||
| #endif | ||||
|             } | ||||
|             break; | ||||
| @@ -540,25 +619,25 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) | ||||
|             // Frequency and OFDM paramaters: | ||||
|  | ||||
| #ifdef NEWSTRUCT | ||||
|             Frontend.frequency = Channel->frequency * 1000UL; | ||||
|             Frontend.inversion = INVERSION_AUTO; | ||||
|             Frontend.u.ofdm.bandwidth=BANDWIDTH_8_MHZ; | ||||
|             Frontend.u.ofdm.code_rate_HP = FEC_2_3; | ||||
|             Frontend.u.ofdm.code_rate_LP = FEC_1_2; | ||||
|             Frontend.u.ofdm.constellation = QAM_64; | ||||
|             Frontend.u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; | ||||
|             Frontend.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; | ||||
|             Frontend.u.ofdm.hierarchy_information = HIERARCHY_NONE; | ||||
|             Frontend.frequency = Channel->Frequency() * 1000UL; | ||||
|             Frontend.inversion = SpectralInversion(Channel->Inversion()); | ||||
|             Frontend.u.ofdm.bandwidth = BandWidth(Channel->Bandwidth()); | ||||
|             Frontend.u.ofdm.code_rate_HP = CodeRate(Channel->CoderateH()); | ||||
|             Frontend.u.ofdm.code_rate_LP = CodeRate(Channel->CoderateL()); | ||||
|             Frontend.u.ofdm.constellation = Modulation(Channel->Modulation()); | ||||
|             Frontend.u.ofdm.transmission_mode = TransmitMode(Channel->Transmission()); | ||||
|             Frontend.u.ofdm.guard_interval = GuardInterval(Channel->Guard()); | ||||
|             Frontend.u.ofdm.hierarchy_information = Hierarchy(Channel->Hierarchy()); | ||||
| #else | ||||
|             Frontend.Frequency = Channel->frequency * 1000UL; | ||||
|             Frontend.Inversion = INVERSION_AUTO; | ||||
|             Frontend.u.ofdm.bandWidth=BANDWIDTH_8_MHZ; | ||||
|             Frontend.u.ofdm.HP_CodeRate=FEC_2_3; | ||||
|             Frontend.u.ofdm.LP_CodeRate=FEC_1_2; | ||||
|             Frontend.u.ofdm.Constellation=QAM_64; | ||||
|             Frontend.u.ofdm.TransmissionMode=TRANSMISSION_MODE_2K; | ||||
|             Frontend.u.ofdm.guardInterval=GUARD_INTERVAL_1_32; | ||||
|             Frontend.u.ofdm.HierarchyInformation=HIERARCHY_NONE; | ||||
|             Frontend.Frequency = Channel->Frequency() * 1000UL; | ||||
|             Frontend.Inversion = SpectralInversion(Channel->Inversion()); | ||||
|             Frontend.u.ofdm.bandWidth = BandWidth(Channel->Bandwidth()); | ||||
|             Frontend.u.ofdm.HP_CodeRate = CodeRate(Channel->CoderateH()); | ||||
|             Frontend.u.ofdm.LP_CodeRate = CodeRate(Channel->CoderateL()); | ||||
|             Frontend.u.ofdm.Constellation = Modulation(Channel->Modulation()); | ||||
|             Frontend.u.ofdm.TransmissionMode = TransmitMode(Channel->Transmission()); | ||||
|             Frontend.u.ofdm.guardInterval = GuardInterval(Channel->Guard()); | ||||
|             Frontend.u.ofdm.HierarchyInformation = Hierarchy(Channel->Hierarchy()); | ||||
| #endif | ||||
|             } | ||||
|             break; | ||||
| @@ -592,7 +671,7 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) | ||||
|          usleep(10 * 1000); | ||||
|          } | ||||
|      if (!(status & FE_HAS_LOCK)) { | ||||
|         esyslog("ERROR: channel %d not locked on DVB card %d!", Channel->number, CardIndex() + 1); | ||||
|         esyslog("ERROR: channel %d not locked on DVB card %d!", Channel->Number(), CardIndex() + 1); | ||||
|         if (LiveView && IsPrimaryDevice()) | ||||
|            cThread::RaisePanic(); | ||||
|         return false; | ||||
| @@ -602,43 +681,44 @@ bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) | ||||
|         FrontendEvent event; | ||||
|         if (ioctl(fd_frontend, FE_GET_EVENT, &event) >= 0) { | ||||
|            if (event.type != FE_COMPLETION_EV) { | ||||
|               esyslog("ERROR: channel %d not sync'ed on DVB card %d!", Channel->number, CardIndex() + 1); | ||||
|               esyslog("ERROR: channel %d not sync'ed on DVB card %d!", Channel->Number(), CardIndex() + 1); | ||||
|               if (LiveView && IsPrimaryDevice()) | ||||
|                  cThread::RaisePanic(); | ||||
|               return false; | ||||
|               } | ||||
|            } | ||||
|         else | ||||
|            esyslog("ERROR in frontend get event (channel %d, card %d): %m", Channel->number, CardIndex() + 1); | ||||
|            esyslog("ERROR in frontend get event (channel %d, card %d): %m", Channel->Number(), CardIndex() + 1); | ||||
|         } | ||||
|      else | ||||
|         esyslog("ERROR: timeout while tuning on DVB card %d", CardIndex() + 1); | ||||
| #endif | ||||
|  | ||||
|      frequency = Channel->frequency; | ||||
|      source = Channel->Source(); | ||||
|      frequency = Channel->Frequency(); | ||||
|  | ||||
|      } | ||||
|  | ||||
|   // PID settings: | ||||
|  | ||||
|   if (TurnOnLivePIDs) { | ||||
|      if (!(AddPid(Channel->apid1, ptAudio) && AddPid(Channel->vpid, ptVideo))) {//XXX+ dolby dpid1!!! (if audio plugins are attached) | ||||
|         esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->number, CardIndex() + 1); | ||||
|      if (!(AddPid(Channel->Apid1(), ptAudio) && AddPid(Channel->Vpid(), ptVideo))) {//XXX+ dolby dpid1!!! (if audio plugins are attached) | ||||
|         esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1); | ||||
|         return false; | ||||
|         } | ||||
|      if (IsPrimaryDevice()) | ||||
|         AddPid(Channel->tpid, ptTeletext); | ||||
|         AddPid(Channel->Tpid(), ptTeletext); | ||||
|      CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true)); | ||||
|      CHECK(ioctl(fd_audio, AUDIO_SET_MUTE, false)); | ||||
|      CHECK(ioctl(fd_video, VIDEO_SET_BLANK, false)); | ||||
|      } | ||||
|   else if (StartTransferMode) | ||||
|      cControl::Launch(new cTransferControl(this, Channel->vpid, Channel->apid1, 0, 0, 0)); | ||||
|      cControl::Launch(new cTransferControl(this, Channel->Vpid(), Channel->Apid1(), 0, 0, 0)); | ||||
|  | ||||
|   // Start setting system time: | ||||
|  | ||||
|   if (siProcessor) | ||||
|      siProcessor->SetCurrentTransponder(Channel->frequency); | ||||
|      siProcessor->SetCurrentTransponder(Channel->Frequency()); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: dvbdevice.h 1.11 2002/09/28 12:21:36 kls Exp $ | ||||
|  * $Id: dvbdevice.h 1.12 2002/10/06 08:57:24 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __DVBDEVICE_H | ||||
| @@ -61,8 +61,12 @@ public: | ||||
| // Channel facilities | ||||
|  | ||||
| private: | ||||
|   int source; | ||||
|   int frequency; | ||||
|   const char *diseqcCommands; | ||||
|   bool IsTunedTo(const cChannel *Channel) const; | ||||
| public: | ||||
|   virtual bool ProvidesSource(int Source) const; | ||||
|   virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const; | ||||
| protected: | ||||
|   virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); | ||||
|   | ||||
							
								
								
									
										7
									
								
								eit.c
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								eit.c
									
									
									
									
									
								
							| @@ -16,7 +16,7 @@ | ||||
|  *   the Free Software Foundation; either version 2 of the License, or     * | ||||
|  *   (at your option) any later version.                                   * | ||||
|  *                                                                         * | ||||
|  * $Id: eit.c 1.52 2002/09/20 16:24:17 kls Exp $ | ||||
|  * $Id: eit.c 1.53 2002/10/05 13:44:23 kls Exp $ | ||||
|  ***************************************************************************/ | ||||
|  | ||||
| #include "eit.h" | ||||
| @@ -40,6 +40,7 @@ | ||||
| #include <sys/types.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| #include "channels.h" | ||||
| #include "config.h" | ||||
| #include "libdtv/libdtv.h" | ||||
| #include "videodir.h" | ||||
| @@ -456,7 +457,7 @@ static void ReportEpgBugFixStats(bool Reset = false) | ||||
|             for (int c = 0; c < p->n; c++) { | ||||
|                 cChannel *channel = Channels.GetByServiceID(p->serviceIDs[c]); | ||||
|                 if (channel) { | ||||
|                    q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->name); | ||||
|                    q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name()); | ||||
|                    delim = ", "; | ||||
|                    } | ||||
|                 } | ||||
| @@ -768,7 +769,7 @@ void cSchedule::Dump(FILE *f, const char *Prefix) const | ||||
|    cChannel *channel = Channels.GetByServiceID(uServiceID); | ||||
|    if (channel) | ||||
|    { | ||||
|       fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->name); | ||||
|       fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->Name()); | ||||
|       for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) | ||||
|          p->Dump(f, Prefix); | ||||
|       fprintf(f, "%sc\n", Prefix); | ||||
|   | ||||
| @@ -4,11 +4,12 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: eitscan.c 1.7 2002/09/08 11:08:52 kls Exp $ | ||||
|  * $Id: eitscan.c 1.8 2002/10/05 13:44:35 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "eitscan.h" | ||||
| #include <stdlib.h> | ||||
| #include "channels.h" | ||||
| #include "dvbdevice.h" | ||||
|  | ||||
| cEITScanner::cEITScanner(void) | ||||
| @@ -28,11 +29,11 @@ cEITScanner::~cEITScanner() | ||||
| bool cEITScanner::TransponderScanned(cChannel *Channel) | ||||
| { | ||||
|   for (int i = 0; i < numTransponders; i++) { | ||||
|       if (transponders[i] == Channel->frequency) | ||||
|       if (transponders[i] == Channel->Frequency()) | ||||
|          return true; | ||||
|       } | ||||
|   transponders = (int *)realloc(transponders, ++numTransponders * sizeof(int)); | ||||
|   transponders[numTransponders - 1] = Channel->frequency; | ||||
|   transponders[numTransponders - 1] = Channel->Frequency(); | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| @@ -66,7 +67,7 @@ void cEITScanner::Process(void) | ||||
|                            if (Channel) { | ||||
|                               if (!Device->ProvidesChannel(Channel)) | ||||
|                                  break; | ||||
|                               if (Channel->pnr && !TransponderScanned(Channel)) { | ||||
|                               if (Channel->Sid() && !TransponderScanned(Channel)) { | ||||
|                                  if (Device == cDevice::PrimaryDevice() && !currentChannel) | ||||
|                                     currentChannel = Device->CurrentChannel(); | ||||
|                                  Device->SwitchChannel(Channel, false); | ||||
|   | ||||
							
								
								
									
										238
									
								
								i18n.c
									
									
									
									
									
								
							
							
						
						
									
										238
									
								
								i18n.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: i18n.c 1.93 2002/09/29 12:32:46 kls Exp $ | ||||
|  * $Id: i18n.c 1.94 2002/10/06 09:55:08 kls Exp $ | ||||
|  * | ||||
|  * Translations provided by: | ||||
|  * | ||||
| @@ -890,21 +890,21 @@ const tI18nPhrase Phrases[] = { | ||||
|     "Polarizare", | ||||
|     "Polariz<EFBFBD>ci<EFBFBD>", | ||||
|   }, | ||||
|   { "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|     "DiSEqC", | ||||
|   { "Source", | ||||
|     "Quelle", | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|     "",//TODO | ||||
|   }, | ||||
|   { "Srate", | ||||
|     "Srate", | ||||
| @@ -1034,21 +1034,149 @@ const tI18nPhrase Phrases[] = { | ||||
|     "Criptare", | ||||
|     "CA", | ||||
|   }, | ||||
|   { "Pnr", | ||||
|     "Pnr", | ||||
|     "Pnr", | ||||
|     "Pnr", | ||||
|     "Pnr", | ||||
|     "N<EFBFBD>m. Progr.", | ||||
|     "Num. Progr.", | ||||
|     "Program Id", | ||||
|     "Ohjelmatunnus", | ||||
|     "Pnr", | ||||
|     "Pnr", | ||||
|     "Pnr", | ||||
|     "Pnr", | ||||
|     "Nr. Prog.", | ||||
|     "Pnr", | ||||
|   { "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|     "Sid", | ||||
|   }, | ||||
|   { "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|     "Inversion", | ||||
|   }, | ||||
|   { "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|     "Bandwidth", | ||||
|   }, | ||||
|   { "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|     "CoderateH", | ||||
|   }, | ||||
|   { "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|     "CoderateL", | ||||
|   }, | ||||
|   { "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|     "Modulation", | ||||
|   }, | ||||
|   { "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|     "Transmission", | ||||
|   }, | ||||
|   { "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|     "Guard", | ||||
|   }, | ||||
|   { "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|     "Hierarchy", | ||||
|   }, | ||||
|   // Timer parameters: | ||||
|   { "Active", | ||||
| @@ -2723,6 +2851,54 @@ const tI18nPhrase Phrases[] = { | ||||
|     "nu", | ||||
|     "nem", | ||||
|   }, | ||||
|   { "off", | ||||
|     "aus", | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|   }, | ||||
|   { "none", | ||||
|     "keine", | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|   }, | ||||
|   { "auto", | ||||
|     "auto", | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|     "",// TODO | ||||
|   }, | ||||
|   { "top", | ||||
|     "oben", | ||||
|     "zgoraj", | ||||
|   | ||||
							
								
								
									
										271
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										271
									
								
								menu.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: menu.c 1.209 2002/09/29 12:50:47 kls Exp $ | ||||
|  * $Id: menu.c 1.210 2002/10/06 09:52:52 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "menu.h" | ||||
| @@ -13,6 +13,7 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include "channels.h" | ||||
| #include "config.h" | ||||
| #include "cutter.h" | ||||
| #include "eit.h" | ||||
| @@ -21,6 +22,7 @@ | ||||
| #include "plugin.h" | ||||
| #include "recording.h" | ||||
| #include "remote.h" | ||||
| #include "sources.h" | ||||
| #include "status.h" | ||||
| #include "videodir.h" | ||||
|  | ||||
| @@ -53,7 +55,7 @@ void cMenuEditChanItem::Set(void) | ||||
|   char buf[255]; | ||||
|   cChannel *channel = Channels.GetByNumber(*value); | ||||
|   if (channel) | ||||
|      snprintf(buf, sizeof(buf), "%d %s", *value, channel->name); | ||||
|      snprintf(buf, sizeof(buf), "%d %s", *value, channel->Name()); | ||||
|   else | ||||
|      *buf = 0; | ||||
|   SetValue(buf); | ||||
| @@ -77,8 +79,8 @@ cMenuEditTranItem::cMenuEditTranItem(const char *Name, int *Value) | ||||
|   transponder = *Value; | ||||
|   cChannel *channel = Channels.First(); | ||||
|   while (channel) { | ||||
|         if (!channel->groupSep && ISTRANSPONDER(channel->frequency, *Value)) { | ||||
|            number = channel->number; | ||||
|         if (!channel->GroupSep() && ISTRANSPONDER(channel->Frequency(), *Value)) { | ||||
|            number = channel->Number(); | ||||
|            break; | ||||
|            } | ||||
|         channel = (cChannel *)channel->Next(); | ||||
| @@ -95,7 +97,7 @@ eOSState cMenuEditTranItem::ProcessKey(eKeys Key) | ||||
|   number = *value; | ||||
|   cChannel *channel = Channels.GetByNumber(*value); | ||||
|   if (channel) | ||||
|      transponder = channel->frequency; | ||||
|      transponder = channel->Frequency(); | ||||
|   *value = transponder; | ||||
|   return state; | ||||
| } | ||||
| @@ -391,12 +393,137 @@ eOSState cMenuEditCaItem::ProcessKey(eKeys Key) | ||||
|   return state; | ||||
| } | ||||
|  | ||||
| // --- cMenuEditSrcItem ------------------------------------------------------ | ||||
|  | ||||
| class cMenuEditSrcItem : public cMenuEditIntItem { | ||||
| private: | ||||
|   const cSource *source; | ||||
| protected: | ||||
|   virtual void Set(void); | ||||
| public: | ||||
|   cMenuEditSrcItem(const char *Name, int *Value); | ||||
|   eOSState ProcessKey(eKeys Key); | ||||
|   }; | ||||
|  | ||||
| cMenuEditSrcItem::cMenuEditSrcItem(const char *Name, int *Value) | ||||
| :cMenuEditIntItem(Name, Value, 0) | ||||
| { | ||||
|   source = Sources.Get(*Value); | ||||
|   Set(); | ||||
| } | ||||
|  | ||||
| void cMenuEditSrcItem::Set(void) | ||||
| { | ||||
|   if (source) { | ||||
|      char *buffer = NULL; | ||||
|      asprintf(&buffer, "%s - %s", cSource::ToString(source->Code()), source->Description()); | ||||
|      SetValue(buffer); | ||||
|      free(buffer); | ||||
|      } | ||||
|   else | ||||
|      cMenuEditIntItem::Set(); | ||||
| } | ||||
|  | ||||
| eOSState cMenuEditSrcItem::ProcessKey(eKeys Key) | ||||
| { | ||||
|   eOSState state = cMenuEditItem::ProcessKey(Key); | ||||
|  | ||||
|   if (state == osUnknown) { | ||||
|      if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly? | ||||
|         if (source && source->Prev()) { | ||||
|            source = (cSource *)source->Prev(); | ||||
|            *value = source->Code(); | ||||
|            } | ||||
|         } | ||||
|      else if (NORMALKEY(Key) == kRight) { | ||||
|         if (source) {  | ||||
|            if (source->Next()) | ||||
|               source = (cSource *)source->Next(); | ||||
|            } | ||||
|         else | ||||
|            source = Sources.First(); | ||||
|         if (source) | ||||
|            *value = source->Code(); | ||||
|         } | ||||
|      else | ||||
|         return state; // we don't call cMenuEditIntItem::ProcessKey(Key) here since we don't accept numerical input | ||||
|      Set(); | ||||
|      state = osContinue; | ||||
|      } | ||||
|   return state; | ||||
| } | ||||
|  | ||||
| // --- cMenuEditMapItem ------------------------------------------------------ | ||||
|  | ||||
| class cMenuEditMapItem : public cMenuEditItem { | ||||
| protected: | ||||
|   int *value; | ||||
|   const tChannelParameterMap *map; | ||||
|   const char *zeroString; | ||||
|   virtual void Set(void); | ||||
| public: | ||||
|   cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString = NULL); | ||||
|   virtual eOSState ProcessKey(eKeys Key); | ||||
|   }; | ||||
|  | ||||
| cMenuEditMapItem::cMenuEditMapItem(const char *Name, int *Value, const tChannelParameterMap *Map, const char *ZeroString) | ||||
| :cMenuEditItem(Name) | ||||
| { | ||||
|   value = Value; | ||||
|   map = Map; | ||||
|   zeroString = ZeroString; | ||||
|   Set(); | ||||
| } | ||||
|  | ||||
| void cMenuEditMapItem::Set(void) | ||||
| { | ||||
|   int n = MapToUser(*value, map); | ||||
|   if (n == 999) | ||||
|      SetValue(tr("auto")); | ||||
|   else if (n == 0 && zeroString) | ||||
|      SetValue(zeroString); | ||||
|   else if (n >= 0) { | ||||
|      char buf[16]; | ||||
|      snprintf(buf, sizeof(buf), "%d", n); | ||||
|      SetValue(buf); | ||||
|      } | ||||
|   else | ||||
|      SetValue("???"); | ||||
| } | ||||
|  | ||||
| eOSState cMenuEditMapItem::ProcessKey(eKeys Key) | ||||
| { | ||||
|   eOSState state = cMenuEditItem::ProcessKey(Key); | ||||
|  | ||||
|   if (state == osUnknown) { | ||||
|      int newValue = *value; | ||||
|      int n = DriverIndex(*value, map); | ||||
|      if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly? | ||||
|         if (n-- > 0) | ||||
|            newValue = map[n].driverValue; | ||||
|         } | ||||
|      else if (NORMALKEY(Key) == kRight) { | ||||
|         if (map[++n].userValue >= 0) | ||||
|            newValue = map[n].driverValue; | ||||
|         } | ||||
|      else | ||||
|         return state; | ||||
|      if (newValue != *value) { | ||||
|         *value = newValue; | ||||
|         Set(); | ||||
|         } | ||||
|      state = osContinue; | ||||
|      } | ||||
|   return state; | ||||
| } | ||||
|  | ||||
| // --- cMenuEditChannel ------------------------------------------------------ | ||||
|  | ||||
| class cMenuEditChannel : public cOsdMenu { | ||||
| private: | ||||
|   cChannel *channel; | ||||
|   cChannel data; | ||||
|   void Setup(void); | ||||
| public: | ||||
|   cMenuEditChannel(int Index); | ||||
|   virtual eOSState ProcessKey(eKeys Key); | ||||
| @@ -408,24 +535,49 @@ cMenuEditChannel::cMenuEditChannel(int Index) | ||||
|   channel = Channels.Get(Index); | ||||
|   if (channel) { | ||||
|      data = *channel; | ||||
|      Add(new cMenuEditStrItem( tr("Name"),          data.name, sizeof(data.name), tr(FileNameChars))); | ||||
|      Add(new cMenuEditIntItem( tr("Frequency"),    &data.frequency)); | ||||
|      Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv")); | ||||
|      Add(new cMenuEditIntItem( tr("DiSEqC"),       &data.diseqc, 0, 10)); //TODO exact limits??? | ||||
|      Add(new cMenuEditIntItem( tr("Srate"),        &data.srate)); | ||||
|      Add(new cMenuEditIntItem( tr("Vpid"),         &data.vpid,  0, 0x1FFF)); | ||||
|      Add(new cMenuEditIntItem( tr("Apid1"),        &data.apid1, 0, 0x1FFF)); | ||||
|      Add(new cMenuEditIntItem( tr("Apid2"),        &data.apid2, 0, 0x1FFF)); | ||||
|      Add(new cMenuEditIntItem( tr("Dpid1"),        &data.dpid1, 0, 0x1FFF)); | ||||
|      Add(new cMenuEditIntItem( tr("Dpid2"),        &data.dpid2, 0, 0x1FFF)); | ||||
|      Add(new cMenuEditIntItem( tr("Tpid"),         &data.tpid,  0, 0x1FFF)); | ||||
|      Add(new cMenuEditCaItem(  tr("CA"),           &data.ca, true)); | ||||
|      Add(new cMenuEditIntItem( tr("Pnr"),          &data.pnr, 0)); | ||||
|      Setup(); | ||||
|      } | ||||
| } | ||||
|  | ||||
| void cMenuEditChannel::Setup(void) | ||||
| { | ||||
|   int current = Current(); | ||||
|   char type = *cSource::ToString(data.source); | ||||
| #define ST(s) if (strchr(s, type)) | ||||
|  | ||||
|   Clear(); | ||||
|  | ||||
|   // Parameters for all types of sources: | ||||
|   Add(new cMenuEditStrItem( tr("Name"),          data.name, sizeof(data.name), tr(FileNameChars))); | ||||
|   Add(new cMenuEditSrcItem( tr("Source"),       &data.source)); | ||||
|   Add(new cMenuEditIntItem( tr("Frequency"),    &data.frequency)); | ||||
|   Add(new cMenuEditIntItem( tr("Vpid"),         &data.vpid,  0, 0x1FFF)); | ||||
|   Add(new cMenuEditIntItem( tr("Apid1"),        &data.apid1, 0, 0x1FFF)); | ||||
|   Add(new cMenuEditIntItem( tr("Apid2"),        &data.apid2, 0, 0x1FFF)); | ||||
|   Add(new cMenuEditIntItem( tr("Dpid1"),        &data.dpid1, 0, 0x1FFF)); | ||||
|   Add(new cMenuEditIntItem( tr("Dpid2"),        &data.dpid2, 0, 0x1FFF)); | ||||
|   Add(new cMenuEditIntItem( tr("Tpid"),         &data.tpid,  0, 0x1FFF)); | ||||
|   Add(new cMenuEditCaItem(  tr("CA"),           &data.ca, true)); | ||||
|   Add(new cMenuEditIntItem( tr("Sid"),          &data.sid, 0)); | ||||
|   // Parameters for specific types of sources: | ||||
|   ST(" S ")  Add(new cMenuEditChrItem( tr("Polarization"), &data.polarization, "hv")); | ||||
|   ST("CS ")  Add(new cMenuEditIntItem( tr("Srate"),        &data.srate)); | ||||
|   ST("CST")  Add(new cMenuEditMapItem( tr("Inversion"),    &data.inversion,    InversionValues, tr("off"))); | ||||
|   ST("CST")  Add(new cMenuEditMapItem( tr("CoderateH"),    &data.coderateH,    CoderateValues, tr("none"))); | ||||
|   ST("  T")  Add(new cMenuEditMapItem( tr("CoderateL"),    &data.coderateL,    CoderateValues, tr("none"))); | ||||
|   ST("C T")  Add(new cMenuEditMapItem( tr("Modulation"),   &data.modulation,   ModulationValues, "QPSK")); | ||||
|   ST("  T")  Add(new cMenuEditMapItem( tr("Bandwidth"),    &data.bandwidth,    BandwidthValues)); | ||||
|   ST("  T")  Add(new cMenuEditMapItem( tr("Transmission"), &data.transmission, TransmissionValues)); | ||||
|   ST("  T")  Add(new cMenuEditMapItem( tr("Guard"),        &data.guard,        GuardValues)); | ||||
|   ST("  T")  Add(new cMenuEditMapItem( tr("Hierarchy"),    &data.hierarchy,    HierarchyValues, tr("none"))); | ||||
|  | ||||
|   SetCurrent(Get(current)); | ||||
|   Display(); | ||||
| } | ||||
|  | ||||
| eOSState cMenuEditChannel::ProcessKey(eKeys Key) | ||||
| { | ||||
|   int oldSource = data.source; | ||||
|   eOSState state = cOsdMenu::ProcessKey(Key); | ||||
|  | ||||
|   if (state == osUnknown) { | ||||
| @@ -436,6 +588,8 @@ eOSState cMenuEditChannel::ProcessKey(eKeys Key) | ||||
|         state = osBack; | ||||
|         } | ||||
|      } | ||||
|   if (Key != kNone && (data.source & cSource::st_Mask) != (oldSource & cSource::st_Mask)) | ||||
|      Setup(); | ||||
|   return state; | ||||
| } | ||||
|  | ||||
| @@ -455,7 +609,7 @@ cMenuChannelItem::cMenuChannelItem(int Index, cChannel *Channel) | ||||
| { | ||||
|   index = Index; | ||||
|   channel = Channel; | ||||
|   if (channel->groupSep) | ||||
|   if (channel->GroupSep()) | ||||
|      SetColor(clrCyan, clrBackground); | ||||
|   Set(); | ||||
| } | ||||
| @@ -463,10 +617,10 @@ cMenuChannelItem::cMenuChannelItem(int Index, cChannel *Channel) | ||||
| void cMenuChannelItem::Set(void) | ||||
| { | ||||
|   char *buffer = NULL; | ||||
|   if (!channel->groupSep) | ||||
|      asprintf(&buffer, "%d\t%s", channel->number, channel->name ); | ||||
|   if (!channel->GroupSep()) | ||||
|      asprintf(&buffer, "%d\t%s", channel->Number(), channel->Name()); | ||||
|   else | ||||
|      asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->name); | ||||
|      asprintf(&buffer, "---\t%s ----------------------------------------------------------------", channel->Name()); | ||||
|   SetText(buffer, false); | ||||
| } | ||||
|  | ||||
| @@ -530,7 +684,7 @@ eOSState cMenuChannels::New(void) | ||||
|   Channels.ReNumber(); | ||||
|   Add(new cMenuChannelItem(channel->Index()/*XXX*/, channel), true); | ||||
|   Channels.Save(); | ||||
|   isyslog("channel %d added", channel->number); | ||||
|   isyslog("channel %d added", channel->Number()); | ||||
|   return AddSubMenu(new cMenuEditChannel(Current())); | ||||
| } | ||||
|  | ||||
| @@ -539,7 +693,7 @@ eOSState cMenuChannels::Del(void) | ||||
|   if (Count() > 0) { | ||||
|      int Index = Current(); | ||||
|      cChannel *channel = Channels.Get(Index); | ||||
|      int DeletedChannel = channel->number; | ||||
|      int DeletedChannel = channel->Number(); | ||||
|      // Check if there is a timer using this channel: | ||||
|      for (cTimer *ti = Timers.First(); ti; ti = (cTimer *)ti->Next()) { | ||||
|          if (ti->channel == DeletedChannel) { | ||||
| @@ -578,8 +732,8 @@ eOSState cMenuChannels::Del(void) | ||||
|  | ||||
| void cMenuChannels::Move(int From, int To) | ||||
| { | ||||
|   int FromNumber = Channels.Get(From)->number; | ||||
|   int ToNumber = Channels.Get(To)->number; | ||||
|   int FromNumber = Channels.Get(From)->Number(); | ||||
|   int ToNumber = Channels.Get(To)->Number(); | ||||
|   // Move and renumber the channels: | ||||
|   Channels.Move(From, To); | ||||
|   Channels.ReNumber(); | ||||
| @@ -933,7 +1087,7 @@ cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch) | ||||
|      cChannel *channel = Channels.GetByServiceID(eventInfo->GetServiceID()); | ||||
|      if (channel) { | ||||
|         char *buffer; | ||||
|         asprintf(&buffer, "%-17.*s\t%.*s  %s - %s", 17, channel->name, 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString()); | ||||
|         asprintf(&buffer, "%-17.*s\t%.*s  %s - %s", 17, channel->Name(), 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString()); | ||||
|         SetTitle(buffer, false); | ||||
|         free(buffer); | ||||
|         int Line = 2; | ||||
| @@ -984,7 +1138,7 @@ cMenuWhatsOnItem::cMenuWhatsOnItem(const cEventInfo *EventInfo) | ||||
|   eventInfo = EventInfo; | ||||
|   char *buffer = NULL; | ||||
|   cChannel *channel = Channels.GetByNumber(eventInfo->GetChannelNumber()); | ||||
|   asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->name : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle()); | ||||
|   asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->Name() : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle()); | ||||
|   SetText(buffer, false); | ||||
| } | ||||
|  | ||||
| @@ -1026,7 +1180,7 @@ cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentCha | ||||
|         if (pArray[num]) { | ||||
|            cChannel *channel = Channels.GetByServiceID(pArray[num]->GetServiceID()); | ||||
|            if (channel) { | ||||
|               pArray[num]->SetChannelNumber(channel->number); | ||||
|               pArray[num]->SetChannelNumber(channel->Number()); | ||||
|               num++; | ||||
|               } | ||||
|            } | ||||
| @@ -1149,7 +1303,7 @@ cMenuSchedule::cMenuSchedule(void) | ||||
|   otherChannel = 0; | ||||
|   cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); | ||||
|   if (channel) { | ||||
|      cMenuWhatsOn::SetCurrentChannel(channel->number); | ||||
|      cMenuWhatsOn::SetCurrentChannel(channel->Number()); | ||||
|      schedules = cSIProcessor::Schedules(mutexLock); | ||||
|      PrepareSchedule(channel); | ||||
|      SetHelp(tr("Record"), tr("Now"), tr("Next")); | ||||
| @@ -1170,11 +1324,11 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel) | ||||
| { | ||||
|   Clear(); | ||||
|   char *buffer = NULL; | ||||
|   asprintf(&buffer, tr("Schedule - %s"), Channel->name); | ||||
|   asprintf(&buffer, tr("Schedule - %s"), Channel->Name()); | ||||
|   SetTitle(buffer); | ||||
|   free(buffer); | ||||
|   if (schedules) { | ||||
|      const cSchedule *Schedule = Channel->pnr ? schedules->GetSchedule(Channel->pnr) : schedules->GetSchedule(); | ||||
|      const cSchedule *Schedule = Channel->Sid() ? schedules->GetSchedule(Channel->Sid()) : schedules->GetSchedule(); | ||||
|      int num = Schedule->NumEvents(); | ||||
|      const cEventInfo **pArray = MALLOC(const cEventInfo *, num); | ||||
|      if (pArray) { | ||||
| @@ -1238,7 +1392,7 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) | ||||
|                            if (Count()) { | ||||
|                               cChannel *channel = Channels.GetByServiceID(((cMenuScheduleItem *)Get(Current()))->eventInfo->GetServiceID()); | ||||
|                               if (channel) | ||||
|                                  ChannelNr = channel->number; | ||||
|                                  ChannelNr = channel->Number(); | ||||
|                               } | ||||
|                            now = true; | ||||
|                            return AddSubMenu(new cMenuWhatsOn(schedules, true, ChannelNr)); | ||||
| @@ -1266,8 +1420,8 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key) | ||||
|         cChannel *channel = Channels.GetByServiceID(ei->GetServiceID()); | ||||
|         if (channel) { | ||||
|            PrepareSchedule(channel); | ||||
|            if (channel->number != cDevice::CurrentChannel()) { | ||||
|               otherChannel = channel->number; | ||||
|            if (channel->Number() != cDevice::CurrentChannel()) { | ||||
|               otherChannel = channel->Number(); | ||||
|               SetHelp(tr("Record"), tr("Now"), tr("Next"), tr("Switch")); | ||||
|               } | ||||
|            Display(); | ||||
| @@ -1636,17 +1790,44 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key) | ||||
| // --- cMenuSetupLNB --------------------------------------------------------- | ||||
|  | ||||
| class cMenuSetupLNB : public cMenuSetupBase { | ||||
| private: | ||||
|   void Setup(void); | ||||
| public: | ||||
|   cMenuSetupLNB(void); | ||||
|   virtual eOSState ProcessKey(eKeys Key); | ||||
|   }; | ||||
|  | ||||
| cMenuSetupLNB::cMenuSetupLNB(void) | ||||
| { | ||||
|   SetSection(tr("LNB")); | ||||
|   Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"),               &data.LnbSLOF)); | ||||
|   Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"),  &data.LnbFrequLo)); | ||||
|   Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi)); | ||||
|   Setup(); | ||||
| } | ||||
|  | ||||
| void cMenuSetupLNB::Setup(void) | ||||
| { | ||||
|   int current = Current(); | ||||
|  | ||||
|   Clear(); | ||||
|  | ||||
|   Add(new cMenuEditBoolItem(tr("Setup.LNB$Use DiSEqC"),               &data.DiSEqC)); | ||||
|   if (!data.DiSEqC) { | ||||
|      Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"),               &data.LnbSLOF)); | ||||
|      Add(new cMenuEditIntItem( tr("Setup.LNB$Low LNB frequency (MHz)"),  &data.LnbFrequLo)); | ||||
|      Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi)); | ||||
|      } | ||||
|  | ||||
|   SetCurrent(Get(current)); | ||||
|   Display(); | ||||
| } | ||||
|  | ||||
| eOSState cMenuSetupLNB::ProcessKey(eKeys Key) | ||||
| { | ||||
|   int oldDiSEqC = data.DiSEqC; | ||||
|   eOSState state = cMenuSetupBase::ProcessKey(Key); | ||||
|  | ||||
|   if (Key != kNone && data.DiSEqC != oldDiSEqC) | ||||
|      Setup(); | ||||
|   return state; | ||||
| } | ||||
|  | ||||
| // --- cMenuSetupCICAM ------------------------------------------------------- | ||||
| @@ -2152,10 +2333,10 @@ void cDisplayChannel::DisplayChannel(const cChannel *Channel) | ||||
| { | ||||
|   int BufSize = Width() + 1; | ||||
|   char buffer[BufSize]; | ||||
|   if (Channel && Channel->number > 0) | ||||
|      snprintf(buffer, BufSize, "%d%s  %s", Channel->number, number ? "-" : "", Channel->name); | ||||
|   if (Channel && Channel->Number() > 0) | ||||
|      snprintf(buffer, BufSize, "%d%s  %s", Channel->Number(), number ? "-" : "", Channel->Name()); | ||||
|   else | ||||
|      snprintf(buffer, BufSize, "%s", Channel ? Channel->name : tr("*** Invalid Channel ***")); | ||||
|      snprintf(buffer, BufSize, "%s", Channel ? Channel->Name() : tr("*** Invalid Channel ***")); | ||||
|   Interface->Fill(0, 0, Setup.OSDwidth, 1, clrBackground); | ||||
|   Interface->Write(0, 0, buffer); | ||||
|   const char *date = DayDateTime(); | ||||
| @@ -2266,7 +2447,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) | ||||
|             if (channel) { | ||||
|                Interface->Clear(); | ||||
|                DisplayChannel(channel); | ||||
|                if (!channel->groupSep) | ||||
|                if (!channel->GroupSep()) | ||||
|                   group = -1; | ||||
|                } | ||||
|             } | ||||
| @@ -2283,7 +2464,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) | ||||
|     //XXX case kGreen:  return osEventNow; | ||||
|     //XXX case kYellow: return osEventNext; | ||||
|     case kOk:     if (group >= 0) | ||||
|                      Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(group))->number); | ||||
|                      Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(group))->Number()); | ||||
|                   return osEnd; | ||||
|     default:      if (NORMALKEY(Key) == kUp || NORMALKEY(Key) == kDown || (Key & (k_Repeat | k_Release)) == 0) { | ||||
|                      cRemote::Put(Key); | ||||
| @@ -2433,7 +2614,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer) | ||||
|   fileName = strdup(Recording.FileName()); | ||||
|   cRecordingUserCommand::InvokeCommand(RUC_BEFORERECORDING, fileName); | ||||
|   cChannel *ch = Channels.GetByNumber(timer->channel); | ||||
|   recorder = new cRecorder(fileName, ch->ca, timer->priority, ch->vpid, ch->apid1, ch->apid2, ch->dpid1, ch->dpid2); | ||||
|   recorder = new cRecorder(fileName, ch->Ca(), timer->priority, ch->Vpid(), ch->Apid1(), ch->Apid2(), ch->Dpid1(), ch->Dpid2()); | ||||
|   if (device->AttachReceiver(recorder)) { | ||||
|      Recording.WriteSummary(); | ||||
|      cStatus::MsgRecording(device, Recording.Name()); | ||||
| @@ -2460,7 +2641,7 @@ bool cRecordControl::GetEventInfo(void) | ||||
|         cMutexLock MutexLock; | ||||
|         const cSchedules *Schedules = cSIProcessor::Schedules(MutexLock); | ||||
|         if (Schedules) { | ||||
|            const cSchedule *Schedule = Schedules->GetSchedule(channel->pnr); | ||||
|            const cSchedule *Schedule = Schedules->GetSchedule(channel->Sid()); | ||||
|            if (Schedule) { | ||||
|               eventInfo = Schedule->GetEventAround(Time); | ||||
|               if (eventInfo) { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: recording.c 1.67 2002/08/24 14:09:49 kls Exp $ | ||||
|  * $Id: recording.c 1.68 2002/10/05 13:44:56 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "recording.h" | ||||
| @@ -14,6 +14,7 @@ | ||||
| #include <string.h> | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| #include "channels.h" | ||||
| #include "i18n.h" | ||||
| #include "interface.h" | ||||
| #include "remux.h" //XXX+ I_FRAME | ||||
|   | ||||
							
								
								
									
										104
									
								
								sources.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								sources.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| /* | ||||
|  * sources.c: Source handling | ||||
|  * | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: sources.c 1.1 2002/10/06 09:27:10 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "sources.h" | ||||
| #include <ctype.h> | ||||
|  | ||||
| // -- cSource ---------------------------------------------------------------- | ||||
|  | ||||
| cSource::cSource(void) | ||||
| { | ||||
|   code = stNone; | ||||
|   description = NULL; | ||||
| } | ||||
|  | ||||
| cSource::~cSource() | ||||
| { | ||||
|   free(description); | ||||
| } | ||||
|  | ||||
| bool cSource::Parse(const char *s) | ||||
| { | ||||
|   char *codeBuf = NULL; | ||||
|   if (2 == sscanf(s, "%a[^ ] %a[^\n]", &codeBuf, &description)) | ||||
|      code = FromString(codeBuf); | ||||
|   free(codeBuf); | ||||
|   return code != stNone && description && *description; | ||||
| } | ||||
|  | ||||
| const char *cSource::ToString(int Code) | ||||
| { | ||||
|   static char buffer[16]; | ||||
|   char *q = buffer; | ||||
|   switch (Code & st_Mask) { | ||||
|     case stCable: *q++ = 'C'; break; | ||||
|     case stSat:   *q++ = 'S'; | ||||
|                   { | ||||
|                     int pos = Code & ~st_Mask; | ||||
|                     q += snprintf(q, sizeof(buffer) - 2, "%u.%u", (pos & ~st_Neg) / 10, (pos & ~st_Neg) % 10); // can't simply use "%g" here since the silly 'locale' messes up the decimal point | ||||
|                     *q++ = (Code & st_Neg) ? 'E' : 'W'; | ||||
|                   } | ||||
|                   break; | ||||
|     case stTerr:  *q++ = 'T'; break; | ||||
|     default:      *q++ = Code + '0'; // backward compatibility | ||||
|     } | ||||
|   *q = 0; | ||||
|   return buffer; | ||||
| } | ||||
|  | ||||
| int cSource::FromString(const char *s) | ||||
| { | ||||
|   int type = stNone; | ||||
|   switch (toupper(*s)) { | ||||
|     case 'C': type = stCable; break; | ||||
|     case 'S': type = stSat;   break; | ||||
|     case 'T': type = stTerr;  break; | ||||
|     case '0' ... '9': type = *s - '0'; break; // backward compatibility | ||||
|     default: esyslog("ERROR: unknown source key '%c'", *s); | ||||
|              return stNone; | ||||
|     } | ||||
|   int code = type; | ||||
|   if (type == stSat) { | ||||
|      int pos = 0; | ||||
|      bool dot = false; | ||||
|      bool neg = false; | ||||
|      while (*++s) { | ||||
|            switch (toupper(*s)) { | ||||
|              case '0' ... '9': pos *= 10; | ||||
|                                pos += *s - '0'; | ||||
|                                break; | ||||
|              case '.':         dot = true; | ||||
|                                break; | ||||
|              case 'E':         neg = true; // fall through to 'W' | ||||
|              case 'W':         if (!dot) | ||||
|                                   pos *= 10; | ||||
|                                break; | ||||
|              default: esyslog("ERROR: unknown source character '%c'", *s); | ||||
|                       return stNone; | ||||
|              } | ||||
|            } | ||||
|      if (neg) | ||||
|         pos |= st_Neg; | ||||
|      code |= pos; | ||||
|      } | ||||
|   return code; | ||||
| } | ||||
|  | ||||
| // -- cSources --------------------------------------------------------------- | ||||
|  | ||||
| cSources Sources; | ||||
|  | ||||
| cSource *cSources::Get(int Code) | ||||
| { | ||||
|   for (cSource *p = First(); p; p = Next(p)) { | ||||
|       if (p->Code() == Code) | ||||
|          return p; | ||||
|       } | ||||
|   return NULL; | ||||
| } | ||||
							
								
								
									
										50
									
								
								sources.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								sources.conf
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| # Sources configuration for VDR | ||||
| # | ||||
| # Format: | ||||
| # | ||||
| # code  description | ||||
| # | ||||
| # Please contact kls@cadsoft.de before assigning a new code | ||||
| # to a description, in order to keep them unique. | ||||
|  | ||||
| # Satellites | ||||
|  | ||||
| S5E     Sirius 2/3 | ||||
| S7E     Eutelsat W3 | ||||
| S10E    Eutelsat W1R | ||||
| S13E    Hotbird 1-5 | ||||
| S16E    Eutelsat W2 | ||||
| S19.2E  Astra 1 | ||||
| S23.5E  Astra 3 | ||||
| S26E    Arabsat 2A/3A | ||||
| S28.2E  Astra 2 | ||||
| S28.5E  Eurobird | ||||
| S30.E   Arabsat 30.5E | ||||
| S31.3   T<>rksat 1B | ||||
| S36E    Eutelsat W4 / Sesat | ||||
| S42E    Turksat 1C / Eurasiasat | ||||
|  | ||||
| S1W     Thor 2/3 / Intelsat 707 | ||||
| S4W     Amos 1 | ||||
| S5W     Telecom 2C | ||||
| S7W     Nilesat 101/102 | ||||
| S8W     Atlantic bird 2 / Telecom 2D | ||||
| S11W    Express 3A | ||||
| S14W    Express 2 | ||||
| S15W    Telstar 12 | ||||
| S18W    Intelsat | ||||
| S21W    NSS 803 | ||||
| S27.W   Intelsat 27.5W | ||||
| S30W    Hispasat 1 | ||||
| S31.5W  Intelsat 31.5W | ||||
| S34.5W  Intelsat 34.5W | ||||
| S37.5W  Telstar 11 | ||||
| S43W    PAS | ||||
|  | ||||
| # Cable | ||||
|  | ||||
| C       Cable | ||||
|  | ||||
| # Terrestrial | ||||
|  | ||||
| T       Terrestrial | ||||
							
								
								
									
										45
									
								
								sources.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								sources.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| /* | ||||
|  * sources.h: Source handling | ||||
|  * | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: sources.h 1.1 2002/10/04 14:25:03 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __SOURCES_H | ||||
| #define __SOURCES_H | ||||
|  | ||||
| #include "config.h" | ||||
|  | ||||
| class cSource : public cListObject { | ||||
| public: | ||||
|   enum eSourceType { | ||||
|     stNone  = 0x0000, | ||||
|     stCable = 0x4000, | ||||
|     stSat   = 0x8000, | ||||
|     stTerr  = 0xC000, | ||||
|     st_Mask = 0xC000, | ||||
|     st_Neg  = 0x0800, | ||||
|     }; | ||||
| private: | ||||
|   int code; | ||||
|   char *description; | ||||
| public: | ||||
|   cSource(void); | ||||
|   ~cSource(); | ||||
|   int Code(void) const { return code; } | ||||
|   const char *Description(void) const { return description; } | ||||
|   bool Parse(const char *s); | ||||
|   static const char *ToString(int Code); | ||||
|   static int FromString(const char *s); | ||||
|   }; | ||||
|  | ||||
| class cSources : public cConfig<cSource> { | ||||
| public: | ||||
|   cSource *Get(int Code); | ||||
|   }; | ||||
|  | ||||
| extern cSources Sources; | ||||
|  | ||||
| #endif //__SOURCES_H | ||||
							
								
								
									
										27
									
								
								svdrp.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								svdrp.c
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ | ||||
|  * and interact with the Video Disk Recorder - or write a full featured | ||||
|  * graphical interface that sits on top of an SVDRP connection. | ||||
|  * | ||||
|  * $Id: svdrp.c 1.43 2002/09/28 15:50:19 kls Exp $ | ||||
|  * $Id: svdrp.c 1.44 2002/10/05 13:45:05 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "svdrp.h" | ||||
| @@ -26,6 +26,7 @@ | ||||
| #include <sys/socket.h> | ||||
| #include <sys/time.h> | ||||
| #include <unistd.h> | ||||
| #include "channels.h" | ||||
| #include "config.h" | ||||
| #include "device.h" | ||||
| #include "keys.h" | ||||
| @@ -412,7 +413,7 @@ void cSVDRP::CmdCHAN(const char *Option) | ||||
|         int i = 1; | ||||
|         cChannel *channel; | ||||
|         while ((channel = Channels.GetByNumber(i)) != NULL) { | ||||
|               if (strcasecmp(channel->name, Option) == 0) { | ||||
|               if (strcasecmp(channel->Name(), Option) == 0) { | ||||
|                  n = i; | ||||
|                  break; | ||||
|                  } | ||||
| @@ -427,7 +428,7 @@ void cSVDRP::CmdCHAN(const char *Option) | ||||
|         cChannel *channel = Channels.GetByNumber(n); | ||||
|         if (channel) { | ||||
|            if (!cDevice::PrimaryDevice()->SwitchChannel(channel, true)) { | ||||
|               Reply(554, "Error switching to channel \"%d\"", channel->number); | ||||
|               Reply(554, "Error switching to channel \"%d\"", channel->Number()); | ||||
|               return; | ||||
|               } | ||||
|            } | ||||
| @@ -441,7 +442,7 @@ void cSVDRP::CmdCHAN(const char *Option) | ||||
|      } | ||||
|   cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel()); | ||||
|   if (channel) | ||||
|      Reply(250, "%d %s", channel->number, channel->name); | ||||
|      Reply(250, "%d %s", channel->Number(), channel->Name()); | ||||
|   else | ||||
|      Reply(550, "Unable to find channel \"%d\"", cDevice::CurrentChannel()); | ||||
| } | ||||
| @@ -630,7 +631,7 @@ void cSVDRP::CmdLSTC(const char *Option) | ||||
|      if (isnumber(Option)) { | ||||
|         cChannel *channel = Channels.GetByNumber(strtol(Option, NULL, 10)); | ||||
|         if (channel) | ||||
|            Reply(250, "%d %s", channel->number, channel->ToText()); | ||||
|            Reply(250, "%d %s", channel->Number(), channel->ToText()); | ||||
|         else | ||||
|            Reply(501, "Channel \"%s\" not defined", Option); | ||||
|         } | ||||
| @@ -640,9 +641,9 @@ void cSVDRP::CmdLSTC(const char *Option) | ||||
|         while (i <= Channels.MaxNumber()) { | ||||
|               cChannel *channel = Channels.GetByNumber(i); | ||||
|               if (channel) { | ||||
|                  if (strcasestr(channel->name, Option)) { | ||||
|                  if (strcasestr(channel->Name(), Option)) { | ||||
|                     if (next) | ||||
|                        Reply(-250, "%d %s", next->number, next->ToText()); | ||||
|                        Reply(-250, "%d %s", next->Number(), next->ToText()); | ||||
|                     next = channel; | ||||
|                     } | ||||
|                  } | ||||
| @@ -653,7 +654,7 @@ void cSVDRP::CmdLSTC(const char *Option) | ||||
|               i++; | ||||
|               } | ||||
|         if (next) | ||||
|            Reply(250, "%d %s", next->number, next->ToText()); | ||||
|            Reply(250, "%d %s", next->Number(), next->ToText()); | ||||
|         else | ||||
|            Reply(501, "Channel \"%s\" not defined", Option); | ||||
|         } | ||||
| @@ -662,7 +663,7 @@ void cSVDRP::CmdLSTC(const char *Option) | ||||
|      for (int i = 1; i <= Channels.MaxNumber(); i++) { | ||||
|          cChannel *channel = Channels.GetByNumber(i); | ||||
|         if (channel) | ||||
|            Reply(i < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->number, channel->ToText()); | ||||
|            Reply(i < Channels.MaxNumber() ? -250 : 250, "%d %s", channel->Number(), channel->ToText()); | ||||
|         else | ||||
|            Reply(501, "Channel \"%d\" not found", i); | ||||
|          } | ||||
| @@ -778,8 +779,8 @@ void cSVDRP::CmdMODC(const char *Option) | ||||
|               } | ||||
|            *channel = c; | ||||
|            Channels.Save(); | ||||
|            isyslog("channel %d modified", channel->number); | ||||
|            Reply(250, "%d %s", channel->number, channel->ToText()); | ||||
|            isyslog("channel %d modified", channel->Number()); | ||||
|            Reply(250, "%d %s", channel->Number(), channel->ToText()); | ||||
|            } | ||||
|         else | ||||
|            Reply(501, "Channel \"%d\" not defined", n); | ||||
| @@ -844,8 +845,8 @@ void cSVDRP::CmdNEWC(const char *Option) | ||||
|         Channels.Add(channel); | ||||
|         Channels.ReNumber(); | ||||
|         Channels.Save(); | ||||
|         isyslog("channel %d added", channel->number); | ||||
|         Reply(250, "%d %s", channel->number, channel->ToText()); | ||||
|         isyslog("channel %d added", channel->Number()); | ||||
|         Reply(250, "%d %s", channel->Number(), channel->ToText()); | ||||
|         } | ||||
|      else | ||||
|         Reply(501, "Error in channel settings"); | ||||
|   | ||||
							
								
								
									
										115
									
								
								vdr.5
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								vdr.5
									
									
									
									
									
								
							| @@ -8,7 +8,7 @@ | ||||
| .\" License as specified in the file COPYING that comes with the | ||||
| .\" vdr distribution. | ||||
| .\" | ||||
| .\" $Id: vdr.5 1.5 2002/09/29 13:06:40 kls Exp $ | ||||
| .\" $Id: vdr.5 1.6 2002/10/06 08:56:01 kls Exp $ | ||||
| .\" | ||||
| .TH vdr 5 "7 Sep 2002" "1.2.0" "Video Disk Recorder Files" | ||||
| .SH NAME | ||||
| @@ -29,7 +29,7 @@ character, followed by arbitrary text. Example: | ||||
| A \fBchannel definition\fR is a line with channel data, where the fields | ||||
| are separated by ':' characters. Example: | ||||
|  | ||||
| \fBRTL:12188:h:1:27500:163:104:105:0:12003\fR | ||||
| \fBRTL:12188:h:S19.2E:27500:163:104:105:0:12003\fR | ||||
|  | ||||
| The line number of a channel definition (not counting group separators!) | ||||
| defines the channel's number in OSD menus and the \fItimers.conf\fR file. | ||||
| @@ -44,16 +44,44 @@ it has to be replaced by '|'). | ||||
| .B Frequency | ||||
| The transponder frequency in MHz for DVB-S and DVB-C, kHz for DVB-T (as an integer). | ||||
| .TP | ||||
| .B Polarization | ||||
| The polarization of the satellite signal. 'h' or 'H' for horizontal, 'v' or 'V' | ||||
| for vertical (DVB-S only). | ||||
| .B Parameters | ||||
| Various parameters, depending on whether this is a DVB-S, DVB-C or DVB-T channel. | ||||
| Each parameter consist of a key character, followed by an integer number that | ||||
| represents the actual setting of that parameter. The valid key characters, their | ||||
| meaning (and allowed values) are | ||||
| .TS | ||||
| tab (@); | ||||
| l l. | ||||
| \fBB\fR@Bandwidth (6, 7, 8) | ||||
| \fBC\fR@Code rate high priority (0, 12, 23, 34, 45, 56, 67, 78, 89) | ||||
| \fBD\fR@Code rate low priority (0, 12, 23, 34, 45, 56, 67, 78, 89) | ||||
| \fBG\fR@Guard interval (4, 8, 16, 32) | ||||
| \fBH\fR@Horizontal polarization | ||||
| \fBI\fR@Inversion (0, 1) | ||||
| \fBM\fR@Modulation (0, 16, 32, 64, 128, 256) | ||||
| \fBT\fR@Transmission mode (2, 8) | ||||
| \fBV\fR@Vertical polarization | ||||
| \fBY\fR@Hierarchy (0, 1, 2, 4) | ||||
| .TE | ||||
| The polarization parameters have no integer numbers following them. This is for | ||||
| compatibility with files from older versions and also to keep the DVB-S entries | ||||
| as simple as possible. | ||||
|  | ||||
| The special value \fB999\fR is used for "automatic", which means the driver | ||||
| will automatically determine the proper value (if possible). | ||||
|  | ||||
| An example of a parameter field for a DVB-T channel might look like this: | ||||
|  | ||||
| \fBB8C23D12M64T2G32Y0\fR | ||||
| .TP | ||||
| .B | ||||
| DiSEqC | ||||
| The DiSEqC code to use for this channel (integer, DVB-S only). | ||||
| .B Source | ||||
| The signal source of this channel, as defined in the file \fIsources.conf\fR. | ||||
| For compatibility with files from older versions numeric values will be accepted | ||||
| and also written back correctly, but they will have no meaning for the \fBDiSEqC\fR | ||||
| settings. You should replace the numerical values with the proper source identifiers | ||||
| defined in \fIsources.conf\fR. | ||||
| .TP | ||||
| .B | ||||
| Srate | ||||
| .B Srate | ||||
| The symbol rate of this channel (DVB-S and DVB-C only). | ||||
| .TP | ||||
| .B VPID | ||||
| @@ -78,8 +106,8 @@ l l. | ||||
| \fB>=100\fR@requires a specific decryption method defined in \fIca.conf\fR | ||||
| .TE | ||||
| .TP | ||||
| .B PNR | ||||
| The program number (aka service ID) of this channel. | ||||
| .B SID | ||||
| The service ID of this channel. | ||||
| .SS TIMERS | ||||
| The file \fItimers.conf\fR contains the timer setup. | ||||
| Each line contains one timer definition, with individual fields | ||||
| @@ -191,6 +219,69 @@ Arbitrary text that describes the recording made by this timer. | ||||
| Any newline characters in the summary have to be replaced by '|', and | ||||
| the summary may contain ':' characters. If this field is not empty, its | ||||
| contents will be written into the \fIsummary.vdr\fR file of the recording. | ||||
| .SS SOURCES | ||||
| The file \fIsources.conf\fR defines the codes to be used in the \fBSource\fR field | ||||
| of channels in \fIchannels.conf\fR and assigns descriptive texts to them. | ||||
| Example: | ||||
|  | ||||
| \fBS19.2E  Astra 1\fR | ||||
|  | ||||
| Anything after (and including) a '#' character is comment. | ||||
|  | ||||
| The first character of the \fBcode\fR must be one of | ||||
| .TS | ||||
| tab (@); | ||||
| l l. | ||||
| \fBS\fR@Satellite | ||||
| \fBC\fR@Cable | ||||
| \fBT\fR@Terrestrial | ||||
| .TE | ||||
| and is followed by further data pertaining to that particular source. In case of | ||||
| \fBS\fRatellite this is the orbital position in degrees, followed by \fBE\fR for | ||||
| east or \fBW\fR for west. | ||||
| .SS DISEQC | ||||
| The file \fIdiseqc.conf\fR defines the \fBDiSEqC\fR control sequences to be sent | ||||
| to the DVB-S card in order to access a given satellite position and/or band. | ||||
| Example: | ||||
|  | ||||
| \fBS19.2E  11700 V  9750  t v W15 [E0 10 38 F0] W15 A W15 t\fR | ||||
|  | ||||
| Anything after (and including) a '#' character is comment. | ||||
|  | ||||
| The first word in a parameter line must be one of the codes defined in the | ||||
| file \fIsources.conf\fR and tells which satellite this line applies to. | ||||
|  | ||||
| Following is the "switch frequency" of the LNB (slof), which is the transponder | ||||
| frequency up to which this entry shall be used; the first entry with an slof greater | ||||
| than the actual transponder frequency will be used. Typically there is only one slof | ||||
| per LNB, but the syntax allows any number of frequency ranges to be defined. | ||||
| Note that there should be a last entry with the value \fB99999\fR for each satellite, | ||||
| which covers the upper frequency range. | ||||
|  | ||||
| The third parameter defines the polarization to which this entry applies. It can | ||||
| be either \fBH\fR for horizontal or \fBV\fR for vertical. | ||||
|  | ||||
| The fourth parameter specifies the "local oscillator frequency" (lof) of the LNB | ||||
| to use for the given frequency range. This number will be subtracted from the | ||||
| actual transponder frequency when tuning to the channel. | ||||
|  | ||||
| The rest of the line holds the actual sequence of DiSEqC actions to be taken. | ||||
| The code letters used here are | ||||
| .TS | ||||
| tab (@); | ||||
| l l. | ||||
| \fBt\fR@22kHz tone off | ||||
| \fBT\fR@22kHz tone on | ||||
| \fBv\fR@voltage low (13V) | ||||
| \fBV\fR@voltage high (18V) | ||||
| \fBA\fR@mini A | ||||
| \fBB\fR@mini B | ||||
| \fBWnn\fR@wait nn milliseconds (nn may be any positive integer number) | ||||
| \fB[xx ...]\fR@hex code sequence (max. 6) | ||||
| .TE | ||||
| There can be any number of actions in a line, including none at all - in which case | ||||
| the entry would be used only to set the LOF to use for the given frequency range | ||||
| and polarization. | ||||
| .SS CONDITIONAL ACCESS | ||||
| The file \fIca.conf\fR defines the numbers to be used in the \fBConditional access\fR | ||||
| field of channels in \fIchannels.conf\fR and assigns descriptive texts to them. | ||||
|   | ||||
							
								
								
									
										9
									
								
								vdr.c
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								vdr.c
									
									
									
									
									
								
							| @@ -22,7 +22,7 @@ | ||||
|  * | ||||
|  * The project's page is at http://www.cadsoft.de/people/kls/vdr | ||||
|  * | ||||
|  * $Id: vdr.c 1.124 2002/09/29 12:55:03 kls Exp $ | ||||
|  * $Id: vdr.c 1.125 2002/10/06 10:25:04 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include <getopt.h> | ||||
| @@ -30,9 +30,11 @@ | ||||
| #include <signal.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include "channels.h" | ||||
| #include "config.h" | ||||
| #include "cutter.h" | ||||
| #include "device.h" | ||||
| #include "diseqc.h" | ||||
| #include "dvbdevice.h" | ||||
| #include "eitscan.h" | ||||
| #include "i18n.h" | ||||
| @@ -44,6 +46,7 @@ | ||||
| #include "plugin.h" | ||||
| #include "rcu.h" | ||||
| #include "recording.h" | ||||
| #include "sources.h" | ||||
| #include "tools.h" | ||||
| #include "videodir.h" | ||||
|  | ||||
| @@ -311,9 +314,11 @@ int main(int argc, char *argv[]) | ||||
|   cPlugin::SetConfigDirectory(ConfigDirectory); | ||||
|  | ||||
|   Setup.Load(AddDirectory(ConfigDirectory, "setup.conf")); | ||||
|   Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true); | ||||
|   Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true); | ||||
|   Channels.Load(AddDirectory(ConfigDirectory, "channels.conf")); | ||||
|   Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")); | ||||
|   Commands.Load(AddDirectory(ConfigDirectory, "commands.conf")); | ||||
|   Commands.Load(AddDirectory(ConfigDirectory, "commands.conf"), true); | ||||
|   SVDRPhosts.Load(AddDirectory(ConfigDirectory, "svdrphosts.conf"), true); | ||||
|   CaDefinitions.Load(AddDirectory(ConfigDirectory, "ca.conf"), true); | ||||
|   Keys.Load(AddDirectory(ConfigDirectory, "remote.conf")); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user