@@ -1880,7 +1880,7 @@ void cCamSlot::AddChannel(const cChannel
source = Channel->Source();
transponder = Channel->Transponder();
if (Channel->Ca() >= CA_ENCRYPTED_MIN) {
- AddPid(Channel->Sid(), Channel->Vpid(), STREAM_TYPE_VIDEO);
+ AddPid(Channel->Sid(), VPID_FROM_ANY(Channel->Vpid()), STREAM_TYPE_VIDEO);
for (const int *Apid = Channel->Apids(); *Apid; Apid++)
AddPid(Channel->Sid(), *Apid, STREAM_TYPE_AUDIO);
for (const int *Dpid = Channel->Dpids(); *Dpid; Dpid++)
@@ -1901,7 +1901,7 @@ bool cCamSlot::CanDecrypt(const cChannel
if (cas && cas->RepliesToQuery()) {
cCiCaPmt CaPmt(CPCI_QUERY, Channel->Source(), Channel->Transponder(), Channel->Sid(), GetCaSystemIds());
CaPmt.SetListManagement(CPLM_ADD); // WORKAROUND: CPLM_ONLY doesn't work with Alphacrypt 3.09 (deletes existing CA_PMTs)
- CaPmt.AddPid(Channel->Vpid(), STREAM_TYPE_VIDEO);
+ CaPmt.AddPid(VPID_FROM_ANY(Channel->Vpid()), STREAM_TYPE_VIDEO);
for (const int *Apid = Channel->Apids(); *Apid; Apid++)
CaPmt.AddPid(*Apid, STREAM_TYPE_AUDIO);
for (const int *Dpid = Channel->Dpids(); *Dpid; Dpid++)
@@ -76,7 +76,7 @@ private:
int tuneTimeout;
int lockTimeout;
time_t lastTimeoutReport;
- fe_type_t frontendType;
+ dvbfe_delsys frontendType;
cChannel channel;
const char *diseqcCommands;
eTunerStatus tunerStatus;
@@ -87,14 +87,14 @@ private:
bool SetFrontend(void);
virtual void Action(void);
public:
- cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType);
+ cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType);
virtual ~cDvbTuner();
bool IsTunedTo(const cChannel *Channel) const;
void Set(const cChannel *Channel, bool Tune);
bool Locked(int TimeoutMs = 0);
};
-cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType)
+cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, dvbfe_delsys FrontendType)
{
fd_frontend = Fd_Frontend;
cardIndex = CardIndex;
@@ -104,7 +104,7 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, in
lastTimeoutReport = 0;
diseqcCommands = NULL;
tunerStatus = tsIdle;
- if (frontendType == FE_QPSK)
+ if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))
CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power
SetDescription("tuner on device %d", cardIndex + 1);
Start();
@@ -173,114 +173,165 @@ static unsigned int FrequencyToHz(unsign
bool cDvbTuner::SetFrontend(void)
{
- dvb_frontend_parameters Frontend;
-
+ dvbfe_params Frontend;
memset(&Frontend, 0, sizeof(Frontend));
- switch (frontendType) {
- case FE_QPSK: { // DVB-S
-
- unsigned int frequency = channel.Frequency();
-
- if (Setup.DiSEqC) {
- cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
- if (diseqc) {
- if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
- cDiseqc::eDiseqcActions da;
- for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
- switch (da) {
- case cDiseqc::daNone: break;
- case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
- case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
- case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
- case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
- case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
- case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
- case cDiseqc::daCodes: {
- int n = 0;
- uchar *codes = diseqc->Codes(n);
- if (codes) {
- struct dvb_diseqc_master_cmd cmd;
- memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
- cmd.msg_len = n;
- CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
- }
- }
- break;
- }
- }
- diseqcCommands = diseqc->Commands();
+ if (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2)) { // DVB-S
+ unsigned int frequency = channel.Frequency();
+ if (Setup.DiSEqC) {
+ cDiseqc *diseqc = Diseqcs.Get(channel.Source(), channel.Frequency(), channel.Polarization());
+ if (diseqc) {
+ if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) {
+fprintf(stderr, "DiSEqC: %s\n", diseqc->Commands());
+ cDiseqc::eDiseqcActions da;
+ for (char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) {
+ switch (da) {
+ case cDiseqc::daNone: break;
+ case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+ case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+ case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+ case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+ case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+ case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+ case cDiseqc::daCodes: {
+ int n = 0;
+ uchar *codes = diseqc->Codes(n);
+ if (codes) {
+ struct dvb_diseqc_master_cmd cmd;
+ memcpy(cmd.msg, codes, min(n, int(sizeof(cmd.msg))));
+ cmd.msg_len = n;
+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd));
+ }
+ }
+ break;
+ }
}
- frequency -= diseqc->Lof();
- }
- else {
- esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
- return false;
- }
- }
- else {
- int tone = SEC_TONE_OFF;
-
- if (frequency < (unsigned int)Setup.LnbSLOF) {
- frequency -= Setup.LnbFrequLo;
- tone = SEC_TONE_OFF;
- }
- else {
- frequency -= Setup.LnbFrequHi;
- tone = SEC_TONE_ON;
- }
- int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
- CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
- CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
- }
-
- frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
- Frontend.frequency = frequency * 1000UL;
- Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
- Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
- Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
-
- tuneTimeout = DVBS_TUNE_TIMEOUT;
- lockTimeout = DVBS_LOCK_TIMEOUT;
- }
- break;
- case FE_QAM: { // DVB-C
-
- // Frequency and symbol rate:
-
- Frontend.frequency = FrequencyToHz(channel.Frequency());
- Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
- Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL;
- Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH());
- Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation());
-
- tuneTimeout = DVBC_TUNE_TIMEOUT;
- lockTimeout = DVBC_LOCK_TIMEOUT;
- }
- break;
- case FE_OFDM: { // DVB-T
-
- // Frequency and OFDM paramaters:
-
- Frontend.frequency = FrequencyToHz(channel.Frequency());
- Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
- Frontend.u.ofdm.bandwidth = fe_bandwidth_t(channel.Bandwidth());
- Frontend.u.ofdm.code_rate_HP = fe_code_rate_t(channel.CoderateH());
- Frontend.u.ofdm.code_rate_LP = fe_code_rate_t(channel.CoderateL());
- Frontend.u.ofdm.constellation = fe_modulation_t(channel.Modulation());
- Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission());
- Frontend.u.ofdm.guard_interval = fe_guard_interval_t(channel.Guard());
- Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy());
-
- tuneTimeout = DVBT_TUNE_TIMEOUT;
- lockTimeout = DVBT_LOCK_TIMEOUT;
- }
- break;
- default:
- esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
- return false;
- }
- if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
+ diseqcCommands = diseqc->Commands();
+ }
+ frequency -= diseqc->Lof();
+ }
+ else {
+ esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number());
+ return false;
+ }
+ }
+ else {
+ int tone = SEC_TONE_OFF;
+ if (frequency < (unsigned int)Setup.LnbSLOF) {
+ frequency -= Setup.LnbFrequLo;
+ tone = SEC_TONE_OFF;
+ }
+ else {
+ frequency -= Setup.LnbFrequHi;
+ tone = SEC_TONE_ON;
+ }
+ int volt = (channel.Polarization() == 'v' || channel.Polarization() == 'V' || channel.Polarization() == 'r' || channel.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
+ CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
+ CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
+ }
+ frequency = abs(frequency); // Allow for C-band, where the frequency is less than the LOF
+ Frontend.frequency = frequency * 1000UL;
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+
+ dvbfe_info feinfo;
+ if (channel.ModulationSystem() == DVBFE_DELSYS_DVBS) {
+ dsyslog("set DVB-S");
+ feinfo.delivery = DVBFE_DELSYS_DVBS;
+ CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+ Frontend.delivery = DVBFE_DELSYS_DVBS;
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+ Frontend.delsys.dvbs.modulation = dvbfe_modulation(channel.Modulation());
+ Frontend.delsys.dvbs.symbol_rate = channel.Srate() * 1000UL;
+ Frontend.delsys.dvbs.fec = dvbfe_fec(channel.CoderateH());
+ }
+ else {
+ dsyslog("set DVB-S2");
+ feinfo.delivery = DVBFE_DELSYS_DVBS2;
+ CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+ Frontend.delivery = DVBFE_DELSYS_DVBS2;
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+ Frontend.delsys.dvbs2.modulation = dvbfe_modulation(channel.Modulation());
+ Frontend.delsys.dvbs2.symbol_rate = channel.Srate() * 1000UL;
+ Frontend.delsys.dvbs2.fec = dvbfe_fec(channel.CoderateH());
+ Frontend.delsys.dvbs2.rolloff = dvbfe_rolloff(channel.RollOff());
+ }
+ tuneTimeout = DVBS_TUNE_TIMEOUT;
+ lockTimeout = DVBS_LOCK_TIMEOUT;
+ }
+ else if (frontendType & DVBFE_DELSYS_DVBC) { // DVB-C
+ dvbfe_info feinfo;
+ feinfo.delivery = DVBFE_DELSYS_DVBC;
+ CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+ Frontend.delivery = DVBFE_DELSYS_DVBC;
+ Frontend.frequency = FrequencyToHz(channel.Frequency());
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+ Frontend.delsys.dvbc.symbol_rate = channel.Srate() * 1000UL;
+ Frontend.delsys.dvbc.fec = dvbfe_fec(channel.CoderateH());
+ Frontend.delsys.dvbc.modulation = dvbfe_modulation(channel.Modulation());
+
+ tuneTimeout = DVBC_TUNE_TIMEOUT;
+ lockTimeout = DVBC_LOCK_TIMEOUT;
+ }
+ else if (frontendType & DVBFE_DELSYS_DVBT) { // DVB-T
+ dvbfe_info feinfo;
+ feinfo.delivery = DVBFE_DELSYS_DVBT;
+ CHECK(ioctl(fd_frontend, DVBFE_GET_INFO, &feinfo)); //switch system
+
+ Frontend.delivery = DVBFE_DELSYS_DVBT;
+ Frontend.frequency = FrequencyToHz(channel.Frequency());
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+ Frontend.delsys.dvbt.bandwidth = dvbfe_bandwidth(channel.Bandwidth());
+ Frontend.delsys.dvbt.code_rate_HP = dvbfe_fec(channel.CoderateH());
+ Frontend.delsys.dvbt.code_rate_LP = dvbfe_fec(channel.CoderateL());
+ Frontend.delsys.dvbt.constellation = dvbfe_modulation(channel.Modulation());
+ Frontend.delsys.dvbt.transmission_mode = dvbfe_transmission_mode(channel.Transmission());
+ Frontend.delsys.dvbt.guard_interval = dvbfe_guard_interval(channel.Guard());
+ Frontend.delsys.dvbt.hierarchy = dvbfe_hierarchy(channel.Hierarchy());
+ Frontend.delsys.dvbt.alpha = dvbfe_alpha(channel.Alpha());
+ Frontend.delsys.dvbt.priority = dvbfe_stream_priority(channel.Priority());
+
+ tuneTimeout = DVBT_TUNE_TIMEOUT;
+ lockTimeout = DVBT_LOCK_TIMEOUT;
+ }
+/* XXX
+ else if (frontendType & DVBFE_DELSYS_DVBH) { // DVB-H
+ Frontend.delivery = DVBFE_DELSYS_DVBH;
+ Frontend.frequency = FrequencyToHz(channel.Frequency());
+ Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
+
+ Frontend.delsys.dvbh.bandwidth = dvbfe_bandwidth(channel.Bandwidth());
+ Frontend.delsys.dvbh.code_rate_HP = dvbfe_fec(channel.CoderateH());
+ Frontend.delsys.dvbh.code_rate_LP = dvbfe_fec(channel.CoderateL());
+ Frontend.delsys.dvbh.constellation = dvbfe_modulation(channel.Modulation());
+ Frontend.delsys.dvbh.transmission_mode = dvbfe_transmission_mode(channel.Transmission());
+ Frontend.delsys.dvbh.guard_interval = dvbfe_guard_interval(channel.Guard());
+ Frontend.delsys.dvbh.hierarchy = dvbfe_hierarchy(channel.Hierarchy());
+
+// Frontend.delsys.dvbh.alpha = 0; //XXX
+// Frontend.delsys.dvbh.interleaver = 0; //XXX
+// Frontend.delsys.dvbh.mpefec = 0; //XXX
+// Frontend.delsys.dvbh.timeslicing = 0; //XXX
+// Frontend.delsys.dvbh.priority = 0; //XXX
+ }
+ else if (frontendType & DVBFE_DELSYS_DSS) { // DDS
+ Frontend.delivery = DVBFE_DELSYS_DSS;
+ Frontend.delsys.dss.modulation = DVBFE_MOD_QPSK; //XXX
+ Frontend.delsys.dss.symbol_rate = channel.Srate() * 1000UL;
+ Frontend.delsys.dss.fec = dvbfe_fec(channel.CoderateH());
+ }
+ else if (frontendType & DVBFE_DELSYS_ATSC) { // ATCS
+ Frontend.delivery = DVBFE_DELSYS_ATSC;
+ Frontend.delsys.atsc.modulation = DVBFE_MOD_QPSK; //XXX
+ }
+*/
+ else {
+ esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
+ return false;
+ }
+ if (ioctl(fd_frontend, DVBFE_SET_PARAMS, &Frontend) < 0) {
esyslog("ERROR: frontend %d: %m", cardIndex);
return false;
}
@@ -355,7 +406,7 @@ cDvbDevice::cDvbDevice(int n)
{
ciAdapter = NULL;
dvbTuner = NULL;
- frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
+ frontendType = DVBFE_DELSYS_DUMMY;
spuDecoder = NULL;
digitalAudio = false;
playMode = pmNone;
@@ -417,11 +468,8 @@ cDvbDevice::cDvbDevice(int n)
// We only check the devices that must be present - the others will be checked before accessing them://XXX
if (fd_frontend >= 0) {
- dvb_frontend_info feinfo;
- if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
- frontendType = feinfo.type;
+ if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0)
dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType);
- }
else
LOG_ERROR;
}
@@ -738,9 +786,9 @@ bool cDvbDevice::ProvidesSource(int Sour
{
int type = Source & cSource::st_Mask;
return type == cSource::stNone
- || type == cSource::stCable && frontendType == FE_QAM
- || type == cSource::stSat && frontendType == FE_QPSK
- || type == cSource::stTerr && frontendType == FE_OFDM;
+ || type == cSource::stCable && (frontendType & DVBFE_DELSYS_DVBC)
+ || type == cSource::stSat && (frontendType & (DVBFE_DELSYS_DVBS | DVBFE_DELSYS_DVBS2))
+ || type == cSource::stTerr && (frontendType & DVBFE_DELSYS_DVBT);
}
bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const
@@ -758,7 +806,7 @@ bool cDvbDevice::ProvidesChannel(const c
result = hasPriority;
if (Priority >= 0 && Receiving(true)) {
if (dvbTuner->IsTunedTo(Channel)) {
- if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) {
+ if (Channel->Vpid() && !HasPid(VPID_FROM_ANY(Channel->Vpid())) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) {
#ifdef DO_MULTIPLE_RECORDINGS
if (CamSlot() && Channel->Ca() >= CA_ENCRYPTED_MIN) {
if (CamSlot()->CanDecrypt(Channel))
@@ -794,7 +842,7 @@ bool cDvbDevice::IsTunedToTransponder(co
bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
{
int apid = Channel->Apid(0);
- int vpid = Channel->Vpid();
+ int vpid = VPID_FROM_ANY(Channel->Vpid());
int dpid = Channel->Dpid(0);
bool DoTune = !dvbTuner->IsTunedTo(Channel);
@@ -855,7 +903,7 @@ bool cDvbDevice::SetChannelDevice(const
CHECK(ioctl(fd_audio, AUDIO_SET_AV_SYNC, true));
}
else if (StartTransferMode)
- cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), vpid, Channel->Apids(), Channel->Dpids(), Channel->Spids()));
+ cControl::Launch(new cTransferControl(this, Channel->GetChannelID(), Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids()));
return true;
}