1 /* tzap-t2 -- simple zapping tool for the Linux DVB S2 API
3 * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4 * Copyright (C) 2013 CrazyCat (crazycat69@narod.ru)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <sys/ioctl.h>
29 #include <sys/types.h>
32 #include <sys/param.h>
40 #include <linux/dvb/frontend.h>
41 #include <linux/dvb/dmx.h>
42 #include <linux/dvb/audio.h>
43 #include <linux/dvb/version.h>
46 #if DVB_API_VERSION < 5 || DVB_API_VERSION_MINOR < 2
47 #error szap-s2 requires Linux DVB driver API version 5.2 and newer!
51 #define DTV_STREAM_ID DTV_ISDBS_TS_ID
54 #ifndef NO_STREAM_ID_FILTER
55 #define NO_STREAM_ID_FILTER (~0U)
65 /* location of channel list file */
66 #define CHANNEL_FILE "channels.conf"
68 /* one line of the szap channel file has the following format:
69 * ^name:frequency_KHz:inversion:bandwidth:coderate_hp:coderate_lp:modulation:transmission_mode:guard_interval:hierarchy:vpid:apid:service_id$
70 * one line of the VDR channel file has the following format:
71 * ^name:frequency_KHz:[bandwidth][delivery][modulation][coderate_hp][coderate_lp][transmission_mode][guard_interval][hierarchy]]plp_id]:vpid:apid:?:?:service_id:?:?:?$
75 #define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d"
76 #define DEMUXDEVICE "/dev/dvb/adapter%d/demux%d"
77 #define AUDIODEVICE "/dev/dvb/adapter%d/audio%d"
79 struct t_channel_parameter_map
{
82 const char *user_string
;
84 /* --- Channel Parameter Maps From VDR---*/
86 static struct t_channel_parameter_map inversion_values
[] = {
87 { 0, INVERSION_OFF
, "off" },
88 { 1, INVERSION_ON
, "on" },
89 { 999, INVERSION_AUTO
},
93 static struct t_channel_parameter_map bw_values
[] = {
94 { 6, BANDWIDTH_6_MHZ
, "6MHz" },
95 { 7, BANDWIDTH_7_MHZ
, "7MHz" },
96 { 8, BANDWIDTH_8_MHZ
, "8MHz" },
97 { 5, BANDWIDTH_6_MHZ
, "5MHz" },
98 { 10, BANDWIDTH_10_MHZ
, "10MHz" },
99 { 999, BANDWIDTH_AUTO
, "auto" },
103 static struct t_channel_parameter_map coderate_values
[] = {
104 { 0, FEC_NONE
, "none" },
105 { 12, FEC_1_2
, "1/2" },
106 { 23, FEC_2_3
, "2/3" },
107 { 34, FEC_3_4
, "3/4" },
108 { 35, FEC_3_5
, "3/5" },
109 { 45, FEC_4_5
, "4/5" },
110 { 56, FEC_5_6
, "5/6" },
111 { 67, FEC_6_7
, "6/7" },
112 { 78, FEC_7_8
, "7/8" },
113 { 89, FEC_8_9
, "8/9" },
114 { 910, FEC_9_10
, "9/10" },
115 { 999, FEC_AUTO
, "auto" },
119 static struct t_channel_parameter_map modulation_values
[] = {
120 // { 0, NONE, "none" },
122 { 10, VSB_8
, "VSB8" },
123 { 11, VSB_16
, "VSB16" },
124 { 16, QAM_16
, "QAM16" },
125 { 64, QAM_64
, "QAM64" },
126 { 128, QAM_128
, "QAM128" },
127 { 256, QAM_256
, "QAM256" },
132 static struct t_channel_parameter_map mode_values
[] = {
133 { 2, TRANSMISSION_MODE_2K
, "2k" },
134 { 8, TRANSMISSION_MODE_2K
, "8k" },
135 { 999, TRANSMISSION_MODE_AUTO
, "auto" },
136 { 4, TRANSMISSION_MODE_4K
, "4k" },
137 { 1, TRANSMISSION_MODE_1K
, "1k" },
138 { 16, TRANSMISSION_MODE_16K
, "16k" },
139 { 32, TRANSMISSION_MODE_32K
, "32k" },
143 static struct t_channel_parameter_map guard_values
[] = {
144 { 32, GUARD_INTERVAL_1_32
, "1/32" },
145 { 16, GUARD_INTERVAL_1_16
, "1/16" },
146 { 8, GUARD_INTERVAL_1_8
, "1/8" },
147 { 4, GUARD_INTERVAL_1_4
, "1/4" },
148 { 999, GUARD_INTERVAL_AUTO
, "auto" },
149 { 1128, GUARD_INTERVAL_1_128
, "1/128" },
150 { 19128, GUARD_INTERVAL_19_128
, "19/128" },
151 { 19256, GUARD_INTERVAL_19_256
, "19/256" },
155 static struct t_channel_parameter_map hierarchy_values
[] = {
156 { 0, HIERARCHY_NONE
, "none" },
157 { 1, HIERARCHY_NONE
, "1" },
158 { 2, HIERARCHY_NONE
, "2" },
159 { 4, HIERARCHY_NONE
, "4" },
160 { 999, HIERARCHY_NONE
, "auto" },
164 static struct t_channel_parameter_map system_values
[] = {
165 { 0, SYS_DVBT
, "DVB-T" },
166 { 1, SYS_DVBT2
, "DVB-T2" },
170 static int user_index(int value
, const struct t_channel_parameter_map
* map
)
172 const struct t_channel_parameter_map
*umap
= map
;
173 while (umap
&& umap
->user_value
!= -1) {
174 if (umap
->user_value
== value
)
181 static int driver_index(int value
, const struct t_channel_parameter_map
*map
)
183 const struct t_channel_parameter_map
*umap
= map
;
184 while (umap
&& umap
->user_value
!= -1) {
185 if (umap
->driver_value
== value
)
192 static int map_to_user(int value
, const struct t_channel_parameter_map
*map
, char **string
)
194 int n
= driver_index(value
, map
);
197 *string
= (char *)map
[n
].user_string
;
198 return map
[n
].user_value
;
203 static int map_to_driver(int value
, const struct t_channel_parameter_map
*map
)
205 int n
= user_index(value
, map
);
207 return map
[n
].driver_value
;
211 static struct lnb_types_st lnb_type
;
213 static int exit_after_tuning
;
214 static int interactive
;
216 static char *usage_str
=
217 "\nusage: tzap-t2 -q\n"
218 " list known channels\n"
219 " tzap-t2 [options] {-n channel-number|channel_name}\n"
220 " zap to channel via number or full name (case insensitive)\n"
221 " -a number : use given adapter (default 0)\n"
222 " -f number : use given frontend (default 0)\n"
223 " -d number : use given demux (default 0)\n"
224 " -c file : read channels list from 'file'\n"
225 " -V : use VDR channels list file format (default zap)\n"
226 " -b : enable Audio Bypass (default no)\n"
227 " -x : exit after tuning\n"
228 " -H : human readable output\n"
229 " -D : params debug\n"
230 " -r : set up /dev/dvb/adapterX/dvr0 for TS recording\n"
231 " -i : run interactively, allowing you to type in channel names\n"
232 " -p : add pat and pmt to TS recording (implies -r)\n"
233 " or -n numbers for zapping\n"
234 " -t : add teletext to TS recording (needs -V)\n"
235 " -S : delivery system type DVB-T=0, DVB-T2=1\n"
236 " -M : modulation 2=QPSK 16=16QAM 64=64QAM 256=256QAM\n"
237 " -C : fec 0=NONE 12=1/2 23=2/3 34=3/4 35=3/5 45=4/5 56=5/6 67=6/7 89=8/9 910=9/10 999=AUTO\n"
238 " -m : physical layer pipe 0-255\n";
240 static int set_demux(int dmxfd
, int pid
, int pes_type
, int dvr
)
242 struct dmx_pes_filter_params pesfilter
;
244 if (pid
< 0 || pid
>= 0x1fff) /* ignore this pid to allow radio services */
248 int buffersize
= 64 * 1024;
249 if (ioctl(dmxfd
, DMX_SET_BUFFER_SIZE
, buffersize
) == -1)
250 perror("DMX_SET_BUFFER_SIZE failed");
254 pesfilter
.input
= DMX_IN_FRONTEND
;
255 pesfilter
.output
= dvr
? DMX_OUT_TS_TAP
: DMX_OUT_DECODER
;
256 pesfilter
.pes_type
= pes_type
;
257 pesfilter
.flags
= DMX_IMMEDIATE_START
;
259 if (ioctl(dmxfd
, DMX_SET_PES_FILTER
, &pesfilter
) == -1) {
260 fprintf(stderr
, "DMX_SET_PES_FILTER failed "
261 "(PID = 0x%04x): %d %m\n", pid
, errno
);
269 int get_pmt_pid(char *dmxdev
, int sid
)
275 unsigned char buft
[4096];
276 unsigned char *buf
= buft
;
277 struct dmx_sct_filter_params f
;
279 memset(&f
, 0, sizeof(f
));
281 f
.filter
.filter
[0] = 0x00;
282 f
.filter
.mask
[0] = 0xff;
284 f
.flags
= DMX_IMMEDIATE_START
| DMX_CHECK_CRC
;
286 if ((patfd
= open(dmxdev
, O_RDWR
)) < 0) {
287 perror("openening pat demux failed");
291 if (ioctl(patfd
, DMX_SET_FILTER
, &f
) == -1) {
292 perror("ioctl DMX_SET_FILTER failed");
298 if (((count
= read(patfd
, buf
, sizeof(buft
))) < 0) && errno
== EOVERFLOW
)
299 count
= read(patfd
, buf
, sizeof(buft
));
301 perror("read_sections: read error");
306 section_length
= ((buf
[1] & 0x0f) << 8) | buf
[2];
307 if (count
!= section_length
+ 3)
313 patread
= 1; /* assumes one section contains the whole pat */
314 while (section_length
> 0) {
315 int service_id
= (buf
[0] << 8) | buf
[1];
316 if (service_id
== sid
) {
317 pmt_pid
= ((buf
[2] & 0x1f) << 8) | buf
[3];
328 static int do_tune(int fefd
, unsigned int freq
, unsigned int bw
, enum fe_delivery_system delsys
,
329 int modulation
, int fec_hp
, int fec_lp
, int mode
, int guard
, int hierarchy
, int stream_id
)
331 struct dvb_frontend_event ev
;
332 struct dtv_property p
[] = {
333 { .cmd
= DTV_DELIVERY_SYSTEM
, .u
.data
= delsys
},
334 { .cmd
= DTV_FREQUENCY
, .u
.data
= freq
},
335 { .cmd
= DTV_BANDWIDTH_HZ
, .u
.data
= bw
},
336 { .cmd
= DTV_MODULATION
, .u
.data
= modulation
},
337 { .cmd
= DTV_CODE_RATE_HP
, .u
.data
= fec_hp
},
338 { .cmd
= DTV_CODE_RATE_LP
, .u
.data
= fec_lp
},
339 { .cmd
= DTV_INVERSION
, .u
.data
= INVERSION_AUTO
},
340 { .cmd
= DTV_TRANSMISSION_MODE
, .u
.data
= mode
},
341 { .cmd
= DTV_GUARD_INTERVAL
, .u
.data
= guard
},
342 { .cmd
= DTV_HIERARCHY
, .u
.data
= hierarchy
},
343 { .cmd
= DTV_STREAM_ID
, .u
.data
= stream_id
},
346 struct dtv_properties cmdseq
= {
347 .num
= sizeof(p
)/sizeof(p
[0]),
351 /* discard stale QPSK events */
353 if (ioctl(fefd
, FE_GET_EVENT
, &ev
) == -1)
357 if ((delsys
!= SYS_DVBT
) && (delsys
!= SYS_DVBT2
))
360 if ((ioctl(fefd
, FE_SET_PROPERTY
, &cmdseq
)) == -1) {
361 perror("FE_SET_PROPERTY failed");
370 int check_frontend (int fe_fd
, int dvr
, int human_readable
, int params_debug
)
374 uint16_t snr
, signal
;
375 uint32_t ber
, uncorrected_blocks
;
378 struct dtv_property p
[] = {
379 { .cmd
= DTV_FREQUENCY
},
380 { .cmd
= DTV_BANDWIDTH_HZ
},
381 { .cmd
= DTV_DELIVERY_SYSTEM
},
382 { .cmd
= DTV_MODULATION
},
383 { .cmd
= DTV_CODE_RATE_HP
},
384 { .cmd
= DTV_CODE_RATE_LP
},
385 { .cmd
= DTV_TRANSMISSION_MODE
},
386 { .cmd
= DTV_GUARD_INTERVAL
},
387 { .cmd
= DTV_HIERARCHY
},
389 struct dtv_properties cmdseq
= {
390 .num
= sizeof(p
)/sizeof(p
[0]),
395 if (ioctl(fe_fd
, FE_READ_STATUS
, &status
) == -1)
396 perror("FE_READ_STATUS failed");
397 /* some frontends might not support all these ioctls, thus we
398 * avoid printing errors
400 if (ioctl(fe_fd
, FE_READ_SIGNAL_STRENGTH
, &signal
) == -1)
402 if (ioctl(fe_fd
, FE_READ_SNR
, &snr
) == -1)
404 if (ioctl(fe_fd
, FE_READ_BER
, &ber
) == -1)
406 if (ioctl(fe_fd
, FE_READ_UNCORRECTED_BLOCKS
, &uncorrected_blocks
) == -1)
407 uncorrected_blocks
= -2;
409 if (human_readable
) {
410 printf ("status %02x | signal %3u%% | snr %3u%% | ber %d | unc %d | ",
411 status
, (signal
* 100) / 0xffff, (snr
* 100) / 0xffff, ber
, uncorrected_blocks
);
413 printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ",
414 status
, signal
, snr
, ber
, uncorrected_blocks
);
416 if (status
& FE_HAS_LOCK
)
417 printf("FE_HAS_LOCK");
420 if (exit_after_tuning
&& ((status
& FE_HAS_LOCK
) || (++timeout
>= 10)))
426 if ((status
& FE_HAS_LOCK
) == 0)
429 if ((ioctl(fe_fd
, FE_GET_PROPERTY
, &cmdseq
)) == -1) {
430 perror("FE_GET_PROPERTY failed");
433 /* printout found parameters here */
435 printf("frequency %d, ", p
[0].u
.data
);
436 printf("bandwidth %d, ", p
[1].u
.data
);
437 printf("delivery %d, ", p
[2].u
.data
);
438 printf("modulation %d, ", p
[3].u
.data
);
439 printf("coderate hp %d, ", p
[4].u
.data
);
440 printf("coderate lp %d, ", p
[5].u
.data
);
441 printf("mode %d, ", p
[6].u
.data
);
442 printf("guard %d, ", p
[7].u
.data
);
443 printf("hierarchy %d", p
[8].u
.data
);
445 printf("frequency %d, ",p
[0].u
.data
);
447 map_to_user(p
[1].u
.data
, bw_values
, &field
);
448 printf("bandwidth %s, ", field
);
450 map_to_user(p
[2].u
.data
, system_values
, &field
);
451 printf("delivery %s, ", field
);
453 map_to_user(p
[3].u
.data
, modulation_values
, &field
);
454 printf("modulation %s, ", field
);
456 map_to_user(p
[4].u
.data
, coderate_values
, &field
);
457 printf("coderate-hp %s, ", field
);
459 map_to_user(p
[5].u
.data
, coderate_values
, &field
);
460 printf("coderate-lp %s, ", field
);
462 map_to_user(p
[6].u
.data
, mode_values
, &field
);
463 printf("mode %s, ", field
);
465 map_to_user(p
[7].u
.data
, guard_values
, &field
);
466 printf("guard %s, ", field
);
468 map_to_user(p
[8].u
.data
, hierarchy_values
, &field
);
469 printf("hierarchy %s", field
);
478 int zap_to(unsigned int adapter
, unsigned int frontend
, unsigned int demux
,
479 unsigned int freq
, unsigned int bw
,
480 unsigned int vpid
, unsigned int apid
,
481 unsigned int tpid
, int sid
,
482 int dvr
, int rec_psi
, int bypass
, unsigned int delivery
,
483 int modulation
, int fec_hp
, int fec_lp
, int mode
, int guard
, int hierarchy
, int stream_id
, int human_readable
,
486 struct dtv_property p
[] = {
487 { .cmd
= DTV_CLEAR
},
490 struct dtv_properties cmdseq
= {
491 .num
= sizeof(p
)/sizeof(p
[0]),
495 char fedev
[128], dmxdev
[128], auddev
[128];
496 static int fefd
, dmxfda
, dmxfdv
, dmxfdt
= -1, audiofd
= -1, patfd
, pmtfd
;
501 snprintf(fedev
, sizeof(fedev
), FRONTENDDEVICE
, adapter
, frontend
);
502 snprintf(dmxdev
, sizeof(dmxdev
), DEMUXDEVICE
, adapter
, demux
);
503 snprintf(auddev
, sizeof(auddev
), AUDIODEVICE
, adapter
, demux
);
504 printf("using '%s' and '%s'\n", fedev
, dmxdev
);
506 if ((fefd
= open(fedev
, O_RDWR
| O_NONBLOCK
)) < 0) {
507 perror("opening frontend failed");
511 if ((dmxfdv
= open(dmxdev
, O_RDWR
)) < 0) {
512 perror("opening video demux failed");
517 if ((dmxfda
= open(dmxdev
, O_RDWR
)) < 0) {
518 perror("opening audio demux failed");
523 if ((dmxfdt
= open(dmxdev
, O_RDWR
)) < 0) {
524 perror("opening teletext demux failed");
529 if (dvr
== 0) /* DMX_OUT_DECODER */
530 audiofd
= open(auddev
, O_RDWR
);
533 if ((patfd
= open(dmxdev
, O_RDWR
)) < 0) {
534 perror("opening pat demux failed");
543 if ((pmtfd
= open(dmxdev
, O_RDWR
)) < 0) {
544 perror("opening pmt demux failed");
559 if ((ioctl(fefd
, FE_SET_PROPERTY
, &cmdseq
)) == -1) {
560 perror("FE_SET_PROPERTY DTV_CLEAR failed");
566 case BANDWIDTH_5_MHZ
: bw
= 5000000; break;
567 case BANDWIDTH_6_MHZ
: bw
= 6000000; break;
568 case BANDWIDTH_7_MHZ
: bw
= 7000000; break;
569 case BANDWIDTH_8_MHZ
: bw
= 8000000; break;
570 case BANDWIDTH_10_MHZ
: bw
= 10000000; break;
575 if (do_tune(fefd
, freq
, bw
, delivery
, modulation
, fec_hp
, fec_lp
, mode
, guard
, hierarchy
, stream_id
))
576 if (set_demux(dmxfdv
, vpid
, DMX_PES_VIDEO
, dvr
))
578 (void)ioctl(audiofd
, AUDIO_SET_BYPASS_MODE
, bypass
);
579 if (set_demux(dmxfda
, apid
, DMX_PES_AUDIO
, dvr
)) {
581 pmtpid
= get_pmt_pid(dmxdev
, sid
);
586 fprintf(stderr
,"couldn't find pmt-pid for sid %04x\n",sid
);
589 if (set_demux(patfd
, 0, DMX_PES_OTHER
, dvr
))
590 if (set_demux(pmtfd
, pmtpid
, DMX_PES_OTHER
, dvr
))
597 if (tpid
!= -1 && !set_demux(dmxfdt
, tpid
, DMX_PES_TELETEXT
, dvr
)) {
598 fprintf(stderr
, "set_demux DMX_PES_TELETEXT failed\n");
601 check_frontend (fefd
, dvr
, human_readable
, params_debug
);
616 static char *parse_parameter(const char *s
, int *value
, const struct t_channel_parameter_map
*map
)
621 int n
= strtol(s
, &p
, 10);
622 if (!errno
&& p
!= s
) {
623 value
[0] = map_to_driver(n
, map
);
628 fprintf(stderr
, "ERROR: invalid value for parameter '%C'\n", *(s
- 1));
632 static int read_channels(const char *filename
, int list_channels
,
633 uint32_t chan_no
, const char *chan_name
,
634 unsigned int adapter
, unsigned int frontend
,
635 unsigned int demux
, int dvr
, int rec_psi
,
636 int bypass
, unsigned int delsys
,
637 int modulation
, int fec_hp
, int fec_lp
, int mode
, int guard
, int hierarchy
, int stream_id
, int human_readable
,
638 int params_debug
, int use_vdr_format
, int use_tpid
)
643 char *field
, *tmp
, *p
;
645 unsigned int freq
= 0, bw
= 0, vpid
, apid
, tpid
, sid
;
650 if (!(cfp
= fopen(filename
, "r"))) {
651 fprintf(stderr
, "error opening channel list '%s': %d %m\n",
657 fprintf(stderr
, "\n>>> ");
658 if (!fgets(inp
, sizeof(inp
), stdin
)) {
662 if (inp
[0] == '-' && inp
[1] == 'n') {
663 chan_no
= strtoul(inp
+2, NULL
, 0);
666 fprintf(stderr
, "bad channel number\n");
670 p
= strchr(inp
, '\n');
679 if (fgets(buf
, sizeof(buf
), cfp
)) {
682 if (chan_no
&& chan_no
!= line
)
686 field
= strsep(&tmp
, ":");
692 printf("%03u %s\n", line
, field
);
696 if (chan_name
&& strcasecmp(chan_name
, field
) != 0)
699 printf("zapping to %d '%s':\n", line
, field
);
701 if (!(field
= strsep(&tmp
, ":")))
704 freq
= strtoul(field
, NULL
, 0);
706 if (!(field
= strsep(&tmp
, ":")))
709 while (field
&& *field
) {
710 switch (toupper(*field
)) {
712 field
= parse_parameter(field
, &bw
, bw_values
);
715 if (modulation
== -1)
716 field
= parse_parameter(field
, &modulation
, modulation_values
);
718 field
= parse_parameter(field
, &trash
, modulation_values
);
720 case 'I':/* ignore */
721 field
= parse_parameter(field
, &ret
, inversion_values
);
725 field
= parse_parameter(field
, &fec_hp
, coderate_values
);
727 field
= parse_parameter(field
, &trash
, coderate_values
);
731 field
= parse_parameter(field
, &fec_lp
, coderate_values
);
733 field
= parse_parameter(field
, &trash
, coderate_values
);
737 field
= parse_parameter(field
, &mode
, mode_values
);
739 field
= parse_parameter(field
, &trash
, mode_values
);
743 field
= parse_parameter(field
, &guard
, guard_values
);
745 field
= parse_parameter(field
, &trash
, guard_values
);
749 field
= parse_parameter(field
, &hierarchy
, hierarchy_values
);
751 field
= parse_parameter(field
, &trash
, hierarchy_values
);
754 stream_id
= strtol(++field
, &field
, 10);
758 field
= parse_parameter(field
, &delsys
, system_values
);
760 field
= parse_parameter(field
, &trash
, system_values
);
766 /* default values for empty parameters */
767 if (modulation
== -1)
780 mode
= TRANSMISSION_MODE_AUTO
;
783 guard
= GUARD_INTERVAL_AUTO
;
786 hierarchy
= HIERARCHY_NONE
;
788 if (stream_id
<0 || stream_id
>255)
789 stream_id
= NO_STREAM_ID_FILTER
;
791 if (!(field
= strsep(&tmp
, ":")))
794 if (!(field
= strsep(&tmp
, ":")))
797 if (!(field
= strsep(&tmp
, ":")))
800 vpid
= strtoul(field
, NULL
, 0);
804 if (!(field
= strsep(&tmp
, ":")))
807 p
= strchr(field
, ';');
819 apid
= strtoul(field
, NULL
, 0);
824 if (use_vdr_format
) {
825 if (!(field
= strsep(&tmp
, ":")))
829 tpid
= strtoul(field
, NULL
, 0);
831 if (!(field
= strsep(&tmp
, ":")))
834 strtoul(field
, NULL
, 0);
837 if (!(field
= strsep(&tmp
, ":")))
840 sid
= strtoul(field
, NULL
, 0);
845 map_to_user(bw
, bw_values
, &field
);
846 printf("frequency %u KHz, bandwidth %s, ",
850 printf("delivery %d, ", delsys
);
853 map_to_user(delsys
, system_values
, &field
);
854 printf("delivery %s, ", field
);
858 printf("modulation %d\n", modulation
);
861 map_to_user(modulation
, modulation_values
, &field
);
862 printf("modulation %s\n", field
);
866 printf("coderate-hp %d, ", fec_hp
);
869 map_to_user(fec_hp
, coderate_values
, &field
);
870 printf("coderate-hp %s, ", field
);
874 printf("coderate-lp %d, ", fec_hp
);
877 map_to_user(fec_lp
, coderate_values
, &field
);
878 printf("coderate-lp %s, ", field
);
882 printf("mode %d, ", mode
);
885 map_to_user(mode
, mode_values
, &field
);
886 printf("mode %s, ", field
);
890 printf("guard %d, ", mode
);
893 map_to_user(guard
, guard_values
, &field
);
894 printf("guard %s, ", field
);
898 printf("hierarchy %d, ", mode
);
901 map_to_user(hierarchy
, hierarchy_values
, &field
);
902 printf("hierarchy %s, ", field
);
905 printf("plp_id %d\n", stream_id
);
907 printf("vpid 0x%04x, apid 0x%04x, sid 0x%04x\n", vpid
, apid
, sid
);
909 ret
= zap_to(adapter
, frontend
, demux
, freq
* 1000, bw
,
910 vpid
, apid
, tpid
, sid
, dvr
, rec_psi
, bypass
,
911 delsys
, modulation
, fec_hp
, fec_lp
, mode
, guard
, hierarchy
, stream_id
, human_readable
,
923 fprintf(stderr
, "syntax error in line %u: '%s'\n", line
, buf
);
924 } else if (ferror(cfp
)) {
925 fprintf(stderr
, "error reading channel list '%s': %d %m\n",
935 if (!list_channels
) {
936 fprintf(stderr
, "channel not found\n");
947 static void handle_sigint(int sig
)
949 fprintf(stderr
, "Interrupted by SIGINT!\n");
954 bad_usage(char *pname
)
956 fprintf (stderr
, usage_str
, pname
);
959 int main(int argc
, char *argv
[])
962 char chanfile
[2 * PATH_MAX
];
963 int list_channels
= 0;
964 unsigned int chan_no
= 0;
965 const char *chan_name
= NULL
;
966 unsigned int adapter
= 0, frontend
= 0, demux
= 0, dvr
= 0, rec_psi
= 0;
969 int human_readable
= 0;
970 int params_debug
= 0;
971 int use_vdr_format
= 0;
978 int stream_id
= NO_STREAM_ID_FILTER
;
980 while ((opt
= getopt(argc
, argv
, "M:m:C:O:HDVhqrpn:a:f:d:S:c:l:xib")) != -1) {
988 parse_parameter(--optarg
, &fec
, coderate_values
);
991 parse_parameter(--optarg
, &modulation
, modulation_values
);
994 stream_id
= strtol(optarg
, NULL
, 0);
997 parse_parameter(--optarg
, &delsys
, system_values
);
1009 chan_no
= strtoul(optarg
, NULL
, 0);
1012 adapter
= strtoul(optarg
, NULL
, 0);
1015 frontend
= strtoul(optarg
, NULL
, 0);
1021 demux
= strtoul(optarg
, NULL
, 0);
1025 strncpy(chanfile
, optarg
, sizeof(chanfile
));
1028 exit_after_tuning
= 1;
1044 exit_after_tuning
= 1;
1048 chan_name
= argv
[optind
];
1049 if (chan_name
&& chan_no
) {
1053 if (list_channels
&& (chan_name
|| chan_no
)) {
1057 if (!list_channels
&& !chan_name
&& !chan_no
&& !interactive
) {
1063 if (!(home
= getenv("HOME"))) {
1064 fprintf(stderr
, "error: $HOME not set\n");
1067 snprintf(chanfile
, sizeof(chanfile
),
1068 "%s/.tzap/%i/%s", home
, adapter
, CHANNEL_FILE
);
1069 if (access(chanfile
, R_OK
))
1070 snprintf(chanfile
, sizeof(chanfile
),
1071 "%s/.tzap/%s", home
, CHANNEL_FILE
);
1074 printf("reading channels from file '%s'\n", chanfile
);
1079 signal(SIGINT
, handle_sigint
);
1081 if (!read_channels(chanfile
, list_channels
, chan_no
, chan_name
,
1082 adapter
, frontend
, demux
, dvr
, rec_psi
, bypass
, delsys
,
1083 modulation
, fec
, -1, -1, -1, -1, stream_id
, human_readable
, params_debug
,
1084 use_vdr_format
, use_tpid
))