Exemplo n.º 1
0
static int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone,
	fe_spectral_inversion_t specInv, unsigned int diseqc, fe_modulation_t modulation, fe_code_rate_t HP_CodeRate,
	fe_transmit_mode_t TransmissionMode, fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth,
	fe_code_rate_t LP_CodeRate, fe_hierarchy_t hier, int timeout)
{
  int res, hi_lo, dfd;
#ifdef HAVE_DVB_HEAD
  struct dvb_frontend_parameters feparams;
  struct dvb_frontend_info fe_info;
#else
  FrontendParameters feparams;
  FrontendInfo fe_info;
  FrontendEvent event;
  struct secStatus sec_state;
#endif


  mp_msg(MSGT_DEMUX, MSGL_V,  "TUNE_IT, fd_frontend %d, fd_sec %d\nfreq %lu, srate %lu, pol %c, tone %i, specInv, diseqc %u, fe_modulation_t modulation,fe_code_rate_t HP_CodeRate, fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth\n",
    fd_frontend, fd_sec, (long unsigned int)freq, (long unsigned int)srate, pol, tone, diseqc);


  memset(&feparams, 0, sizeof(feparams));
  if ( (res = ioctl(fd_frontend,FE_GET_INFO, &fe_info) < 0))
  {
        mp_msg(MSGT_DEMUX, MSGL_FATAL, "FE_GET_INFO FAILED\n");
        return -1;
  }


#ifdef HAVE_DVB_HEAD
  mp_msg(MSGT_DEMUX, MSGL_V, "Using DVB card \"%s\"\n", fe_info.name);
#endif

  switch(fe_info.type)
  {
    case FE_OFDM:
#ifdef HAVE_DVB_HEAD
      if (freq < 1000000) freq*=1000UL;
      feparams.frequency=freq;
      feparams.inversion=specInv;
      feparams.u.ofdm.bandwidth=bandwidth;
      feparams.u.ofdm.code_rate_HP=HP_CodeRate;
      feparams.u.ofdm.code_rate_LP=LP_CodeRate;
      feparams.u.ofdm.constellation=modulation;
      feparams.u.ofdm.transmission_mode=TransmissionMode;
      feparams.u.ofdm.guard_interval=guardInterval;
      feparams.u.ofdm.hierarchy_information=hier;
#else
      if (freq < 1000000) freq*=1000UL;
      feparams.Frequency=freq;
      feparams.Inversion=specInv;
      feparams.u.ofdm.bandWidth=bandwidth;
      feparams.u.ofdm.HP_CodeRate=HP_CodeRate;
      feparams.u.ofdm.LP_CodeRate=LP_CodeRate;
      feparams.u.ofdm.Constellation=modulation;
      feparams.u.ofdm.TransmissionMode=TransmissionMode;
      feparams.u.ofdm.guardInterval=guardInterval;
      feparams.u.ofdm.HierarchyInformation=hier;
#endif
      mp_msg(MSGT_DEMUX, MSGL_V, "tuning DVB-T to %d Hz, bandwidth: %d\n",freq, bandwidth);
      break;
    case FE_QPSK:
      if (freq > 2200000)
      {
        // this must be an absolute frequency
        if (freq < SLOF)
        {
#ifdef HAVE_DVB_HEAD
          freq = feparams.frequency=(freq-LOF1);
#else
          freq = feparams.Frequency=(freq-LOF1);
#endif
          hi_lo = 0;
        }
        else
        {
#ifdef HAVE_DVB_HEAD
          freq = feparams.frequency=(freq-LOF2);
#else
          freq = feparams.Frequency=(freq-LOF2);
#endif
          hi_lo = 1;
        }
      }
      else
      {
        // this is an L-Band frequency
#ifdef HAVE_DVB_HEAD
       feparams.frequency=freq;
#else
       feparams.Frequency=freq;
#endif
      }

#ifdef HAVE_DVB_HEAD
      feparams.inversion=specInv;
      feparams.u.qpsk.symbol_rate=srate;
      feparams.u.qpsk.fec_inner=HP_CodeRate;
      dfd = fd_frontend;
#else
      feparams.Inversion=specInv;
      feparams.u.qpsk.SymbolRate=srate;
      feparams.u.qpsk.FEC_inner=HP_CodeRate;
      dfd = fd_sec;
#endif

      mp_msg(MSGT_DEMUX, MSGL_V, "tuning DVB-S to Freq: %u, Pol: %c Srate: %d, 22kHz: %s, LNB:  %d\n",freq,pol,srate,hi_lo ? "on" : "off", diseqc);

      if(do_diseqc(dfd, diseqc, (pol == 'V' ? 1 : 0), hi_lo) == 0)
          mp_msg(MSGT_DEMUX, MSGL_V, "DISEQC SETTING SUCCEDED\n");
      else
      {
          mp_msg(MSGT_DEMUX, MSGL_ERR, "DISEQC SETTING FAILED\n");
          return -1;
      }
      break;
    case FE_QAM:
      mp_msg(MSGT_DEMUX, MSGL_V, "tuning DVB-C to %d, srate=%d\n",freq,srate);
#ifdef HAVE_DVB_HEAD
      feparams.frequency=freq;
      feparams.inversion=specInv;
      feparams.u.qam.symbol_rate = srate;
      feparams.u.qam.fec_inner = HP_CodeRate;
      feparams.u.qam.modulation = modulation;
#else
      feparams.Frequency=freq;
      feparams.Inversion=specInv;
      feparams.u.qam.SymbolRate = srate;
      feparams.u.qam.FEC_inner = HP_CodeRate;
      feparams.u.qam.QAM = modulation;
#endif
      break;
#ifdef DVB_ATSC
    case FE_ATSC:
      mp_msg(MSGT_DEMUX, MSGL_V, "tuning ATSC to %d, modulation=%d\n",freq,modulation);
      feparams.frequency=freq;
      feparams.u.vsb.modulation = modulation;
      break;
#endif
    default:
      mp_msg(MSGT_DEMUX, MSGL_V, "Unknown FE type. Aborting\n");
      return 0;
  }
  usleep(100000);

#ifndef HAVE_DVB_HEAD
  if (fd_sec) SecGetStatus(fd_sec, &sec_state);
  while(1)
  {
    if(ioctl(fd_frontend, FE_GET_EVENT, &event) == -1)
    break;
  }
#endif

  if(ioctl(fd_frontend,FE_SET_FRONTEND,&feparams) < 0)
  {
    mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR tuning channel\n");
    return -1;
  }

  return(check_status(fd_frontend, timeout));
}
Exemplo n.º 2
0
static int tune_it(dvb_priv_t *priv, int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone,
        fe_spectral_inversion_t specInv, unsigned int diseqc, fe_modulation_t modulation, fe_code_rate_t HP_CodeRate,
        fe_transmit_mode_t TransmissionMode, fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth,
        fe_code_rate_t LP_CodeRate, fe_hierarchy_t hier, int timeout)
{
  int hi_lo = 0, dfd;
  struct dvb_frontend_parameters feparams;
  struct dvb_frontend_info fe_info;

  MP_VERBOSE(priv, "TUNE_IT, fd_frontend %d, fd_sec %d\nfreq %lu, srate %lu, pol %c, tone %i, specInv, diseqc %u, fe_modulation_t modulation,fe_code_rate_t HP_CodeRate, fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth\n",
    fd_frontend, fd_sec, (long unsigned int)freq, (long unsigned int)srate, pol, tone, diseqc);


  memset(&feparams, 0, sizeof(feparams));
  if ( ioctl(fd_frontend,FE_GET_INFO, &fe_info) < 0)
  {
        MP_FATAL(priv, "FE_GET_INFO FAILED\n");
        return -1;
  }

  MP_VERBOSE(priv, "Using DVB card \"%s\"\n", fe_info.name);

  switch(fe_info.type)
  {
    case FE_OFDM:
      if (freq < 1000000) freq*=1000UL;
      feparams.frequency=freq;
      feparams.inversion=specInv;
      feparams.u.ofdm.bandwidth=bandwidth;
      feparams.u.ofdm.code_rate_HP=HP_CodeRate;
      feparams.u.ofdm.code_rate_LP=LP_CodeRate;
      feparams.u.ofdm.constellation=modulation;
      feparams.u.ofdm.transmission_mode=TransmissionMode;
      feparams.u.ofdm.guard_interval=guardInterval;
      feparams.u.ofdm.hierarchy_information=hier;
      MP_VERBOSE(priv, "tuning DVB-T to %d Hz, bandwidth: %d\n",freq, bandwidth);
      break;
    case FE_QPSK:
      if (freq > 2200000)
      {
        // this must be an absolute frequency
        if (freq < SLOF)
        {
          freq = feparams.frequency=(freq-LOF1);
          hi_lo = 0;
        }
        else
        {
          freq = feparams.frequency=(freq-LOF2);
          hi_lo = 1;
        }
      }
      else
      {
        // this is an L-Band frequency
       feparams.frequency=freq;
      }

      feparams.inversion=specInv;
      feparams.u.qpsk.symbol_rate=srate;
      feparams.u.qpsk.fec_inner=HP_CodeRate;
      dfd = fd_frontend;

      MP_VERBOSE(priv, "tuning DVB-S to Freq: %u, Pol: %c Srate: %d, 22kHz: %s, LNB:  %d\n",freq,pol,srate,hi_lo ? "on" : "off", diseqc);

      if(do_diseqc(dfd, diseqc, (pol == 'V' ? 1 : 0), hi_lo) == 0)
          MP_VERBOSE(priv, "DISEQC SETTING SUCCEDED\n");
      else
      {
          MP_ERR(priv, "DISEQC SETTING FAILED\n");
          return -1;
      }
      break;
    case FE_QAM:
      MP_VERBOSE(priv, "tuning DVB-C to %d, srate=%d\n",freq,srate);
      feparams.frequency=freq;
      feparams.inversion=specInv;
      feparams.u.qam.symbol_rate = srate;
      feparams.u.qam.fec_inner = HP_CodeRate;
      feparams.u.qam.modulation = modulation;
      break;
#ifdef DVB_ATSC
    case FE_ATSC:
      MP_VERBOSE(priv, "tuning ATSC to %d, modulation=%d\n",freq,modulation);
      feparams.frequency=freq;
      feparams.u.vsb.modulation = modulation;
      break;
#endif
    default:
      MP_VERBOSE(priv, "Unknown FE type. Aborting\n");
      return 0;
  }
  usleep(100000);

  if(ioctl(fd_frontend,FE_SET_FRONTEND,&feparams) < 0)
  {
    MP_ERR(priv, "ERROR tuning channel\n");
    return -1;
  }

  return check_status(priv, fd_frontend, timeout);
}
Exemplo n.º 3
0
int tune_it(int fd_frontend, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned char diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth, fe_code_rate_t LP_CodeRate, fe_hierarchy_t hier) {
  int res, hi_lo, dfd;
  unsigned int base;
  struct dvb_frontend_parameters feparams;
  struct dvb_frontend_info fe_info;

  if ( (res = ioctl(fd_frontend,FE_GET_INFO, &fe_info) < 0)){
     perror("FE_GET_INFO: ");
     return -1;
  }
  
  fprintf(stderr,"Using DVB card \"%s\", freq=%d\n",fe_info.name, freq);

  if (freq < 1000000) freq*=1000UL;
  switch(fe_info.type) {
    case FE_OFDM:
      feparams.frequency=freq;
      feparams.inversion=INVERSION_OFF;
      feparams.u.ofdm.bandwidth=bandwidth;
      feparams.u.ofdm.code_rate_HP=HP_CodeRate;
      feparams.u.ofdm.code_rate_LP=LP_CodeRate;
      feparams.u.ofdm.constellation=modulation;
      feparams.u.ofdm.transmission_mode=TransmissionMode;
      feparams.u.ofdm.guard_interval=guardInterval;
      feparams.u.ofdm.hierarchy_information=hier;
      fprintf(stderr,"tuning DVB-T (%s) to %d Hz, Bandwidth: %d\n",DVB_T_LOCATION,freq, 
	bandwidth==BANDWIDTH_8_MHZ ? 8 : (bandwidth==BANDWIDTH_7_MHZ ? 7 : 6));
      break;
    case FE_QPSK:
    	pol = toupper(pol);
	if (freq > 2200000) {
        if (freq < SLOF) {
          feparams.frequency=(freq-LOF1);
	  hi_lo = 0;
	  base = LOF1;
        } else {
          feparams.frequency=(freq-LOF2);
	  hi_lo = 1;
	  base = LOF2;
      } 
      } else {
          feparams.frequency=freq;
	  base = 0;
      }

      fprintf(stderr,"tuning DVB-S to Freq: %u, Pol:%c Srate=%d, 22kHz tone=%s, LNB: %d\n",feparams.frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off", diseqc);
      feparams.inversion=specInv;
      feparams.u.qpsk.symbol_rate=srate;
      feparams.u.qpsk.fec_inner=FEC_AUTO;
      dfd = fd_frontend;

   if(do_diseqc(dfd, diseqc, (pol == 'V' ? 1 : 0), hi_lo) == 0)
	fprintf(stderr, "DISEQC SETTING SUCCEDED\n");
   else  {
	fprintf(stderr, "DISEQC SETTING FAILED\n");
          return -1;
        }
      break;
    case FE_QAM:
      fprintf(stderr,"tuning DVB-C to %d, srate=%d\n",freq,srate);
      feparams.frequency=freq;
      feparams.inversion=INVERSION_OFF;
      feparams.u.qam.symbol_rate = srate;
      feparams.u.qam.fec_inner = FEC_AUTO;
      feparams.u.qam.modulation = modulation;
      break;
#ifdef DVB_ATSC
    case FE_ATSC:
      fprintf(stderr, "tuning ATSC to %d, modulation=%d\n",freq,modulation);
      feparams.frequency=freq;
      feparams.u.vsb.modulation = modulation;
      break;
#endif
    default:
      fprintf(stderr,"Unknown FE type. Aborting\n");
      exit(-1);
  }
  usleep(100000);

  return(check_status(fd_frontend,fe_info.type,&feparams,base));
}
Exemplo n.º 4
0
bool
tune_service_id(unsigned int adapter, unsigned int frontend, unsigned int timeout, uint16_t service_id, int* tuner_fd)
{
	char fe_dev[PATH_MAX];
	bool got_info;
	struct dvb_frontend_info fe_info;
	struct dvb_frontend_parameters current_params;
	struct dvb_frontend_parameters needed_params;
	char polarity;
	unsigned int sat_no;
	bool hi_lo;
	struct dvb_frontend_event event;
//	fe_status_t status;
	bool lock;
	/* need to keep the frontend device open to stop it untuning itself */
	static int fe_fd = -1;
	static bool first_time = true;
  
  #if 0
  if (*tuner_fd = -1)
  {
    fe_fd = -1;
    bool first_time = true;
  }
  #endif

	if(fe_fd < 0)
	{
		snprintf(fe_dev, sizeof(fe_dev), FE_DEVICE, adapter, frontend);
		/*
		 * need O_RDWR if you want to tune, O_RDONLY is okay for getting info
		 * if someone else is using the frontend, we can only open O_RDONLY
		 * => we can still download data, but just not retune
		 */
		if((fe_fd = open(fe_dev, O_RDWR | O_NONBLOCK)) < 0)
		{
			error("Unable to open '%s' read/write; you will not be able to retune", fe_dev);
			if((fe_fd = open(fe_dev, O_RDONLY | O_NONBLOCK)) < 0)
				fatal("open '%s': %s", fe_dev, strerror(errno));
			/* don't try to tune in */
			first_time = false;
		}
	}

	vverbose("Getting frontend info");

	do
	{
		/* maybe interrupted by a signal */
		got_info = (ioctl(fe_fd, FE_GET_INFO, &fe_info) >= 0);
		if(!got_info && errno != EINTR)
			fatal("ioctl FE_GET_INFO: %s", strerror(errno));
	}
	while(!got_info);

	/* see what we are currently tuned to */
	if(ioctl(fe_fd, FE_GET_FRONTEND, &current_params) < 0)
		fatal("ioctl FE_GET_FRONTEND: %s", strerror(errno));

	/* find the tuning params for the service */
	if(!get_tune_params(fe_info.type, service_id, &needed_params, &polarity, &sat_no))
	{
		error("service_id %u not found in channels.conf file", service_id);
		return false;
	}

	/*
	 * if no-one was using the frontend when we open it
	 * FE_GET_FRONTEND may say we are tuned to the frequency we want
	 * but when we try to read any data, it fails
	 * checking if we have a lock doesn't seem to work
	 * so, always retune the first time we are called
	 */
#if 0
	if(ioctl(fe_fd, FE_READ_STATUS, &status) < 0)
		lock = false;
	else
		lock = status & FE_HAS_LOCK;
#endif

	/* are we already tuned to the right frequency */
	vverbose("Current frequency %u; needed %u; first_time=%d", current_params.frequency, needed_params.frequency, first_time);

	/* frequency resolution is up to 1 kHz */
	if(first_time
	|| abs(current_params.frequency - needed_params.frequency) >= ONE_kHz)
	{
		first_time = false;
		verbose("Retuning to frequency %u", needed_params.frequency);
		/* empty event queue */
		while(ioctl(fe_fd, FE_GET_EVENT, &event) >= 0)
			; /* do nothing */
		/* do DISEQC (whatever that is) for DVB-S */
		if(fe_info.type == FE_QPSK)
		{
			if(needed_params.frequency < SLOF)
			{
				needed_params.frequency -= LOF1;
				hi_lo = false;
			}
			else
			{
				needed_params.frequency -= LOF2;
				hi_lo = true;
			}
			if(do_diseqc(fe_fd, sat_no, polarity, hi_lo) < 0)
				error("DISEQC command failed for service_id %u", service_id);
		}
		/* tune in */
		if(ioctl(fe_fd, FE_SET_FRONTEND, &needed_params) < 0)
			fatal("Unable to retune: ioctl FE_SET_FRONTEND: %s", strerror(errno));
		/* wait for lock */
		vverbose("Waiting for tuner to lock on");
		/* TODO: use timeout value here */
    struct timeval start, end;
    gettimeofday(&start, NULL);
		lock = false;
		while(!lock)
		{
			if(ioctl(fe_fd, FE_GET_EVENT, &event) >= 0)
				lock = event.status & FE_HAS_LOCK;
      gettimeofday(&end, NULL);
      if (end.tv_sec  - start.tv_sec > 120)
        return false;
		}
		vverbose("Retuned");
	}

	*tuner_fd = fe_fd;
  return true;
}
Exemplo n.º 5
0
static int tune_it(dvb_priv_t *priv, int fd_frontend, int fd_sec,
                   unsigned int freq, unsigned int srate, char pol, int tone,
                   bool is_dvb_s2, int stream_id,
                   fe_spectral_inversion_t specInv, unsigned int diseqc,
                   fe_modulation_t modulation,
                   fe_code_rate_t HP_CodeRate,
                   fe_transmit_mode_t TransmissionMode,
                   fe_guard_interval_t guardInterval,
                   fe_bandwidth_t bandwidth,
                   fe_code_rate_t LP_CodeRate, fe_hierarchy_t hier,
                   int timeout)
{
    int hi_lo = 0, dfd;
    struct dvb_frontend_parameters feparams;
    struct dvb_frontend_info fe_info;

    MP_VERBOSE(priv, "TUNE_IT, fd_frontend %d, fd_sec %d\nfreq %lu, srate %lu, "
               "pol %c, tone %i, diseqc %u\n", fd_frontend, fd_sec,
               (long unsigned int)freq, (long unsigned int)srate, pol,
               tone, diseqc);

    memset(&feparams, 0, sizeof(feparams));
    if (ioctl(fd_frontend, FE_GET_INFO, &fe_info) < 0) {
        MP_FATAL(priv, "FE_GET_INFO FAILED\n");
        return -1;
    }

    MP_VERBOSE(priv, "Using DVB card \"%s\"\n", fe_info.name);

    {
        /* discard stale QPSK events */
        struct dvb_frontend_event ev;
        while (true) {
            if (ioctl(fd_frontend, FE_GET_EVENT, &ev) == -1)
                break;
        }
    }

    switch (fe_info.type) {
    case FE_OFDM:
        if (freq < 1000000)
            freq *= 1000UL;
        feparams.frequency = freq;
        feparams.inversion = specInv;
        feparams.u.ofdm.bandwidth = bandwidth;
        feparams.u.ofdm.code_rate_HP = HP_CodeRate;
        feparams.u.ofdm.code_rate_LP = LP_CodeRate;
        feparams.u.ofdm.constellation = modulation;
        feparams.u.ofdm.transmission_mode = TransmissionMode;
        feparams.u.ofdm.guard_interval = guardInterval;
        feparams.u.ofdm.hierarchy_information = hier;
        MP_VERBOSE(priv, "tuning DVB-T to %d Hz, bandwidth: %d\n",
                   freq, bandwidth);
        if (ioctl(fd_frontend, FE_SET_FRONTEND, &feparams) < 0) {
            MP_ERR(priv, "ERROR tuning channel\n");
            return -1;
        }
        break;
    case FE_QPSK:
        // DVB-S
        if (freq > 2200000) {
            // this must be an absolute frequency
            if (freq < SLOF) {
                freq = feparams.frequency = (freq - LOF1);
                hi_lo = 0;
            } else {
                freq = feparams.frequency = (freq - LOF2);
                hi_lo = 1;
            }
        } else {
            // this is an L-Band frequency
            feparams.frequency = freq;
        }

        feparams.inversion = specInv;
        feparams.u.qpsk.symbol_rate = srate;
        feparams.u.qpsk.fec_inner = HP_CodeRate;
        dfd = fd_frontend;

        MP_VERBOSE(priv, "tuning DVB-S%sto Freq: %u, Pol: %c Srate: %d, "
                   "22kHz: %s, LNB:  %d\n", is_dvb_s2 ? "2 " : " ", freq,
                   pol, srate, hi_lo ? "on" : "off", diseqc);

        if (do_diseqc(dfd, diseqc, (pol == 'V' ? 1 : 0), hi_lo) == 0) {
            MP_VERBOSE(priv, "DISEQC setting succeeded\n");
        } else {
            MP_ERR(priv, "DISEQC setting failed\n");
            return -1;
        }
        usleep(100000);

#ifdef DVB_USE_S2API
        /* S2API is the DVB API new since 2.6.28.
         * It is needed to tune to new delivery systems, e.g. DVB-S2.
         * It takes a struct with a list of pairs of command + parameter.
         */

        fe_delivery_system_t delsys = SYS_DVBS;
        if (is_dvb_s2)
            delsys = SYS_DVBS2;
        fe_rolloff_t rolloff = ROLLOFF_AUTO;

        struct dtv_property p[] = {
            { .cmd = DTV_DELIVERY_SYSTEM, .u.data = delsys },
            { .cmd = DTV_FREQUENCY, .u.data = freq },
            { .cmd = DTV_MODULATION, .u.data = modulation },