static int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) { uint32_t mstd; if (check_frontend(fe_fd, FE_ATSC, &mstd) < 0) { close(fe_fd); return -1; } /* TODO! Some frontends need to be explicit delivery system */ printf ("tuning to %i Hz\n", frontend->frequency); if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) { PERROR("ioctl FE_SET_FRONTEND failed"); return -1; } return 0; }
static int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) { int ret; uint32_t mstd; if (check_frontend(fe_fd, FE_OFDM, &mstd) < 0) { close(fe_fd); return -1; } ret = dvbfe_set_delsys(fe_fd, SYS_DVBT); if (ret) { PERROR("SET Delsys failed"); return -1; } if (silent < 2) fprintf (stderr,"tuning to %i Hz\n", frontend->frequency); if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) { PERROR("ioctl FE_SET_FRONTEND failed"); return -1; } return 0; }
static int do_mon(unsigned int adapter, unsigned int frontend, int human_readable, unsigned int count) { int result; struct dvbfe_handle *fe; struct dvbfe_info fe_info; char *fe_type = "UNKNOWN"; fe = dvbfe_open(adapter, frontend, 1); if (fe == NULL) { perror("opening frontend failed"); return 0; } dvbfe_get_info(fe, 0, &fe_info, DVBFE_INFO_QUERYTYPE_IMMEDIATE, 0); switch(fe_info.type) { case DVBFE_TYPE_DVBS: fe_type = "DVBS"; break; case DVBFE_TYPE_DVBC: fe_type = "DVBC"; break; case DVBFE_TYPE_DVBT: fe_type = "DVBT"; break; case DVBFE_TYPE_ATSC: fe_type = "ATSC"; break; } printf("FE: %s (%s)\n", fe_info.name, fe_type); result = check_frontend (fe, human_readable, count); dvbfe_close(fe); return result; }
int main(int argc, char **argv) { struct arguments args; char *homedir = getenv("HOME"); char *channel = NULL; int lnb = -1, idx = -1; int vpid = -1, apid = -1, sid = -1; int pmtpid = 0; int pat_fd = -1, pmt_fd = -1; int audio_fd = 0, video_fd = 0; int dvr_fd, file_fd; struct dvb_v5_fe_parms *parms; const struct argp argp = { .options = options, .parser = parse_opt, .doc = "DVB zap utility", .args_doc = "<initial file>", }; memset(&args, 0, sizeof(args)); args.sat_number = -1; argp_parse(&argp, argc, argv, 0, &idx, &args); if (idx < argc) channel = argv[idx]; if (!channel) { argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME); return -1; } if (args.input_format == FILE_UNKNOWN) { fprintf(stderr, "ERROR: Please specify a valid format\n"); argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME); return -1; } if (args.lnb_name) { lnb = search_lnb(args.lnb_name); if (lnb < 0) { printf("Please select one of the LNBf's below:\n"); print_all_lnb(); exit(1); } else { printf("Using LNBf "); print_lnb(lnb); } } asprintf(&args.demux_dev, "/dev/dvb/adapter%i/demux%i", args.adapter, args.demux); asprintf(&args.dvr_dev, "/dev/dvb/adapter%i/dvr%i", args.adapter, args.demux); if (args.silent < 2) fprintf(stderr, "using demux '%s'\n", args.demux_dev); if (!args.confname) { if (!homedir) ERROR("$HOME not set"); asprintf(&args.confname, "%s/.tzap/%i/%s", homedir, args.adapter, CHANNEL_FILE); if (access(args.confname, R_OK)) asprintf(&args.confname, "%s/.tzap/%s", homedir, CHANNEL_FILE); } printf("reading channels from file '%s'\n", args.confname); parms = dvb_fe_open(args.adapter, args.frontend, 0, 0); if (!parms) return -1; if (lnb) parms->lnb = get_lnb(lnb); if (args.sat_number > 0) parms->sat_number = args.sat_number % 3; parms->diseqc_wait = args.diseqc_wait; parms->freq_bpf = args.freq_bpf; if (parse(&args, parms, channel, &vpid, &apid, &sid)) return -1; if (setup_frontend(&args, parms) < 0) return -1; if (args.frontend_only) { check_frontend(&args, parms); dvb_fe_close(parms); return 0; } if (args.rec_psi) { if (sid < 0) { fprintf(stderr, "Service id 0x%04x was not specified at the file\n", sid); return -1; } pmtpid = get_pmt_pid(args.demux_dev, sid); if (pmtpid <= 0) { fprintf(stderr, "couldn't find pmt-pid for sid %04x\n", sid); return -1; } if ((pat_fd = open(args.demux_dev, O_RDWR)) < 0) { perror("opening pat demux failed"); return -1; } if (set_pesfilter(pat_fd, 0, DMX_PES_OTHER, args.dvr) < 0) return -1; if ((pmt_fd = open(args.demux_dev, O_RDWR)) < 0) { perror("opening pmt demux failed"); return -1; } if (set_pesfilter(pmt_fd, pmtpid, DMX_PES_OTHER, args.dvr) < 0) return -1; } if (vpid >= 0) { if (args.silent < 2) fprintf(stderr, "video pid %d\n", vpid); if ((video_fd = open(args.demux_dev, O_RDWR)) < 0) { PERROR("failed opening '%s'", args.demux_dev); return -1; } if (set_pesfilter(video_fd, vpid, DMX_PES_VIDEO, args.dvr) < 0) return -1; } if (apid >= 0) { if (args.silent < 2) fprintf(stderr, "audio pid %d\n", apid); if ((audio_fd = open(args.demux_dev, O_RDWR)) < 0) { PERROR("failed opening '%s'", args.demux_dev); return -1; } if (set_pesfilter(audio_fd, apid, DMX_PES_AUDIO, args.dvr) < 0) return -1; } signal(SIGALRM, do_timeout); if (args.timeout > 0) alarm(args.timeout); if (args.record) { if (args.filename != NULL) { if (strcmp(args.filename, "-") != 0) { file_fd = open(args.filename, O_WRONLY | O_LARGEFILE | O_CREAT, 0644); if (file_fd < 0) { PERROR("open of '%s' failed", args.filename); return -1; } } else { file_fd = 1; } } else { PERROR("Record mode but no filename!"); return -1; } if ((dvr_fd = open(args.dvr_dev, O_RDONLY)) < 0) { PERROR("failed opening '%s'", args.dvr_dev); return -1; } if (args.silent < 2) print_frontend_stats(parms, args.human_readable); copy_to_file(dvr_fd, file_fd, args.timeout, args.silent); if (args.silent < 2) print_frontend_stats(parms, args.human_readable); } else { check_frontend(&args, parms); } close(pat_fd); close(pmt_fd); close(audio_fd); close(video_fd); dvb_fe_close(parms); return 0; }
static int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux, unsigned int sat_no, unsigned int freq, unsigned int pol, unsigned int sr, unsigned int vpid, unsigned int apid, int sid, int dvr, int rec_psi, int bypass, int human_readable) { char fedev[128], dmxdev[128], auddev[128]; static int fefd, dmxfda, dmxfdv, audiofd = -1, patfd, pmtfd; int pmtpid; uint32_t ifreq, mstd; int hiband, result; if (!fefd) { snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend); snprintf(dmxdev, sizeof(dmxdev), DEMUXDEVICE, adapter, demux); snprintf(auddev, sizeof(auddev), AUDIODEVICE, adapter, demux); printf("using '%s' and '%s'\n", fedev, dmxdev); if ((fefd = open(fedev, O_RDWR | O_NONBLOCK)) < 0) { perror("opening frontend failed"); return FALSE; } if (check_frontend(fefd, FE_QPSK, &mstd) < 0) { close(fefd); return FALSE; } /* TODO! Some frontends need to be explicit delivery system */ if ((dmxfdv = open(dmxdev, O_RDWR)) < 0) { perror("opening video demux failed"); close(fefd); return FALSE; } if ((dmxfda = open(dmxdev, O_RDWR)) < 0) { perror("opening audio demux failed"); close(fefd); return FALSE; } if (dvr == 0) /* DMX_OUT_DECODER */ audiofd = open(auddev, O_RDWR); if (rec_psi) { if ((patfd = open(dmxdev, O_RDWR)) < 0) { perror("opening pat demux failed"); close(audiofd); close(dmxfda); close(dmxfdv); close(fefd); return FALSE; } if ((pmtfd = open(dmxdev, O_RDWR)) < 0) { perror("opening pmt demux failed"); close(patfd); close(audiofd); close(dmxfda); close(dmxfdv); close(fefd); return FALSE; } } } hiband = 0; if (lnb_type.switch_val && lnb_type.high_val && freq >= lnb_type.switch_val) hiband = 1; if (hiband) ifreq = freq - lnb_type.high_val; else { if (freq < lnb_type.low_val) ifreq = lnb_type.low_val - freq; else ifreq = freq - lnb_type.low_val; } result = FALSE; if (diseqc(fefd, sat_no, pol, hiband)) if (do_tune(fefd, ifreq, sr)) if (set_pesfilter(dmxfdv, vpid, DMX_PES_VIDEO, dvr)) if (audiofd >= 0) (void)ioctl(audiofd, AUDIO_SET_BYPASS_MODE, bypass); if (set_pesfilter(dmxfda, apid, DMX_PES_AUDIO, dvr)) { if (rec_psi) { pmtpid = get_pmt_pid(dmxdev, sid); if (pmtpid < 0) { result = FALSE; } if (pmtpid == 0) { fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid); result = FALSE; } if (set_pesfilter(patfd, 0, DMX_PES_OTHER, dvr)) if (set_pesfilter(pmtfd, pmtpid, DMX_PES_OTHER, dvr)) result = TRUE; } else { result = TRUE; } } monitor_frontend (fefd, dvr, human_readable); if (!interactive) { close(patfd); close(pmtfd); if (audiofd >= 0) close(audiofd); close(dmxfda); close(dmxfdv); close(fefd); } return result; }
static int run_scan(struct arguments *args, struct dvb_v5_fe_parms *parms) { struct dvb_file *dvb_file = NULL, *dvb_file_new = NULL; struct dvb_entry *entry; int i, rc, count = 0, dmx_fd, shift; uint32_t freq, sys; /* This is used only when reading old formats */ switch (parms->current_sys) { case SYS_DVBT: case SYS_DVBS: case SYS_DVBC_ANNEX_A: case SYS_ATSC: sys = parms->current_sys; break; case SYS_DVBC_ANNEX_C: sys = SYS_DVBC_ANNEX_A; break; case SYS_DVBC_ANNEX_B: sys = SYS_ATSC; break; case SYS_ISDBT: sys = SYS_DVBT; break; default: sys = SYS_UNDEFINED; break; } dvb_file = dvb_read_file_format(args->confname, sys, args->input_format); if (!dvb_file) return -2; dmx_fd = open(args->demux_dev, O_RDWR); if (dmx_fd < 0) { perror("openening pat demux failed"); return -3; } for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) { struct dvb_v5_descriptors *dvb_desc = NULL; /* First of all, set the delivery system */ for (i = 0; i < entry->n_props; i++) if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM) dvb_set_compat_delivery_system(parms, entry->props[i].u.data); /* Copy data into parms */ for (i = 0; i < entry->n_props; i++) { uint32_t data = entry->props[i].u.data; /* Don't change the delivery system */ if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM) continue; dvb_fe_store_parm(parms, entry->props[i].cmd, data); if (parms->current_sys == SYS_ISDBT) { dvb_fe_store_parm(parms, DTV_ISDBT_PARTIAL_RECEPTION, 0); dvb_fe_store_parm(parms, DTV_ISDBT_SOUND_BROADCASTING, 0); dvb_fe_store_parm(parms, DTV_ISDBT_LAYER_ENABLED, 0x07); if (entry->props[i].cmd == DTV_CODE_RATE_HP) { dvb_fe_store_parm(parms, DTV_ISDBT_LAYERA_FEC, data); dvb_fe_store_parm(parms, DTV_ISDBT_LAYERB_FEC, data); dvb_fe_store_parm(parms, DTV_ISDBT_LAYERC_FEC, data); } else if (entry->props[i].cmd == DTV_MODULATION) { dvb_fe_store_parm(parms, DTV_ISDBT_LAYERA_MODULATION, data); dvb_fe_store_parm(parms, DTV_ISDBT_LAYERB_MODULATION, data); dvb_fe_store_parm(parms, DTV_ISDBT_LAYERC_MODULATION, data); } } if (parms->current_sys == SYS_ATSC && entry->props[i].cmd == DTV_MODULATION) { if (data != VSB_8 && data != VSB_16) dvb_fe_store_parm(parms, DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_B); } } /* * If the channel file has duplicated frequencies, or some * entries without any frequency at all, discard. */ freq = 0; for (i = 0; i < entry->n_props; i++) { if (entry->props[i].cmd == DTV_FREQUENCY) { freq = entry->props[i].u.data; break; } } if (!freq) continue; shift = estimate_freq_shift(parms); if (dvb_desc && !new_freq_is_needed(dvb_file->first_entry, entry, freq, dvb_desc->nit_table.pol, shift)) continue; rc = dvb_fe_set_parms(parms); if (rc < 0) { PERROR("dvb_fe_set_parms failed"); return -1; } /* As the DVB core emulates it, better to always use auto */ dvb_fe_store_parm(parms, DTV_INVERSION, INVERSION_AUTO); dvb_fe_retrieve_parm(parms, DTV_FREQUENCY, &freq); count++; dvb_log("Scanning frequency #%d %d", count, freq); if (verbose) dvb_fe_prt_parms(parms); rc = check_frontend(args, parms); if (rc < 0) continue; dvb_desc = dvb_get_ts_tables(parms, dmx_fd, parms->current_sys, args->other_nit, args->timeout_multiply, verbose); if (!dvb_desc) continue; for (i = 0; i < dvb_desc->sdt_table.service_table_len; i++) { struct service_table *service_table = &dvb_desc->sdt_table.service_table[i]; entry->vchannel = dvb_vchannel(dvb_desc, i); printf("Service #%d (%d)", i, service_table->service_id); if (service_table->service_name) printf(" %s", service_table->service_name); if (entry->vchannel) printf(" channel %s", entry->vchannel); printf("\n"); } store_dvb_channel(&dvb_file_new, parms, dvb_desc, args->get_detected, args->get_nit); if (!args->dont_add_new_freqs) add_other_freq_entries(dvb_file, parms, dvb_desc); dvb_free_ts_tables(dvb_desc); } if (dvb_file_new) write_file_format(args->output, dvb_file_new, parms->current_sys, args->output_format); dvb_file_free(dvb_file); if (dvb_file_new) dvb_file_free(dvb_file_new); close(dmx_fd); return 0; }
/** * basic options needed * @adapter * @frontend * @freq (Mhz) * @pol (13/18) * @srate (kSps) * @pos (0 - 3) * @LNB (low, high, switch) Mhz * */ int main(int argc, char *argv[]) { int opt; int ret, fd, adapter=0, frontend=0, pos; int simple; struct lnb_types_st lnb; struct sec_params sec; memset(&sec, 0, sizeof(sec)); lnb = lnbs[0]; /* default is Universal LNB */ while ((opt = getopt(argc, argv, "Hh:a:f:p:s:l:")) != -1) { switch (opt) { case '?': case 'h': default: /* help */ bad_usage(argv[0], 0); break; case 'a': /* adapter */ adapter = strtoul(optarg, NULL, 0); break; case 'f': /* demodulator (device) */ frontend = strtoul(optarg, NULL, 0); break; case 'p': /* parameters */ if (params_decode(optarg, argv, &sec) < 0) { bad_usage(argv[0], 1); return -1; } break; case 's': /* diseqc position */ pos = strtoul(optarg, NULL, 0); pos % 2 ? (sec.burst = SEC_MINI_B) : (sec.burst = SEC_MINI_A); break; case 'l': if (lnb_parse(optarg, &lnb) < 0) { bad_usage(argv[0], 1); return -1; } break; case 'H': simple = 1; /* human readable */ break; } } lnb.low_val *= 1000; /* kHz */ lnb.high_val *= 1000; /* kHz */ lnb.switch_val *= 1000; /* kHz */ sec.freq *= 1000; /* kHz */ sec.srate *= 1000; ret = frontend_open(&fd, adapter, frontend); if (ret < 0) { fprintf(stderr, "Adapter:%d Frontend:%d open failed, err=%d\n", adapter, frontend, ret); return -1; } ret = lnb_setup(&lnb, &sec); if (ret < 0) { fprintf(stderr, "LNB setup failed, err=%d\n", ret); fprintf(stderr, "%s", usage_str); goto err; } ret = diseqc_setup(fd, &sec); if (ret < 0) { fprintf(stderr, "SEC setup failed, err=%d\n", ret); goto err;; } ret = tune_to(fd, &sec); if (ret < 0) { fprintf(stderr, "Adapter:%d Frontend:%d tune_to %d %d failed, err=%d\n", adapter, frontend, sec.freq, sec.srate, ret); goto err;; } ret = check_frontend(fd, 1); if (ret < 0) { fprintf(stderr, "check frontend failed\n"); goto err;; } err: return ret; }
int main(int argc, char **argv) { struct arguments args; char *homedir = getenv("HOME"); char *channel = NULL; int lnb = -1, idx = -1; int vpid = -1, apid = -1, sid = -1; int pmtpid = 0; int pat_fd = -1, pmt_fd = -1, sid_fd = -1; int audio_fd = -1, video_fd = -1; int dvr_fd = -1, file_fd = -1; int err = -1; int r; struct dvb_v5_fe_parms *parms = NULL; const struct argp argp = { .options = options, .parser = parse_opt, .doc = N_("DVB zap utility"), .args_doc = N_("<channel name> [or <frequency> if in monitor mode]"), }; #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif memset(&args, 0, sizeof(args)); args.sat_number = -1; args.lna = LNA_AUTO; args.input_format = FILE_DVBV5; argp_parse(&argp, argc, argv, ARGP_NO_HELP | ARGP_NO_EXIT, &idx, &args); if (idx < argc) channel = argv[idx]; if (!channel) { argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME); return -1; } if (args.input_format == FILE_UNKNOWN) { fprintf(stderr, _("ERROR: Please specify a valid format\n")); argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME); return -1; } if (!args.traffic_monitor && args.search) { fprintf(stderr, _("ERROR: search string can be used only on monitor mode\n")); argp_help(&argp, stderr, ARGP_HELP_STD_HELP, PROGRAM_NAME); return -1; } if (args.lnb_name) { lnb = dvb_sat_search_lnb(args.lnb_name); if (lnb < 0) { printf(_("Please select one of the LNBf's below:\n")); dvb_print_all_lnb(); exit(1); } else { printf(_("Using LNBf ")); dvb_print_lnb(lnb); } } r = asprintf(&args.demux_dev, "/dev/dvb/adapter%i/demux%i", args.adapter, args.demux); if (r < 0) { fprintf(stderr, _("asprintf error\n")); return -1; } r = asprintf(&args.dvr_dev, "/dev/dvb/adapter%i/dvr%i", args.adapter, args.demux); if (r < 0) { fprintf(stderr, _("asprintf error\n")); return -1; } if (args.silent < 2) fprintf(stderr, _("using demux '%s'\n"), args.demux_dev); if (!args.confname) { if (!homedir) ERROR(_("$HOME not set")); r = asprintf(&args.confname, "%s/.tzap/%i/%s", homedir, args.adapter, CHANNEL_FILE); if (access(args.confname, R_OK)) { free(args.confname); r = asprintf(&args.confname, "%s/.tzap/%s", homedir, CHANNEL_FILE); } } fprintf(stderr, _("reading channels from file '%s'\n"), args.confname); parms = dvb_fe_open(args.adapter, args.frontend, args.verbose, args.force_dvbv3); if (!parms) goto err; if (lnb >= 0) parms->lnb = dvb_sat_get_lnb(lnb); if (args.sat_number > 0) parms->sat_number = args.sat_number % 3; parms->diseqc_wait = args.diseqc_wait; parms->freq_bpf = args.freq_bpf; parms->lna = args.lna; r = dvb_fe_set_default_country(parms, args.cc); if (r < 0) fprintf(stderr, _("Failed to set the country code:%s\n"), args.cc); if (parse(&args, parms, channel, &vpid, &apid, &sid)) goto err; if (setup_frontend(&args, parms) < 0) goto err; if (args.exit_after_tuning) { err = 0; check_frontend(&args, parms); goto err; } if (args.traffic_monitor) { signal(SIGTERM, do_timeout); signal(SIGINT, do_timeout); if (args.timeout > 0) { signal(SIGINT, do_timeout); alarm(args.timeout); } err = do_traffic_monitor(&args, parms); goto err; } if (args.rec_psi) { if (sid < 0) { fprintf(stderr, _("Service id 0x%04x was not specified at the file\n"), sid); goto err; } sid_fd = dvb_dmx_open(args.adapter, args.demux); if (sid_fd < 0) { perror(_("opening pat demux failed")); return -1; } pmtpid = dvb_get_pmt_pid(sid_fd, sid); dvb_dmx_close(sid_fd); if (pmtpid <= 0) { fprintf(stderr, _("couldn't find pmt-pid for sid %04x\n"), sid); goto err; } if ((pat_fd = open(args.demux_dev, O_RDWR)) < 0) { perror(_("opening pat demux failed")); goto err; } if (dvb_set_pesfilter(pat_fd, 0, DMX_PES_OTHER, args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER, args.dvr ? 64 * 1024 : 0) < 0) goto err; if ((pmt_fd = open(args.demux_dev, O_RDWR)) < 0) { perror(_("opening pmt demux failed")); goto err; } if (dvb_set_pesfilter(pmt_fd, pmtpid, DMX_PES_OTHER, args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER, args.dvr ? 64 * 1024 : 0) < 0) goto err; } if (args.all_pids++) { vpid = 0x2000; apid = 0; } if (vpid >= 0) { if (args.silent < 2) { if (vpid == 0x2000) fprintf(stderr, _("pass all PID's to TS\n")); else fprintf(stderr, _("video pid %d\n"), vpid); } if ((video_fd = open(args.demux_dev, O_RDWR)) < 0) { PERROR(_("failed opening '%s'"), args.demux_dev); goto err; } if (args.silent < 2) fprintf(stderr, _(" dvb_set_pesfilter %d\n"), vpid); if (vpid == 0x2000) { if (ioctl(video_fd, DMX_SET_BUFFER_SIZE, 1024 * 1024) == -1) perror(_("DMX_SET_BUFFER_SIZE failed")); if (dvb_set_pesfilter(video_fd, vpid, DMX_PES_OTHER, DMX_OUT_TS_TAP, 0) < 0) goto err; } else { if (dvb_set_pesfilter(video_fd, vpid, DMX_PES_VIDEO, args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER, args.dvr ? 64 * 1024 : 0) < 0) goto err; } } if (apid > 0) { if (args.silent < 2) fprintf(stderr, _("audio pid %d\n"), apid); if ((audio_fd = open(args.demux_dev, O_RDWR)) < 0) { PERROR(_("failed opening '%s'"), args.demux_dev); goto err; } if (args.silent < 2) fprintf(stderr, _(" dvb_set_pesfilter %d\n"), apid); if (dvb_set_pesfilter(audio_fd, apid, DMX_PES_AUDIO, args.dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER, args.dvr ? 64 * 1024 : 0) < 0) goto err; } signal(SIGALRM, do_timeout); signal(SIGTERM, do_timeout); if (args.timeout > 0) { signal(SIGINT, do_timeout); alarm(args.timeout); } if (!check_frontend(&args, parms)) { err = 1; fprintf(stderr, _("frontend doesn't lock\n")); goto err; } if (args.dvr) { if (args.filename) { file_fd = STDOUT_FILENO; if (strcmp(args.filename, "-") != 0) { file_fd = open(args.filename, #ifdef O_LARGEFILE O_LARGEFILE | #endif O_WRONLY | O_CREAT, 0644); if (file_fd < 0) { PERROR(_("open of '%s' failed"), args.filename); return -1; } } } if (args.silent < 2) get_show_stats(&args, parms, 0); if (file_fd >= 0) { if ((dvr_fd = open(args.dvr_dev, O_RDONLY)) < 0) { PERROR(_("failed opening '%s'"), args.dvr_dev); goto err; } if (!timeout_flag) fprintf(stderr, _("Record to file '%s' started\n"), args.filename); copy_to_file(dvr_fd, file_fd, args.timeout, args.silent); } else { if (!timeout_flag) fprintf(stderr, _("DVR interface '%s' can now be opened\n"), args.dvr_dev); get_show_stats(&args, parms, 1); } if (args.silent < 2) get_show_stats(&args, parms, 0); } err = 0; err: if (file_fd > 0) close(file_fd); if (dvr_fd > 0) close(dvr_fd); if (pat_fd > 0) close(pat_fd); if (pmt_fd > 0) close(pmt_fd); if (audio_fd > 0) close(audio_fd); if (video_fd > 0) close(video_fd); if (parms) dvb_fe_close(parms); if (args.confname) free(args.confname); if (args.demux_dev) free(args.demux_dev); if (args.dvr_dev) free(args.dvr_dev); return err; }
int do_traffic_monitor(struct arguments *args, struct dvb_v5_fe_parms *parms) { int fd, dvr_fd; long long unsigned pidt[0x2001], wait; int packets = 0; struct timeval startt; memset(pidt, 0, sizeof(pidt)); args->exit_after_tuning = 1; check_frontend(args, parms); if ((dvr_fd = open(args->dvr_dev, O_RDONLY)) < 0) { PERROR(_("failed opening '%s'"), args->dvr_dev); return -1; } if (ioctl(dvr_fd, DMX_SET_BUFFER_SIZE, 1024 * 1024) == -1) perror(_("DMX_SET_BUFFER_SIZE failed")); if ((fd = open(args->demux_dev, O_RDWR)) < 0) { PERROR(_("failed opening '%s'"), args->demux_dev); close(dvr_fd); return -1; } if (args->silent < 2) fprintf(stderr, _(" dvb_set_pesfilter to 0x2000\n")); if (dvb_set_pesfilter(fd, 0x2000, DMX_PES_OTHER, DMX_OUT_TS_TAP, 0) < 0) { PERROR(_("couldn't set filter")); return -1; } gettimeofday(&startt, 0); wait = 1000; while (1) { unsigned char buffer[BSIZE]; struct dvb_ts_packet_header *h = (void *)buffer; int pid, ok; ssize_t r; if (timeout_flag) break; if ((r = read(dvr_fd, buffer, BSIZE)) <= 0) { if (errno == EOVERFLOW) { struct timeval now; int diff; gettimeofday(&now, 0); diff = (now.tv_sec - startt.tv_sec) * 1000 + (now.tv_usec - startt.tv_usec) / 1000; fprintf(stderr, _("%.2fs: buffer overrun\n"), diff / 1000.); continue; } perror(_("read")); break; } if (r != BSIZE) { fprintf(stderr, _("dvbtraffic: only read %zd bytes\n"), r); break; } if (h->sync_byte != 0x47) { continue; } bswap16(h->bitfield); #if 0 /* * ITU-T Rec. H.222.0 decoders shall discard Transport Stream * packets with theadaptation_field_control field set to * a value of '00'. */ if (h->adaptation_field_control == 0) continue; #endif ok = 1; pid = h->pid; if (args->search) { int i, sl = strlen(args->search); ok = 0; if (pid != 0x1fff) { for (i = 0; i < (188 - sl); ++i) { if (!memcmp(buffer + i, args->search, sl)) ok = 1; } } } if (ok) { pidt[pid]++; pidt[0x2000]++; } packets++; if (!(packets & 0xFF)) { struct timeval now; int diff; gettimeofday(&now, 0); diff = (now.tv_sec - startt.tv_sec) * 1000 + (now.tv_usec - startt.tv_usec) / 1000; if (diff > wait) { if (isatty(STDOUT_FILENO)) printf("\x1b[1H\x1b[2J"); args->n_status_lines = 0; printf(_(" PID FREQ SPEED TOTAL\n")); int _pid = 0; for (_pid = 0; _pid < 0x2000; _pid++) { if (pidt[_pid]) { if (!args->low_traffic && (pidt[_pid] * 1000. / diff) < 1) continue; printf("%04x %9.2f p/s %8.1f Kbps ", _pid, pidt[_pid] * 1000. / diff, pidt[_pid] * 1000. / diff * 8 * 188 / 1024); if (pidt[_pid] * 188 / 1024) printf("%8llu KB\n", pidt[_pid] * 188 / 1024); else printf(" %8llu B\n", pidt[_pid] * 188); } } /* 0x2000 is the total traffic */ printf("TOT %10.2f p/s %8.1f Kbps %8llu KB\n", pidt[_pid] * 1000. / diff, pidt[_pid] * 1000. / diff * 8 * 188 / 1024, pidt[_pid] * 188 / 1024); printf("\n\n"); get_show_stats(args, parms, 0); wait += 1000; } } } close(dvr_fd); close(fd); return 0; }
int do_traffic_monitor(struct arguments *args, struct dvb_v5_fe_parms *parms) { int fd, dvr_fd; long long unsigned pidt[0x2001], wait; int packets = 0; struct timeval startt; memset(pidt, 0, sizeof(pidt)); args->exit_after_tuning = 1; check_frontend(args, parms); if ((dvr_fd = open(args->dvr_dev, O_RDONLY)) < 0) { PERROR("failed opening '%s'", args->dvr_dev); return -1; } if (ioctl(dvr_fd, DMX_SET_BUFFER_SIZE, 1024 * 1024) == -1) perror("DMX_SET_BUFFER_SIZE failed"); if ((fd = open(args->demux_dev, O_RDWR)) < 0) { PERROR("failed opening '%s'", args->demux_dev); return -1; } if (args->silent < 2) fprintf(stderr, " dvb_set_pesfilter to 0x2000\n"); if (dvb_set_pesfilter(fd, 0x2000, DMX_PES_OTHER, DMX_OUT_TS_TAP, 0) < 0) { PERROR("couldn't set filter"); return -1; } gettimeofday(&startt, 0); wait = 1000; while (1) { unsigned char buffer[BSIZE]; int pid, ok; ssize_t r; if ((r = read(dvr_fd, buffer, BSIZE)) <= 0) { if (errno == EOVERFLOW) { struct timeval now; int diff; gettimeofday(&now, 0); diff = (now.tv_sec - startt.tv_sec) * 1000 + (now.tv_usec - startt.tv_usec) / 1000; fprintf(stderr, "%.2fs: buffer overrun\n", diff / 1000.); continue; } perror("read"); break; } if (r != BSIZE) { fprintf(stderr, "dvbtraffic: only read %zd bytes\n", r); break; } if (buffer[0] != 0x47) { continue; printf("desync (%x)\n", buffer[0]); while (buffer[0] != 0x47) read(fd, buffer, 1); continue; } ok = 1; pid = ((((unsigned) buffer[1]) << 8) | ((unsigned) buffer[2])) & 0x1FFF; if (args->search) { int i, sl = strlen(args->search); ok = 0; if (pid != 0x1fff) { for (i = 0; i < (188 - sl); ++i) { if (!memcmp(buffer + i, args->search, sl)) ok = 1; } } } if (ok) { pidt[pid]++; pidt[0x2000]++; } packets++; if (!(packets & 0xFF)) { struct timeval now; int diff; gettimeofday(&now, 0); diff = (now.tv_sec - startt.tv_sec) * 1000 + (now.tv_usec - startt.tv_usec) / 1000; if (diff > wait) { if (isatty(STDOUT_FILENO)) printf("\x1b[1H\x1b[2J"); args->n_status_lines = 0; printf(" PID FREQ SPEED TOTAL\n"); int _pid = 0; for (_pid = 0; _pid < 0x2000; _pid++) { if (pidt[_pid]) { if (!args->low_traffic && (pidt[_pid] * 1000. / diff) < 1) continue; printf("%04x %9.2f p/s %8.1f Kbps ", _pid, pidt[_pid] * 1000. / diff, pidt[_pid] * 1000. / diff * 8 * 188 / 1024); if (pidt[_pid] * 188 / 1024) printf("%8llu KB\n", pidt[_pid] * 188 / 1024); else printf(" %8llu B\n", pidt[_pid] * 188); } } /* 0x2000 is the total traffic */ printf("TOT %10.2f p/s %8.1f Kbps %8llu KB\n", pidt[_pid] * 1000. / diff, pidt[_pid] * 1000. / diff * 8 * 188 / 1024, pidt[_pid] * 188 / 1024); printf("\n\n"); print_frontend_stats(stdout, args, parms); wait += 1000; } } } close (fd); return 0; }
int main(int argc, char **argv) { struct dvb_frontend_parameters frontend_param; char *homedir = getenv ("HOME"); char *confname = NULL; char *channel = NULL; int adapter = 0, frontend = 0, demux = 0, dvr = 0; int vpid, apid, sid, pmtpid = 0; int pat_fd, pmt_fd; int frontend_fd, audio_fd, video_fd; int opt; int rec_psi = 0; while ((opt = getopt(argc, argv, "hrpn:a:f:d:c:")) != -1) { switch (opt) { case 'a': adapter = strtoul(optarg, NULL, 0); break; case 'f': frontend = strtoul(optarg, NULL, 0); break; case 'd': demux = strtoul(optarg, NULL, 0); break; case 'r': dvr = 1; break; case 'p': rec_psi = 1; break; case 'c': confname = optarg; break; case '?': case 'h': default: fprintf (stderr, usage, argv[0]); return -1; }; } if (optind < argc) channel = argv[optind]; if (!channel) { fprintf (stderr, usage, argv[0]); return -1; } snprintf (FRONTEND_DEV, sizeof(FRONTEND_DEV), "/dev/dvb/adapter%i/frontend%i", adapter, frontend); snprintf (DEMUX_DEV, sizeof(DEMUX_DEV), "/dev/dvb/adapter%i/demux%i", adapter, demux); printf ("using '%s' and '%s'\n", FRONTEND_DEV, DEMUX_DEV); if (!confname) { if (!homedir) ERROR ("$HOME not set"); confname = malloc (strlen(homedir) + strlen(CHANNEL_FILE) + 1); memcpy (confname, homedir, strlen(homedir)); memcpy (confname + strlen(homedir), CHANNEL_FILE, strlen(CHANNEL_FILE) + 1); } memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters)); if (parse (confname, channel, &frontend_param, &vpid, &apid, &sid)) return -1; if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { PERROR ("failed opening '%s'", FRONTEND_DEV); return -1; } if (setup_frontend (frontend_fd, &frontend_param) < 0) return -1; if (rec_psi) { pmtpid = get_pmt_pid(DEMUX_DEV, sid); if (pmtpid <= 0) { fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid); return -1; } if ((pat_fd = open(DEMUX_DEV, O_RDWR)) < 0) { perror("opening pat demux failed"); return -1; } if (set_pesfilter(pat_fd, 0, DMX_PES_OTHER, dvr) < 0) return -1; if ((pmt_fd = open(DEMUX_DEV, O_RDWR)) < 0) { perror("opening pmt demux failed"); return -1; } if (set_pesfilter(pmt_fd, pmtpid, DMX_PES_OTHER, dvr) < 0) return -1; } if ((video_fd = open(DEMUX_DEV, O_RDWR)) < 0) { PERROR("failed opening '%s'", DEMUX_DEV); return -1; } printf ("video pid 0x%04x, audio pid 0x%04x\n", vpid, apid); if (set_pesfilter (video_fd, vpid, DMX_PES_VIDEO, dvr) < 0) return -1; if ((audio_fd = open(DEMUX_DEV, O_RDWR)) < 0) { PERROR("failed opening '%s'", DEMUX_DEV); return -1; } if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0) return -1; check_frontend (frontend_fd); close (pat_fd); close (pmt_fd); close (audio_fd); close (video_fd); close (frontend_fd); return 0; }