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);
209 return Value >= 0 && Value != 999 ? sprintf(p,
"%c%d", Name, Value) : 0;
214 #define ST(s) if (strchr(s, Type) && (strchr(s, '0' + system + 1) || strchr(s, '*')))
242 int n = strtol(s, &p, 10);
243 if (!errno && p != s) {
249 esyslog(
"ERROR: invalid value for parameter '%c'", *(s - 1));
263 guard = GUARD_INTERVAL_AUTO;
272 switch (toupper(*s)) {
292 default:
esyslog(
"ERROR: unknown parameter key '%c'", *s);
301 #define TUNER_POLL_TIMEOUT 10 // ms
341 virtual void Action(
void);
353 bool Locked(
int TimeoutMs = 0);
355 bool GetSignalStats(
int &Valid,
double *Strength = NULL,
double *Cnr = NULL,
double *BerPre = NULL,
double *BerPost = NULL,
double *Per = NULL,
int *Status = NULL)
const;
425 while (t->bondedTuner !=
this)
428 t->bondedTuner = NULL;
443 return diseqc->Commands();
447 bool VoltOff = dtp.Polarization() ==
'V' || dtp.Polarization() ==
'R';
459 if (t->device->Priority() >
IDLEPRIORITY || ConsiderOccupied && t->device->Occupied()) {
460 if (strcmp(BondingParams, t->GetBondedMaster()->GetBondingParams()) != 0)
506 if (BondedMaster ==
this) {
536 if (isLocked || !TimeoutMs)
549 dvb_frontend_event Event;
550 while (ioctl(
fd_frontend, FE_GET_EVENT, &Event) == 0)
559 if (ioctl(
fd_frontend, FE_READ_STATUS, &Status) != -1)
571 #define MAXFRONTENDCMDS 16
572 #define SETCMD(c, d) { Props[CmdSeq.num].cmd = (c);\
573 Props[CmdSeq.num].u.data = (d);\
574 if (CmdSeq.num++ > MAXFRONTENDCMDS) {\
575 esyslog("ERROR: too many tuning commands on frontend %d/%d", adapter, frontend);\
580 bool cDvbTuner::GetSignalStats(
int &Valid,
double *Strength,
double *Cnr,
double *BerPre,
double *BerPost,
double *Per,
int *Status)
const
583 fe_status_t FeStatus;
585 dtv_properties CmdSeq;
586 memset(&Props, 0,
sizeof(Props));
587 memset(&CmdSeq, 0,
sizeof(CmdSeq));
588 CmdSeq.props = Props;
590 if (ioctl(
fd_frontend, FE_READ_STATUS, &FeStatus) != 0) {
603 if (Strength)
SETCMD(DTV_STAT_SIGNAL_STRENGTH, 0);
604 if (Cnr)
SETCMD(DTV_STAT_CNR, 0);
605 if (BerPre) {
SETCMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0);
606 SETCMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0); }
607 if (BerPost) {
SETCMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0);
608 SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0); }
609 if (Per) {
SETCMD(DTV_STAT_ERROR_BLOCK_COUNT, 0);
610 SETCMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0); }
611 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
617 if (Props[i].u.st.len > 0) {
618 switch (Props[i].u.st.stat[0].scale) {
619 case FE_SCALE_DECIBEL: *Strength = double(Props[i].u.st.stat[0].svalue) / 1000;
628 if (Props[i].u.st.len > 0) {
629 switch (Props[i].u.st.stat[0].scale) {
630 case FE_SCALE_DECIBEL: *Cnr = double(Props[i].u.st.stat[0].svalue) / 1000;
639 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
640 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
641 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
642 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
644 *BerPre = double(ebc) / tbc;
652 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
653 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
654 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
655 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
657 *BerPost = double(ebc) / tbc;
665 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
666 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
667 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
668 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
670 *Per = double(ebc) / tbc;
677 #ifdef DEBUG_SIGNALSTATS
685 fprintf(stderr,
"\n");
701 double v = 10.0 * (dB1000 - High) / (Low - High);
705 #define REF_S1(q1) (mod == QPSK) ? q1 : 0
706 #define REF_S2(q1, q2, q3, q4) (mod == QPSK) ? q1 : (mod == PSK_8) ? q2 : (mod == APSK_16) ? q3 : (mod == APSK_32) ? q4 : 0
707 #define REF_T1(q1, q2, q3) (mod == QPSK) ? q1 : (mod == QAM_16) ? q2 : (mod == QAM_64) ? q3 : 0
708 #define REF_T2(q1, q2, q3, q4) (mod == QPSK) ? q1 : (mod == QAM_16) ? q2 : (mod == QAM_64) ? q3 : (mod == QAM_256) ? q4 : 0
709 #define REF_C1(q1, q2, q3, q4, q5) (mod == QAM_16) ? q1 : (mod == QAM_32) ? q2 : (mod == QAM_64) ? q3 : (mod == QAM_128) ? q4 : (mod == QAM_256) ? q5: 0
716 int mod = (FeModulation >= 0) ? FeModulation : dtp.
Modulation();
717 int cod = (FeCoderateH >= 0) ? FeCoderateH : dtp.CoderateH();
718 int fec = (FeFec >= 0) ? FeFec : dtp.CoderateH();
725 if (mod == QAM_AUTO) mod = QPSK;
727 case FEC_1_2: pref =
REF_T1(-93, -87, -82);
break;
729 case FEC_2_3: pref =
REF_T1(-91, -85, -80);
break;
730 case FEC_3_4: pref =
REF_T1(-90, -84, -78);
break;
731 case FEC_5_6: pref =
REF_T1(-89, -83, -77);
break;
732 case FEC_7_8: pref =
REF_T1(-88, -82, -76);
break;
736 if (mod == QAM_AUTO) mod = QAM_64;
738 case FEC_1_2: pref =
REF_T2(-96, -91, -86, -82);
break;
740 case FEC_3_5: pref =
REF_T2(-95, -89, -85, -80);
break;
741 case FEC_2_3: pref =
REF_T2(-94, -88, -83, -78);
break;
742 case FEC_3_4: pref =
REF_T2(-93, -87, -82, -76);
break;
743 case FEC_4_5: pref =
REF_T2(-92, -86, -81, -75);
break;
744 case FEC_5_6: pref =
REF_T2(-92, -86, -80, -74);
break;
748 int prel = (Strength / 1000) - pref;
749 ssi = (prel < -15) ? 0 :
750 (prel < 0) ? (prel + 15) * 2 / 3 :
751 (prel < 20) ? prel * 4 + 10 :
752 (prel < 35) ? (prel - 20) * 2 / 3 + 90 :
754 #ifdef DEBUG_SIGNALSTRENGTH
755 fprintf(stderr,
"SSI-T: STR:%d, Pref:%d, Prel:%d, ssi:%d%%(sys:%d, mod:%d, fec:%d)\n", Strength, pref, prel, ssi, dtp.System(), mod, fec);
764 if (mod == QAM_AUTO) mod = QAM_256;
766 int pref =
REF_C1(-79, -76, -73, -70, -67);
768 int prel = (Strength / 1000) - pref;
769 ssi = (prel < -15) ? 0 :
770 (prel < 0) ? (prel + 15) * 2 / 3 :
771 (prel < 20) ? prel * 4 + 10 :
772 (prel < 35) ? (prel - 20) * 2 / 3 + 90 :
774 #ifdef DEBUG_SIGNALSTRENGTH
775 fprintf(stderr,
"SSI-C: STR:%d, Pref:%d, Prel:%d, ssi:%d%%(mod:%d)\n", Strength, pref, prel, ssi, mod);
779 else if (Channel->
IsSat())
786 #define BER_ERROR_FREE (1000*1000*1000) // 1/10^-9
788 int SignalToSQI(
const cChannel *Channel,
int Signal,
int Ber,
int FeModulation,
int FeCoderateH,
int FeFec)
796 int mod = (FeModulation >= 0) ? FeModulation : dtp.
Modulation();
797 int cod = (FeCoderateH >= 0) ? FeCoderateH : dtp.CoderateH();
798 int fec = (FeFec >= 0) ? FeFec : dtp.CoderateH();
805 if (mod == QAM_AUTO) mod = QPSK;
807 case FEC_1_2: cnref =
REF_T1(51, 108, 165);
break;
809 case FEC_2_3: cnref =
REF_T1(69, 131, 187);
break;
810 case FEC_3_4: cnref =
REF_T1(79, 146, 202);
break;
811 case FEC_5_6: cnref =
REF_T1(89, 156, 216);
break;
812 case FEC_7_8: cnref =
REF_T1(97, 160, 225);
break;
816 if (mod == QAM_AUTO) mod = QAM_64;
818 case FEC_1_2: cnref =
REF_T2(35, 87, 130, 170);
break;
820 case FEC_3_5: cnref =
REF_T2(47, 101, 148, 194);
break;
821 case FEC_2_3: cnref =
REF_T2(56, 114, 162, 208);
break;
822 case FEC_3_4: cnref =
REF_T2(66, 125, 177, 229);
break;
823 case FEC_4_5: cnref =
REF_T2(72, 133, 187, 243);
break;
824 case FEC_5_6: cnref =
REF_T2(77, 138, 194, 251);
break;
828 int cnrel = (Signal/100) - cnref;
832 ber_sqi = (Ber < 1000) ? 0 :
833 (Ber >= 10000000) ? 100 :
834 (int)(20 * log10(Ber)) - 40;
836 cnr_sqi = (cnrel < -70) ? 0 :
837 (cnrel < +30) ? (100 + (cnrel - 30)) :
839 sqi = (cnr_sqi * ber_sqi) / 100;
844 ber_sqi = (Ber < 10000) ? 0 :
845 (Ber >= 10000000) ? 100 * 100 / 6 :
848 sqi = (cnrel < -30) ? 0 :
849 (cnrel <= +30) ? (cnrel + 30) * ber_sqi / 1000 :
854 #ifdef DEBUG_SIGNALQUALITY
855 fprintf(stderr,
"SQI-T: SIG:%d, BER:%d, CNref:%d, CNrel:%d, bersqi:%d, sqi:%d%%(sys:%d, mod:%d, fec:%d)\n", Signal, Ber, cnref, cnrel, ber_sqi, sqi, dtp.System(), mod, fec);
860 if (mod == QAM_AUTO) mod = QAM_256;
862 int cnref =
REF_C1(200, 230, 260, 290, 320);
864 int cnrel = (Signal / 100) - cnref;
865 int ber_sqi = (Ber < 1000) ? 0 :
866 (Ber >= 10000000) ? 100 :
867 (int)(20 * log10(Ber)) - 40;
869 int cnr_sqi = (cnrel < -70) ? 0 :
870 (cnrel < +30) ? (100 + (cnrel - 30)) :
872 sqi = (cnr_sqi * ber_sqi) / 100;
875 #ifdef DEBUG_SIGNALQUALITY
876 dsyslog(
"SQI-C: SIG:%d, BER:%d, CNref:%d, CNrel:%d, bersqi:%d, sqi:%d%%(sys:%d, mod:%d, fec:%d)\n", Signal, Ber, cnref, cnrel, ber_sqi, sqi, dtp.System(), mod, fec);
880 else if (Channel->
IsSat()) {
883 if (mod == QAM_AUTO) mod = QPSK;
885 case FEC_1_2: cnref =
REF_S1(38);
break;
887 case FEC_2_3: cnref =
REF_S1(56);
break;
888 case FEC_3_4: cnref =
REF_S1(67);
break;
889 case FEC_5_6: cnref =
REF_S1(77);
break;
890 case FEC_7_8: cnref =
REF_S1(84);
break;
896 #ifdef DEBUG_SIGNALQUALITY
897 dsyslog(
"SQI-S1: SIG:%d, BER:%d, CNref:%d, sqi:%d%%(mod:%d, fec:%d)\n", Signal, Ber, cnref, sqi, mod, fec);
902 if (mod == QAM_AUTO) mod = QAM_64;
906 case FEC_2_5: cnref =
REF_S2( 7, 65, 90, 126);
break;
907 case FEC_1_2: cnref =
REF_S2( 20, 65, 90, 126);
break;
908 case FEC_3_5: cnref =
REF_S2( 32, 65, 90, 126);
break;
910 case FEC_2_3: cnref =
REF_S2( 41, 76, 90, 126);
break;
911 case FEC_3_4: cnref =
REF_S2( 50, 66, 102, 126);
break;
912 case FEC_4_5: cnref =
REF_S2( 57, 89, 110, 136);
break;
913 case FEC_5_6: cnref =
REF_S2( 62, 104, 116, 143);
break;
914 case FEC_8_9: cnref =
REF_S2( 72, 117, 129, 157);
break;
915 case FEC_9_10: cnref =
REF_S2( 74, 120, 131, 161);
break;
921 #ifdef DEBUG_SIGNALQUALITY
922 dsyslog(
"SQI-S2: SIG:%d, BER:%d, CNref:%d, sqi:%d%%(mod:%d, fec:%d)\n", Signal, Ber, cnref, sqi, mod, fec);
934 for (
int i = 0; i < 1; i++) {
936 dtv_properties CmdSeq;
937 memset(&Props, 0,
sizeof(Props));
938 memset(&CmdSeq, 0,
sizeof(CmdSeq));
939 CmdSeq.props = Props;
940 SETCMD(DTV_STAT_SIGNAL_STRENGTH, 0);
941 SETCMD(DTV_MODULATION, 0);
942 SETCMD(DTV_CODE_RATE_HP, 0);
944 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
948 int FeMod = (Props[1].u.st.len > 0) ? (
int)Props[1].u.data : -1;
949 int FeCod = (Props[2].u.st.len > 0) ? (
int)Props[2].u.data : -1;
950 int FeFec = (Props[3].u.st.len > 0) ? (
int)Props[3].u.data : -1;
952 if (Props[0].u.st.len > 0) {
953 switch (Props[0].u.st.stat[0].scale) {
954 case FE_SCALE_DECIBEL: Signal =
StrengthToSSI(&
channel, Props[0].u.st.stat[0].svalue, FeMod, FeCod, FeFec);
956 case FE_SCALE_RELATIVE: Signal = 100 * Props[0].u.st.stat[0].uvalue / 0xFFFF;
960 #ifdef DEBUG_SIGNALSTRENGTH
961 fprintf(stderr,
"FE %d/%d: API5 %d %08X %.1f S = %d\n",
adapter,
frontend, Props[0].u.st.stat[0].scale,
int(Props[0].u.st.stat[0].svalue),
int(Props[0].u.st.stat[0].svalue) / 1000.0, Signal);
971 if (ioctl(
fd_frontend, FE_READ_SIGNAL_STRENGTH, &Signal) != -1)
976 uint16_t MaxSignal = 0xFFFF;
982 MaxSignal = 670;
break;
984 int s = int(Signal) * 100 / MaxSignal;
987 #ifdef DEBUG_SIGNALSTRENGTH
993 #define LOCK_THRESHOLD 5 // indicates that all 5 FE_HAS_* flags are set
998 for (
int i = 0; i < 1; i++) {
1000 dtv_properties CmdSeq;
1001 memset(&Props, 0,
sizeof(Props));
1002 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1003 CmdSeq.props = Props;
1005 SETCMD(DTV_MODULATION, 0);
1006 SETCMD(DTV_CODE_RATE_HP, 0);
1007 SETCMD(DTV_INNER_FEC, 0);
1008 SETCMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0);
1009 SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0);
1010 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
1014 int FeMod = (Props[1].u.st.len > 0) ? (
int)Props[1].u.data : -1;
1015 int FeCod = (Props[2].u.st.len > 0) ? (
int)Props[2].u.data : -1;
1016 int FeFec = (Props[3].u.st.len > 0) ? (
int)Props[3].u.data : -1;
1018 if (Props[4].u.st.len > 0 && Props[4].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[5].u.st.len > 0 && Props[5].u.st.stat[0].scale == FE_SCALE_COUNTER) {
1019 uint64_t ebc = Props[4].u.st.stat[0].uvalue;
1020 uint64_t tbc = Props[5].u.st.stat[0].uvalue;
1022 uint64_t BerRev = tbc / ebc;
1028 if (Props[0].u.st.len > 0) {
1029 switch (Props[0].u.st.stat[0].scale) {
1030 case FE_SCALE_DECIBEL: Cnr =
SignalToSQI(&
channel, Props[0].u.st.stat[0].svalue, Ber, FeMod, FeCod, FeFec);
1032 case FE_SCALE_RELATIVE: Cnr = 100 * Props[0].u.st.stat[0].uvalue / 0xFFFF;
1036 #ifdef DEBUG_SIGNALQUALITY
1037 fprintf(stderr,
"FE %d/%d: API5 %d %08X %.1f Q = %d\n",
adapter,
frontend, Props[0].u.st.stat[0].scale,
int(Props[0].u.st.stat[0].svalue),
int(Props[0].u.st.stat[0].svalue) / 1000.0, Cnr);
1048 if ((Status & FE_HAS_LOCK) == 0) {
1049 if ((Status & FE_HAS_SIGNAL) == 0)
1051 if ((Status & FE_HAS_CARRIER) == 0)
1053 if ((Status & FE_HAS_VITERBI) == 0)
1055 if ((Status & FE_HAS_SYNC) == 0)
1059 #ifdef DEBUG_SIGNALQUALITY
1066 if (errno != EINTR) {
1068 #ifdef DEBUG_SIGNALQUALITY
1074 #ifdef DEBUG_SIGNALQUALITY
1081 if (errno != EINTR) {
1083 #ifdef DEBUG_SIGNALQUALITY
1089 #ifdef DEBUG_SIGNALQUALITY
1094 if (ioctl(
fd_frontend, FE_READ_UNCORRECTED_BLOCKS, &Unc) != -1) {
1096 #ifdef DEBUG_SIGNALQUALITY
1117 Unc >>=
min(t,
int(
sizeof(Unc) * 8 - 1));
1120 #ifdef DEBUG_SIGNALQUALITY
1126 if (errno != EINTR) {
1128 #ifdef DEBUG_SIGNALQUALITY
1134 uint16_t MinSnr = 0x0000;
1135 uint16_t MaxSnr = 0xFFFF;
1150 MaxSnr = 255;
break;
1152 int a = int(
constrain(Snr, MinSnr, MaxSnr)) * 100 / (MaxSnr - MinSnr);
1153 int b = 100 - (Unc * 10 + (Ber / 256) * 5);
1159 #ifdef DEBUG_SIGNALQUALITY
1160 fprintf(stderr,
"FE %d/%d: API3 %08X Q = %04X %04X %d %5d %5d %3d%%\n",
adapter,
frontend,
subsystemId, MaxSnr, Snr, HasSnr, HasBer ?
int(Ber) : -1, HasUnc ?
int(Unc) : -1, q);
1169 while (f && f < 1000000)
1190 if (Diseqc->
IsScr())
1192 struct dvb_diseqc_master_cmd cmd;
1193 const char *CurrentAction = NULL;
1196 for (
int i = 0; !Break; i++) {
1197 cmd.msg_len =
sizeof(cmd.msg);
1228 default:
esyslog(
"ERROR: unknown diseqc command %d", da);
1236 if (Diseqc->
IsScr())
1248 int ds = SYS_UNDEFINED;
1252 ds = SYS_DVBC_ANNEX_AC;
1253 else if (Channel->
IsSat())
1255 else if (Channel->
IsTerr())
1258 esyslog(
"ERROR: can't determine frontend type for channel %d (%s)", Channel->
Number(), Channel->
Name());
1265 memset(&Props, 0,
sizeof(Props));
1266 dtv_properties CmdSeq;
1267 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1268 CmdSeq.props = Props;
1270 if (ioctl(
fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
1280 if (frontendType == SYS_UNDEFINED)
1283 SETCMD(DTV_DELIVERY_SYSTEM, frontendType);
1284 if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) {
1288 frequency -= diseqc->Lof();
1307 int tone = SEC_TONE_OFF;
1310 tone = SEC_TONE_OFF;
1316 int volt = (dtp.Polarization() ==
'V' || dtp.Polarization() ==
'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
1318 tone = SEC_TONE_OFF;
1319 volt = SEC_VOLTAGE_13;
1324 frequency = abs(frequency);
1327 SETCMD(DTV_FREQUENCY, frequency * 1000UL);
1328 SETCMD(DTV_MODULATION, dtp.Modulation());
1330 SETCMD(DTV_INNER_FEC, dtp.CoderateH());
1331 SETCMD(DTV_INVERSION, dtp.Inversion());
1332 if (frontendType == SYS_DVBS2) {
1334 SETCMD(DTV_PILOT, dtp.Pilot());
1335 SETCMD(DTV_ROLLOFF, dtp.RollOff());
1341 SETCMD(DTV_ROLLOFF, ROLLOFF_35);
1347 else if (frontendType == SYS_DVBC_ANNEX_AC || frontendType == SYS_DVBC_ANNEX_B) {
1350 SETCMD(DTV_INVERSION, dtp.Inversion());
1352 SETCMD(DTV_INNER_FEC, dtp.CoderateH());
1353 SETCMD(DTV_MODULATION, dtp.Modulation());
1358 else if (frontendType == SYS_DVBT || frontendType ==
SYS_DVBT2) {
1361 SETCMD(DTV_INVERSION, dtp.Inversion());
1362 SETCMD(DTV_BANDWIDTH_HZ, dtp.Bandwidth());
1363 SETCMD(DTV_CODE_RATE_HP, dtp.CoderateH());
1364 SETCMD(DTV_CODE_RATE_LP, dtp.CoderateL());
1365 SETCMD(DTV_MODULATION, dtp.Modulation());
1366 SETCMD(DTV_TRANSMISSION_MODE, dtp.Transmission());
1367 SETCMD(DTV_GUARD_INTERVAL, dtp.Guard());
1368 SETCMD(DTV_HIERARCHY, dtp.Hierarchy());
1371 SETCMD(DTV_INNER_FEC, dtp.CoderateH());
1381 else if (frontendType == SYS_ATSC) {
1384 SETCMD(DTV_INVERSION, dtp.Inversion());
1385 SETCMD(DTV_MODULATION, dtp.Modulation());
1391 esyslog(
"ERROR: attempt to set channel with unknown DVB frontend type");
1395 if (ioctl(
fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
1405 bool LostLock =
false;
1406 fe_status_t Status = (fe_status_t)0;
1408 fe_status_t NewStatus;
1412 int WaitTime = 1000;
1448 if (Status & FE_REINIT) {
1456 else if (Status & FE_HAS_LOCK) {
1518 #define ST(s) if (strchr(s, type))
1536 default:
return NULL;
1609 if (fd_frontend >= 0) {
1637 int fd = open(FileName, Mode);
1638 if (fd < 0 && ReportError)
1646 if (access(FileName, F_OK) == 0) {
1647 int f = open(FileName, O_RDONLY);
1652 else if (errno != ENODEV && errno != EINVAL)
1655 else if (errno != ENOENT)
1663 dsyslog(
"probing %s", *FileName);
1665 if (dp->Probe(Adapter, Frontend))
1668 dsyslog(
"creating cDvbDevice");
1699 while ((a = DvbDir.
Next()) != NULL) {
1703 if (AdapterDir.
Ok()) {
1705 while ((f = AdapterDir.
Next()) != NULL) {
1717 if (Nodes.
Size() > 0) {
1719 for (
int i = 0; i < Nodes.
Size(); i++) {
1722 if (2 == sscanf(Nodes[i],
"%d %d", &Adapter, &Frontend)) {
1723 if (
Exists(Adapter, Frontend)) {
1727 if (
Probe(Adapter, Frontend))
1738 isyslog(
"found %d DVB device%s", Found, Found > 1 ?
"s" :
"");
1740 isyslog(
"using only %d DVB device%s", Used, Used != 1 ?
"s" :
"");
1743 isyslog(
"no DVB device found");
1750 if (ioctl(fd_frontend, FE_GET_INFO, &
frontendInfo) < 0) {
1754 dtv_property Props[1];
1755 dtv_properties CmdSeq;
1758 memset(&Props, 0,
sizeof(Props));
1759 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1760 CmdSeq.props = Props;
1761 SETCMD(DTV_API_VERSION, 0);
1762 if (ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
1770 bool LegacyMode =
true;
1772 memset(&Props, 0,
sizeof(Props));
1773 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1774 CmdSeq.props = Props;
1776 int Result = ioctl(fd_frontend, FE_GET_PROPERTY, &CmdSeq);
1778 for (uint i = 0; i < Props[0].u.buffer.len; i++) {
1788 esyslog(
"ERROR: can't query delivery systems on frontend %d/%d - falling back to legacy mode",
adapter,
frontend);
1822 ms =
"unknown modulations";
1839 int ErrorDevice = 0;
1842 if (
cDvbDevice *DvbDevice1 = dynamic_cast<cDvbDevice *>(Device1)) {
1843 if (
cDvbDevice *DvbDevice2 = dynamic_cast<cDvbDevice *>(Device2)) {
1844 if (!DvbDevice1->Bond(DvbDevice2))
1848 ErrorDevice = d + 1;
1851 ErrorDevice = i + 1;
1853 esyslog(
"ERROR: device '%d' in device bondings '%s' is not a cDvbDevice", ErrorDevice, Bondings);
1858 ErrorDevice = d + 1;
1861 ErrorDevice = i + 1;
1863 esyslog(
"ERROR: unknown device '%d' in device bondings '%s'", ErrorDevice, Bondings);
1884 if (Device !=
this) {
1894 esyslog(
"ERROR: can't bond device %d with device %d (only DVB-S(2) devices can be bonded)",
CardIndex() + 1, Device->
CardIndex() + 1);
1911 while (d->bondedDevice !=
this)
1912 d = d->bondedDevice;
1914 d->bondedDevice = NULL;
1937 dmx_pes_filter_params pesFilterParams;
1938 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
1940 if (Handle->
handle < 0) {
1942 if (Handle->
handle < 0) {
1947 pesFilterParams.pid = Handle->
pid;
1948 pesFilterParams.input = DMX_IN_FRONTEND;
1949 pesFilterParams.output = DMX_OUT_TS_TAP;
1950 pesFilterParams.pes_type= DMX_PES_OTHER;
1951 pesFilterParams.flags = DMX_IMMEDIATE_START;
1952 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
1957 else if (!Handle->
used) {
1960 pesFilterParams.pid = 0x1FFF;
1961 pesFilterParams.input = DMX_IN_FRONTEND;
1962 pesFilterParams.output = DMX_OUT_DECODER;
1963 pesFilterParams.pes_type= DMX_PES_OTHER;
1964 pesFilterParams.flags = DMX_IMMEDIATE_START;
1965 CHECK(ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams));
1977 int f = open(FileName, O_RDWR | O_NONBLOCK);
1979 dmx_sct_filter_params sctFilterParams;
1980 memset(&sctFilterParams, 0,
sizeof(sctFilterParams));
1981 sctFilterParams.pid = Pid;
1982 sctFilterParams.timeout = 0;
1983 sctFilterParams.flags = DMX_IMMEDIATE_START;
1984 sctFilterParams.filter.filter[0] = Tid;
1985 sctFilterParams.filter.mask[0] = Mask;
1986 if (ioctl(f, DMX_SET_FILTER, &sctFilterParams) >= 0)
1989 esyslog(
"ERROR: can't set filter (pid=%d, tid=%02X, mask=%02X): %m", Pid, Tid, Mask);
1994 esyslog(
"ERROR: can't open filter handle on '%s'", *FileName);
2029 dtp.Modulation() == QPSK && !(
frontendInfo.caps & FE_CAN_QPSK) ||
2030 dtp.Modulation() == QAM_16 && !(
frontendInfo.caps & FE_CAN_QAM_16) ||
2031 dtp.Modulation() == QAM_32 && !(
frontendInfo.caps & FE_CAN_QAM_32) ||
2032 dtp.Modulation() == QAM_64 && !(
frontendInfo.caps & FE_CAN_QAM_64) ||
2033 dtp.Modulation() == QAM_128 && !(
frontendInfo.caps & FE_CAN_QAM_128) ||
2034 dtp.Modulation() == QAM_256 && !(
frontendInfo.caps & FE_CAN_QAM_256) ||
2035 dtp.Modulation() == QAM_AUTO && !(
frontendInfo.caps & FE_CAN_QAM_AUTO) ||
2036 dtp.Modulation() == VSB_8 && !(
frontendInfo.caps & FE_CAN_8VSB) ||
2037 dtp.Modulation() == VSB_16 && !(
frontendInfo.caps & FE_CAN_16VSB) ||
2048 bool result =
false;
2050 bool needsDetachReceivers =
false;
2054 result = hasPriority;
2063 needsDetachReceivers =
true;
2083 needsDetachReceivers |= d->Receiving();
2091 if (NeedsDetachReceivers)
2092 *NeedsDetachReceivers = needsDetachReceivers;
2111 bool cDvbDevice::SignalStats(
int &Valid,
double *Strength,
double *Cnr,
double *BerPre,
double *BerPost,
double *Per,
int *Status)
const
2181 if (cs->WantsTsData()) {
2186 Data = cs->Decrypt(Data, Available);
2203 d->cDevice::DetachAllReceivers();
2215 DvbDeviceProbes.
Add(
this);
2220 DvbDeviceProbes.
Del(
this,
false);
2225 uint32_t SubsystemId = 0;
2228 if (stat(FileName, &st) == 0) {
2232 while ((e = d.
Next()) != NULL) {
2233 if (strstr(e->d_name,
"frontend")) {
2235 if (FILE *f = fopen(FileName,
"r")) {
2237 char *s = ReadLine.
Read(f);
2241 if (s && 2 == sscanf(s,
"%u:%u", &Major, &Minor)) {
2242 if (((Major << 8) | Minor) == st.st_rdev) {
2243 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_vendor", e->d_name);
2244 if ((f = fopen(FileName,
"r")) != NULL) {
2245 if (
char *s = ReadLine.
Read(f))
2246 SubsystemId = strtoul(s, NULL, 0) << 16;
2250 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idVendor", e->d_name);
2251 if ((f = fopen(FileName,
"r")) != NULL) {
2252 if (
char *s = ReadLine.
Read(f))
2253 SubsystemId = strtoul(s, NULL, 16) << 16;
2257 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_device", e->d_name);
2258 if ((f = fopen(FileName,
"r")) != NULL) {
2259 if (
char *s = ReadLine.
Read(f))
2260 SubsystemId |= strtoul(s, NULL, 0);
2264 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idProduct", e->d_name);
2265 if ((f = fopen(FileName,
"r")) != NULL) {
2266 if (
char *s = ReadLine.
Read(f))
2267 SubsystemId |= strtoul(s, NULL, 16);
static unsigned int FrequencyToHz(unsigned int f)
struct dirent * Next(void)
#define DTV_STAT_VALID_PER
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)
bool GetSignalStats(int &Valid, double *Strength=NULL, double *Cnr=NULL, double *BerPre=NULL, double *BerPost=NULL, double *Per=NULL, int *Status=NULL) const
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
static bool Exists(int Adapter, int Frontend)
Checks whether the given adapter/frontend exists.
#define DTV_STAT_VALID_NONE
The cDevice class is the base from which actual devices can be derived.
bool IsScr(void) const
Returns true if this DiSEqC sequence uses Satellite Channel Routing.
void ResetToneAndVoltage(void)
#define SCR_RANDOM_TIMEOUT
#define DTV_STAT_HAS_VITERBI
int SignalToSQI(const cChannel *Channel, int Signal, int Ber, int FeModulation, int FeCoderateH, int FeFec)
bool Receiving(bool Dummy=false) const
Returns true if we are currently receiving. The parameter has no meaning (for backwards compatibility...
void ExecuteDiseqc(const cDiseqc *Diseqc, int *Frequency)
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.
void SetDescription(const char *Description,...) __attribute__((format(printf
#define REF_S2(q1, q2, q3, q4)
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.
#define DTV_STAT_HAS_SYNC
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...
static const int DeliverySystemNamesMax
#define DVBS_LOCK_TIMEOUT
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
static const char * GetDeliverySystemName(int Index)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
#define DVBC_LOCK_TIMEOUT
const tDvbParameterMap SystemValuesSat[]
virtual void Append(T Data)
void SetFrontend(int Frontend)
This function is called whenever the positioner is connected to a DVB frontend.
#define DVBT_LOCK_TIMEOUT
static uint32_t GetSubsystemId(int Adapter, int Frontend)
const tDvbParameterMap InversionValues[]
#define REF_C1(q1, q2, q3, q4, q5)
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).
static int NumDevices(void)
Returns the total number of devices.
#define DTV_STAT_HAS_CARRIER
bool IsTunedTo(const cChannel *Channel) const
#define TUNER_POLL_TIMEOUT
void DelLivePids(void)
Deletes the live viewing PIDs.
int GetSignalStrength(void) const
#define DTV_STAT_VALID_BERPOST
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)
#define REF_T2(q1, q2, q3, q4)
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.
bool IsPrimaryDevice(void) const
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...
int Modulation(void) const
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...
int StrengthToSSI(const cChannel *Channel, int Strength, int FeModulation, int FeCoderateH, int FeFec)
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.
#define DTV_STAT_VALID_STATUS
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 SignalStats(int &Valid, double *Strength=NULL, double *Cnr=NULL, double *BerPre=NULL, double *BerPost=NULL, double *Per=NULL, int *Status=NULL) const
Returns statistics about the currently received signal (if available).
virtual void SetData(cChannel *Channel)
Sets all source specific parameters to those of the given Channel.
cDvbDevice * bondedDevice
eDiseqcActions Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes, const cScr *Scr, int *Frequency) const
Parses the DiSEqC commands and returns the appropriate action code with every call.
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()...
static cDvbCiAdapter * CreateCiAdapter(cDevice *Device, int Fd)
#define DTV_STAT_HAS_LOCK
cList< cDvbDeviceProbe > DvbDeviceProbes
virtual cString DeviceName(void) const
Returns a string identifying the name of this device.
int dB1000toPercent(int dB1000, int Low, int High)
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
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)
int DriverIndex(int Value, const tDvbParameterMap *Map)
#define ATSC_LOCK_TIMEOUT
#define REF_T1(q1, q2, q3)
const tDvbParameterMap ModulationValues[]
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
#define DTV_STAT_VALID_STRENGTH
int deliverySystems[MAXDELIVERYSYSTEMS]
bool TimedWait(cMutex &Mutex, int TimeoutMs)
bool Locked(int TimeoutMs=0)
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)
static bool useDvbDevices
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
const cDiseqc * lastDiseqc
uchar * Get(int *Available=NULL, bool CheckAvailable=false)
Returns a pointer to the first TS packet in the buffer.
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
#define DTV_STAT_HAS_SIGNAL
const cChannel * GetTransponder(void) const
#define DTV_STAT_VALID_BERPRE
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 CanDecrypt(const cChannel *Channel, cMtdMapper *MtdMapper=NULL)
Returns true if there is a CAM in this slot that is able to decrypt the given Channel (or at least cl...
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...
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_STAT_HAS_NONE
#define DTV_DVBT2_PLP_ID_LEGACY
const tDvbParameterMap SystemValuesTerr[]
#define DTV_STAT_VALID_CNR
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
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.
cDvbDevice(int Adapter, int Frontend)
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
virtual int SignalStrength(void) const
Returns the "strength" of the currently received signal.
cString GetBondingParams(const cChannel *Channel=NULL) const
bool SetFrontendType(const cChannel *Channel)
#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)
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...