int main(int argc, char *argv[]) { struct dvb_v5_fe_parms *parms; int fe_flags = O_RDWR; argp_parse(&argp, argc, argv, 0, 0, 0); /* * If called without any option, be verbose, to print the * DVB frontend information. */ if (!get && !delsys && !set_params && !femon) verbose++; if (!delsys && !set_params) fe_flags = O_RDONLY; parms = dvb_fe_open_flags(adapter, frontend, verbose, dvbv3, NULL, fe_flags); if (!parms) return -1; if (delsys) { printf("Changing delivery system to: %s\n", delivery_system_name[delsys]); dvb_set_sys(parms, delsys); goto ret; } #if 0 if (set_params) do_something(); #endif if (get) { dvb_fe_get_parms(parms); dvb_fe_prt_parms(parms); } if (femon) get_show_stats(parms); ret: dvb_fe_close(parms); return 0; }
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; }
bool Frontend::Tune( Transponder &t ) { if( !IsPresent( )) { LogWarn( "device not present '%s'", name.c_str( )); return false; } Lock( ); if( transponder ) { if( transponder == &t ) { usecount++; Unlock( ); return true; } Log( "Frontend busy" ); Unlock( ); return false; } if( !Open( )) { Unlock( ); return false; } state = State_Tuning; transponder = &t; usecount++; Unlock( ); t.SetState( Transponder::State_Tuning ); Log( "Tuning %s", t.toString( ).c_str( )); uint8_t signal, noise; LogWarn( "dvb_set_compat_delivery_system %d", t.GetDelSys( )); int r = dvb_set_compat_delivery_system( fe, t.GetDelSys( )); if( r != 0 ) { LogError( "dvb_set_compat_delivery_system return %d", r ); goto fail; } SetTuneParams( t ); t.GetParams( fe ); LogWarn( "dvb_estimate_freq_shift"); dvb_estimate_freq_shift( fe ); r = dvb_fe_set_parms( fe ); if( r != 0 ) { LogError( "dvb_fe_set_parms failed with %d.", r ); dvb_fe_prt_parms( fe ); goto fail; } dvb_fe_prt_parms( fe ); /* As the DVB core emulates it, better to always use auto */ dvb_fe_store_parm(fe, DTV_INVERSION, INVERSION_AUTO); uint32_t freq; dvb_fe_retrieve_parm(fe, DTV_FREQUENCY, &freq); dvb_fe_prt_parms(fe); if( !GetLockStatus( signal, noise, tune_timeout )) { LogError( "Tuning failed" ); goto fail; } t.SetState( Transponder::State_Tuned ); t.SetSignal( signal, noise ); return true; fail: t.SetState( Transponder::State_TuningFailed ); t.SaveConfig( ); Release( ); return false; }
int main(int argc, char *argv[]) { struct dvb_device *dvb; struct dvb_dev_list *dvb_dev; struct dvb_v5_fe_parms *parms; int ret, fe_flags = O_RDWR; #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif if (argp_parse(&argp, argc, argv, ARGP_NO_HELP | ARGP_NO_EXIT, 0, 0)) { argp_help(&argp, stderr, ARGP_HELP_SHORT_USAGE, PROGRAM_NAME); return -1; } /* * If called without any option, be verbose, to print the * DVB frontend information. */ if (!get && !delsys && !set_params && !femon) verbose++; if (!delsys && !set_params) fe_flags = O_RDONLY; dvb = dvb_dev_alloc(); if (!dvb) return -1; if (server && port) { printf(_("Connecting to %s:%d\n"), server, port); ret = dvb_dev_remote_init(dvb, server, port); if (ret < 0) return -1; } dvb_dev_set_log(dvb, verbose, NULL); if (device_mon) { dvb_dev_find(dvb, &dev_change_monitor, NULL); while (1) { usleep(1000000); } } dvb_dev_find(dvb, NULL, NULL); parms = dvb->fe_parms; dvb_dev = dvb_dev_seek_by_adapter(dvb, adapter, frontend, DVB_DEVICE_FRONTEND); if (!dvb_dev) return -1; if (!dvb_dev_open(dvb, dvb_dev->sysname, fe_flags)) return -1; if (delsys) { printf(_("Changing delivery system to: %s\n"), delivery_system_name[delsys]); dvb_set_sys(parms, delsys); goto ret; } #if 0 if (set_params) do_something(); #endif if (get) { dvb_fe_get_parms(parms); dvb_fe_prt_parms(parms); } if (femon) get_show_stats(parms); ret: dvb_dev_free(dvb); return 0; }
int dvb_fe_set_parms(struct dvb_v5_fe_parms *p) { struct dvb_v5_fe_parms_priv *parms = (void *)p; /* Use a temporary copy of the parameters so we can safely perform * adjustments for satellite */ struct dvb_v5_fe_parms_priv tmp_parms = *parms; struct dtv_properties prop; struct dvb_frontend_parameters v3_parms; uint32_t bw; if (parms->p.lna != LNA_AUTO && !parms->p.legacy_fe) { struct dvb_v5_fe_parms_priv tmp_lna_parms; memset(&prop, 0, sizeof(prop)); prop.props = tmp_lna_parms.dvb_prop; prop.props[0].cmd = DTV_LNA; prop.props[0].u.data = parms->p.lna; prop.num = 1; if (xioctl(parms->fd, FE_SET_PROPERTY, &prop) == -1) { dvb_perror(_("Setting LNA")); parms->p.lna = LNA_AUTO; } else if (parms->p.lna != LNA_AUTO && parms->p.verbose) dvb_logdbg(_("LNA is %s"), parms->p.lna ? _("ON") : _("OFF")); } if (dvb_fe_is_satellite(tmp_parms.p.current_sys)) { dvb_sat_set_parms(&tmp_parms.p); /* * even though the frequncy prop is kept un-modified here, * a later call to dvb_fe_get_parms() issues FE_GET_PROPERTY * ioctl and overwrites it with the offset-ed value from * the FE. So we need to save the offset here and * re-add it in dvb_fe_get_parms(). * note that dvbv5-{scan,zap} utilities call dvb_fe_get_parms() * indirectly from check_frontend() via dvb_fe_get_stats(). */ parms->freq_offset = tmp_parms.freq_offset; } dvb_setup_delsys_default(p); /* Filter out any user DTV_foo property such as DTV_POLARIZATION */ tmp_parms.n_props = dvb_copy_fe_props(tmp_parms.dvb_prop, tmp_parms.n_props, tmp_parms.dvb_prop); memset(&prop, 0, sizeof(prop)); prop.props = tmp_parms.dvb_prop; prop.num = tmp_parms.n_props; prop.props[prop.num].cmd = DTV_TUNE; prop.num++; if (!parms->p.legacy_fe) { if (xioctl(parms->fd, FE_SET_PROPERTY, &prop) == -1) { dvb_perror("FE_SET_PROPERTY"); if (parms->p.verbose) dvb_fe_prt_parms(&parms->p); return -1; } return 0; } /* DVBv3 call */ dvb_fe_retrieve_parm(&tmp_parms.p, DTV_FREQUENCY, &v3_parms.frequency); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_INVERSION, &v3_parms.inversion); switch (tmp_parms.p.current_sys) { case SYS_DVBS: dvb_fe_retrieve_parm(&tmp_parms.p, DTV_SYMBOL_RATE, &v3_parms.u.qpsk.symbol_rate); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_INNER_FEC, &v3_parms.u.qpsk.fec_inner); break; case SYS_DVBC_ANNEX_AC: dvb_fe_retrieve_parm(&tmp_parms.p, DTV_SYMBOL_RATE, &v3_parms.u.qam.symbol_rate); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_INNER_FEC, &v3_parms.u.qam.fec_inner); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_MODULATION, &v3_parms.u.qam.modulation); break; case SYS_ATSC: case SYS_ATSCMH: case SYS_DVBC_ANNEX_B: dvb_fe_retrieve_parm(&tmp_parms.p, DTV_MODULATION, &v3_parms.u.vsb.modulation); break; case SYS_DVBT: for (bw = 0; fe_bandwidth_name[bw] != 0; bw++) { if (fe_bandwidth_name[bw] == v3_parms.u.ofdm.bandwidth) break; } dvb_fe_retrieve_parm(&tmp_parms.p, DTV_BANDWIDTH_HZ, &bw); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_CODE_RATE_HP, &v3_parms.u.ofdm.code_rate_HP); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_CODE_RATE_LP, &v3_parms.u.ofdm.code_rate_LP); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_MODULATION, &v3_parms.u.ofdm.constellation); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_TRANSMISSION_MODE, &v3_parms.u.ofdm.transmission_mode); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_GUARD_INTERVAL, &v3_parms.u.ofdm.guard_interval); dvb_fe_retrieve_parm(&tmp_parms.p, DTV_HIERARCHY, &v3_parms.u.ofdm.hierarchy_information); break; default: return -1; } if (xioctl(tmp_parms.fd, FE_SET_FRONTEND, &v3_parms) == -1) { dvb_perror("FE_SET_FRONTEND"); if (tmp_parms.p.verbose) dvb_fe_prt_parms(&tmp_parms.p); return -1; } return 0; }
int dvb_fe_get_parms(struct dvb_v5_fe_parms *p) { struct dvb_v5_fe_parms_priv *parms = (void *)p; int i, n = 0; const unsigned int *sys_props; struct dtv_properties prop; struct dvb_frontend_parameters v3_parms; uint32_t bw; sys_props = dvb_v5_delivery_system[parms->p.current_sys]; if (!sys_props) return EINVAL; while (sys_props[n]) { parms->dvb_prop[n].cmd = sys_props[n]; n++; } parms->dvb_prop[n].cmd = DTV_DELIVERY_SYSTEM; parms->dvb_prop[n].u.data = parms->p.current_sys; n++; /* Keep it ready for set */ parms->dvb_prop[n].cmd = DTV_TUNE; parms->n_props = n; struct dtv_property fe_prop[DTV_MAX_COMMAND]; n = dvb_copy_fe_props(parms->dvb_prop, n, fe_prop); prop.props = fe_prop; prop.num = n; if (!parms->p.legacy_fe) { if (xioctl(parms->fd, FE_GET_PROPERTY, &prop) == -1) { dvb_perror("FE_GET_PROPERTY"); return errno; } /* copy back params from temporary fe_prop */ for (i = 0; i < n; i++) { if (dvb_fe_is_satellite(p->current_sys) && fe_prop[i].cmd == DTV_FREQUENCY) fe_prop[i].u.data += parms->freq_offset; dvb_fe_store_parm(&parms->p, fe_prop[i].cmd, fe_prop[i].u.data); } if (parms->p.verbose) { dvb_log(_("Got parameters for %s:"), delivery_system_name[parms->p.current_sys]); dvb_fe_prt_parms(&parms->p); } return 0; } /* DVBv3 call */ if (xioctl(parms->fd, FE_GET_FRONTEND, &v3_parms) == -1) { dvb_perror("FE_GET_FRONTEND"); return EINVAL; } dvb_fe_store_parm(&parms->p, DTV_FREQUENCY, v3_parms.frequency); dvb_fe_store_parm(&parms->p, DTV_INVERSION, v3_parms.inversion); switch (parms->p.current_sys) { case SYS_DVBS: dvb_fe_store_parm(&parms->p, DTV_SYMBOL_RATE, v3_parms.u.qpsk.symbol_rate); dvb_fe_store_parm(&parms->p, DTV_INNER_FEC, v3_parms.u.qpsk.fec_inner); break; case SYS_DVBC_ANNEX_A: dvb_fe_store_parm(&parms->p, DTV_SYMBOL_RATE, v3_parms.u.qam.symbol_rate); dvb_fe_store_parm(&parms->p, DTV_INNER_FEC, v3_parms.u.qam.fec_inner); dvb_fe_store_parm(&parms->p, DTV_MODULATION, v3_parms.u.qam.modulation); break; case SYS_ATSC: case SYS_ATSCMH: case SYS_DVBC_ANNEX_B: dvb_fe_store_parm(&parms->p, DTV_MODULATION, v3_parms.u.vsb.modulation); break; case SYS_DVBT: if (v3_parms.u.ofdm.bandwidth < ARRAY_SIZE(fe_bandwidth_name) -1) bw = fe_bandwidth_name[v3_parms.u.ofdm.bandwidth]; else bw = 0; dvb_fe_store_parm(&parms->p, DTV_BANDWIDTH_HZ, bw); dvb_fe_store_parm(&parms->p, DTV_CODE_RATE_HP, v3_parms.u.ofdm.code_rate_HP); dvb_fe_store_parm(&parms->p, DTV_CODE_RATE_LP, v3_parms.u.ofdm.code_rate_LP); dvb_fe_store_parm(&parms->p, DTV_MODULATION, v3_parms.u.ofdm.constellation); dvb_fe_store_parm(&parms->p, DTV_TRANSMISSION_MODE, v3_parms.u.ofdm.transmission_mode); dvb_fe_store_parm(&parms->p, DTV_GUARD_INTERVAL, v3_parms.u.ofdm.guard_interval); dvb_fe_store_parm(&parms->p, DTV_HIERARCHY, v3_parms.u.ofdm.hierarchy_information); break; default: return EINVAL; } return 0; }