1 /*
2  * Copyright (c) 2011-2012 - Mauro Carvalho Chehab
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation version 2
7  * of the License.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18  *
19  * Based on dvb-apps tzap utility, made by:
20  *	Bernard Hatt 24/2/04
21  */
22 
23 #define _FILE_OFFSET_BITS 64
24 #define _LARGEFILE_SOURCE 1
25 #define _LARGEFILE64_SOURCE 1
26 
27 /*
28  * Use a buffer big enough at least 1 second of data. It is interesting
29  * To have it multiple of a page. So, define it as a multiply of
30  * 4096.
31  */
32 #define DVB_BUF_SIZE	(4096 * 8 * 188)
33 
34 /*
35  * Size of the buffer on read operations. The better is if it is
36  * smaller than DVB_BUF_SIZE, as we want to give more time for
37  * write() syscalls to be able to flush data.
38  */
39 #define BUFLEN (188 * 512)
40 
41 #include <unistd.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <ctype.h>
46 #include <errno.h>
47 #include <signal.h>
48 #include <argp.h>
49 #include <sys/time.h>
50 #include <time.h>
51 
52 #include <config.h>
53 
54 #ifdef ENABLE_NLS
55 # define _(string) gettext(string)
56 # include <stdio.h>
57 # include <locale.h>
58 # include <langinfo.h>
59 # include <iconv.h>
60 #else
61 # define _(string) string
62 #endif
63 
64 # define N_(string) string
65 
66 #include <linux/dvb/dmx.h>
67 #include "libdvbv5/dvb-file.h"
68 #include "libdvbv5/dvb-demux.h"
69 #include "libdvbv5/dvb-dev.h"
70 #include "libdvbv5/dvb-scan.h"
71 #include "libdvbv5/header.h"
72 #include "libdvbv5/countries.h"
73 
74 #define CHANNEL_FILE	"channels.conf"
75 #define PROGRAM_NAME	"dvbv5-zap"
76 
77 
78 #ifndef O_LARGEFILE
79 #  define O_LARGEFILE 0
80 #endif
81 
82 
83 const int NANO_SECONDS_IN_SEC = 1000000000;
84 
85 const char *argp_program_version = PROGRAM_NAME " version " V4L_UTILS_VERSION;
86 const char *argp_program_bug_address = "Mauro Carvalho Chehab <mchehab@kernel.org>";
87 
88 struct arguments {
89 	char *confname, *lnb_name, *output, *demux_dev, *dvr_dev, *dvr_fname;
90 	char *filename, *dvr_pipe;
91 	unsigned adapter, frontend, demux, get_detected, get_nit;
92 	int lna, lnb, sat_number;
93 	unsigned diseqc_wait, silent, verbose, frontend_only, freq_bpf;
94 	unsigned timeout, dvr, rec_psi, exit_after_tuning;
95 	unsigned n_apid, n_vpid, all_pids;
96 	enum dvb_file_formats input_format, output_format;
97 	unsigned traffic_monitor, low_traffic, non_human, port;
98 	char *search, *server;
99 	const char *cc;
100 
101 	/* Used by status print */
102 	unsigned n_status_lines;
103 };
104 
105 static const struct argp_option options[] = {
106 	{"adapter",	'a', N_("adapter#"),		0, N_("use given adapter (default 0)"), 0},
107 	{"audio_pid",	'A', N_("audio_pid#"),		0, N_("audio pid program to use (default 0)"), 0},
108 	{"channels",	'c', N_("file"),		0, N_("read channels list from 'file'"), 0},
109 	{"demux",	'd', N_("demux#"),		0, N_("use given demux (default 0)"), 0},
110 	{"frontend",	'f', N_("frontend#"),		0, N_("use given frontend (default 0)"), 0},
111 	{"input-format", 'I',	N_("format"),		0, N_("Input format: ZAP, CHANNEL, DVBV5 (default: DVBV5)"), 0},
112 	{"lna",		'w', N_("LNA (0, 1, -1)"),	0, N_("enable/disable/auto LNA power"), 0},
113 	{"lnbf",	'l', N_("LNBf_type"),		0, N_("type of LNBf to use. 'help' lists the available ones"), 0},
114 	{"search",	'L', N_("string"),		0, N_("search/look for a string inside the traffic"), 0},
115 	{"monitor",	'm', NULL,			0, N_("monitors the DVB traffic"), 0},
116 	{"output",	'o', N_("file"),		0, N_("output filename (use -o - for stdout)"), 0},
117 	{"pat",		'p', NULL,			0, N_("add pat and pmt to TS recording (implies -r)"), 0},
118 	{"all-pids",	'P', NULL,			0, N_("don't filter any pids. Instead, outputs all of them"), 0 },
119 	{"record",	'r', NULL,			0, N_("set up /dev/dvb/adapterX/dvr0 for TS recording"), 0},
120 	{"silence",	's', NULL,			0, N_("increases silence (can be used more than once)"), 0},
121 	{"sat_number",	'S', N_("satellite_number"),	0, N_("satellite number. If not specified, disable DISEqC"), 0},
122 	{"timeout",	't', N_("seconds"),		0, N_("timeout for zapping and for recording"), 0},
123 	{"freq_bpf",	'U', N_("frequency"),		0, N_("SCR/Unicable band-pass filter frequency to use, in kHz"), 0},
124 	{"verbose",	'v', NULL,			0, N_("verbose debug messages (can be used more than once)"), 0},
125 	{"video_pid",	'V', N_("video_pid#"),		0, N_("video pid program to use (default 0)"), 0},
126 	{"wait",	'W', N_("time"),		0, N_("adds additional wait time for DISEqC command completion"), 0},
127 	{"exit",	'x', NULL,			0, N_("exit after tuning"), 0},
128 	{"low_traffic",	'X', N_("packets_per_sec"),	0, N_("sets DVB low traffic threshold. PIDs with less than this amount of packets per second will be ignored. Default: 1 packet per second"), 0},
129 	{"cc",		'C', N_("country_code"),	0, N_("Set the default country to be used (in ISO 3166-1 two letter code)"), 0},
130 	{"non-numan",	'N', NULL,			0, N_("Non-human formatted stats (useful for scripts)"), 0},
131 	{"server",	'H', N_("SERVER"),		0, N_("dvbv5-daemon host IP address"), 0},
132 	{"tcp-port",	'T', N_("PORT"),		0, N_("dvbv5-daemon host tcp port"), 0},
133 	{"dvr-pipe",	'D', N_("PIPE"),		0, N_("Named pipe for DVR output, when using remote access (by default: /tmp/dvr-pipe)"), 0},
134 	{"help",        '?', 0,				0, N_("Give this help list"), -1},
135 	{"usage",	-3,  0,				0, N_("Give a short usage message")},
136 	{"version",	-4,  0,				0, N_("Print program version"), -1},
137 	{ 0, 0, 0, 0, 0, 0 }
138 };
139 
140 static int timeout_flag = 0;
141 
142 #define ERROR(x...)                                                     \
143 	do {                                                            \
144 		fprintf(stderr, _("ERROR: "));                             \
145 		fprintf(stderr, x);                                     \
146 		fprintf(stderr, "\n");                                 \
147 	} while (0)
148 
149 #define PERROR(x...)                                                    \
150 	do {                                                            \
151 		fprintf(stderr, _("ERROR: "));                             \
152 		fprintf(stderr, x);                                     \
153 		fprintf(stderr, " (%s)\n", strerror(errno));		\
154 	} while (0)
155 
156 #define monitor_log(msg, args...)						\
157 	do {									\
158 		struct timespec __now = { 0 };					\
159 		float __diff;							\
160 										\
161 		clock_gettime(CLOCK_MONOTONIC, &__now);				\
162 		__diff = __now.tv_sec * 1.					\
163 			 + __now.tv_nsec *1. / NANO_SECONDS_IN_SEC;		\
164 		fprintf(stderr, msg, __diff, ##args);				\
165 	} while (0)
166 
167 
parse(struct arguments * args,struct dvb_v5_fe_parms * parms,char * channel,int * vpid,int * apid,int * sid)168 static int parse(struct arguments *args,
169 		 struct dvb_v5_fe_parms *parms,
170 		 char *channel,
171 		 int *vpid, int *apid, int *sid)
172 {
173 	struct dvb_file *dvb_file;
174 	struct dvb_entry *entry;
175 	int i;
176 	uint32_t sys;
177 
178 	/* This is used only when reading old formats */
179 	switch (parms->current_sys) {
180 	case SYS_DVBT:
181 	case SYS_DVBS:
182 	case SYS_DVBC_ANNEX_A:
183 	case SYS_ATSC:
184 		sys = parms->current_sys;
185 		break;
186 	case SYS_DVBC_ANNEX_C:
187 		sys = SYS_DVBC_ANNEX_A;
188 		break;
189 	case SYS_DVBC_ANNEX_B:
190 		sys = SYS_ATSC;
191 		break;
192 	case SYS_ISDBT:
193 	case SYS_DTMB:
194 		sys = SYS_DVBT;
195 		break;
196 	default:
197 		sys = SYS_UNDEFINED;
198 		break;
199 	}
200 	dvb_file = dvb_read_file_format(args->confname, sys,
201 				    args->input_format);
202 	if (!dvb_file)
203 		return -2;
204 
205 	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
206 		if (entry->channel && !strcmp(entry->channel, channel))
207 			break;
208 		if (entry->vchannel && !strcmp(entry->vchannel, channel))
209 			break;
210 	}
211 	/*
212 	 * Give a second shot, using a case insensitive seek
213 	 */
214 	if (!entry) {
215 		for (entry = dvb_file->first_entry; entry != NULL;
216 		     entry = entry->next) {
217 			if (entry->channel && !strcasecmp(entry->channel, channel))
218 				break;
219 		}
220 	}
221 
222 	/*
223 	 * When this tool is used to just tune to a channel, to monitor it or
224 	 * to capture all PIDs, all it needs is a frequency.
225 	 * So, let the tool to accept a frequency as the tuning channel on those
226 	 * cases.
227 	 * This way, a file in "channel" format can be used instead of a zap file.
228 	 * It is also easier to use it for testing purposes.
229 	 */
230 	if (!entry && (!args->dvr && !args->rec_psi)) {
231 		uint32_t f, freq = atoi(channel);
232 		if (freq) {
233 			for (entry = dvb_file->first_entry; entry != NULL;
234 			entry = entry->next) {
235 				dvb_retrieve_entry_prop(entry, DTV_FREQUENCY, &f);
236 				if (f == freq)
237 					break;
238 			}
239 
240 		}
241 	}
242 
243 	if (!entry) {
244 		ERROR("Can't find channel");
245 		dvb_file_free(dvb_file);
246 		return -3;
247 	}
248 
249 	/*
250 	 * Both the DVBv5 format and the command line parameters may
251 	 * specify the LNBf. If both have the definition, use the one
252 	 * provided by the command line parameter, overriding the one
253 	 * stored in the channel file.
254 	 */
255 	if (entry->lnb && !parms->lnb) {
256 		int lnb = dvb_sat_search_lnb(entry->lnb);
257 		if (lnb == -1) {
258 			ERROR("unknown LNB %s\n", entry->lnb);
259 			dvb_file_free(dvb_file);
260 			return -1;
261 		}
262 		parms->lnb = dvb_sat_get_lnb(lnb);
263 	}
264 
265 	if (parms->sat_number < 0 && entry->sat_number >= 0)
266 		parms->sat_number = entry->sat_number;
267 
268 	if (entry->video_pid) {
269 		if (args->n_vpid < entry->video_pid_len)
270 			*vpid = entry->video_pid[args->n_vpid];
271 		else
272 			*vpid = entry->video_pid[0];
273 	}
274 	if (entry->audio_pid) {
275 		if (args->n_apid < entry->audio_pid_len)
276 			*apid = entry->audio_pid[args->n_apid];
277 		else
278 		*apid = entry->audio_pid[0];
279 	}
280 	if (entry->other_el_pid) {
281 		int i, type = -1;
282 		for (i = 0; i < entry->other_el_pid_len; i++) {
283 			if (type != entry->other_el_pid[i].type) {
284 				type = entry->other_el_pid[i].type;
285 				if (i)
286 					fprintf(stderr, "\n");
287 				fprintf(stderr, _("service has pid type %02x: "), type);
288 			}
289 			fprintf(stderr, " %d", entry->other_el_pid[i].pid);
290 		}
291 		fprintf(stderr, "\n");
292 	}
293 	*sid = entry->service_id;
294 
295         /* First of all, set the delivery system */
296 	dvb_retrieve_entry_prop(entry, DTV_DELIVERY_SYSTEM, &sys);
297 	dvb_set_compat_delivery_system(parms, sys);
298 
299 	/* Copy data into parms */
300 	for (i = 0; i < entry->n_props; i++) {
301 		uint32_t data = entry->props[i].u.data;
302 		/* Don't change the delivery system */
303 		if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM)
304 			continue;
305 		dvb_fe_store_parm(parms, entry->props[i].cmd, data);
306 		if (parms->current_sys == SYS_ISDBT) {
307 			dvb_fe_store_parm(parms, DTV_ISDBT_PARTIAL_RECEPTION, 0);
308 			dvb_fe_store_parm(parms, DTV_ISDBT_SOUND_BROADCASTING, 0);
309 			dvb_fe_store_parm(parms, DTV_ISDBT_LAYER_ENABLED, 0x07);
310 			if (entry->props[i].cmd == DTV_CODE_RATE_HP) {
311 				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERA_FEC,
312 						  data);
313 				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERB_FEC,
314 						  data);
315 				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERC_FEC,
316 						  data);
317 			} else if (entry->props[i].cmd == DTV_MODULATION) {
318 				dvb_fe_store_parm(parms,
319 						  DTV_ISDBT_LAYERA_MODULATION,
320 						  data);
321 				dvb_fe_store_parm(parms,
322 						  DTV_ISDBT_LAYERB_MODULATION,
323 						  data);
324 				dvb_fe_store_parm(parms,
325 						  DTV_ISDBT_LAYERC_MODULATION,
326 						  data);
327 			}
328 		}
329 		if (parms->current_sys == SYS_ATSC &&
330 		    entry->props[i].cmd == DTV_MODULATION) {
331 			if (data != VSB_8 && data != VSB_16)
332 				dvb_fe_store_parm(parms,
333 						  DTV_DELIVERY_SYSTEM,
334 						  SYS_DVBC_ANNEX_B);
335 		}
336 	}
337 
338 	dvb_file_free(dvb_file);
339 	return 0;
340 }
341 
setup_frontend(struct arguments * args,struct dvb_v5_fe_parms * parms)342 static int setup_frontend(struct arguments *args,
343 			  struct dvb_v5_fe_parms *parms)
344 {
345 	int rc;
346 	uint32_t freq;
347 
348 	if (args->silent < 2) {
349 		rc = dvb_fe_retrieve_parm(parms, DTV_FREQUENCY, &freq);
350 		if (rc < 0) {
351 			ERROR("can't get the frequency");
352 			return -1;
353 		}
354 		fprintf(stderr, _("tuning to %i Hz\n"), freq);
355 	}
356 
357 	rc = dvb_fe_set_parms(parms);
358 	if (rc < 0) {
359 		ERROR("dvb_fe_set_parms failed");
360 		return -1;
361 	}
362 
363 	return 0;
364 }
365 
do_timeout(int x)366 static void do_timeout(int x)
367 {
368 	(void)x;
369 
370 	if (timeout_flag == 0) {
371 		timeout_flag = 1;
372 		alarm(2);
373 		signal(SIGALRM, do_timeout);
374 	} else {
375 		/* something has gone wrong ... exit */
376 		fprintf(stderr, "Forcing program stop due to timeout or terminate signal\n");
377 		exit(1);
378 	}
379 }
380 
print_non_human_stats(FILE * fd,struct dvb_v5_fe_parms * parms)381 static int print_non_human_stats(FILE *fd, struct dvb_v5_fe_parms *parms)
382 {
383 	int rc;
384 	fe_status_t status;
385 	uint32_t snr = 0, _signal = 0, quality = 0;
386 	uint32_t ber = 0, per = 0, pre_ber = 0, uncorrected_blocks = 0;
387 
388 	rc = dvb_fe_get_stats(parms);
389 	if (rc < 0) {
390 		PERROR("dvb_fe_get_stats failed");
391 		return -1;
392 	}
393 
394 	dvb_fe_retrieve_stats(parms, DTV_STATUS, &status);
395 	dvb_fe_retrieve_stats(parms, DTV_QUALITY, &quality);
396 	dvb_fe_retrieve_stats(parms, DTV_STAT_SIGNAL_STRENGTH, &_signal);
397 	dvb_fe_retrieve_stats(parms, DTV_STAT_CNR, &snr);
398 	dvb_fe_retrieve_stats(parms, DTV_BER, &ber);
399 	dvb_fe_retrieve_stats(parms, DTV_STAT_ERROR_BLOCK_COUNT, &uncorrected_blocks);
400 	dvb_fe_retrieve_stats(parms, DTV_PRE_BER, &pre_ber);
401 	dvb_fe_retrieve_stats(parms, DTV_PER, &per);
402 
403 	fprintf(fd,"status %02x | quality %02x | signal %04x | snr %04x | ber %08x | unc %08x | pre_ber %08x | per %08x | ",
404 		status, quality, _signal, snr, ber, uncorrected_blocks, pre_ber, per);
405 
406 	if (status & FE_HAS_LOCK)
407 		fprintf(fd, "FE_HAS_LOCK");
408 
409 	fprintf(fd, "\n");
410 	fflush(fd);
411 
412 	return 0;
413 }
414 
print_frontend_stats(FILE * fd,struct arguments * args,struct dvb_v5_fe_parms * parms)415 static int print_frontend_stats(FILE *fd,
416 				struct arguments *args,
417 				struct dvb_v5_fe_parms *parms)
418 {
419 	char buf[512], *p;
420 	int rc, i, len, show;
421 	uint32_t status = 0;
422 
423 	if (args->non_human)
424 		return print_non_human_stats(fd, parms);
425 
426 	/* Move cursor up and cleans down */
427 	if (isatty(fileno(fd)) && args->n_status_lines)
428 		fprintf(fd, "\r\x1b[%dA\x1b[J", args->n_status_lines);
429 
430 	args->n_status_lines = 0;
431 
432 	rc = dvb_fe_get_stats(parms);
433 	if (rc) {
434 		ERROR("dvb_fe_get_stats failed");
435 		return -1;
436 	}
437 
438 	p = buf;
439 	len = sizeof(buf);
440 	dvb_fe_snprintf_stat(parms,  DTV_STATUS, NULL, 0, &p, &len, &show);
441 
442 	for (i = 0; i < MAX_DTV_STATS; i++) {
443 		show = 1;
444 
445 		dvb_fe_snprintf_stat(parms, DTV_QUALITY, _("Quality"),
446 				     i, &p, &len, &show);
447 
448 		dvb_fe_snprintf_stat(parms, DTV_STAT_SIGNAL_STRENGTH, _("Signal"),
449 				     i, &p, &len, &show);
450 
451 		dvb_fe_snprintf_stat(parms, DTV_STAT_CNR, _("C/N"),
452 				     i, &p, &len, &show);
453 
454 		dvb_fe_snprintf_stat(parms, DTV_STAT_ERROR_BLOCK_COUNT, _("UCB"),
455 				     i,  &p, &len, &show);
456 
457 		dvb_fe_snprintf_stat(parms, DTV_BER, _("postBER"),
458 				     i,  &p, &len, &show);
459 
460 		dvb_fe_snprintf_stat(parms, DTV_PRE_BER, _("preBER"),
461 				     i,  &p, &len, &show);
462 
463 		dvb_fe_snprintf_stat(parms, DTV_PER, _("PER"),
464 				     i,  &p, &len, &show);
465 
466 		if (p != buf) {
467 			if (args->n_status_lines)
468 				fprintf(fd, "\t%s\n", buf);
469 			else
470 				fprintf(fd, "%s\n", buf);
471 
472 			args->n_status_lines++;
473 
474 			p = buf;
475 			len = sizeof(buf);
476 		}
477 	}
478 
479 	fflush(fd);
480 
481 	/* While not lock, display status on a new line */
482 	dvb_fe_retrieve_stats(parms, DTV_STATUS, &status);
483 	if (!isatty(fileno(fd)) || !(status & FE_HAS_LOCK))
484 		fprintf(fd, "\n");
485 
486 	return 0;
487 }
488 
check_frontend(struct arguments * args,struct dvb_v5_fe_parms * parms)489 static int check_frontend(struct arguments *args,
490 			  struct dvb_v5_fe_parms *parms)
491 {
492 	int rc;
493 	fe_status_t status = 0;
494 	do {
495 		rc = dvb_fe_get_stats(parms);
496 		if (rc) {
497 			ERROR("dvb_fe_get_stats failed");
498 			usleep(1000000);
499 			continue;
500 		}
501 
502 		status = 0;
503 		rc = dvb_fe_retrieve_stats(parms, DTV_STATUS, &status);
504 		if (!args->silent)
505 			print_frontend_stats(stderr, args, parms);
506 		if (status & FE_HAS_LOCK)
507 			break;
508 		usleep(1000000);
509 	} while (!timeout_flag);
510 	if (args->silent < 2)
511 		print_frontend_stats(stderr, args, parms);
512 
513 	return status & FE_HAS_LOCK;
514 }
515 
get_show_stats(FILE * fp,struct arguments * args,struct dvb_v5_fe_parms * parms,int loop)516 static void get_show_stats(FILE *fp, struct arguments *args,
517 			   struct dvb_v5_fe_parms *parms,
518 			   int loop)
519 {
520 	int rc;
521 
522 	args->n_status_lines = 0;
523 	do {
524 		rc = dvb_fe_get_stats(parms);
525 		if (!rc)
526 			print_frontend_stats(fp, args, parms);
527 		if (!timeout_flag && loop)
528 			usleep(1000000);
529 	} while (!timeout_flag && loop);
530 }
531 
elapsed_time(struct timespec * start)532 static struct timespec *elapsed_time(struct timespec *start)
533 {
534 	static struct timespec elapsed;
535 	struct timespec end;
536 
537 	if (!start->tv_sec && !start->tv_nsec)
538 		return NULL;
539 
540 	if (clock_gettime(CLOCK_MONOTONIC, &end))
541 		return NULL;
542 
543 	elapsed.tv_sec = end.tv_sec - start->tv_sec;
544 	elapsed.tv_nsec = end.tv_nsec - start->tv_nsec;
545 	if (elapsed.tv_nsec < 0) {
546 		elapsed.tv_sec--;
547 		elapsed.tv_nsec += NANO_SECONDS_IN_SEC;
548 	}
549 	return &elapsed;
550 }
551 
copy_to_file(struct dvb_open_descriptor * in_fd,int out_fd,int timeout,int silent)552 static void copy_to_file(struct dvb_open_descriptor *in_fd, int out_fd,
553 			 int timeout, int silent)
554 {
555 	char buf[BUFLEN];
556 	int r, first = 1;
557 	long long int rc = 0LL;
558 	struct timespec start, *elapsed;
559 
560 	while (timeout_flag == 0) {
561 		r = dvb_dev_read(in_fd, buf, sizeof(buf));
562 		if (r < 0) {
563 			if (r == -EOVERFLOW) {
564 				elapsed = elapsed_time(&start);
565 				if (!elapsed)
566 					fprintf(stderr, _("buffer overrun at %lld\n"), rc);
567 				else
568 					fprintf(stderr, _("buffer overrun after %lld.%02ld seconds\n"),
569 						(long long)elapsed->tv_sec,
570 						elapsed->tv_nsec / 10000000);
571 				continue;
572 			}
573 			ERROR("Read failed");
574 			break;
575 		}
576 
577 		/*
578 		 * It takes a while for a DVB device to start streaming, as the
579 		 * hardware may be waiting for some locks. The safest way to
580 		 * ensure that a program record will have the start amount of
581 		 * time specified by the user is to restart the timeout alarm
582 		 * here, after the first succeded read.
583 		 */
584 		if (first) {
585 			if (timeout > 0)
586 				alarm(timeout);
587 
588 			clock_gettime(CLOCK_MONOTONIC, &start);
589 			first = 0;
590 		}
591 
592 		if (write(out_fd, buf, r) < 0) {
593 			PERROR(_("Write failed"));
594 			break;
595 		}
596 
597 		rc += r;
598 	}
599 	if (silent < 2) {
600 		if (timeout)
601 			fprintf(stderr, _("received %lld bytes (%lld Kbytes/sec)\n"), rc,
602 				rc / (1024 * timeout));
603 		else
604 			fprintf(stderr, _("received %lld bytes\n"), rc);
605 	}
606 }
607 
parse_opt(int k,char * optarg,struct argp_state * state)608 static int parse_opt(int k, char *optarg, struct argp_state *state)
609 {
610 	struct arguments *args = state->input;
611 
612 	switch (k) {
613 	case 'a':
614 		args->adapter = strtoul(optarg, NULL, 0);
615 		break;
616 	case 'f':
617 		args->frontend = strtoul(optarg, NULL, 0);
618 		break;
619 	case 'd':
620 		args->demux = strtoul(optarg, NULL, 0);
621 		break;
622 	case 't':
623 		args->timeout = strtoul(optarg, NULL, 0);
624 		break;
625 	case 'I':
626 		args->input_format = dvb_parse_format(optarg);
627 		break;
628 	case 'o':
629 		args->filename = strdup(optarg);
630 		/* fall through */
631 	case 'r':
632 		args->dvr = 1;
633 		break;
634 	case 'p':
635 		args->rec_psi = 1;
636 		break;
637 	case 'x':
638 		args->exit_after_tuning = 1;
639 		break;
640 	case 'c':
641 		args->confname = strdup(optarg);
642 		break;
643 	case 'w':
644 		if (!strcasecmp(optarg,"on")) {
645 			args->lna = 1;
646 		} else if (!strcasecmp(optarg,"off")) {
647 			args->lna = 0;
648 		} else if (!strcasecmp(optarg,"auto")) {
649 			args->lna = LNA_AUTO;
650 		} else {
651 			int val = strtoul(optarg, NULL, 0);
652 			if (!val)
653 				args->lna = 0;
654 			else if (val > 0)
655 				args->lna = 1;
656 			else
657 				args->lna = LNA_AUTO;
658 		}
659 		break;
660 	case 'l':
661 		args->lnb_name = strdup(optarg);
662 		break;
663 	case 'S':
664 		args->sat_number = strtoul(optarg, NULL, 0);
665 		break;
666 	case 'U':
667 		args->freq_bpf = strtoul(optarg, NULL, 0);
668 		break;
669 	case 'W':
670 		args->diseqc_wait = strtoul(optarg, NULL, 0);
671 		break;
672 	case 's':
673 		args->silent++;
674 		break;
675 	case 'v':
676 		args->verbose++;
677 		break;
678 	case 'A':
679 		args->n_apid = strtoul(optarg, NULL, 0);
680 		break;
681 	case 'V':
682 		args->n_vpid = strtoul(optarg, NULL, 0);
683 		break;
684 	case 'P':
685 		args->all_pids++;
686 		break;
687 	case 'm':
688 		args->traffic_monitor = 1;
689 		break;
690 	case 'N':
691 		args->non_human = 1;
692 		break;
693 	case 'X':
694 		args->low_traffic = atoi(optarg);
695 		break;
696 	case 'L':
697 		args->search = strdup(optarg);
698 		break;
699 	case 'C':
700 		args->cc = strndup(optarg, 2);
701 		break;
702 	case 'H':
703 		args->server = strdup(optarg);
704 		break;
705 	case 'T':
706 		args->port = atoi(optarg);
707 		break;
708 	case 'D':
709 		args->dvr_pipe = strdup(optarg);
710 		break;
711 	case '?':
712 		argp_state_help(state, state->out_stream,
713 				ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG
714 				| ARGP_HELP_DOC);
715 		fprintf(state->out_stream, _("\nReport bugs to %s.\n"), argp_program_bug_address);
716 		exit(0);
717 	case -4:
718 		fprintf (state->out_stream, "%s\n", argp_program_version);
719 		exit(0);
720 	case -3:
721 		argp_state_help(state, state->out_stream, ARGP_HELP_USAGE);
722 		exit(0);
723 	default:
724 		return ARGP_ERR_UNKNOWN;
725 	};
726 	return 0;
727 }
728 
print_bytes(float val)729 static char *print_bytes(float val)
730 {
731 	static char buf[20];
732 	char *prefix = "";
733 
734 	if (val >= 500 * 1024 * 1024) {
735 		prefix = "G";
736 		val /= 1024 * 1024 * 1024.;
737 	} else if (val >= 500 * 1024) {
738 		prefix = "M";
739 		val /= 1024 * 1024.;
740 	} else if (val >= 500) {
741 		prefix = "K";
742 		val /= 1024.;
743 	}
744 	if (*prefix) {
745 		if (snprintf(buf, sizeof(buf), "%8.3f %s", val, prefix) <= 0)
746 			return "      NaN ";
747 	} else {
748 		if (snprintf(buf, sizeof(buf), "%9.3f ", val) <= 0)
749 			return "      NaN ";
750 	}
751 
752 	return buf;
753 }
754 
do_traffic_monitor(struct arguments * args,struct dvb_device * dvb,int out_fd,int timeout)755 int do_traffic_monitor(struct arguments *args, struct dvb_device *dvb,
756 		       int out_fd, int timeout)
757 {
758 	struct dvb_open_descriptor *fd, *dvr_fd;
759 	struct timespec startt;
760 	struct dvb_v5_fe_parms *parms = dvb->fe_parms;
761 	unsigned long long pidt[0x2001], wait, cont_err = 0;
762 	unsigned long long err_cnt[0x2000];
763 	signed char pid_cont[0x2000];
764 	int i, first = 1;
765 
766 	memset(pidt, 0, sizeof(pidt));
767 	memset(err_cnt, 0, sizeof(err_cnt));
768 	memset(pid_cont, 0, sizeof(pid_cont));
769 
770 	args->exit_after_tuning = 1;
771 	check_frontend(args, parms);
772 
773 	dvr_fd = dvb_dev_open(dvb, args->dvr_dev, O_RDONLY);
774 	if (!dvr_fd)
775 		return -1;
776 
777 	fprintf(stderr, _("dvb_dev_set_bufsize: buffer set to %d\n"), DVB_BUF_SIZE);
778 	dvb_dev_set_bufsize(dvr_fd, DVB_BUF_SIZE);
779 
780 	fd = dvb_dev_open(dvb, args->demux_dev, O_RDWR);
781 	if (!fd) {
782 		dvb_dev_close(dvr_fd);
783 		return -1;
784 	}
785 
786 	if (args->silent < 2)
787 		fprintf(stderr, _("  dvb_set_pesfilter to 0x2000\n"));
788 	if (dvb_dev_dmx_set_pesfilter(fd, 0x2000, DMX_PES_OTHER,
789 				      DMX_OUT_TS_TAP, 0) < 0) {
790 		dvb_dev_close(dvr_fd);
791 		dvb_dev_close(fd);
792 		return -1;
793 	}
794 
795 	if (clock_gettime(CLOCK_MONOTONIC, &startt)) {
796 		fprintf(stderr, _("Can't get timespec\n"));
797                 return -1;
798 	}
799 
800 	wait = 1000;
801 
802 	monitor_log(_("%.2fs: Starting capture\n"));
803 	while (1) {
804 		struct timespec *elapsed;
805 		unsigned char buffer[BUFLEN];
806 		int pid, ok, diff;
807 		ssize_t r;
808 
809 		if (timeout_flag)
810 			break;
811 
812 		if ((r = dvb_dev_read(dvr_fd, buffer, BUFLEN)) <= 0) {
813 			if (r == -EOVERFLOW) {
814 				monitor_log(_("%.2fs: buffer overrun\n"));
815 				continue;
816 			}
817 			monitor_log(_("%.2fs: read() returned error %zd\n"), r);
818 			break;
819 		}
820 
821 		/*
822 		 * It takes a while for a DVB device to start streaming, as the
823 		 * hardware may be waiting for some locks. The safest way to
824 		 * ensure that a program record will have the start amount of
825 		 * time specified by the user is to restart the timeout alarm
826 		 * here, after the first succeded read.
827 		 */
828 		if (first) {
829 			if (timeout > 0)
830 				alarm(timeout);
831 			first = 0;
832 		}
833 		if (out_fd >= 0) {
834 			if (write(out_fd, buffer, r) < 0) {
835 				PERROR(_("Write failed"));
836 				break;
837 			}
838 		}
839 		if (r != BUFLEN) {
840 			monitor_log(_("%.2fs: only read %zd bytes\n"), r);
841 			break;
842 		}
843 
844 		for (i = 0; i < BUFLEN; i += 188) {
845 			struct dvb_ts_packet_header *h = (void *)&buffer[i];
846 			if (h->sync_byte != 0x47) {
847 				monitor_log(_("%.2fs: invalid sync byte. Discarding %zd bytes\n"), r);
848 				continue;
849 			}
850 
851 			bswap16(h->bitfield);
852 
853 #if 0
854 			/*
855 			 * ITU-T Rec. H.222.0 decoders shall discard Transport
856 			 * Stream packets with the adaptation_field_control
857 			 * field set to a value of '00' (invalid). Packets with
858 			 * a value of '01' are NULL packets. Yet, as those are
859 			 * actually part of the stream, we won't be discarding,
860 			 * as we want to take them into account for traffic
861 			 * estimation purposes.
862 			 */
863 			if (h->adaptation_field_control == 0)
864 				continue;
865 #endif
866 			ok = 1;
867 			pid = h->pid;
868 
869 			if (pid > 0x1fff) {
870 				monitor_log(_("%.2fs: invalid pid: 0x%04x\n"),
871 					    pid);
872 				pid = 0x1fff;
873 			}
874 
875 			/*
876 			 * After 1 second of processing, check if are there
877 			 * any issues with regards to frame continuity for
878 			 * non-NULL packets.
879 			 *
880 			 * According to ITU-T H.222.0 | ISO/IEC 13818-1, the
881 			 * continuity counter isn't incremented if the packet
882 			 * is 00 or 10. It is only incremented on odd values.
883 			 *
884 			 * Also, don't check continuity errors on the first
885 			 * second, as the frontend is still starting streaming
886 			 */
887 			if (pid < 0x1fff && h->adaptation_field_control & 1) {
888 				int discontinued = 0;
889 
890 				if (err_cnt[pid] < 0)
891 					err_cnt[pid] = 0;
892 
893 				if (h->adaptation_field_control & 2) {
894 					if (h->adaptation_field_length >= 1) {
895 						discontinued = h->discontinued;
896 					} else {
897 						monitor_log(_("%.2fs: pid %d has adaption layer, but size is too small!\n"),
898 							    pid);
899 					}
900 				}
901 
902 				if (wait < 2000)
903 					discontinued = 1;
904 
905 				if (!discontinued && pid_cont[pid] >= 0) {
906 					unsigned int next = (pid_cont[pid] + 1) % 16;
907 					if (next != h->continuity_counter) {
908 						monitor_log(_("%.2fs: pid %d, expecting %d received %d\n"),
909 							    pid, next,
910 							    h->continuity_counter);
911 						discontinued = 1;
912 						cont_err++;
913 						err_cnt[pid]++;
914 					}
915 				}
916 				if (discontinued)
917 					pid_cont[pid] = -1;
918 				else
919 					pid_cont[pid] = h->continuity_counter;
920 			}
921 
922 			if (args->search) {
923 				int i, sl = strlen(args->search);
924 				ok = 0;
925 				if (pid != 0x1fff) {
926 					for (i = 0; i < (188 - sl); ++i) {
927 						if (!memcmp((char *)h + i, args->search, sl))
928 							ok = 1;
929 					}
930 				}
931 			}
932 
933 			if (ok) {
934 				pidt[pid]++;
935 				pidt[0x2000]++;
936 			}
937 		}
938 
939 		elapsed = elapsed_time(&startt);
940 		if (!elapsed)
941 			diff = wait;
942 		else
943 			diff = (unsigned long long)elapsed->tv_sec * 1000
944 				+ elapsed->tv_nsec * 1000 / NANO_SECONDS_IN_SEC;
945 
946 		if (diff > wait) {
947 			unsigned long long other_pidt = 0, other_err_cnt = 0;
948 
949 			if (isatty(STDOUT_FILENO))
950 				printf("\x1b[1H\x1b[2J");
951 
952 			args->n_status_lines = 0;
953 			printf(_(" PID           FREQ         SPEED       TOTAL\n"));
954 			int _pid = 0;
955 			for (_pid = 0; _pid < 0x2000; _pid++) {
956 				if (pidt[_pid]) {
957 					if (args->low_traffic && (pidt[_pid] * 1000. / diff) < args->low_traffic) {
958 						other_pidt += pidt[_pid];
959 						other_err_cnt += err_cnt[_pid];
960 						continue;
961 					}
962 					printf("%5d %9.2f p/s %sbps ",
963 						_pid,
964 						pidt[_pid] * 1000. / diff,
965 						print_bytes(pidt[_pid] * 1000. * 8 * 188/ diff));
966 					if (pidt[_pid] * 188 / 1024)
967 						printf("%8llu KB", (pidt[_pid] * 188 + 512) / 1024);
968 					else
969 						printf(" %8llu B", pidt[_pid] * 188);
970 					if (err_cnt[_pid] > 0)
971 						printf(" %8llu continuity errors",
972 						       err_cnt[_pid]);
973 
974 					printf("\n");
975 				}
976 			}
977 			if (other_pidt) {
978 				printf(_("OTHER"));
979 				printf(" %9.2f p/s %sbps ",
980 					other_pidt * 1000. / diff,
981 					print_bytes(other_pidt * 1000. * 8 * 188/ diff));
982 				if (other_pidt * 188 / 1024)
983 					printf("%8llu KB", (other_pidt * 188 + 512) / 1024);
984 				else
985 					printf(" %8llu B", other_pidt * 188);
986 				if (other_err_cnt > 0)
987 					printf(" %8llu continuity errors",
988 					       other_err_cnt);
989 				printf("\n");
990 			}
991 
992 			/* 0x2000 is the total traffic */
993 			printf("TOT %11.2f p/s %sbps %8llu KB\n",
994 				pidt[_pid] * 1000. / diff,
995 				print_bytes(pidt[_pid] * 1000. * 8 * 188/ diff),
996 				(pidt[_pid] * 188 + 512) / 1024);
997 			printf("\n");
998 			get_show_stats(stdout, args, parms, 0);
999 			wait += 1000;
1000 			if (cont_err)
1001 				printf("CONTINUITY errors: %llu\n", cont_err);
1002 		}
1003 	}
1004 	monitor_log(_("%.2fs: Stopping capture\n"));
1005 	dvb_dev_close(dvr_fd);
1006 	dvb_dev_close(fd);
1007 	return 0;
1008 }
1009 
set_signals(struct arguments * args)1010 static void set_signals(struct arguments *args)
1011 {
1012 	signal(SIGTERM, do_timeout);
1013 	signal(SIGINT, do_timeout);
1014 	if (args->timeout > 0) {
1015 		signal(SIGALRM, do_timeout);
1016 		alarm(args->timeout);
1017 	}
1018 }
1019 
1020 static char *default_dvr_pipe = "/tmp/dvr-pipe";
1021 
main(int argc,char ** argv)1022 int main(int argc, char **argv)
1023 {
1024 	struct arguments args = {};
1025 	char *homedir = getenv("HOME");
1026 	char *channel = NULL;
1027 	int lnb = -1, idx = -1;
1028 	int vpid = -1, apid = -1, sid = -1;
1029 	int pmtpid = 0;
1030 	struct dvb_open_descriptor *pat_fd = NULL, *pmt_fd = NULL;
1031 	struct dvb_open_descriptor *sid_fd = NULL, *dvr_fd = NULL;
1032 	struct dvb_open_descriptor *audio_fd = NULL, *video_fd = NULL;
1033 	int file_fd = -1;
1034 	int err = -1;
1035 	int r, ret;
1036 	struct dvb_v5_fe_parms *parms = NULL;
1037 	struct dvb_device *dvb;
1038 	struct dvb_dev_list *dvb_dev;
1039 	const struct argp argp = {
1040 		.options = options,
1041 		.parser = parse_opt,
1042 		.doc = N_("DVB zap utility"),
1043 		.args_doc = N_("<channel name> [or <frequency> if in monitor mode]"),
1044 	};
1045 
1046 #ifdef ENABLE_NLS
1047 	setlocale (LC_ALL, "");
1048 	bindtextdomain (PACKAGE, LOCALEDIR);
1049 	textdomain (PACKAGE);
1050 #endif
1051 
1052 	args.sat_number = -1;
1053 	args.lna = LNA_AUTO;
1054 	args.input_format = FILE_DVBV5;
1055 	args.dvr_pipe = default_dvr_pipe;
1056 	args.low_traffic = 1;
1057 
1058 	if (argp_parse(&argp, argc, argv, ARGP_NO_HELP | ARGP_NO_EXIT, &idx, &args)) {
1059 		argp_help(&argp, stderr, ARGP_HELP_SHORT_USAGE, PROGRAM_NAME);
1060 		return -1;
1061 	}
1062 
1063 	if (idx < argc)
1064 		channel = argv[idx];
1065 
1066 	if (!channel) {
1067 		argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME);
1068 		return -1;
1069 	}
1070 
1071 	if (args.input_format == FILE_UNKNOWN) {
1072 		ERROR("Please specify a valid format\n");
1073 		argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME);
1074 		return -1;
1075 	}
1076 
1077 	if (!args.traffic_monitor && args.search) {
1078 		ERROR("search string can be used only on monitor mode\n");
1079 		argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME);
1080 		return -1;
1081 	}
1082 
1083 	if (args.lnb_name) {
1084 		lnb = dvb_sat_search_lnb(args.lnb_name);
1085 		if (lnb < 0) {
1086 			printf(_("Please select one of the LNBf's below:\n"));
1087 			dvb_print_all_lnb();
1088 			exit(1);
1089 		} else {
1090 			printf(_("Using LNBf "));
1091 			dvb_print_lnb(lnb);
1092 		}
1093 	}
1094 
1095 	dvb = dvb_dev_alloc();
1096 	if (!dvb)
1097 		return -1;
1098 
1099 	if (args.server && args.port) {
1100 		printf(_("Connecting to %s:%d\n"), args.server, args.port);
1101 		ret = dvb_dev_remote_init(dvb, args.server, args.port);
1102 		if (ret < 0)
1103 			return -1;
1104 	}
1105 
1106 	dvb_dev_set_log(dvb, args.verbose, NULL);
1107 	dvb_dev_find(dvb, NULL, NULL);
1108 	parms = dvb->fe_parms;
1109 
1110 	dvb_dev = dvb_dev_seek_by_adapter(dvb, args.adapter, args.demux, DVB_DEVICE_DEMUX);
1111 	if (!dvb_dev) {
1112 		fprintf(stderr, _("Couldn't find demux device node\n"));
1113 		dvb_dev_free(dvb);
1114 		return -1;
1115 	}
1116 	args.demux_dev = dvb_dev->sysname;
1117 
1118 	dvb_dev = dvb_dev_seek_by_adapter(dvb, args.adapter, args.demux, DVB_DEVICE_DVR);
1119 	if (!dvb_dev) {
1120 		fprintf(stderr, _("Couldn't find dvr device node\n"));
1121 		dvb_dev_free(dvb);
1122 		return -1;
1123 	}
1124 	args.dvr_dev = dvb_dev->sysname;
1125 	args.dvr_fname = dvb_dev->path;
1126 
1127 	if (args.silent < 2)
1128 		fprintf(stderr, _("using demux '%s'\n"), args.demux_dev);
1129 
1130 	if (!args.confname) {
1131 		if (!homedir)
1132 			ERROR("$HOME not set");
1133 		r = asprintf(&args.confname, "%s/.tzap/%i/%s",
1134 			 homedir, args.adapter, CHANNEL_FILE);
1135 		if (access(args.confname, R_OK)) {
1136 			free(args.confname);
1137 			r = asprintf(&args.confname, "%s/.tzap/%s",
1138 				homedir, CHANNEL_FILE);
1139 		}
1140 	}
1141 	fprintf(stderr, _("reading channels from file '%s'\n"), args.confname);
1142 
1143 	dvb_dev = dvb_dev_seek_by_adapter(dvb, args.adapter, args.frontend,
1144 					  DVB_DEVICE_FRONTEND);
1145 	if (!dvb_dev)
1146 		return -1;
1147 
1148 	if (!dvb_dev_open(dvb, dvb_dev->sysname, O_RDWR))
1149 		goto err;
1150 	if (lnb >= 0)
1151 		parms->lnb = dvb_sat_get_lnb(lnb);
1152 	if (args.sat_number >= 0)
1153 		parms->sat_number = args.sat_number;
1154 	parms->diseqc_wait = args.diseqc_wait;
1155 	parms->freq_bpf = args.freq_bpf;
1156 	parms->lna = args.lna;
1157 
1158 	r = dvb_fe_set_default_country(parms, args.cc);
1159 	if (r < 0)
1160 		fprintf(stderr, _("Failed to set the country code:%s\n"), args.cc);
1161 
1162 	if (parse(&args, parms, channel, &vpid, &apid, &sid))
1163 		goto err;
1164 
1165 	if (setup_frontend(&args, parms) < 0)
1166 		goto err;
1167 
1168 	if (args.exit_after_tuning) {
1169 		set_signals(&args);
1170 		err = 0;
1171 		check_frontend(&args, parms);
1172 		goto err;
1173 	}
1174 
1175 	if (args.traffic_monitor) {
1176 		if (args.filename) {
1177 			file_fd = open(args.filename,
1178 					 O_LARGEFILE |
1179 					 O_WRONLY | O_CREAT | O_TRUNC,
1180 					 0644);
1181 			if (file_fd < 0) {
1182 				PERROR(_("open of '%s' failed"), args.filename);
1183 				return -1;
1184 			}
1185 		}
1186 		set_signals(&args);
1187 		err = do_traffic_monitor(&args, dvb, file_fd, args.timeout);
1188 		goto err;
1189 	}
1190 
1191 	if (args.rec_psi) {
1192 		if (sid < 0) {
1193 			fprintf(stderr, _("Service id 0x%04x was not specified at the file\n"),
1194 				sid);
1195 			goto err;
1196 		}
1197 
1198 		sid_fd = dvb_dev_open(dvb, args.demux_dev, O_RDWR);
1199 		if (!sid_fd) {
1200 			ERROR("opening sid demux failed");
1201 			return -1;
1202 		}
1203 		pmtpid = dvb_dev_dmx_get_pmt_pid(sid_fd, sid);
1204 		dvb_dev_close(sid_fd);
1205 		if (pmtpid <= 0) {
1206 			fprintf(stderr, _("couldn't find pmt-pid for sid %04x\n"),
1207 				sid);
1208 
1209 			goto err;
1210 		}
1211 
1212 		pat_fd = dvb_dev_open(dvb, args.demux_dev, O_RDWR);
1213 		if (!pat_fd) {
1214 			ERROR("opening pat demux failed");
1215 			goto err;
1216 		}
1217 		if (dvb_dev_dmx_set_pesfilter(pat_fd, 0, DMX_PES_OTHER,
1218 				args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER,
1219 				args.dvr ? 64 * 1024 : 0) < 0)
1220 			goto err;
1221 
1222 		pmt_fd = dvb_dev_open(dvb, args.demux_dev, O_RDWR);
1223 		if (!pmt_fd) {
1224 			ERROR("opening pmt demux failed");
1225 			goto err;
1226 		}
1227 		if (dvb_dev_dmx_set_pesfilter(pmt_fd, pmtpid, DMX_PES_OTHER,
1228 				args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER,
1229 				args.dvr ? 64 * 1024 : 0) < 0)
1230 			goto err;
1231 	}
1232 
1233 	if (args.all_pids++) {
1234 		vpid = 0x2000;
1235 		apid = 0;
1236 	}
1237 	if (vpid >= 0) {
1238 		if (args.silent < 2) {
1239 			if (vpid == 0x2000)
1240 				fprintf(stderr, _("pass all PID's to TS\n"));
1241 			else
1242 				fprintf(stderr, _("video pid %d\n"), vpid);
1243 		}
1244 		video_fd = dvb_dev_open(dvb, args.demux_dev, O_RDWR);
1245 		if (!video_fd) {
1246 			ERROR("failed opening '%s'", args.demux_dev);
1247 			goto err;
1248 		}
1249 
1250 		if (args.silent < 2)
1251 			fprintf(stderr, _("  dvb_set_pesfilter %d\n"), vpid);
1252 
1253 		fprintf(stderr, _("dvb_dev_set_bufsize: buffer set to %d\n"), DVB_BUF_SIZE);
1254 		dvb_dev_set_bufsize(video_fd, DVB_BUF_SIZE);
1255 
1256 		if (vpid == 0x2000) {
1257 			if (dvb_dev_dmx_set_pesfilter(video_fd, vpid, DMX_PES_OTHER,
1258 					      DMX_OUT_TS_TAP, 0) < 0)
1259 				goto err;
1260 		} else {
1261 			if (dvb_dev_dmx_set_pesfilter(video_fd, vpid, DMX_PES_VIDEO,
1262 				args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER,
1263 				args.dvr ? 64 * 1024 : 0) < 0)
1264 				goto err;
1265 		}
1266 	}
1267 
1268 	if (apid > 0) {
1269 		if (args.silent < 2)
1270 			fprintf(stderr, _("audio pid %d\n"), apid);
1271 		audio_fd = dvb_dev_open(dvb, args.demux_dev, O_RDWR);
1272 		if (!audio_fd) {
1273 			ERROR("failed opening '%s'", args.demux_dev);
1274 			goto err;
1275 		}
1276 		if (args.silent < 2)
1277 			fprintf(stderr, _("  dvb_set_pesfilter %d\n"), apid);
1278 		if (dvb_dev_dmx_set_pesfilter(audio_fd, apid, DMX_PES_AUDIO,
1279 				args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER,
1280 				args.dvr ? 64 * 1024 : 0) < 0)
1281 			goto err;
1282 	}
1283 
1284 	set_signals(&args);
1285 
1286 	if (!check_frontend(&args, parms)) {
1287 		err = 1;
1288 		fprintf(stderr, _("frontend doesn't lock\n"));
1289 		goto err;
1290 	}
1291 
1292 	if (args.dvr) {
1293 		if (args.filename) {
1294 			file_fd = STDOUT_FILENO;
1295 
1296 			if (strcmp(args.filename, "-") != 0) {
1297 				file_fd = open(args.filename,
1298 					 O_LARGEFILE |
1299 					 O_WRONLY | O_CREAT | O_TRUNC,
1300 					 0644);
1301 				if (file_fd < 0) {
1302 					PERROR(_("open of '%s' failed"),
1303 					       args.filename);
1304 					return -1;
1305 				}
1306 			}
1307 		}
1308 
1309 		if (args.silent < 2)
1310 			get_show_stats(stderr, &args, parms, 0);
1311 
1312 		if (file_fd >= 0) {
1313 			dvr_fd = dvb_dev_open(dvb, args.dvr_dev, O_RDONLY);
1314 			if (!dvr_fd) {
1315 				ERROR("failed opening '%s'", args.dvr_dev);
1316 				goto err;
1317 			}
1318 			if (!timeout_flag)
1319 				fprintf(stderr, _("Record to file '%s' started\n"), args.filename);
1320 			copy_to_file(dvr_fd, file_fd, args.timeout, args.silent);
1321 		} else if (args.server && args.port) {
1322 			struct stat st;
1323 			if (stat(args.dvr_pipe, &st) == -1) {
1324 				if (mknod(args.dvr_pipe,
1325 					S_IRUSR | S_IWUSR | S_IFIFO, 0) < 0) {
1326 					PERROR("Can't create pipe %s",
1327 					args.dvr_pipe);
1328 					return -1;
1329 				}
1330 			} else {
1331 				if (!S_ISFIFO(st.st_mode)) {
1332 					ERROR("%s exists but is not a pipe",
1333 					args.dvr_pipe);
1334 					return -1;
1335 				}
1336 			}
1337 
1338 			fprintf(stderr, _("DVR pipe interface '%s' will be opened\n"), args.dvr_pipe);
1339 
1340 			dvr_fd = dvb_dev_open(dvb, args.dvr_dev, O_RDONLY);
1341 			if (!dvr_fd) {
1342 				ERROR("failed opening '%s'", args.dvr_dev);
1343 				err = -1;
1344 				goto err;
1345 			}
1346 
1347 			file_fd = open(args.dvr_pipe,
1348 #ifdef O_LARGEFILE
1349 					O_LARGEFILE |
1350 #endif
1351 					O_WRONLY,
1352 					0644);
1353 			if (file_fd < 0) {
1354 				PERROR(_("open of '%s' failed"),
1355 					args.filename);
1356 				err = -1;
1357 				goto err;
1358 			}
1359 			copy_to_file(dvr_fd, file_fd, args.timeout, args.silent);
1360 		} else {
1361 			if (!timeout_flag)
1362 				fprintf(stderr, _("DVR interface '%s' can now be opened\n"), args.dvr_fname);
1363 
1364 			get_show_stats(stderr, &args, parms, 1);
1365 		}
1366 		if (args.silent < 2)
1367 			get_show_stats(stderr, &args, parms, 0);
1368 	} else {
1369 		/* Wait until timeout or being killed */
1370 		while (!timeout_flag) {
1371 			get_show_stats(stderr, &args, parms, 1);
1372 			usleep(1000000);
1373 		}
1374 	}
1375 	err = 0;
1376 
1377 err:
1378 	dvb_dev_free(dvb);
1379 
1380 	/*
1381 	 * Just to make Valgrind happier. It should be noticed
1382 	 * That, if an error happens or if the program exits via
1383 	 * timeout code at forced mode, it may not free those.
1384 	 */
1385 	if (args.confname)
1386 		free(args.confname);
1387 	if (args.filename)
1388 		free(args.filename);
1389 	if (args.lnb_name)
1390 		free(args.lnb_name);
1391 	if (args.search)
1392 		free(args.search);
1393 	if (args.server)
1394 		free(args.search);
1395 	if (args.dvr_pipe != default_dvr_pipe)
1396 		free(args.dvr_pipe);
1397 
1398 	return err;
1399 }
1400