コード例 #1
0
ファイル: dvb-fe.c プロジェクト: Distrotech/v4l-utils
/* set the delsys default/fixed parameters and replace DVBv5 default values */
static void dvb_setup_delsys_default(struct dvb_v5_fe_parms *p)
{
	struct dvb_v5_fe_parms_priv *parms = (void *)p;
	uint32_t cc;

	switch (p->current_sys) {
	case SYS_ISDBT:
		/* Set country code. */
		/* if the default country is not known, fallback to BR */
		cc = COUNTRY_UNKNOWN;
		dvb_fe_retrieve_parm(p, DTV_COUNTRY_CODE, &cc);
		if (cc == COUNTRY_UNKNOWN) {
			cc = (parms->country == COUNTRY_UNKNOWN)
				? BR : parms->country;
			dvb_fe_store_parm(p, DTV_COUNTRY_CODE, cc);
		}
		switch (cc) {
		case JP:
			p->default_charset = "arib-std-b24";
			dvb_fe_store_parm(p, DTV_BANDWIDTH_HZ, 6000000);
			break;
		/* Americas (SBTVD) */
		case AR:
		case BO:
		case BR:
		case CL:
		case CR:
		case EC:
		case GT:
		case HN:
		case NI:
		case PE:
		case PY:
		case UY:
		case VE:
			p->default_charset = "iso8859-15";
			break;
		}
		break;
	case SYS_ISDBS:
		p->default_charset = "arib-std-b24";
		if (!p->lnb)
			p->lnb = dvb_sat_get_lnb(dvb_sat_search_lnb("110BS"));
		break;
	default:
		break;
	}
}
コード例 #2
0
ファイル: dvbv5-zap.c プロジェクト: danig19/RogueSquadran
static int setup_frontend(struct arguments *args,
			  struct dvb_v5_fe_parms *parms)
{
	int rc;
	uint32_t freq;

	if (args->silent < 2) {
		rc = dvb_fe_retrieve_parm(parms, DTV_FREQUENCY, &freq);
		if (rc < 0) {
			PERROR("can't get the frequency");
			return -1;
		}
		fprintf(stderr, "tuning to %i Hz\n", freq);
	}

	rc = dvb_fe_set_parms(parms);
	if (rc < 0) {
		PERROR("dvb_fe_set_parms failed");
		return -1;
	}

	return 0;
}
コード例 #3
0
ファイル: dvbv5-scan.c プロジェクト: cemot/galileo-hack
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;
}
コード例 #4
0
ファイル: dvbv5-scan.c プロジェクト: cemot/galileo-hack
static int estimate_freq_shift(struct dvb_v5_fe_parms *parms)
{
	uint32_t shift = 0, bw = 0, symbol_rate, ro;
	int rolloff = 0;
	int divisor = 100;

	/* Need to handle only cable/satellite and ATSC standards */
	switch (parms->current_sys) {
	case SYS_DVBC_ANNEX_A:
		rolloff = 115;
		break;
	case SYS_DVBC_ANNEX_C:
		rolloff = 115;
		break;
	case SYS_DVBS:
	case SYS_ISDBS:	/* FIXME: not sure if this rollof is right for ISDB-S */
		divisor = 100000;
		rolloff = 135;
		break;
	case SYS_DVBS2:
	case SYS_DSS:
	case SYS_TURBO:
		divisor = 100000;
		dvb_fe_retrieve_parm(parms, DTV_ROLLOFF, &ro);
		switch (ro) {
		case ROLLOFF_20:
			rolloff = 120;
			break;
		case ROLLOFF_25:
			rolloff = 125;
			break;
		default:
		case ROLLOFF_AUTO:
		case ROLLOFF_35:
			rolloff = 135;
			break;
		}
		break;
	case SYS_ATSC:
	case SYS_DVBC_ANNEX_B:
		bw = 6000000;
		break;
	default:
		break;
	}
	if (rolloff) {
		/*
		 * This is not 100% correct for DVB-S2, as there is a bw
		 * guard interval there but it should be enough for the
		 * purposes of estimating a max frequency shift here.
		 */
		dvb_fe_retrieve_parm(parms, DTV_SYMBOL_RATE, &symbol_rate);
		bw = (symbol_rate * rolloff) / divisor;
	}
	if (!bw)
		dvb_fe_retrieve_parm(parms, DTV_BANDWIDTH_HZ, &bw);

	/*
	 * If the max frequency shift between two frequencies is below
	 * than the used bandwidth / 8, it should be the same channel.
	 */
	shift = bw / 8;

	return shift;
}
コード例 #5
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;
}
コード例 #6
0
ファイル: dvb-fe.c プロジェクト: Distrotech/v4l-utils
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;
}
コード例 #7
0
ファイル: dvb-fe.c プロジェクト: Distrotech/v4l-utils
int dvb_fe_get_event(struct dvb_v5_fe_parms *p)
{
	struct dvb_v5_fe_parms_priv *parms = (void *)p;
	struct dvb_frontend_event event;
	fe_status_t status;
	int i;

	if (!parms->p.legacy_fe) {
		dvb_fe_get_parms(&parms->p);
		return dvb_fe_get_stats(&parms->p);
	}

	if (xioctl(parms->fd, FE_GET_EVENT, &event) == -1) {
		dvb_perror("FE_GET_EVENT");
		return errno;
	}
	status = event.status;
	if (parms->p.verbose > 1) {
		dvb_log(_("Status: "));
		for (i = 0; i < ARRAY_SIZE(fe_status_name); i++) {
			if (status & fe_status_name[i].idx)
				dvb_log ("    %s", fe_status_name[i].name);
		}
	}
	dvb_fe_store_stats(parms, DTV_STATUS, FE_SCALE_RELATIVE, 0, status);

	dvb_fe_retrieve_parm(&parms->p, DTV_FREQUENCY, &event.parameters.frequency);
	dvb_fe_retrieve_parm(&parms->p, DTV_INVERSION, &event.parameters.inversion);
	switch (parms->p.current_sys) {
	case SYS_DVBS:
		dvb_fe_retrieve_parm(&parms->p, DTV_SYMBOL_RATE, &event.parameters.u.qpsk.symbol_rate);
		dvb_fe_retrieve_parm(&parms->p, DTV_INNER_FEC, &event.parameters.u.qpsk.fec_inner);
		break;
	case SYS_DVBC_ANNEX_AC:
		dvb_fe_retrieve_parm(&parms->p, DTV_SYMBOL_RATE, &event.parameters.u.qam.symbol_rate);
		dvb_fe_retrieve_parm(&parms->p, DTV_INNER_FEC, &event.parameters.u.qam.fec_inner);
		dvb_fe_retrieve_parm(&parms->p, DTV_MODULATION, &event.parameters.u.qam.modulation);
		break;
	case SYS_ATSC:
	case SYS_ATSCMH:
	case SYS_DVBC_ANNEX_B:
		dvb_fe_retrieve_parm(&parms->p, DTV_MODULATION, &event.parameters.u.vsb.modulation);
		break;
	case SYS_DVBT:
		dvb_fe_retrieve_parm(&parms->p, DTV_BANDWIDTH_HZ, &event.parameters.u.ofdm.bandwidth);
		dvb_fe_retrieve_parm(&parms->p, DTV_CODE_RATE_HP, &event.parameters.u.ofdm.code_rate_HP);
		dvb_fe_retrieve_parm(&parms->p, DTV_CODE_RATE_LP, &event.parameters.u.ofdm.code_rate_LP);
		dvb_fe_retrieve_parm(&parms->p, DTV_MODULATION, &event.parameters.u.ofdm.constellation);
		dvb_fe_retrieve_parm(&parms->p, DTV_TRANSMISSION_MODE, &event.parameters.u.ofdm.transmission_mode);
		dvb_fe_retrieve_parm(&parms->p, DTV_GUARD_INTERVAL, &event.parameters.u.ofdm.guard_interval);
		dvb_fe_retrieve_parm(&parms->p, DTV_HIERARCHY, &event.parameters.u.ofdm.hierarchy_information);
		break;
	default:
		return EINVAL;
	}

	return dvb_fe_get_stats(&parms->p);
}
コード例 #8
0
ファイル: dvb-fe.c プロジェクト: Distrotech/v4l-utils
static enum dvb_quality dvbv_fe_cnr_to_quality(struct dvb_v5_fe_parms_priv *parms,
					       struct dtv_stats *cnr)
{
	uint32_t modulation, fec;
	enum dvb_quality qual = DVB_QUAL_UNKNOWN;

	switch (cnr->scale) {
	case FE_SCALE_RELATIVE:
		if (cnr->uvalue == 65535)
			return DVB_QUAL_GOOD;
		else if (cnr->uvalue >= 65535 / 2)
			return DVB_QUAL_OK;
		else
			return DVB_QUAL_POOR;
		return qual;
	case FE_SCALE_DECIBEL:
		break;
	default:
		return DVB_QUAL_UNKNOWN;
	}

	switch (parms->p.current_sys) {
	case SYS_DVBC_ANNEX_A:
	case SYS_DVBC_ANNEX_C:
		dvb_fe_retrieve_parm(&parms->p, DTV_MODULATION, &modulation);
		if (modulation == QAM_AUTO)
			modulation = QAM_64;	/* Assume worse case */
		qual = cnr_arr_to_qual(modulation, FEC_NONE, cnr->svalue,
				       dvb_c_cnr_2_qual,
				       ARRAY_SIZE(dvb_c_cnr_2_qual));
		break;
	case SYS_DVBS:
		dvb_fe_retrieve_parm(&parms->p, DTV_INNER_FEC, &fec);
		qual = cnr_arr_to_qual(QPSK, fec, cnr->svalue,
				       dvb_s_cnr_2_qual,
				       ARRAY_SIZE(dvb_s_cnr_2_qual));
		break;
	case SYS_DVBS2:
		dvb_fe_retrieve_parm(&parms->p, DTV_MODULATION, &modulation);
		dvb_fe_retrieve_parm(&parms->p, DTV_INNER_FEC, &fec);
		qual = cnr_arr_to_qual(modulation, fec, cnr->svalue,
			               dvb_s2_cnr_2_qual,
				       ARRAY_SIZE(dvb_s_cnr_2_qual));
		break;
	case SYS_ISDBT:
		dvb_fe_retrieve_parm(&parms->p, DTV_ISDBT_LAYERA_MODULATION, &modulation);
		dvb_fe_retrieve_parm(&parms->p, DTV_ISDBT_LAYERA_FEC, &fec);
		if (modulation == QAM_AUTO)
			modulation = QAM_64;	/* Assume worse case */
		qual = cnr_arr_to_qual(modulation, fec, cnr->svalue,
			               isdb_t_cnr_2_qual,
				       ARRAY_SIZE(isdb_t_cnr_2_qual));
		break;
	case SYS_DVBT:
		dvb_fe_retrieve_parm(&parms->p, DTV_MODULATION, &modulation);
		dvb_fe_retrieve_parm(&parms->p, DTV_CODE_RATE_LP, &fec);
		qual = cnr_arr_to_qual(modulation, fec, cnr->svalue,
			               dvb_t_cnr_2_qual,
				       ARRAY_SIZE(isdb_t_cnr_2_qual));
		break;
	case SYS_DVBT2:
	case SYS_TURBO:
	case SYS_ISDBS:
	case SYS_DSS:
	case SYS_DTMB:
	case SYS_ATSC:
	case SYS_ATSCMH:
	case SYS_DVBC_ANNEX_B:
	default:
		/* Quality unknown */
		break;
	}

	return qual;
};