@@ -50,12 +50,21 @@ const tChannelParameterMap CoderateValue
};
const tChannelParameterMap ModulationValues[] = {
+ { 0, MOD_QPSK },
{ 0, QPSK },
+ { 8, MOD_8PSK },
+ { 16, MOD_QAM_16 },
{ 16, QAM_16 },
+ { 32, MOD_QAM_32 },
{ 32, QAM_32 },
+ { 64, MOD_QAM_64 },
{ 64, QAM_64 },
+ { 128, MOD_QAM_128 },
{ 128, QAM_128 },
+ { 256, MOD_QAM_256 },
{ 256, QAM_256 },
+ { 512, MOD_BPSK },
+ { 999, MOD_QAM_AUTO },
{ 999, QAM_AUTO },
{ -1 }
};
@@ -171,7 +180,7 @@ cChannel::cChannel(void)
bandwidth = BANDWIDTH_AUTO;
coderateH = FEC_AUTO;
coderateL = FEC_AUTO;
- modulation = QAM_AUTO;
+ modulation = QPSK;
transmission = TRANSMISSION_MODE_AUTO;
guard = GUARD_INTERVAL_AUTO;
hierarchy = HIERARCHY_AUTO;
@@ -283,7 +292,7 @@ void cChannel::CopyTransponderData(const
}
}
-bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH)
+bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation)
{
// Workarounds for broadcaster stupidity:
// Some providers broadcast the transponder frequency of their channels with two different
@@ -297,7 +306,7 @@ bool cChannel::SetSatTransponderData(int
if (abs(srate - Srate) <= 1)
Srate = srate;
- if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH) {
+ if (source != Source || frequency != Frequency || polarization != Polarization || srate != Srate || coderateH != CoderateH || modulation != Modulation) {
if (Number()) {
dsyslog("changing transponder data of channel %d from %s:%d:%c:%d:%d to %s:%d:%c:%d:%d", Number(), *cSource::ToString(source), frequency, polarization, srate, coderateH, *cSource::ToString(Source), Frequency, Polarization, Srate, CoderateH);
modification |= CHANNELMOD_TRANSP;
@@ -308,7 +317,7 @@ bool cChannel::SetSatTransponderData(int
polarization = Polarization;
srate = Srate;
coderateH = CoderateH;
- modulation = QPSK;
+ modulation = Modulation;
schedule = NULL;
}
return true;
@@ -600,7 +609,7 @@ cString cChannel::ParametersToString(voi
ST("CST") q += PrintParameter(q, 'I', MapToUser(inversion, InversionValues));
ST("CST") q += PrintParameter(q, 'C', MapToUser(coderateH, CoderateValues));
ST(" T") q += PrintParameter(q, 'D', MapToUser(coderateL, CoderateValues));
- ST("C T") q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues));
+ ST("CST") q += PrintParameter(q, 'M', MapToUser(modulation, ModulationValues));
ST(" T") q += PrintParameter(q, 'B', MapToUser(bandwidth, BandwidthValues));
ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
ST(" T") q += PrintParameter(q, 'G', MapToUser(guard, GuardValues));
@@ -206,7 +206,7 @@ public:
bool HasTimer(void) const;
int Modification(int Mask = CHANNELMOD_ALL);
void CopyTransponderData(const cChannel *Channel);
- bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH);
+ bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation);
bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission);
void SetId(int Nid, int Tid, int Sid, int Rid = 0);
@@ -104,7 +104,7 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, in
lastTimeoutReport = 0;
diseqcCommands = NULL;
tunerStatus = tsIdle;
- if (frontendType == FE_QPSK)
+ if (frontendType == FE_QPSK || frontendType == FE_DVB_S || frontendType == FE_DVB_S2)
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,13 +173,14 @@ static unsigned int FrequencyToHz(unsign
bool cDvbTuner::SetFrontend(void)
{
- dvb_frontend_parameters Frontend;
+ dvb_frontend_parameters_new Frontend;
memset(&Frontend, 0, sizeof(Frontend));
switch (frontendType) {
- case FE_QPSK: { // DVB-S
-
+ case FE_QPSK: // DVB-S
+ case FE_DVB_S: // DVB-S
+ case FE_DVB_S2: { // DVB-S
unsigned int frequency = channel.Frequency();
if (Setup.DiSEqC) {
@@ -237,8 +238,14 @@ bool cDvbTuner::SetFrontend(void)
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());
+ if (frontendType == FE_DVB_S2) {
+ Frontend.u.qpsk2.symbol_rate = channel.Srate() * 1000UL;
+ Frontend.u.qpsk2.fec_inner = fe_code_rate_t(channel.CoderateH());
+ Frontend.u.qpsk2.modulation = fe_modulation_t(channel.Modulation());
+ } else {
+ 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;
@@ -280,10 +287,17 @@ bool cDvbTuner::SetFrontend(void)
esyslog("ERROR: attempt to set channel with unknown DVB frontend type");
return false;
}
- if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) < 0) {
- esyslog("ERROR: frontend %d: %m", cardIndex);
- return false;
+ if (frontendType == FE_DVB_S2) {
+ if (ioctl(fd_frontend, FE_SET_FRONTEND2, &Frontend) == -1) {
+ esyslog("ERROR: frontend %d: %m", cardIndex);
+ return false;
+ }
+ } else {
+ if (ioctl(fd_frontend, FE_SET_FRONTEND, &Frontend) == -1) {
+ esyslog("ERROR: frontend %d: %m", cardIndex);
+ return false;
}
+ }
return true;
}
@@ -419,7 +433,16 @@ cDvbDevice::cDvbDevice(int n)
if (fd_frontend >= 0) {
dvb_frontend_info feinfo;
if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
- frontendType = feinfo.type;
+ frontendType = feinfo.type;
+ if ( ((feinfo.type == FE_QPSK) || (feinfo.type == FE_DVB_S2)) && (feinfo.caps & FE_HAS_EXTENDED_INFO) ) {
+ dvb_fe_caps_extended feextinfo;
+ if (ioctl(fd_frontend, FE_GET_EXTENDED_INFO, &feextinfo) >= 0) {
+ if (feextinfo.standards & FE_DVB_S2) {
+ CHECK(ioctl(fd_frontend, FE_SET_STANDARD, FE_DVB_S2));
+ frontendType = FE_DVB_S2;
+ }
+ }
+ }
dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType);
}
else
@@ -745,6 +768,8 @@ bool cDvbDevice::ProvidesSource(int Sour
return type == cSource::stNone
|| type == cSource::stCable && frontendType == FE_QAM
|| type == cSource::stSat && frontendType == FE_QPSK
+ || type == cSource::stSat && frontendType == FE_DVB_S
+ || type == cSource::stSat && frontendType == FE_DVB_S2
|| type == cSource::stTerr && frontendType == FE_OFDM;
}
@@ -129,6 +129,8 @@ void cNitFilter::Process(u_short Pid, u_
char Polarization = Polarizations[sd->getPolarization()];
static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
int CodeRate = CodeRates[sd->getFecInner()];
+ static int Modulations[] = { MOD_QPSK, QPSK, MOD_QAM_16, QAM_16, MOD_QAM_32, QAM_32, MOD_QAM_64, QAM_64, MOD_QAM_128, QAM_128, MOD_QAM_256, QAM_256, MOD_QAM_AUTO, QAM_AUTO, MOD_BPSK, MOD_8PSK };
+ int Modulation = Modulations[min(sd->getModulationType(), 15)];
int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
if (ThisNIT >= 0) {
for (int n = 0; n < NumFrequencies; n++) {
@@ -154,7 +156,7 @@ void cNitFilter::Process(u_short Pid, u_
}
}
if (ISTRANSPONDER(cChannel::Transponder(Frequency, Polarization), Transponder())) // only modify channels if we're actually receiving this transponder
- Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate);
+ Channel->SetSatTransponderData(Source, Frequency, Polarization, SymbolRate, CodeRate, Modulation);
}
found = true;
}
@@ -162,7 +164,7 @@ void cNitFilter::Process(u_short Pid, u_
for (int n = 0; n < NumFrequencies; n++) {
cChannel *Channel = new cChannel;
Channel->SetId(ts.getOriginalNetworkId(), ts.getTransportStreamId(), 0, 0);
- if (Channel->SetSatTransponderData(Source, Frequencies[n], Polarization, SymbolRate, CodeRate))
+ if (Channel->SetSatTransponderData(Source, Frequencies[n], Polarization, SymbolRate, CodeRate, Modulation))
EITScanner.AddTransponder(Channel);
else
delete Channel;
@@ -178,8 +180,8 @@ void cNitFilter::Process(u_short Pid, u_
//XXX FEC_outer???
static int CodeRates[] = { FEC_NONE, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_AUTO, FEC_NONE };
int CodeRate = CodeRates[sd->getFecInner()];
- static int Modulations[] = { QPSK, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO };
- int Modulation = Modulations[min(sd->getModulation(), 6)];
+ static int Modulations[] = { MOD_QPSK, MOD_8PSK, MOD_QAM_16, MOD_QAM_32, MOD_QAM_64, MOD_QAM_128, MOD_QAM_256, MOD_QAM_AUTO };
+ int Modulation = Modulations[min(sd->getModulation(), 7)];
int SymbolRate = BCD2INT(sd->getSymbolRate()) / 10;
if (ThisNIT >= 0) {
for (int n = 0; n < NumFrequencies; n++) {