14 #include <linux/dvb/dmx.h> 15 #include <linux/dvb/frontend.h> 16 #include <sys/ioctl.h> 26 #define DVBS_TUNE_TIMEOUT 9000 //ms 27 #define DVBS_LOCK_TIMEOUT 2000 //ms 28 #define DVBC_TUNE_TIMEOUT 9000 //ms 29 #define DVBC_LOCK_TIMEOUT 2000 //ms 30 #define DVBT_TUNE_TIMEOUT 9000 //ms 31 #define DVBT_LOCK_TIMEOUT 2000 //ms 32 #define ATSC_TUNE_TIMEOUT 9000 //ms 33 #define ATSC_LOCK_TIMEOUT 2000 //ms 35 #define SCR_RANDOM_TIMEOUT 500 // ms (add random value up to this when tuning SCR device to avoid lockups) 40 { 0, PILOT_OFF,
trNOOP(
"off") },
41 { 1, PILOT_ON,
trNOOP(
"on") },
42 { 999, PILOT_AUTO,
trNOOP(
"auto") },
47 { 0, INVERSION_OFF,
trNOOP(
"off") },
48 { 1, INVERSION_ON,
trNOOP(
"on") },
49 { 999, INVERSION_AUTO,
trNOOP(
"auto") },
54 { 5, 5000000,
"5 MHz" },
55 { 6, 6000000,
"6 MHz" },
56 { 7, 7000000,
"7 MHz" },
57 { 8, 8000000,
"8 MHz" },
58 { 10, 10000000,
"10 MHz" },
59 { 1712, 1712000,
"1.712 MHz" },
64 { 0, FEC_NONE,
trNOOP(
"none") },
65 { 12, FEC_1_2,
"1/2" },
66 { 23, FEC_2_3,
"2/3" },
67 { 34, FEC_3_4,
"3/4" },
68 { 35, FEC_3_5,
"3/5" },
69 { 45, FEC_4_5,
"4/5" },
70 { 56, FEC_5_6,
"5/6" },
71 { 67, FEC_6_7,
"6/7" },
72 { 78, FEC_7_8,
"7/8" },
73 { 89, FEC_8_9,
"8/9" },
74 { 910, FEC_9_10,
"9/10" },
75 { 999, FEC_AUTO,
trNOOP(
"auto") },
80 { 16, QAM_16,
"QAM16" },
81 { 32, QAM_32,
"QAM32" },
82 { 64, QAM_64,
"QAM64" },
83 { 128, QAM_128,
"QAM128" },
84 { 256, QAM_256,
"QAM256" },
87 { 6, APSK_16,
"16APSK" },
88 { 7, APSK_32,
"32APSK" },
89 { 10, VSB_8,
"VSB8" },
90 { 11, VSB_16,
"VSB16" },
91 { 12, DQPSK,
"DQPSK" },
92 { 999, QAM_AUTO,
trNOOP(
"auto") },
96 #define DVB_SYSTEM_1 0 // see also nit.c 97 #define DVB_SYSTEM_2 1 113 { 2, TRANSMISSION_MODE_2K,
"2K" },
115 { 8, TRANSMISSION_MODE_8K,
"8K" },
118 { 999, TRANSMISSION_MODE_AUTO,
trNOOP(
"auto") },
123 { 4, GUARD_INTERVAL_1_4,
"1/4" },
124 { 8, GUARD_INTERVAL_1_8,
"1/8" },
125 { 16, GUARD_INTERVAL_1_16,
"1/16" },
126 { 32, GUARD_INTERVAL_1_32,
"1/32" },
130 { 999, GUARD_INTERVAL_AUTO,
trNOOP(
"auto") },
135 { 0, HIERARCHY_NONE,
trNOOP(
"none") },
136 { 1, HIERARCHY_1,
"1" },
137 { 2, HIERARCHY_2,
"2" },
138 { 4, HIERARCHY_4,
"4" },
139 { 999, HIERARCHY_AUTO,
trNOOP(
"auto") },
144 { 0, ROLLOFF_AUTO,
trNOOP(
"auto") },
145 { 20, ROLLOFF_20,
"0.20" },
146 { 25, ROLLOFF_25,
"0.25" },
147 { 35, ROLLOFF_35,
"0.35" },
178 *String =
tr(Map[n].userString);
212 guard = GUARD_INTERVAL_AUTO;
224 return Value >= 0 && Value != 999 ? sprintf(p,
"%c%d", Name, Value) : 0;
229 #define ST(s) if (strchr(s, Type) && (strchr(s, '0' + system + 1) || strchr(s, '*'))) 256 int n = strtol(s, &p, 10);
257 if (!errno && p != s) {
263 esyslog(
"ERROR: invalid value for parameter '%c'", *(s - 1));
270 switch (toupper(*s)) {
289 default:
esyslog(
"ERROR: unknown parameter key '%c'", *s);
298 #define TUNER_POLL_TIMEOUT 10 // ms 325 bool SetFrontendType(
const cChannel *Channel);
329 void ClearEventQueue(
void)
const;
330 bool GetFrontendStatus(fe_status_t &Status)
const;
332 void ExecuteDiseqc(
const cDiseqc *Diseqc,
unsigned int *Frequency);
333 void ResetToneAndVoltage(
void);
334 bool SetFrontend(
void);
335 virtual void Action(
void);
338 bool OpenFrontend(
void)
const;
339 bool CloseFrontend(
void);
346 bool BondingOk(
const cChannel *Channel,
bool ConsiderOccupied =
false)
const;
349 bool IsTunedTo(
const cChannel *Channel)
const;
350 void SetChannel(
const cChannel *Channel);
351 bool Locked(
int TimeoutMs = 0);
353 int GetSignalStrength(
void)
const;
354 int GetSignalQuality(
void)
const;
356 bool SetIdle(
bool Idle);
357 bool IsIdle(
void)
const {
return isIdle; }
364 frontendType = SYS_UNDEFINED;
366 fd_frontend = Fd_Frontend;
372 lastTimeoutReport = 0;
378 lnbPowerTurnedOn =
false;
379 tunerStatus = tsIdle;
381 bondedMaster =
false;
383 SetDescription(
"frontend %d/%d tuner", adapter, frontend);
389 tunerStatus = tsIdle;
400 if (device && device->IsSubDevice())
408 ResetToneAndVoltage();
409 bondedMaster =
false;
412 dsyslog(
"tuner %d/%d bonded with tuner %d/%d", adapter, frontend, bondedTuner->adapter, bondedTuner->frontend);
416 esyslog(
"ERROR: tuner %d/%d already bonded with tuner %d/%d, can't bond with tuner %d/%d", adapter, frontend, bondedTuner->adapter, bondedTuner->frontend, Tuner->
adapter, Tuner->
frontend);
424 dsyslog(
"tuner %d/%d unbonded from tuner %d/%d", adapter, frontend, bondedTuner->adapter, bondedTuner->frontend);
425 while (t->bondedTuner !=
this)
427 if (t == bondedTuner)
428 t->bondedTuner = NULL;
430 t->bondedTuner = bondedTuner;
431 bondedMaster =
false;
443 return diseqc->Commands();
447 bool VoltOff = dtp.Polarization() ==
'V' || dtp.Polarization() ==
'R';
457 cString BondingParams = GetBondingParams(Channel);
459 if (t->device->Priority() >
IDLEPRIORITY || ConsiderOccupied && t->device->Occupied()) {
460 if (strcmp(BondingParams, t->GetBondedMaster()->GetBondingParams()) != 0)
464 }
while (t != bondedTuner);
486 dsyslog(
"tuner %d/%d is now bonded master", adapter, frontend);
492 if (tunerStatus == tsIdle)
494 if (channel.Source() != Channel->
Source() || channel.Transponder() != Channel->
Transponder())
497 return strcmp(channel.Parameters(), Channel->
Parameters()) == 0;
505 cDvbTuner *BondedMaster = GetBondedMaster();
506 if (BondedMaster ==
this) {
507 if (strcmp(GetBondingParams(Channel), GetBondingParams()) != 0) {
513 else if (strcmp(GetBondingParams(Channel), BondedMaster->
GetBondingParams()) != 0)
517 if (!IsTunedTo(Channel))
521 lastTimeoutReport = 0;
526 tunerStatus = tsIdle;
527 ResetToneAndVoltage();
529 if (bondedTuner && device->IsPrimaryDevice())
535 bool isLocked = (tunerStatus >= tsLocked);
536 if (isLocked || !TimeoutMs)
540 if (TimeoutMs && tunerStatus < tsLocked)
541 locked.TimedWait(mutex, TimeoutMs);
542 return tunerStatus >= tsLocked;
551 dvb_frontend_event Event;
552 while (ioctl(fd_frontend, FE_GET_EVENT, &Event) == 0)
561 if (ioctl(fd_frontend, FE_READ_STATUS, &Status) != -1)
577 if (ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &Signal) != -1)
582 uint16_t MaxSignal = 0xFFFF;
585 switch (subsystemId) {
588 MaxSignal = 670;
break;
590 int s = int(Signal) * 100 / MaxSignal;
593 #ifdef DEBUG_SIGNALSTRENGTH 594 fprintf(stderr,
"FE %d/%d: %08X S = %04X %04X %3d%%\n", adapter, frontend, subsystemId, MaxSignal, Signal, s);
599 #define LOCK_THRESHOLD 5 // indicates that all 5 FE_HAS_* flags are set 604 if (GetFrontendStatus(Status)) {
606 if ((Status & FE_HAS_LOCK) == 0) {
607 if ((Status & FE_HAS_SIGNAL) == 0)
609 if ((Status & FE_HAS_CARRIER) == 0)
611 if ((Status & FE_HAS_VITERBI) == 0)
613 if ((Status & FE_HAS_SYNC) == 0)
617 #ifdef DEBUG_SIGNALQUALITY 622 if (ioctl(fd_frontend, FE_READ_SNR, &Snr) != -1)
624 if (errno != EINTR) {
626 #ifdef DEBUG_SIGNALQUALITY 632 #ifdef DEBUG_SIGNALQUALITY 637 if (ioctl(fd_frontend, FE_READ_BER, &Ber) != -1)
639 if (errno != EINTR) {
641 #ifdef DEBUG_SIGNALQUALITY 647 #ifdef DEBUG_SIGNALQUALITY 652 if (ioctl(fd_frontend, FE_READ_UNCORRECTED_BLOCKS, &Unc) != -1)
654 if (errno != EINTR) {
656 #ifdef DEBUG_SIGNALQUALITY 662 uint16_t MinSnr = 0x0000;
663 uint16_t MaxSnr = 0xFFFF;
666 switch (subsystemId) {
669 if (frontendType == SYS_DVBS2) {
680 int a = int(
constrain(Snr, MinSnr, MaxSnr)) * 100 / (MaxSnr - MinSnr);
681 int b = 100 - (Unc * 10 + (Ber / 256) * 5);
687 #ifdef DEBUG_SIGNALQUALITY 688 fprintf(stderr,
"FE %d/%d: %08X Q = %04X %04X %d %5d %5d %3d%%\n", adapter, frontend, subsystemId, MaxSnr, Snr, HasSnr, HasBer ?
int(Ber) : -1, HasUnc ?
int(Unc) : -1, q);
697 while (f && f < 1000000)
706 positioner->SetFrontend(fd_frontend);
713 if (!lnbPowerTurnedOn) {
714 CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13));
715 lnbPowerTurnedOn =
true;
720 struct dvb_diseqc_master_cmd cmd;
721 const char *CurrentAction = NULL;
724 for (
int i = 0; !Break; i++) {
725 cmd.msg_len =
sizeof(cmd.msg);
731 bool d = i >= diseqcOffset;
756 default:
esyslog(
"ERROR: unknown diseqc command %d", da);
759 diseqcOffset = i + 1;
761 positioner = Positioner;
763 ResetToneAndVoltage();
770 CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, bondedTuner ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_13));
771 CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF));
776 int ds = SYS_UNDEFINED;
780 ds = SYS_DVBC_ANNEX_AC;
781 else if (Channel->
IsSat())
783 else if (Channel->
IsTerr())
786 esyslog(
"ERROR: can't determine frontend type for channel %d (%s)", Channel->
Number(), Channel->
Name());
794 #define MAXFRONTENDCMDS 16 795 #define SETCMD(c, d) { Frontend[CmdSeq.num].cmd = (c);\ 796 Frontend[CmdSeq.num].u.data = (d);\ 797 if (CmdSeq.num++ > MAXFRONTENDCMDS) {\ 798 esyslog("ERROR: too many tuning commands on frontend %d/%d", adapter, frontend);\ 803 memset(&Frontend, 0,
sizeof(Frontend));
804 dtv_properties CmdSeq;
805 memset(&CmdSeq, 0,
sizeof(CmdSeq));
806 CmdSeq.props = Frontend;
808 if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
809 esyslog(
"ERROR: frontend %d/%d: %m", adapter, frontend);
818 if (frontendType == SYS_UNDEFINED)
821 SETCMD(DTV_DELIVERY_SYSTEM, frontendType);
822 if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) {
823 unsigned int frequency = channel.Frequency();
825 if (
const cDiseqc *diseqc =
Diseqcs.
Get(device->CardIndex() + 1, channel.Source(), frequency, dtp.Polarization(), &scr)) {
826 frequency -= diseqc->Lof();
827 if (diseqc != lastDiseqc || diseqc->IsScr() || diseqc->Position() >= 0 && channel.Source() != lastSource) {
828 if (IsBondedMaster()) {
829 ExecuteDiseqc(diseqc, &frequency);
834 ResetToneAndVoltage();
836 lastSource = channel.Source();
840 esyslog(
"ERROR: no DiSEqC parameters found for channel %d (%s)", channel.Number(), channel.Name());
845 int tone = SEC_TONE_OFF;
854 int volt = (dtp.Polarization() ==
'V' || dtp.Polarization() ==
'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
855 if (!IsBondedMaster()) {
857 volt = SEC_VOLTAGE_13;
859 CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt));
860 CHECK(ioctl(fd_frontend, FE_SET_TONE, tone));
862 frequency = abs(frequency);
865 SETCMD(DTV_FREQUENCY, frequency * 1000UL);
866 SETCMD(DTV_MODULATION, dtp.Modulation());
867 SETCMD(DTV_SYMBOL_RATE, channel.Srate() * 1000UL);
868 SETCMD(DTV_INNER_FEC, dtp.CoderateH());
869 SETCMD(DTV_INVERSION, dtp.Inversion());
870 if (frontendType == SYS_DVBS2) {
872 SETCMD(DTV_PILOT, dtp.Pilot());
873 SETCMD(DTV_ROLLOFF, dtp.RollOff());
879 SETCMD(DTV_ROLLOFF, ROLLOFF_35);
885 else if (frontendType == SYS_DVBC_ANNEX_AC || frontendType == SYS_DVBC_ANNEX_B) {
888 SETCMD(DTV_INVERSION, dtp.Inversion());
889 SETCMD(DTV_SYMBOL_RATE, channel.Srate() * 1000UL);
890 SETCMD(DTV_INNER_FEC, dtp.CoderateH());
891 SETCMD(DTV_MODULATION, dtp.Modulation());
896 else if (frontendType == SYS_DVBT || frontendType ==
SYS_DVBT2) {
899 SETCMD(DTV_INVERSION, dtp.Inversion());
900 SETCMD(DTV_BANDWIDTH_HZ, dtp.Bandwidth());
901 SETCMD(DTV_CODE_RATE_HP, dtp.CoderateH());
902 SETCMD(DTV_CODE_RATE_LP, dtp.CoderateL());
903 SETCMD(DTV_MODULATION, dtp.Modulation());
904 SETCMD(DTV_TRANSMISSION_MODE, dtp.Transmission());
905 SETCMD(DTV_GUARD_INTERVAL, dtp.Guard());
906 SETCMD(DTV_HIERARCHY, dtp.Hierarchy());
919 else if (frontendType == SYS_ATSC) {
922 SETCMD(DTV_INVERSION, dtp.Inversion());
923 SETCMD(DTV_MODULATION, dtp.Modulation());
929 esyslog(
"ERROR: attempt to set channel with unknown DVB frontend type");
933 if (ioctl(fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
934 esyslog(
"ERROR: frontend %d/%d: %m", adapter, frontend);
943 bool LostLock =
false;
944 fe_status_t Status = (fe_status_t)0;
947 fe_status_t NewStatus;
948 if (GetFrontendStatus(NewStatus))
953 switch (tunerStatus) {
957 tunerStatus = SetFrontend() ? tsPositioning : tsIdle;
961 if (positioner->IsMoving())
963 else if (diseqcOffset) {
969 tunerStatus = tsTuned;
979 if (time(NULL) - lastTimeoutReport > 60) {
980 isyslog(
"frontend %d/%d timed out while tuning to channel %d (%s), tp %d", adapter, frontend, channel.Number(), channel.Name(), channel.Transponder());
981 lastTimeoutReport = time(NULL);
988 if (Status & FE_REINIT) {
992 isyslog(
"frontend %d/%d was reinitialized", adapter, frontend);
993 lastTimeoutReport = 0;
996 else if (Status & FE_HAS_LOCK) {
998 isyslog(
"frontend %d/%d regained lock on channel %d (%s), tp %d", adapter, frontend, channel.Number(), channel.Name(), channel.Transponder());
1001 tunerStatus = tsLocked;
1003 lastTimeoutReport = 0;
1005 else if (tunerStatus == tsLocked) {
1007 isyslog(
"frontend %d/%d lost lock on channel %d (%s), tp %d", adapter, frontend, channel.Number(), channel.Name(), channel.Transponder());
1008 tunerStatus = tsTuned;
1009 Timer.
Set(lockTimeout);
1010 lastTimeoutReport = 0;
1014 default:
esyslog(
"ERROR: unknown tuner status %d", tunerStatus);
1016 newSet.TimedWait(mutex, WaitTime);
1026 return CloseFrontend();
1027 return OpenFrontend();
1032 if (fd_frontend >= 0)
1036 if (fd_frontend < 0)
1044 if (fd_frontend < 0)
1047 tunerStatus = tsIdle;
1063 virtual void SetData(
cChannel *Channel);
1064 virtual void GetData(
cChannel *Channel);
1065 virtual cOsdItem *GetOsdItem(
void);
1092 #define ST(s) if (strchr(s, type)) 1110 default:
return NULL;
1171 if (fd_frontend >= 0) {
1199 int fd = open(FileName, Mode);
1200 if (fd < 0 && ReportError)
1208 if (access(FileName, F_OK) == 0) {
1209 int f = open(FileName, O_RDONLY);
1214 else if (errno != ENODEV && errno != EINVAL)
1217 else if (errno != ENOENT)
1225 dsyslog(
"probing %s", *FileName);
1227 if (dp->Probe(Adapter, Frontend))
1230 dsyslog(
"creating cDvbDevice");
1261 while ((a = DvbDir.
Next()) != NULL) {
1265 if (AdapterDir.
Ok()) {
1267 while ((f = AdapterDir.
Next()) != NULL) {
1279 if (Nodes.
Size() > 0) {
1281 for (
int i = 0; i < Nodes.
Size(); i++) {
1284 if (2 == sscanf(Nodes[i],
"%d %d", &Adapter, &Frontend)) {
1285 if (
Exists(Adapter, Frontend)) {
1289 if (
Probe(Adapter, Frontend))
1300 isyslog(
"found %d DVB device%s", Found, Found > 1 ?
"s" :
"");
1302 isyslog(
"using only %d DVB device%s", Used, Used > 1 ?
"s" :
"");
1305 isyslog(
"no DVB device found");
1312 if (ioctl(fd_frontend, FE_GET_INFO, &
frontendInfo) < 0) {
1317 dtv_properties CmdSeq;
1320 memset(&Frontend, 0,
sizeof(Frontend));
1321 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1323 SETCMD(DTV_API_VERSION, 0);
1324 if (ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
1332 bool LegacyMode =
true;
1334 memset(&Frontend, 0,
sizeof(Frontend));
1335 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1338 int Result = ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq);
1340 for (uint i = 0; i < Frontend[0].u.buffer.len; i++) {
1350 esyslog(
"ERROR: can't query delivery systems on frontend %d/%d - falling back to legacy mode",
adapter,
frontend);
1384 ms =
"unknown modulations";
1401 int ErrorDevice = 0;
1403 if (Device1->HasSubDevice())
1404 Device1 = Device1->SubDevice();
1406 if (Device2->HasSubDevice())
1407 Device2 = Device2->SubDevice();
1408 if (
cDvbDevice *DvbDevice1 = dynamic_cast<cDvbDevice *>(Device1)) {
1409 if (
cDvbDevice *DvbDevice2 = dynamic_cast<cDvbDevice *>(Device2)) {
1410 if (!DvbDevice1->Bond(DvbDevice2))
1414 ErrorDevice = d + 1;
1417 ErrorDevice = i + 1;
1419 esyslog(
"ERROR: device '%d' in device bondings '%s' is not a cDvbDevice", ErrorDevice, Bondings);
1424 ErrorDevice = d + 1;
1427 ErrorDevice = i + 1;
1429 esyslog(
"ERROR: unknown device '%d' in device bondings '%s'", ErrorDevice, Bondings);
1444 if (
cDvbDevice *d = dynamic_cast<cDvbDevice *>(dev))
1453 if (Device !=
this) {
1463 esyslog(
"ERROR: can't bond device %d with device %d (only DVB-S(2) devices can be bonded)",
CardIndex() + 1, Device->
CardIndex() + 1);
1480 while (d->bondedDevice !=
this)
1481 d = d->bondedDevice;
1483 d->bondedDevice = NULL;
1526 dmx_pes_filter_params pesFilterParams;
1527 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
1529 if (Handle->
handle < 0) {
1531 if (Handle->
handle < 0) {
1536 pesFilterParams.pid = Handle->
pid;
1537 pesFilterParams.input = DMX_IN_FRONTEND;
1538 pesFilterParams.output = DMX_OUT_TS_TAP;
1539 pesFilterParams.pes_type= DMX_PES_OTHER;
1540 pesFilterParams.flags = DMX_IMMEDIATE_START;
1541 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
1546 else if (!Handle->
used) {
1549 pesFilterParams.pid = 0x1FFF;
1550 pesFilterParams.input = DMX_IN_FRONTEND;
1551 pesFilterParams.output = DMX_OUT_DECODER;
1552 pesFilterParams.pes_type= DMX_PES_OTHER;
1553 pesFilterParams.flags = DMX_IMMEDIATE_START;
1554 CHECK(ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams));
1566 int f = open(FileName, O_RDWR | O_NONBLOCK);
1568 dmx_sct_filter_params sctFilterParams;
1569 memset(&sctFilterParams, 0,
sizeof(sctFilterParams));
1570 sctFilterParams.pid = Pid;
1571 sctFilterParams.timeout = 0;
1572 sctFilterParams.flags = DMX_IMMEDIATE_START;
1573 sctFilterParams.filter.filter[0] = Tid;
1574 sctFilterParams.filter.mask[0] = Mask;
1575 if (ioctl(f, DMX_SET_FILTER, &sctFilterParams) >= 0)
1578 esyslog(
"ERROR: can't set filter (pid=%d, tid=%02X, mask=%02X): %m", Pid, Tid, Mask);
1583 esyslog(
"ERROR: can't open filter handle on '%s'", *FileName);
1618 dtp.Modulation() == QPSK && !(
frontendInfo.caps & FE_CAN_QPSK) ||
1619 dtp.Modulation() == QAM_16 && !(
frontendInfo.caps & FE_CAN_QAM_16) ||
1620 dtp.Modulation() == QAM_32 && !(
frontendInfo.caps & FE_CAN_QAM_32) ||
1621 dtp.Modulation() == QAM_64 && !(
frontendInfo.caps & FE_CAN_QAM_64) ||
1622 dtp.Modulation() == QAM_128 && !(
frontendInfo.caps & FE_CAN_QAM_128) ||
1623 dtp.Modulation() == QAM_256 && !(
frontendInfo.caps & FE_CAN_QAM_256) ||
1624 dtp.Modulation() == QAM_AUTO && !(
frontendInfo.caps & FE_CAN_QAM_AUTO) ||
1625 dtp.Modulation() == VSB_8 && !(
frontendInfo.caps & FE_CAN_8VSB) ||
1626 dtp.Modulation() == VSB_16 && !(
frontendInfo.caps & FE_CAN_16VSB) ||
1637 bool result =
false;
1639 bool needsDetachReceivers =
false;
1643 result = hasPriority;
1652 needsDetachReceivers =
true;
1672 needsDetachReceivers |= d->Receiving();
1680 if (NeedsDetachReceivers)
1681 *NeedsDetachReceivers = needsDetachReceivers;
1765 if (cs->WantsTsData()) {
1769 Data = cs->Decrypt(Data, Available);
1786 d->cDevice::DetachAllReceivers();
1798 DvbDeviceProbes.
Add(
this);
1803 DvbDeviceProbes.
Del(
this,
false);
1808 uint32_t SubsystemId = 0;
1811 if (stat(FileName, &st) == 0) {
1815 while ((e = d.
Next()) != NULL) {
1816 if (strstr(e->d_name,
"frontend")) {
1818 if (FILE *f = fopen(FileName,
"r")) {
1820 char *s = ReadLine.
Read(f);
1824 if (s && 2 == sscanf(s,
"%u:%u", &Major, &Minor)) {
1825 if (((Major << 8) | Minor) == st.st_rdev) {
1826 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_vendor", e->d_name);
1827 if ((f = fopen(FileName,
"r")) != NULL) {
1828 if (
char *s = ReadLine.
Read(f))
1829 SubsystemId = strtoul(s, NULL, 0) << 16;
1833 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idVendor", e->d_name);
1834 if ((f = fopen(FileName,
"r")) != NULL) {
1835 if (
char *s = ReadLine.
Read(f))
1836 SubsystemId = strtoul(s, NULL, 16) << 16;
1840 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_device", e->d_name);
1841 if ((f = fopen(FileName,
"r")) != NULL) {
1842 if (
char *s = ReadLine.
Read(f))
1843 SubsystemId |= strtoul(s, NULL, 0);
1847 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idProduct", e->d_name);
1848 if ((f = fopen(FileName,
"r")) != NULL) {
1849 if (
char *s = ReadLine.
Read(f))
1850 SubsystemId |= strtoul(s, NULL, 16);
static unsigned int FrequencyToHz(unsigned int f)
struct dirent * Next(void)
virtual ~cDvbDeviceProbe()
static bool UseDevice(int n)
Tells whether the device with the given card index shall be used in this instance of VDR...
const char * DeliverySystemNames[]
cDvbTransponderParameters(const char *Parameters=NULL)
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
int PrintParameter(char *p, char Name, int Value) const
virtual cString DeviceType(void) const
Returns a string identifying the type of this device (like "DVB-S").
bool IsBondedMaster(void) const
uchar * Get(int *Available=NULL)
Returns a pointer to the first TS packet in the buffer.
virtual bool SetIdle(bool Idle, bool TestOnly)
static bool Exists(int Adapter, int Frontend)
Checks whether the given adapter/frontend exists.
bool IsScr(void) const
Returns true if this DiSEqC sequence uses Satellite Channel Routing.
void ResetToneAndVoltage(void)
#define SCR_RANDOM_TIMEOUT
bool Receiving(bool Dummy=false) const
Returns true if we are currently receiving. The parameter has no meaning (for backwards compatibility...
friend class cDvbSourceParam
const char * ParseParameter(const char *s, int &Value, const tDvbParameterMap *Map=NULL)
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
int Position(void) const
Indicates which positioning mode to use in order to move the dish to a given satellite position...
static bool Initialize(void)
Initializes the DVB devices.
virtual bool GetTSPacket(uchar *&Data)
Gets exactly one TS packet from the DVR of this device and returns a pointer to it in Data...
#define DVBT_TUNE_TIMEOUT
int UserIndex(int Value, const tDvbParameterMap *Map)
void Add(cListObject *Object, cListObject *After=NULL)
virtual const cPositioner * Positioner(void) const
Returns a pointer to the positioner (if any) this device has used to move the satellite dish to the r...
void UnBond(void)
Removes this device from any bonding it might have with other devices.
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
#define DVBC_TUNE_TIMEOUT
int Ca(int Index=0) const
void ClearEventQueue(void) const
bool DeviceHooksProvidesTransponder(const cChannel *Channel) const
virtual int SignalQuality(void) const
Returns the "quality" of the currently received signal.
virtual cOsdItem * GetOsdItem(void)
Returns all the OSD items necessary for editing the source specific parameters of the channel that wa...
#define DVBS_LOCK_TIMEOUT
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
#define DVBC_LOCK_TIMEOUT
const tDvbParameterMap SystemValuesSat[]
virtual void Append(T Data)
#define DVBT_LOCK_TIMEOUT
static uint32_t GetSubsystemId(int Adapter, int Frontend)
const tDvbParameterMap InversionValues[]
bool Parse(const char *s)
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
eDiseqcActions Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes, const cScr *Scr, uint *Frequency) const
Parses the DiSEqC commands and returns the appropriate action code with every call.
static int NumDevices(void)
Returns the total number of devices.
bool IsTunedTo(const cChannel *Channel) const
#define TUNER_POLL_TIMEOUT
void DelLivePids(void)
Deletes the live viewing PIDs.
int GetSignalStrength(void) const
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
cDvbTuner * GetBondedMaster(void)
cString ToString(char Type) const
bool Poll(int TimeoutMs=0)
int MapToDriver(int Value, const tDvbParameterMap *Map)
bool QueryDeliverySystems(int fd_frontend)
cPositioner * GetPositioner(void)
const char * Parameters(void) const
bool needsDetachBondedReceivers
static int NextCardIndex(int n=0)
Calculates the next card index.
bool SetTransponderData(int Source, int Frequency, int Srate, const char *Parameters, bool Quiet=false)
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
A steerable satellite dish generally points to the south on the northern hemisphere, and to the north on the southern hemisphere (unless you're located directly on the equator, in which case the general direction is "up").
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
cCamSlot * CamSlot(void) const
Returns the CAM slot that is currently used with this device, or NULL if no CAM slot is in use...
virtual bool MaySwitchTransponder(const cChannel *Channel) const
Returns true if it is ok to switch to the Channel's transponder on this device, without disturbing an...
cDvbDevice(int Adapter, int Frontend, cDevice *ParentDevice=NULL)
const tDvbParameterMap HierarchyValues[]
const char * Name(void) const
void StartSectionHandler(void)
A derived device that provides section data must call this function (typically in its constructor) to...
static bool BondDevices(const char *Bondings)
Bonds the devices as defined in the given Bondings string.
static bool Probe(int Adapter, int Frontend)
Probes for existing DVB devices.
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
uint32_t SubsystemId(void) const
void StopSectionHandler(void)
A device that has called StartSectionHandler() must call this function (typically in its destructor) ...
#define MAXDELIVERYSYSTEMS
virtual bool CanDecrypt(const cChannel *Channel)
Returns true if there is a CAM in this slot that is able to decrypt the given Channel (or at least cl...
virtual void SetData(cChannel *Channel)
Sets all source specific parameters to those of the given Channel.
cDvbDevice * bondedDevice
cDvbSourceParam(char Source, const char *Description)
int MapToUser(int Value, const tDvbParameterMap *Map, const char **String)
bool TimedOut(void) const
virtual bool IsMoving(void) const
Returns true if the dish is currently moving as a result of a call to GotoPosition() or GotoAngle()...
cList< cDvbDeviceProbe > DvbDeviceProbes
virtual cString DeviceName(void) const
Returns a string identifying the name of this device.
virtual void CloseDvr(void)
Shuts down the DVR.
#define DVBS_TUNE_TIMEOUT
virtual void CloseFilter(int Handle)
Closes a file handle that has previously been opened by OpenFilter().
static bool IsSat(int Code)
bool HasSubDevice(void) const
int DriverIndex(int Value, const tDvbParameterMap *Map)
#define ATSC_LOCK_TIMEOUT
bool OpenFrontend(void) const
const tDvbParameterMap ModulationValues[]
int deliverySystems[MAXDELIVERYSYSTEMS]
bool Locked(int TimeoutMs=0)
static cDvbCiAdapter * CreateCiAdapter(cDevice *Device, int Fd, int Adapter=-1, int Frontend=-1)
int Frequency(void) const
Returns the actual frequency, as given in 'channels.conf'.
void Skip(int Count)
If after a call to Get() more or less than TS_SIZE of the available data has been processed...
virtual bool OpenDvr(void)
Opens the DVR of this device and prepares it to deliver a Transport Stream for use in a cReceiver...
int GetSignalQuality(void) const
bool Bond(cDvbTuner *Tuner)
virtual void DetachAllReceivers(void)
Detaches all receivers from this device.
static void UnBondDevices(void)
Unbonds all devices.
const char * MapToUserString(int Value, const tDvbParameterMap *Map)
virtual const cChannel * GetCurrentlyTunedTransponder(void) const
Returns a pointer to the currently tuned transponder.
virtual bool HasCi(void)
Returns true if this device has a Common Interface.
int CardIndex(void) const
Returns the card index of this device (0 ... MAXDEVICES - 1).
const tDvbParameterMap PilotValues[]
int Priority(void) const
Returns the priority of the current receiving session (-MAXPRIORITY..MAXPRIORITY), or IDLEPRIORITY if no receiver is currently active.
virtual bool HasLock(int TimeoutMs=0) const
Returns true if the device has a lock on the requested transponder.
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
dvb_frontend_info frontendInfo
int FrontendType(void) const
virtual bool IsIdle(void) const
const cDiseqc * lastDiseqc
static int GetRequiredDeliverySystem(const cChannel *Channel, const cDvbTransponderParameters *Dtp)
void Del(cListObject *Object, bool DeleteObject=true)
cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend)
int FirstDeviceIndex(int DeviceIndex) const
Returns the first device index (starting at 0) that uses the same sat cable number as the device with...
virtual bool ProvidesDeliverySystem(int DeliverySystem) const
const tDvbParameterMap RollOffValues[]
static cDevice * PrimaryDevice(void)
Returns the primary device.
static int setTransferModeForDolbyDigital
const tDvbParameterMap CoderateValues[]
bool Bond(cDvbDevice *Device)
Bonds this device with the given Device, making both of them use the same satellite cable and LNB...
const cPositioner * Positioner(void) const
const cChannel * GetTransponder(void) const
virtual bool ProvidesTransponder(const cChannel *Channel) const
Returns true if this device can provide the transponder of the given Channel (which implies that it c...
const cDiseqc * Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const
Selects a DiSEqC entry suitable for the given Device and tuning parameters.
virtual bool ProvidesChannel(const cChannel *Channel, int Priority=IDLEPRIORITY, bool *NeedsDetachReceivers=NULL) const
Returns true if this device can provide the given channel.
void Sort(bool IgnoreCase=false)
bool BondingOk(const cChannel *Channel, bool ConsiderOccupied=false) const
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API...
virtual bool SetIdleDevice(bool Idle, bool TestOnly)
Called by SetIdle if TestOnly, don't do anything, just return, if the device can be set to the new id...
void SetChannel(const cChannel *Channel)
int Position(void)
Returns the orbital position of the satellite in case this is a DVB-S source (zero otherwise)...
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
bool GetFrontendStatus(fe_status_t &Status) const
#define DTV_DVBT2_PLP_ID_LEGACY
const tDvbParameterMap SystemValuesTerr[]
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
cDevice * SubDevice(void) const
const tDvbParameterMap BandwidthValues[]
bool BondingOk(const cChannel *Channel, bool ConsiderOccupied=false) const
Returns true if this device is either not bonded to any other device, or the given Channel is on the ...
Derived cDevice classes that can receive channels will have to provide Transport Stream (TS) packets ...
virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask)
Opens a file handle for the given filter data.
virtual int SignalStrength(void) const
Returns the "strength" of the currently received signal.
cString GetBondingParams(const cChannel *Channel=NULL) const
#define ATSC_TUNE_TIMEOUT
virtual bool MaySwitchTransponder(const cChannel *Channel) const
Returns true if it is ok to switch to the Channel's transponder on this device, without disturbing an...
cDvbTransponderParameters dtp
static cString DvbName(const char *Name, int Adapter, int Frontend)
The cDevice class is the base from which actual devices can be derived.
static int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError=false)
const cDvbDevice * device
const tDvbParameterMap GuardValues[]
virtual void GetData(cChannel *Channel)
Copies all source specific parameters to the given Channel.
const tDvbParameterMap TransmissionValues[]
static void SetTransferModeForDolbyDigital(int Mode)
virtual bool ProvidesEIT(void) const
Returns true if this device provides EIT data and thus wants to be tuned to the channels it can recei...