Revision bfdb7446

View differences:

.cvsignore
1
doc
2
dvbcat
3
dvbclient
4
dvbd
5
dvblist
6
dvbsched
7
header.txt
8
rundvbd
9
schedule.pl
.gdbinit
1
set args debug
2

  
AUTHORS
1
John Knottenbelt <jak@users.sourceforge.net>
2

  
3
See CREDITS for credits and acknowledgements to people who the code
4
that this is based on.
BUILDING
1
This program depends on
2
C++ STL
3
Linux DVB API version 3
4

  
COPYING
1
		    GNU GENERAL PUBLIC LICENSE
2
		       Version 2, June 1991
3

  
4
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5
                          675 Mass Ave, Cambridge, MA 02139, USA
6
 Everyone is permitted to copy and distribute verbatim copies
7
 of this license document, but changing it is not allowed.
8

  
9
			    Preamble
10

  
11
  The licenses for most software are designed to take away your
12
freedom to share and change it.  By contrast, the GNU General Public
13
License is intended to guarantee your freedom to share and change free
14
software--to make sure the software is free for all its users.  This
15
General Public License applies to most of the Free Software
16
Foundation's software and to any other program whose authors commit to
17
using it.  (Some other Free Software Foundation software is covered by
18
the GNU Library General Public License instead.)  You can apply it to
19
your programs, too.
20

  
21
  When we speak of free software, we are referring to freedom, not
22
price.  Our General Public Licenses are designed to make sure that you
23
have the freedom to distribute copies of free software (and charge for
24
this service if you wish), that you receive source code or can get it
25
if you want it, that you can change the software or use pieces of it
26
in new free programs; and that you know you can do these things.
27

  
28
  To protect your rights, we need to make restrictions that forbid
29
anyone to deny you these rights or to ask you to surrender the rights.
30
These restrictions translate to certain responsibilities for you if you
31
distribute copies of the software, or if you modify it.
32

  
33
  For example, if you distribute copies of such a program, whether
34
gratis or for a fee, you must give the recipients all the rights that
35
you have.  You must make sure that they, too, receive or can get the
36
source code.  And you must show them these terms so they know their
37
rights.
38

  
39
  We protect your rights with two steps: (1) copyright the software, and
40
(2) offer you this license which gives you legal permission to copy,
41
distribute and/or modify the software.
42

  
43
  Also, for each author's protection and ours, we want to make certain
44
that everyone understands that there is no warranty for this free
45
software.  If the software is modified by someone else and passed on, we
46
want its recipients to know that what they have is not the original, so
47
that any problems introduced by others will not reflect on the original
48
authors' reputations.
49

  
50
  Finally, any free program is threatened constantly by software
51
patents.  We wish to avoid the danger that redistributors of a free
52
program will individually obtain patent licenses, in effect making the
53
program proprietary.  To prevent this, we have made it clear that any
54
patent must be licensed for everyone's free use or not licensed at all.
55

  
56
  The precise terms and conditions for copying, distribution and
57
modification follow.
58

59
		    GNU GENERAL PUBLIC LICENSE
60
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61

  
62
  0. This License applies to any program or other work which contains
63
a notice placed by the copyright holder saying it may be distributed
64
under the terms of this General Public License.  The "Program", below,
65
refers to any such program or work, and a "work based on the Program"
66
means either the Program or any derivative work under copyright law:
67
that is to say, a work containing the Program or a portion of it,
68
either verbatim or with modifications and/or translated into another
69
language.  (Hereinafter, translation is included without limitation in
70
the term "modification".)  Each licensee is addressed as "you".
71

  
72
Activities other than copying, distribution and modification are not
73
covered by this License; they are outside its scope.  The act of
74
running the Program is not restricted, and the output from the Program
75
is covered only if its contents constitute a work based on the
76
Program (independent of having been made by running the Program).
77
Whether that is true depends on what the Program does.
78

  
79
  1. You may copy and distribute verbatim copies of the Program's
80
source code as you receive it, in any medium, provided that you
81
conspicuously and appropriately publish on each copy an appropriate
82
copyright notice and disclaimer of warranty; keep intact all the
83
notices that refer to this License and to the absence of any warranty;
84
and give any other recipients of the Program a copy of this License
85
along with the Program.
86

  
87
You may charge a fee for the physical act of transferring a copy, and
88
you may at your option offer warranty protection in exchange for a fee.
89

  
90
  2. You may modify your copy or copies of the Program or any portion
91
of it, thus forming a work based on the Program, and copy and
92
distribute such modifications or work under the terms of Section 1
93
above, provided that you also meet all of these conditions:
94

  
95
    a) You must cause the modified files to carry prominent notices
96
    stating that you changed the files and the date of any change.
97

  
98
    b) You must cause any work that you distribute or publish, that in
99
    whole or in part contains or is derived from the Program or any
100
    part thereof, to be licensed as a whole at no charge to all third
101
    parties under the terms of this License.
102

  
103
    c) If the modified program normally reads commands interactively
104
    when run, you must cause it, when started running for such
105
    interactive use in the most ordinary way, to print or display an
106
    announcement including an appropriate copyright notice and a
107
    notice that there is no warranty (or else, saying that you provide
108
    a warranty) and that users may redistribute the program under
109
    these conditions, and telling the user how to view a copy of this
110
    License.  (Exception: if the Program itself is interactive but
111
    does not normally print such an announcement, your work based on
112
    the Program is not required to print an announcement.)
113

114
These requirements apply to the modified work as a whole.  If
115
identifiable sections of that work are not derived from the Program,
116
and can be reasonably considered independent and separate works in
117
themselves, then this License, and its terms, do not apply to those
118
sections when you distribute them as separate works.  But when you
119
distribute the same sections as part of a whole which is a work based
120
on the Program, the distribution of the whole must be on the terms of
121
this License, whose permissions for other licensees extend to the
122
entire whole, and thus to each and every part regardless of who wrote it.
123

  
124
Thus, it is not the intent of this section to claim rights or contest
125
your rights to work written entirely by you; rather, the intent is to
126
exercise the right to control the distribution of derivative or
127
collective works based on the Program.
128

  
129
In addition, mere aggregation of another work not based on the Program
130
with the Program (or with a work based on the Program) on a volume of
131
a storage or distribution medium does not bring the other work under
132
the scope of this License.
133

  
134
  3. You may copy and distribute the Program (or a work based on it,
135
under Section 2) in object code or executable form under the terms of
136
Sections 1 and 2 above provided that you also do one of the following:
137

  
138
    a) Accompany it with the complete corresponding machine-readable
139
    source code, which must be distributed under the terms of Sections
140
    1 and 2 above on a medium customarily used for software interchange; or,
141

  
142
    b) Accompany it with a written offer, valid for at least three
143
    years, to give any third party, for a charge no more than your
144
    cost of physically performing source distribution, a complete
145
    machine-readable copy of the corresponding source code, to be
146
    distributed under the terms of Sections 1 and 2 above on a medium
147
    customarily used for software interchange; or,
148

  
149
    c) Accompany it with the information you received as to the offer
150
    to distribute corresponding source code.  (This alternative is
151
    allowed only for noncommercial distribution and only if you
152
    received the program in object code or executable form with such
153
    an offer, in accord with Subsection b above.)
154

  
155
The source code for a work means the preferred form of the work for
156
making modifications to it.  For an executable work, complete source
157
code means all the source code for all modules it contains, plus any
158
associated interface definition files, plus the scripts used to
159
control compilation and installation of the executable.  However, as a
160
special exception, the source code distributed need not include
161
anything that is normally distributed (in either source or binary
162
form) with the major components (compiler, kernel, and so on) of the
163
operating system on which the executable runs, unless that component
164
itself accompanies the executable.
165

  
166
If distribution of executable or object code is made by offering
167
access to copy from a designated place, then offering equivalent
168
access to copy the source code from the same place counts as
169
distribution of the source code, even though third parties are not
170
compelled to copy the source along with the object code.
171

172
  4. You may not copy, modify, sublicense, or distribute the Program
173
except as expressly provided under this License.  Any attempt
174
otherwise to copy, modify, sublicense or distribute the Program is
175
void, and will automatically terminate your rights under this License.
176
However, parties who have received copies, or rights, from you under
177
this License will not have their licenses terminated so long as such
178
parties remain in full compliance.
179

  
180
  5. You are not required to accept this License, since you have not
181
signed it.  However, nothing else grants you permission to modify or
182
distribute the Program or its derivative works.  These actions are
183
prohibited by law if you do not accept this License.  Therefore, by
184
modifying or distributing the Program (or any work based on the
185
Program), you indicate your acceptance of this License to do so, and
186
all its terms and conditions for copying, distributing or modifying
187
the Program or works based on it.
188

  
189
  6. Each time you redistribute the Program (or any work based on the
190
Program), the recipient automatically receives a license from the
191
original licensor to copy, distribute or modify the Program subject to
192
these terms and conditions.  You may not impose any further
193
restrictions on the recipients' exercise of the rights granted herein.
194
You are not responsible for enforcing compliance by third parties to
195
this License.
196

  
197
  7. If, as a consequence of a court judgment or allegation of patent
198
infringement or for any other reason (not limited to patent issues),
199
conditions are imposed on you (whether by court order, agreement or
200
otherwise) that contradict the conditions of this License, they do not
201
excuse you from the conditions of this License.  If you cannot
202
distribute so as to satisfy simultaneously your obligations under this
203
License and any other pertinent obligations, then as a consequence you
204
may not distribute the Program at all.  For example, if a patent
205
license would not permit royalty-free redistribution of the Program by
206
all those who receive copies directly or indirectly through you, then
207
the only way you could satisfy both it and this License would be to
208
refrain entirely from distribution of the Program.
209

  
210
If any portion of this section is held invalid or unenforceable under
211
any particular circumstance, the balance of the section is intended to
212
apply and the section as a whole is intended to apply in other
213
circumstances.
214

  
215
It is not the purpose of this section to induce you to infringe any
216
patents or other property right claims or to contest validity of any
217
such claims; this section has the sole purpose of protecting the
218
integrity of the free software distribution system, which is
219
implemented by public license practices.  Many people have made
220
generous contributions to the wide range of software distributed
221
through that system in reliance on consistent application of that
222
system; it is up to the author/donor to decide if he or she is willing
223
to distribute software through any other system and a licensee cannot
224
impose that choice.
225

  
226
This section is intended to make thoroughly clear what is believed to
227
be a consequence of the rest of this License.
228

229
  8. If the distribution and/or use of the Program is restricted in
230
certain countries either by patents or by copyrighted interfaces, the
231
original copyright holder who places the Program under this License
232
may add an explicit geographical distribution limitation excluding
233
those countries, so that distribution is permitted only in or among
234
countries not thus excluded.  In such case, this License incorporates
235
the limitation as if written in the body of this License.
236

  
237
  9. The Free Software Foundation may publish revised and/or new versions
238
of the General Public License from time to time.  Such new versions will
239
be similar in spirit to the present version, but may differ in detail to
240
address new problems or concerns.
241

  
242
Each version is given a distinguishing version number.  If the Program
243
specifies a version number of this License which applies to it and "any
244
later version", you have the option of following the terms and conditions
245
either of that version or of any later version published by the Free
246
Software Foundation.  If the Program does not specify a version number of
247
this License, you may choose any version ever published by the Free Software
248
Foundation.
249

  
250
  10. If you wish to incorporate parts of the Program into other free
251
programs whose distribution conditions are different, write to the author
252
to ask for permission.  For software which is copyrighted by the Free
253
Software Foundation, write to the Free Software Foundation; we sometimes
254
make exceptions for this.  Our decision will be guided by the two goals
255
of preserving the free status of all derivatives of our free software and
256
of promoting the sharing and reuse of software generally.
257

  
258
			    NO WARRANTY
259

  
260
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
262
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
266
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
267
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
REPAIR OR CORRECTION.
269

  
270
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
POSSIBILITY OF SUCH DAMAGES.
279

  
280
		     END OF TERMS AND CONDITIONS
281

282
	Appendix: How to Apply These Terms to Your New Programs
283

  
284
  If you develop a new program, and you want it to be of the greatest
285
possible use to the public, the best way to achieve this is to make it
286
free software which everyone can redistribute and change under these terms.
287

  
288
  To do so, attach the following notices to the program.  It is safest
289
to attach them to the start of each source file to most effectively
290
convey the exclusion of warranty; and each file should have at least
291
the "copyright" line and a pointer to where the full notice is found.
292

  
293
    <one line to give the program's name and a brief idea of what it does.>
294
    Copyright (C) 19yy  <name of author>
295

  
296
    This program is free software; you can redistribute it and/or modify
297
    it under the terms of the GNU General Public License as published by
298
    the Free Software Foundation; either version 2 of the License, or
299
    (at your option) any later version.
300

  
301
    This program is distributed in the hope that it will be useful,
302
    but WITHOUT ANY WARRANTY; without even the implied warranty of
303
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
304
    GNU General Public License for more details.
305

  
306
    You should have received a copy of the GNU General Public License
307
    along with this program; if not, write to the Free Software
308
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
309

  
310
Also add information on how to contact you by electronic and paper mail.
311

  
312
If the program is interactive, make it output a short notice like this
313
when it starts in an interactive mode:
314

  
315
    Gnomovision version 69, Copyright (C) 19yy name of author
316
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
    This is free software, and you are welcome to redistribute it
318
    under certain conditions; type `show c' for details.
319

  
320
The hypothetical commands `show w' and `show c' should show the appropriate
321
parts of the General Public License.  Of course, the commands you use may
322
be called something other than `show w' and `show c'; they could even be
323
mouse-clicks or menu items--whatever suits your program.
324

  
325
You should also get your employer (if you work as a programmer) or your
326
school, if any, to sign a "copyright disclaimer" for the program, if
327
necessary.  Here is a sample; alter the names:
328

  
329
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
331

  
332
  <signature of Ty Coon>, 1 April 1989
333
  Ty Coon, President of Vice
334

  
335
This General Public License does not permit incorporating your program into
336
proprietary programs.  If your program is a subroutine library, you may
337
consider it more useful to permit linking proprietary applications with the
338
library.  If this is what you want to do, use the GNU Library General
339
Public License instead of this License.
CREDITS
1
CREDITS AND ACKNOWLEDGEMENTS
2

  
3
* includes parts of 
4
dvbstream code (C) Dave Chapman <dave@dchapman.com> 2001, 2002.
5

  
6
* which also includes
7
The ts2ps conversion is taken from the "mpegtools" package distributed
8
with the linuxtv.org DVB driver.  
9

  
10
This code is (C) 2000, 2001 Marcus Metzler for 
11
Convergence Integrated Media Gmbh and released under the
12
GNU GPL.
13

  
14
* parsetime code from the GNU at project
15
 Copyright (C) 1993  Thomas Koenig
Makefile
1
PROGRAMS = dvbd dvbcat dvblist dvbsched
2

  
3
all: $(PROGRAMS)
4

  
5
DEBUGCXX=-g
6
DEBUGLINK=-g
7

  
8
#DEBUGCXX=-O2
9
#DEBUGLINK=-O2
10

  
11
CXX=c++ $(DEBUGCXX)
12
LINK=c++ $(DEBUGLINK)
13
COMMONFLAGS=-Wall
14
CFLAGS=$(COMMONFLAGS)
15
CXXFLAGS = $(COMMONFLAGS)
16

  
17
CXXSOURCES1 = connection.cpp controlledconnection.cpp					\
18
	      connectionmanager.cpp demuxer.cpp dvbchannels.cpp dvbd.cpp		\
19
	      dvbttuneparams.cpp select.cpp source.cpp stringutil.cpp tuner.cpp		\
20
	      tunermanager.cpp tuneparams.cpp debug.cpp unixserversocket.cpp		\
21
	      lobby.cpp circularbuffer.cpp inputbuffer.cpp outputbuffer.cpp		\
22
	      signals.cpp configfile.cpp scheduler.cpp fakedemuxer.cpp faketuner.cpp	\
23
              faketunermanager.cpp recording.cpp utils.cpp stringrep.cpp
24
CSOURCES1 = transform.c tune.c ringbuffy.c remux.c ctools.c
25
OBJECTS1 = $(CXXSOURCES1:%.cpp=%.o) $(CSOURCES1:%.c=%.o)
26

  
27
dvbd: $(OBJECTS1)
28
	$(LINK) -o $@ $(OBJECTS1)
29

  
30
CXXSOURCES2_COMMON = unixclientsocket.cpp stringutil.cpp			\
31
                     debug.cpp utils.cpp circularbuffer.cpp inputbuffer.cpp	\
32
                     outputbuffer.cpp select.cpp clientconnection.cpp 
33

  
34
CXXSOURCES2 = $(CXXSOURCES2_COMMON) dvbsched.cpp 
35
CSOURCES2 = lex.yy.c y.tab.c
36
OBJECTS2 = $(CXXSOURCES2:%.cpp=%.o) $(CSOURCES2:%.c=%.o)
37

  
38
dvbsched: $(OBJECTS2)
39
	$(LINK) -o $@ $(OBJECTS2)
40

  
41
CXXSOURCES3 = dvblist.cpp $(CXXSOURCES2_COMMON)
42
OBJECTS3 = $(CXXSOURCES3:%.cpp=%.o)
43

  
44
dvblist: $(OBJECTS3)
45
	$(LINK) -o $@ $(OBJECTS3)
46

  
47
CXXSOURCES4 = dvbcat.cpp $(CXXSOURCES2_COMMON)
48
OBJECTS4 = $(CXXSOURCES4:%.cpp=%.o)
49

  
50
dvbcat: $(OBJECTS4)
51
	$(LINK) -o $@ $(OBJECTS4)
52

  
53

  
54
clean:
55
	rm -f *.o $(PROGRAMS)
56

  
57
ALLSOURCES := $(sort $(CXXSOURCES1) $(CSOURCES1) $(CXXSOURCES2))
58

  
59
make.Dep: $(ALLSOURCES)
60
	-gcc -MM $(ALLSOURCES) 2>/dev/null >$@
61

  
62

  
63
documentation:
64
	doxygen dvbd.doxygen
65

  
66
include make.Dep
README
1
* dvbd
2

  
3
** INTRODUCTION
4

  
5
The idea behind dvbd is to make maximum use of your DVB card by
6
allowing multiple channels on the same frequency to be tuned. It is
7
split into a daemon (dvbd) and client programs (dvbclient, dvblist).
8
It is possible to associate a priority with a connection to the
9
daemon, so that (depending on the given priority) the tuner can be
10
made available by dropping connections of inferior priority.
11

  
12
NB, at the moment only DVB-T is supported (that's the type of DVB that
13
I have), but it should be fairly easy to add support for DVB-S and
14
DVB-C.
15

  
16
** CONFIGURATION
17

  
18
The daemon has a configuration file which by default is
19
/etc/dvbd/config. The format of the file is lines of key=value. Line
20
comments can be begun with #.
21

  
22
The following configuration fields are available:
23
  socket   - the (unix) socket to listen on. 
24
	     Default is /var/run/dvbd/dvbd.socket
25
  pid      - the pid file to write to once
26
	     it has become a daemon.
27
	     Default is /var/run/dvbd/dvbd.pid
28
  log      - the log file to write to
29
	     Default is /var/log/dvbd.log
30
  schedule - the schedule file to write to
31
	     Default is /var/spool/dvbd/schedule
32
  debug    - the debug level (default is 0) If a higher
33
             debug level is set, dvbd will not go into the
34
	     background.
35
  numcards - the number of DVB cards your system supports
36
  card0    - the first DVB card. The format of this field is 
37
             type:frontend:channels
38
             Where 
39
               - type may be one of dvb-t, dvb-s or dvb-t.
40
               - frontend is the path to the frontend (tuner)
41
                 for the card
42
               - channels is the path to the tzap/szap/czap format
43
                 channels.conf file for the card.
44

  
45
If no cards are specified, a default of one dvb-t card is assumed with
46
channels file /etc/tzap.channels.conf and frontend
47
/dev/dvb/adapter0/frontend0
48

  
49
** CLIENT PROGRAMS
50

  
51
At the moment there are three client programs. dvbcat, dvblist and dvbsched.
52
dvbcat can be used to extract a stream from the dvbd for live TV.
53

  
54
For example:
55

  
56
  dvbcat dvb-t "BBC ONE" | mplayer -
57

  
58
dvbsched is used to schedule a recording. Note that an output file
59
must be specified whose containing directory must be owned by the user
60
issuing the request. The directory must also be writable by the dvbd
61
program.
62

  
63
The time format is in at(1) format. See at's manpage for more
64
information about it.
65

  
66
For example:
67

  
68
  mkdir /tmp/recordings
69
  dvbsched dvb-t "ITV 2" 19.20 32 /tmp/recordings/itv2.mpg
70

  
71
If there is a clash the program will ask you if you want
72
to cancel your job.
73

  
74
dvblist shows the channels available to tune at the given 
75
priority (default is 10). 
76

  
77
For example:
78

  
79
  dvblist dvb-t
80

  
81
If there are some existing connections the list of channels
82
may be shorter than the full list. 
83

  
84
** CONTRIBUTING AND COMMENTS 
85

  
86
Feedback, bug fixes, new features, patches and suggestions are very
87
welcome.  Please send to jak@users.sourceforge.net or post on the
88
SourceForge project page.
TODO
1
If you can help with any of the following, or if
2
you have suggestions on what else to put on this
3
list please contact me at jak@users.sourceforge.net
4
   
5
Autoconf / Automake
6
Debian packages
7
Display job number of scheduled job (dvbsched)
8
Allow scheduled jobs to be removed (dvbsched)
9
Xine input plugin
10
Satellite and Cable support.   
11
Refactor classes:
12
  Tuner FakeTuner should derive from TunerBase
13
  TunerManager FakeTunerManager should derive from TunerManagerBase
14
  Demuxer FakeDemuxer should derive from DemuxerBase
15
  Connection hierarchy should really look like this:
16

  
17
                 Connection
18
                     |
19
     +---------------+---------------+
20
     |                               |
21
  ControlledConnection       RecordableConnectionBase
22
                                     |
23
              +----------------------+-------------------+
24
              |                                          |
25
   FakeRecordableConnection                    RecordableConnection
26

  
27
  This will allow the RecordableConnection to keep a copy of the 
28
  item it is recording. The Scheduler would deal only with 
29
  RecordableConnectionBase objects.
30

  
circularbuffer.cpp
1
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (at your option) any later version.
8
 
9
  This program is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18

  
19
#include "circularbuffer.h"
20
#include <cstring>
21
#include <iostream>
22

  
23
CircularBuffer::CircularBuffer(int initSize, int maxSize)
24
  : start(0), size(initSize), maxSize(maxSize), used(0), overflow(false)
25
{
26
  buffer = new char[size];
27
}
28

  
29
CircularBuffer::~CircularBuffer()
30
{
31
  delete [] buffer;
32
}
33

  
34

  
35
void CircularBuffer::grow()
36
{
37
  if (size == maxSize)
38
    return;
39

  
40
  int size1;
41
  int size2;
42

  
43
  if (start + used <= size) {
44
    size1 = used;
45
    size2 = 0;
46
  }
47
  else {
48
    size1 = size - start;
49
    size2 = used - size1;
50
  }
51

  
52
  int newSize = size * 2;
53
  if (newSize > maxSize)
54
    newSize = maxSize;
55
  
56
  char *newData = new char[newSize];
57
  memcpy(newData, buffer + start, size1);
58
  memcpy(newData + size1, buffer, size2);
59

  
60
  delete [] buffer;
61
  buffer = newData;
62
  size = newSize;
63
  start = 0;
64
}
65

  
66
bool CircularBuffer::write(const std::string &data)
67
{
68
  return write(data.data(), data.size());
69
}
70

  
71

  
72
bool CircularBuffer::write(const char *data, int count)
73
{
74
  while (size - used < count) {
75
    if (size == maxSize) {
76
      overflow = true;
77
      return false;
78
    }
79
    grow();
80
  }
81

  
82
  int tail = (start + used) % size;
83

  
84
  // We are using a circular buffer
85

  
86
  if (tail + count <= size) {
87
    memcpy(buffer + tail, data, count);
88
    used += count;
89
  }
90
  else {
91
    // Wrap around
92
    int size1 = size - tail;    //        - tail + size 
93
    int size2 = count - size1;	//  count + tail - size 
94

  
95
    memcpy(buffer + tail, data, size1);
96
    memcpy(buffer, data + size1, size2);
97
    used += count;
98
  }
99

  
100
  return true;
101
}
102

  
103
void CircularBuffer::discard(int count)
104
{
105
  if (count >= used)
106
    count = used;
107

  
108
  start = (start + count) % size;
109
  used -= count;
110
}
111

  
112
void CircularBuffer::getSections(char *&buffer1, int &count1, 
113
			       char *&buffer2, int &count2)
114
{
115
  buffer1 = buffer + start;
116
  buffer2 = buffer;
117

  
118
  if (start + used > size) {
119
    count1 = size - start;
120
    count2 = used - count1;
121
  }
122
  else {
123
    count1 = used;
124
    count2 = 0;
125
  }
126
}
127

  
128
bool CircularBuffer::read(char *data, int count)
129
{
130
  if (count > used)
131
    return false;
132

  
133
  char *buf1, *buf2;
134
  int len1, len2;
135

  
136
  getSections(buf1, len1, buf2, len2);
137

  
138
  if (count <= len1) 
139
    memcpy(data, buf1, count);
140
  else {
141
    memcpy(data, buf1, len1);
142
    memcpy(data + len1, buf2, count - len1);
143
  }
144

  
145
  start = (start + count) % size;
146
  used -= count;
147

  
148
  return true;
149
}
150

  
151
bool CircularBuffer::read(std::string &data, int count)
152
{
153
  char buf[count];
154
  bool result = read(buf, count);
155
  if (result) 
156
    data = std::string(buf, count);
157
  return result;
158
}
159

  
160
bool CircularBuffer::readLine(std::string &data, char ch)
161
{
162
  char *buf1, *buf2;
163
  int len1, len2;
164

  
165
  getSections(buf1, len1, buf2, len2);
166
  char *p = (char *) memchr(buf1, ch, len1);
167
  if (p != NULL) 
168
    return read(data, p - buf1 + 1);
169

  
170
  p = (char *) memchr(buf2, ch, len2);
171
  if (p == NULL)
172
    return false;
173

  
174
  int readLen = len1 + (p - buf2 + 1);
175
  return read(data, readLen);
176
}
circularbuffer.h
1
// -*- c++ -*-
2
/*
3
  Copyright 2003 John Knottenbelt
4
  
5
  This program is free software; you can redistribute it and/or modify
6
  it under the terms of the GNU General Public License as published by
7
  the Free Software Foundation; either version 2 of the License, or
8
  (at your option) any later version.
9
 
10
  This program is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
  GNU General Public License for more details.
14
 
15
  You should have received a copy of the GNU General Public License
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
18
*/
19

  
20
#if !defined __CIRCULARBUFFER_H
21
#define __CIRCULARBUFFER_H
22

  
23
#include <string>
24

  
25
class CircularBuffer {
26
public:
27
  CircularBuffer(int initSize, int maxSize);
28
  virtual ~CircularBuffer();
29

  
30
  // returns number of bytes waiting to be sent
31
  int getUsed() const {
32
    return used;
33
  }
34

  
35
  // returns number of free bytes remaining in the buffer
36
  int getFree() const {
37
    return maxSize - used;
38
  }
39

  
40
  int getMaxSize() const {
41
    return maxSize;
42
  }
43

  
44
  bool hasOverflowed() const {
45
    return overflow;
46
  }
47

  
48
  void clearOverflowed() {
49
    overflow = false;
50
  }
51

  
52
  bool write(const char *data, int size);
53
  bool write(const std::string &data);
54

  
55
  bool read(char *data, int size);
56
  bool read(std::string &data, int count);
57
  bool readLine(std::string &data, char ch = '\n');
58

  
59
  void discard(int size);
60

  
61
protected:
62
  void getSections(char *&buffer1, int &count1, 
63
		   char *&buffer2, int &count2);
64

  
65
  void setOverflowed() {
66
    overflow = true;
67
  }
68

  
69
private:
70
  char *buffer;
71
  int start, size, maxSize, used;
72
  bool overflow;
73

  
74
  void grow();
75
};
76

  
77
#endif // __CIRCULARBUFFER_H
clientconnection.cpp
1
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (at your option) any later version.
8
 
9
  This program is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18

  
19
#include "clientconnection.h"
20
#include "unixclientsocket.h"
21
#include "stringutil.h"
22
#include "utils.h"
23
#include <iostream>
24

  
25
class SetBlocking {
26
public:
27
  SetBlocking(UnixClientSocket &client, bool desiredState)
28
    : client_(client), savedState_(client.isBlocking())
29
  {
30
    client_.setBlocking(desiredState);
31
  }
32

  
33
  ~SetBlocking()
34
  {
35
    client_.setBlocking(savedState_);
36
  }
37

  
38
private:
39
  UnixClientSocket &client_;
40
  bool savedState_;
41
};
42

  
43
ClientConnection::ClientConnection( const std::string &socketFile )
44
 : control_(socketFile), data_(socketFile), good_(true)
45
{
46
  if (control_ && data_) {
47
    control_.write("CONTROL\n");
48
    std::string key;
49
    if (!control_.readLine(key)) {
50
      good_ = false;
51
      return;
52
    }
53
    key = stripTrailingWS(key);
54
    data_.write("DATA " + key + "\n");
55
    std::string welcome;
56
    if (!control_.readLine(welcome)) {
57
      good_ = false;
58
      return;
59
    }
60
  }
61
}
62

  
63
ClientConnection::operator bool () const
64
{
65
  return good_ && control_ && data_;
66
}
67

  
68
std::string ClientConnection::getError() const
69
{
70
  return error_;
71
}
72

  
73
bool ClientConnection::getChannels(const std::string &type, int priority, StringList &channels)
74
{
75
  SetBlocking blocking(control_, true);
76

  
77
  // Check if the command is to list the channels
78
  control_.write("LIST " + type + " " + toString(priority) + "\n");
79

  
80
  do {
81
    std::string reply;
82
    if (!control_.readLine(reply)) {
83
      error_ = "failed to read channel from control socket";
84
      return false;
85
    }
86

  
87
    if (reply.substr(0, 5) == "ERROR") {
88
      return false;
89
    }
90
    else if (reply == "OK\n") 
91
      return true;
92
    else 
93
      channels.push_back( stripTrailingWS(reply.substr(1)) );
94

  
95
  } while (true);
96

  
97
}
98

  
99
UnixClientSocket& ClientConnection::control()
100
{
101
  return control_;
102
}
103

  
104
UnixClientSocket& ClientConnection::data()
105
{
106
  return data_;
107
}
108

  
109
int ClientConnection::schedule(const std::string &type, const std::string &channel,
110
			       time_t when, unsigned duration, int priority,
111
			       const std::string &outputFile)
112
{
113
  SetBlocking saveBlocking(control_, true);
114
  // Convert the time to the right format
115
  char data[256];
116
  strftime(data, sizeof(data), "%Y-%m-%d %H:%M:%S", localtime(&when));
117
  std::string dateTime = data;
118

  
119
  std::string command = 
120
    "SCHEDULE " + dateTime + " " + type + " " + escapeWS(channel) + " " + 
121
    toString(priority) + " " + toString(duration * 60) + " " + outputFile + "\n";
122
  std::cerr << command;
123

  
124
  control_.write(command);
125
    
126
  std::string reply;
127
  control_.readLine(reply);
128
  
129
  if (reply.substr(0, 3) == "JOB") {
130
    int job = toInt(reply.substr(5));
131
    control_.readLine(reply);	// Ok
132
    return job;
133
  }
134
  error_ = stripTrailingWS(reply);
135
  return -1;
136
}
137

  
138
void ClientConnection::checkSchedule(StringList &messages)
139
{
140
  SetBlocking saveBlocking(control_, true);
141
  control_.write("CHECK\n");
142
  do {
143
    std::string reply;
144
    control_.readLine(reply);
145
    if (reply == "OK\n")
146
      break;
147
    messages.push_back(stripTrailingWS(reply));
148
  } while (true);
149
}
150

  
151
bool ClientConnection::listSchedule(StringList &s)
152
{
153
  SetBlocking saveBlocking(control_, true);
154
  control_.write("LISTSCHEDULE\n");
155
  do {
156
    std::string reply;
157
    control_.readLine(reply);
158
    if (reply == "OK\n")
159
      break;
160
    s.push_back(stripTrailingWS(reply));
161
  } while (true);
162
  return true;
163
}
164

  
165
bool ClientConnection::removeJob(int job)
166
{
167
  SetBlocking saveBlocking(control_, true);
168
  control_.write("REMOVEJOB " + toString(job) + "\n");
169
  std::string reply;
170
  control_.readLine(reply);
171
  if (reply == "OK\n")
172
    return true;
173
  error_ = stripTrailingWS(reply);
174
  return false;
175
}
176

  
177
bool ClientConnection::tune(const std::string &type, const std::string &channel, int priority)
178
{
179
  SetBlocking saveBlocking(control_, true);
180
  control_.write("TUNE " + type + " " + escapeWS(channel) + " " + toString(priority) + "\n");
181
  std::string reply;
182
  control_.readLine(reply);
183
  if (reply == "OK\n")
184
    return true;
185
  error_ = stripTrailingWS(reply);
186
  return false;
187
}
188

  
189
bool ClientConnection::getNextJobTime(time_t &nextJobTime)
190
{
191
  SetBlocking saveBlocking(control_, true);
192
  control_.write("NEXTJOBTIME\n");
193

  
194
  std::string reply;
195
  control_.readLine(reply);
196
  if (reply.substr(0, 5) == "ERROR") {
197
    error_ = stripTrailingWS(reply);
198
    return false;
199
  }
200
  struct tm tm;
201
  if (strptime(reply.c_str(), "%Y-%m-%d %H:%M:%S", &tm) == NULL) {
202
    error_ = "Invalid date/time: " + stripTrailingWS(reply);
203
    return false;
204
  }
205
  nextJobTime = mktime(&tm);
206
  return true;
207
}
208

  
209
bool ClientConnection::listConnections(StringList &s)
210
{
211
  SetBlocking saveBlocking(control_, true);
212
  control_.write("LISTCONNECTIONS\n");
213
  do {
214
    std::string reply;
215
    control_.readLine(reply);
216
    if (reply == "OK\n")
217
      break;
218
    s.push_back(stripTrailingWS(reply));
219
  } while (true);
220
  return true;
221
}
222

  
clientconnection.h
1
// -*- c++ -*-
2
/*
3
  Copyright 2003 John Knottenbelt
4
  
5
  This program is free software; you can redistribute it and/or modify
6
  it under the terms of the GNU General Public License as published by
7
  the Free Software Foundation; either version 2 of the License, or
8
  (at your option) any later version.
9
 
10
  This program is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
  GNU General Public License for more details.
14
 
15
  You should have received a copy of the GNU General Public License
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
18
*/
19

  
20
#if !defined __CLIENTCONNECTION_H
21
#define __CLIENTCONNECTION_H
22

  
23
#include <string>
24
#include "dvbd.h"
25
#include "unixclientsocket.h"
26

  
27
class UnixClientSocket;
28

  
29
/** Establish a pair of connections with the server */
30
class ClientConnection {
31
public:  
32
  ClientConnection( const std::string &socketFile );
33

  
34
  operator bool () const;
35

  
36
  bool getChannels(const std::string &type, int priority, StringList &channels);
37

  
38
  std::string getError() const;
39

  
40
  UnixClientSocket& data();
41
  UnixClientSocket& control();
42

  
43
  void checkSchedule(StringList&);
44

  
45
  int schedule(const std::string &type, const std::string &channel,
46
	       time_t when, unsigned duration, int priority,
47
	       const std::string &outputFile);
48

  
49
  bool removeJob(int job);
50

  
51
  bool listSchedule(StringList &);
52

  
53
  bool tune(const std::string &type, const std::string &channel, int priority);
54

  
55
  bool getNextJobTime(time_t &nextJobTime);
56

  
57
  bool listConnections(StringList &);
58

  
59
private:
60
  UnixClientSocket control_, data_;
61
  bool good_;
62
  std::string error_;
63
};
64

  
65
#endif // __CLIENTCONNECTION_H
config.h
1
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (at your option) any later version.
8
 
9
  This program is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18

  
19
#define _FILE_OFFSET_BITS 64 
20
#define _LARGEFILE_SOURCE 
21
#define _LARGEFILE64_SOURCE
22

  
23
#define UK
24
#define NEWSTRUCT 1
25

  
26
typedef unsigned uint32_t;
configfile.cpp
1
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (at your option) any later version.
8
 
9
  This program is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18

  
19
#include "configfile.h"
20
#include "stringutil.h"
21
#include <fstream>
22
#include <iostream>
23

  
24
ConfigFile::ConfigFile()
25
{
26
}
27

  
28
void ConfigFile::clear()
29
{
30
  data.clear();
31
}
32

  
33
bool ConfigFile::read(const std::string &file)
34
{
35
  std::ifstream input(file.c_str());
36
  if (!input)
37
    return false;
38

  
39
  std::string line;
40
  int lineno = 0;
41

  
42
  while (getline(input, line)) {
43
    lineno++;
44
    line = stripTrailingWS(stripLeadingWS(stripLineComment(line)));
45

  
46
    if (line == "")
47
      continue;
48

  
49
    std::string::size_type pos = line.find('=');
50
    if (pos == std::string::npos) {
51
      std::cerr << "Warning: error reading configuration file, no '=' found on line " 
52
		<< lineno << std::endl;
53
      continue;
54
    }
55

  
56
    std::string key = stripTrailingWS(line.substr(0, pos));
57
    std::string value = stripLeadingWS(line.substr(pos + 1));
58

  
59
    data[key] = value;
60
  }
61

  
62
  input.close();
63
  return true;
64
}
65

  
66
void ConfigFile::set(const std::string &key, const std::string &value)
67
{
68
  data[key] = value;
69
}
70

  
71
std::string ConfigFile::get(const std::string &key) 
72
{
73
  return data[key];
74
}
configfile.h
1
// -*- c++ -*-
2
/*
3
  Copyright 2003 John Knottenbelt
4
  
5
  This program is free software; you can redistribute it and/or modify
6
  it under the terms of the GNU General Public License as published by
7
  the Free Software Foundation; either version 2 of the License, or
8
  (at your option) any later version.
9
 
10
  This program is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
  GNU General Public License for more details.
14
 
15
  You should have received a copy of the GNU General Public License
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
18
*/
19

  
20
#if !defined __CONFIGFILE_H
21
#define __CONFIGFILE_H
22

  
23
#include <map>
24
#include <string>
25

  
26
class ConfigFile {
27
public:
28
  ConfigFile();
29

  
30
  void clear();
31
  bool read(const std::string &file);
32
  void set(const std::string &key, const std::string &value);
33
  std::string get(const std::string &key);
34

  
35
private:
36
  
37
  typedef std::map<std::string, std::string> StringMap;
38
  StringMap data;
39
};
40

  
41
#endif // __CONFIGFILE_H
connection.cpp
1
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (at your option) any later version.
8
 
9
  This program is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18

  
19
#include "config.h"
20
#include "connection.h"
21
#include "demuxer.h"
22
#include "utils.h"
23
#include "stringutil.h"
24
#include "inputbuffer.h"
25
#include "outputbuffer.h"
26
#include "scheduler.h"
27

  
28
#include <iostream>
29
#include <cstring>
30
#include <vector>
31
#include <unistd.h>
32
#include <cerrno>
33
#include <ctime>
34
#include <algorithm>
35

  
36
Connection::Connection(TunerManager *tm, int dataFD)
37
  : dataFD(dataFD), priority(0), 
38
    tuned(false), retuning(false), 
39
    tm(tm), removeMe(false),
40
    stopTime(0),
41
    interrupted(false)
42
{
43
  if (debugLevel > 1)
44
    std::cerr << "New client connection" << std::endl;
45

  
46
  dataOutput = new OutputBuffer(dataFD, 16384, 65536);
47
}
48

  
49
Connection::~Connection()
50
{
51
  if (debugLevel > 1)
52
    std::cerr << "Client connection closed" << std::endl;
53

  
54
  retuning=true;
55
  doUnsubscribe();
56
  
57
  delete dataOutput;
58

  
59
  close(dataFD);
60
}
61

  
62
void Connection::doUnsubscribe()
63
{
64
  DemuxerList copy = demuxers;
65
  for (DemuxerList::iterator i = copy.begin(); i != copy.end(); i++)
66
    (*i)->unsubscribe(this);
67
}
68

  
69
bool Connection::doSubscribe()
70
{
71
  bool result = true;
72

  
73
  for (DemuxerList::iterator i = demuxers.begin(); i != demuxers.end(); i++)
74
    result = (*i)->subscribe(this) && result;
75

  
76
  if (!result) {
77
    doUnsubscribe();
78
    return false;
79
  }
80
  return true;
81
}
82

  
83
void Connection::notifyUnsubscribe(Source *s)
84
{
85
  Demuxer *d = (Demuxer *) s;
86
  demuxers.remove(d);
87
  interrupted = true;
88
}
89

  
90
time_t Connection::getCurrentTime() const
91
{
92
  return time(NULL);
93
}
94

  
95
void Connection::addSelectFDs(Select &s) const
96
{
97
  dataOutput->addSelectFDs(s);
98

  
99
  if (stopTime != 0)
100
    s.addAlarm(std::max(0L, stopTime - getCurrentTime()), 0);
101
}
102

  
103
bool Connection::isReady(const Select &s) const
104
{
105
  if (removeMe)
106
    return true;
107

  
108
  return dataOutput->isReady(s);
109
}
110

  
111
int Connection::getPriority() const
112
{
113
  return priority;
114
}
115

  
116
void Connection::setPriority(int p)
117
{
118
  priority = p;
119
}
120

  
121
void Connection::setStopTime(time_t newStopTime)
122
{
123
  stopTime = newStopTime;
124
}
125

  
126
time_t Connection::getStopTime() const
127
{
128
  return stopTime;
129
}
130

  
131
bool Connection::isValidType(const std::string &type ) const
132
{
133
  return tm->validType(type);
134
}
135

  
136
bool Connection::isValidChannel(const std::string &type, const std::string &channel) const
137
{
138
  return tm->validChannel(type, channel);
139
}
140

  
141
bool Connection::canTune(const std::string &newType, const std::string &newChannel, int p) const
142
{
143
  SavePriority save(const_cast<Connection *>(this), p - 1);
144
  
145
  return tm->canGetDemuxers(newType, newChannel, p);
146
}
147

  
148
void Connection::getTunableChannels(const std::string &type, int priority, StringList &channels) const
149
{
150
  tm->getTunableChannels(type, priority, channels);
151
}
152

  
153
bool Connection::isRetuning() const {
154
  return retuning;
155
}
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff