14#include <linux/dvb/dmx.h>
15#include <linux/dvb/frontend.h>
26#define DVBS_TUNE_TIMEOUT 9000
27#define DVBS_LOCK_TIMEOUT 2000
28#define DVBC_TUNE_TIMEOUT 9000
29#define DVBC_LOCK_TIMEOUT 2000
30#define DVBT_TUNE_TIMEOUT 9000
31#define DVBT_LOCK_TIMEOUT 2000
32#define ATSC_TUNE_TIMEOUT 9000
33#define ATSC_LOCK_TIMEOUT 2000
35#define SCR_RANDOM_TIMEOUT 500
37#define TSBUFFERSIZE MEGABYTE(16)
42 { 0, PILOT_OFF,
trNOOP(
"off") },
43 { 1, PILOT_ON,
trNOOP(
"on") },
44 { 999, PILOT_AUTO,
trNOOP(
"auto") },
49 { 0, INVERSION_OFF,
trNOOP(
"off") },
50 { 1, INVERSION_ON,
trNOOP(
"on") },
51 { 999, INVERSION_AUTO,
trNOOP(
"auto") },
56 { 5, 5000000,
"5 MHz" },
57 { 6, 6000000,
"6 MHz" },
58 { 7, 7000000,
"7 MHz" },
59 { 8, 8000000,
"8 MHz" },
60 { 10, 10000000,
"10 MHz" },
61 { 1712, 1712000,
"1.712 MHz" },
66 { 0, FEC_NONE,
trNOOP(
"none") },
67 { 12, FEC_1_2,
"1/2" },
68 { 23, FEC_2_3,
"2/3" },
69 { 34, FEC_3_4,
"3/4" },
70 { 35, FEC_3_5,
"3/5" },
71 { 45, FEC_4_5,
"4/5" },
72 { 56, FEC_5_6,
"5/6" },
73 { 67, FEC_6_7,
"6/7" },
74 { 78, FEC_7_8,
"7/8" },
75 { 89, FEC_8_9,
"8/9" },
76 { 910, FEC_9_10,
"9/10" },
77 { 999, FEC_AUTO,
trNOOP(
"auto") },
82 { 16, QAM_16,
"QAM16" },
83 { 32, QAM_32,
"QAM32" },
84 { 64, QAM_64,
"QAM64" },
85 { 128, QAM_128,
"QAM128" },
86 { 256, QAM_256,
"QAM256" },
89 { 6, APSK_16,
"16APSK" },
90 { 7, APSK_32,
"32APSK" },
91 { 10, VSB_8,
"VSB8" },
92 { 11, VSB_16,
"VSB16" },
93 { 12, DQPSK,
"DQPSK" },
94 { 999, QAM_AUTO,
trNOOP(
"auto") },
115 { 2, TRANSMISSION_MODE_2K,
"2K" },
117 { 8, TRANSMISSION_MODE_8K,
"8K" },
120 { 999, TRANSMISSION_MODE_AUTO,
trNOOP(
"auto") },
125 { 4, GUARD_INTERVAL_1_4,
"1/4" },
126 { 8, GUARD_INTERVAL_1_8,
"1/8" },
127 { 16, GUARD_INTERVAL_1_16,
"1/16" },
128 { 32, GUARD_INTERVAL_1_32,
"1/32" },
132 { 999, GUARD_INTERVAL_AUTO,
trNOOP(
"auto") },
137 { 0, HIERARCHY_NONE,
trNOOP(
"none") },
138 { 1, HIERARCHY_1,
"1" },
139 { 2, HIERARCHY_2,
"2" },
140 { 4, HIERARCHY_4,
"4" },
141 { 999, HIERARCHY_AUTO,
trNOOP(
"auto") },
146 { 0, ROLLOFF_AUTO,
trNOOP(
"auto") },
147 { 20, ROLLOFF_20,
"0.20" },
148 { 25, ROLLOFF_25,
"0.25" },
149 { 35, ROLLOFF_35,
"0.35" },
180 *String =
tr(Map[n].userString);
211 return Value >= 0 && Value != 999 ? sprintf(p,
"%c%d", Name, Value) : 0;
216#define ST(s) if (strchr(s, Type) && (strchr(s, '0' + system + 1) || strchr(s, '*')))
243 int n = strtol(s, &p, 10);
244 if (!errno && p != s) {
250 esyslog(
"ERROR: invalid value for parameter '%c'", *(s - 1));
264 guard = GUARD_INTERVAL_AUTO;
272 switch (toupper(*s)) {
291 default:
esyslog(
"ERROR: unknown parameter key '%c'", *s);
333#define MAXFRONTENDCMDS 16
334#define SETCMD(c, d) { Props[CmdSeq.num].cmd = (c);\
335 Props[CmdSeq.num].u.data = (d);\
336 if (CmdSeq.num++ > MAXFRONTENDCMDS) {\
337 esyslog("ERROR: too many tuning commands on frontend %d/%d", adapter, frontend);\
412 if (Modulation == QPSK && !(
frontendInfo.caps & FE_CAN_QPSK) ||
413 Modulation == QAM_16 && !(
frontendInfo.caps & FE_CAN_QAM_16) ||
414 Modulation == QAM_32 && !(
frontendInfo.caps & FE_CAN_QAM_32) ||
415 Modulation == QAM_64 && !(
frontendInfo.caps & FE_CAN_QAM_64) ||
416 Modulation == QAM_128 && !(
frontendInfo.caps & FE_CAN_QAM_128) ||
417 Modulation == QAM_256 && !(
frontendInfo.caps & FE_CAN_QAM_256) ||
418 Modulation == QAM_AUTO && !(
frontendInfo.caps & FE_CAN_QAM_AUTO) ||
419 Modulation == VSB_8 && !(
frontendInfo.caps & FE_CAN_8VSB) ||
420 Modulation == VSB_16 && !(
frontendInfo.caps & FE_CAN_16VSB) ||
434 dtv_property Props[1];
435 dtv_properties CmdSeq;
438 memset(&Props, 0,
sizeof(Props));
439 memset(&CmdSeq, 0,
sizeof(CmdSeq));
440 CmdSeq.props = Props;
441 SETCMD(DTV_API_VERSION, 0);
442 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
450 bool LegacyMode =
true;
452 memset(&Props, 0,
sizeof(Props));
453 memset(&CmdSeq, 0,
sizeof(CmdSeq));
454 CmdSeq.props = Props;
456 int Result = ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq);
458 for (uint i = 0; i < Props[0].u.buffer.len; i++) {
466 esyslog(
"ERROR: can't query delivery systems on frontend %d/%d - falling back to legacy mode",
adapter,
frontend);
500 ms =
"unknown modulations";
511#define TUNER_POLL_TIMEOUT 10
515 int ds = SYS_UNDEFINED;
519 ds = SYS_DVBC_ANNEX_AC;
520 else if (Channel->
IsSat())
522 else if (Channel->
IsTerr())
525 esyslog(
"ERROR: can't determine frontend type for channel %d (%s)", Channel->
Number(), Channel->
Name());
570 virtual void Action(
void);
588 bool Locked(
int TimeoutMs = 0);
590 bool GetSignalStats(
int &Valid,
double *Strength = NULL,
double *Cnr = NULL,
double *BerPre = NULL,
double *BerPost = NULL,
double *Per = NULL,
int *Status = NULL)
const;
627 for (
int i = 1; ; i++) {
727 while (t->bondedTuner !=
this)
730 t->bondedTuner = NULL;
745 return diseqc->Commands();
761 if (t->device->Priority() >
IDLEPRIORITY || ConsiderOccupied && t->device->Occupied()) {
762 if (strcmp(BondingParams, t->GetBondedMaster()->GetBondingParams()) != 0)
808 if (BondedMaster ==
this) {
838 if (isLocked || !TimeoutMs)
851 dvb_frontend_event Event;
852 while (ioctl(
fd_frontend, FE_GET_EVENT, &Event) == 0)
860 Status = (fe_status_t)0;
862 if (ioctl(
fd_frontend, FE_READ_STATUS, &Status) != -1)
874bool cDvbTuner::GetSignalStats(
int &Valid,
double *Strength,
double *Cnr,
double *BerPre,
double *BerPost,
double *Per,
int *Status)
const
877 fe_status_t FeStatus = (fe_status_t)0;
879 dtv_properties CmdSeq;
880 memset(&Props, 0,
sizeof(Props));
881 memset(&CmdSeq, 0,
sizeof(CmdSeq));
882 CmdSeq.props = Props;
884 if (ioctl(
fd_frontend, FE_READ_STATUS, &FeStatus) != 0) {
897 if (Strength)
SETCMD(DTV_STAT_SIGNAL_STRENGTH, 0);
898 if (Cnr)
SETCMD(DTV_STAT_CNR, 0);
899 if (BerPre) {
SETCMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0);
900 SETCMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0); }
901 if (BerPost) {
SETCMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0);
902 SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0); }
903 if (Per) {
SETCMD(DTV_STAT_ERROR_BLOCK_COUNT, 0);
904 SETCMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0); }
905 if (CmdSeq.num && ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
911 if (Props[i].u.st.len > 0) {
912 switch (Props[i].u.st.stat[0].scale) {
913 case FE_SCALE_DECIBEL: *Strength = double(Props[i].u.st.stat[0].svalue) / 1000;
922 if (Props[i].u.st.len > 0) {
923 switch (Props[i].u.st.stat[0].scale) {
924 case FE_SCALE_DECIBEL: *Cnr = double(Props[i].u.st.stat[0].svalue) / 1000;
933 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
934 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
935 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
936 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
938 *BerPre = double(ebc) / tbc;
946 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
947 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
948 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
949 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
951 *BerPost = double(ebc) / tbc;
959 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
960 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
961 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
962 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
964 *Per = double(ebc) / tbc;
971#ifdef DEBUG_SIGNALSTATS
979 fprintf(stderr,
"\n");
995 double v = 10.0 * (dB1000 - High) / (Low - High);
999#define REF_S1(q1) (mod == QPSK) ? q1 : 0
1000#define REF_S2(q1, q2, q3, q4) (mod == QPSK) ? q1 : (mod == PSK_8) ? q2 : (mod == APSK_16) ? q3 : (mod == APSK_32) ? q4 : 0
1001#define REF_T1(q1, q2, q3) (mod == QPSK) ? q1 : (mod == QAM_16) ? q2 : (mod == QAM_64) ? q3 : 0
1002#define REF_T2(q1, q2, q3, q4) (mod == QPSK) ? q1 : (mod == QAM_16) ? q2 : (mod == QAM_64) ? q3 : (mod == QAM_256) ? q4 : 0
1003#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
1010 int mod = (FeModulation >= 0) ? FeModulation : dtp.
Modulation();
1011 int cod = (FeCoderateH >= 0) ? FeCoderateH : dtp.
CoderateH();
1012 int fec = (FeFec >= 0) ? FeFec : dtp.
CoderateH();
1019 if (mod == QAM_AUTO) mod = QPSK;
1021 case FEC_1_2: pref =
REF_T1(-93, -87, -82);
break;
1023 case FEC_2_3: pref =
REF_T1(-91, -85, -80);
break;
1024 case FEC_3_4: pref =
REF_T1(-90, -84, -78);
break;
1025 case FEC_5_6: pref =
REF_T1(-89, -83, -77);
break;
1026 case FEC_7_8: pref =
REF_T1(-88, -82, -76);
break;
1030 if (mod == QAM_AUTO) mod = QAM_64;
1032 case FEC_1_2: pref =
REF_T2(-96, -91, -86, -82);
break;
1034 case FEC_3_5: pref =
REF_T2(-95, -89, -85, -80);
break;
1035 case FEC_2_3: pref =
REF_T2(-94, -88, -83, -78);
break;
1036 case FEC_3_4: pref =
REF_T2(-93, -87, -82, -76);
break;
1037 case FEC_4_5: pref =
REF_T2(-92, -86, -81, -75);
break;
1038 case FEC_5_6: pref =
REF_T2(-92, -86, -80, -74);
break;
1042 int prel = (Strength / 1000) - pref;
1043 ssi = (prel < -15) ? 0 :
1044 (prel < 0) ? (prel + 15) * 2 / 3 :
1045 (prel < 20) ? prel * 4 + 10 :
1046 (prel < 35) ? (prel - 20) * 2 / 3 + 90 :
1048#ifdef DEBUG_SIGNALSTRENGTH
1049 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);
1053 else if (Channel->
IsCable()) {
1058 if (mod == QAM_AUTO) mod = QAM_256;
1060 int pref =
REF_C1(-79, -76, -73, -70, -67);
1062 int prel = (Strength / 1000) - pref;
1063 ssi = (prel < -15) ? 0 :
1064 (prel < 0) ? (prel + 15) * 2 / 3 :
1065 (prel < 20) ? prel * 4 + 10 :
1066 (prel < 35) ? (prel - 20) * 2 / 3 + 90 :
1068#ifdef DEBUG_SIGNALSTRENGTH
1069 fprintf(stderr,
"SSI-C: STR:%d, Pref:%d, Prel:%d, ssi:%d%%(mod:%d)\n", Strength, pref, prel, ssi, mod);
1073 else if (Channel->
IsSat())
1080#define BER_ERROR_FREE (1000*1000*1000)
1090 int mod = (FeModulation >= 0) ? FeModulation : dtp.
Modulation();
1091 int cod = (FeCoderateH >= 0) ? FeCoderateH : dtp.
CoderateH();
1092 int fec = (FeFec >= 0) ? FeFec : dtp.
CoderateH();
1099 if (mod == QAM_AUTO) mod = QPSK;
1101 case FEC_1_2: cnref =
REF_T1(51, 108, 165);
break;
1103 case FEC_2_3: cnref =
REF_T1(69, 131, 187);
break;
1104 case FEC_3_4: cnref =
REF_T1(79, 146, 202);
break;
1105 case FEC_5_6: cnref =
REF_T1(89, 156, 216);
break;
1106 case FEC_7_8: cnref =
REF_T1(97, 160, 225);
break;
1110 if (mod == QAM_AUTO) mod = QAM_64;
1112 case FEC_1_2: cnref =
REF_T2(35, 87, 130, 170);
break;
1114 case FEC_3_5: cnref =
REF_T2(47, 101, 148, 194);
break;
1115 case FEC_2_3: cnref =
REF_T2(56, 114, 162, 208);
break;
1116 case FEC_3_4: cnref =
REF_T2(66, 125, 177, 229);
break;
1117 case FEC_4_5: cnref =
REF_T2(72, 133, 187, 243);
break;
1118 case FEC_5_6: cnref =
REF_T2(77, 138, 194, 251);
break;
1122 int cnrel = (Signal/100) - cnref;
1126 ber_sqi = (Ber < 1000) ? 0 :
1127 (Ber >= 10000000) ? 100 :
1128 (int)(20 * log10(Ber)) - 40;
1130 cnr_sqi = (cnrel < -70) ? 0 :
1131 (cnrel < +30) ? (100 + (cnrel - 30)) :
1133 sqi = (cnr_sqi * ber_sqi) / 100;
1138 ber_sqi = (Ber < 10000) ? 0 :
1139 (Ber >= 10000000) ? 100 * 100 / 6 :
1142 sqi = (cnrel < -30) ? 0 :
1143 (cnrel <= +30) ? (cnrel + 30) * ber_sqi / 1000 :
1148#ifdef DEBUG_SIGNALQUALITY
1149 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);
1153 else if (Channel->
IsCable()) {
1154 if (mod == QAM_AUTO) mod = QAM_256;
1156 int cnref =
REF_C1(200, 230, 260, 290, 320);
1158 int cnrel = (Signal / 100) - cnref;
1159 int ber_sqi = (Ber < 1000) ? 0 :
1160 (Ber >= 10000000) ? 100 :
1161 (int)(20 * log10(Ber)) - 40;
1163 int cnr_sqi = (cnrel < -70) ? 0 :
1164 (cnrel < +30) ? (100 + (cnrel - 30)) :
1166 sqi = (cnr_sqi * ber_sqi) / 100;
1169#ifdef DEBUG_SIGNALQUALITY
1170 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);
1174 else if (Channel->
IsSat()) {
1177 if (mod == QAM_AUTO) mod = QPSK;
1179 case FEC_1_2: cnref =
REF_S1(38);
break;
1181 case FEC_2_3: cnref =
REF_S1(56);
break;
1182 case FEC_3_4: cnref =
REF_S1(67);
break;
1183 case FEC_5_6: cnref =
REF_S1(77);
break;
1184 case FEC_7_8: cnref =
REF_S1(84);
break;
1190#ifdef DEBUG_SIGNALQUALITY
1191 dsyslog(
"SQI-S1: SIG:%d, BER:%d, CNref:%d, sqi:%d%%(mod:%d, fec:%d)\n", Signal, Ber, cnref, sqi, mod, fec);
1196 if (mod == QAM_AUTO) mod = QAM_64;
1200 case FEC_2_5: cnref =
REF_S2( 7, 65, 90, 126);
break;
1201 case FEC_1_2: cnref =
REF_S2( 20, 65, 90, 126);
break;
1202 case FEC_3_5: cnref =
REF_S2( 32, 65, 90, 126);
break;
1204 case FEC_2_3: cnref =
REF_S2( 41, 76, 90, 126);
break;
1205 case FEC_3_4: cnref =
REF_S2( 50, 66, 102, 126);
break;
1206 case FEC_4_5: cnref =
REF_S2( 57, 89, 110, 136);
break;
1207 case FEC_5_6: cnref =
REF_S2( 62, 104, 116, 143);
break;
1208 case FEC_8_9: cnref =
REF_S2( 72, 117, 129, 157);
break;
1209 case FEC_9_10: cnref =
REF_S2( 74, 120, 131, 161);
break;
1215#ifdef DEBUG_SIGNALQUALITY
1216 dsyslog(
"SQI-S2: SIG:%d, BER:%d, CNref:%d, sqi:%d%%(mod:%d, fec:%d)\n", Signal, Ber, cnref, sqi, mod, fec);
1228 for (
int i = 0; i < 1; i++) {
1230 dtv_properties CmdSeq;
1231 memset(&Props, 0,
sizeof(Props));
1232 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1233 CmdSeq.props = Props;
1234 SETCMD(DTV_STAT_SIGNAL_STRENGTH, 0);
1235 SETCMD(DTV_MODULATION, 0);
1236 SETCMD(DTV_CODE_RATE_HP, 0);
1237 SETCMD(DTV_INNER_FEC, 0);
1238 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
1242 int FeMod = (Props[1].u.st.len > 0) ? (
int)Props[1].u.data : -1;
1243 int FeCod = (Props[2].u.st.len > 0) ? (
int)Props[2].u.data : -1;
1244 int FeFec = (Props[3].u.st.len > 0) ? (
int)Props[3].u.data : -1;
1246 if (Props[0].u.st.len > 0) {
1247 switch (Props[0].u.st.stat[0].scale) {
1248 case FE_SCALE_DECIBEL: Signal =
StrengthToSSI(&
channel, Props[0].u.st.stat[0].svalue, FeMod, FeCod, FeFec);
1250 case FE_SCALE_RELATIVE: Signal = 100 * Props[0].u.st.stat[0].uvalue / 0xFFFF;
1254#ifdef DEBUG_SIGNALSTRENGTH
1255 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);
1265 if (ioctl(
fd_frontend, FE_READ_SIGNAL_STRENGTH, &Signal) != -1)
1270 uint16_t MaxSignal = 0xFFFF;
1276 MaxSignal = 670;
break;
1278 int s = int(Signal) * 100 / MaxSignal;
1281#ifdef DEBUG_SIGNALSTRENGTH
1287#define LOCK_THRESHOLD 5
1292 for (
int i = 0; i < 1; i++) {
1294 dtv_properties CmdSeq;
1295 memset(&Props, 0,
sizeof(Props));
1296 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1297 CmdSeq.props = Props;
1299 SETCMD(DTV_MODULATION, 0);
1300 SETCMD(DTV_CODE_RATE_HP, 0);
1301 SETCMD(DTV_INNER_FEC, 0);
1302 SETCMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0);
1303 SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0);
1304 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
1308 int FeMod = (Props[1].u.st.len > 0) ? (
int)Props[1].u.data : -1;
1309 int FeCod = (Props[2].u.st.len > 0) ? (
int)Props[2].u.data : -1;
1310 int FeFec = (Props[3].u.st.len > 0) ? (
int)Props[3].u.data : -1;
1312 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) {
1313 uint64_t ebc = Props[4].u.st.stat[0].uvalue;
1314 uint64_t tbc = Props[5].u.st.stat[0].uvalue;
1316 uint64_t BerRev = tbc / ebc;
1322 if (Props[0].u.st.len > 0) {
1323 switch (Props[0].u.st.stat[0].scale) {
1324 case FE_SCALE_DECIBEL: Cnr =
SignalToSQI(&
channel, Props[0].u.st.stat[0].svalue, Ber, FeMod, FeCod, FeFec);
1326 case FE_SCALE_RELATIVE: Cnr = 100 * Props[0].u.st.stat[0].uvalue / 0xFFFF;
1330#ifdef DEBUG_SIGNALQUALITY
1331 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);
1342 if ((Status & FE_HAS_LOCK) == 0) {
1343 if ((Status & FE_HAS_SIGNAL) == 0)
1345 if ((Status & FE_HAS_CARRIER) == 0)
1347 if ((Status & FE_HAS_VITERBI) == 0)
1349 if ((Status & FE_HAS_SYNC) == 0)
1353#ifdef DEBUG_SIGNALQUALITY
1360 if (errno != EINTR) {
1362#ifdef DEBUG_SIGNALQUALITY
1368#ifdef DEBUG_SIGNALQUALITY
1375 if (errno != EINTR) {
1377#ifdef DEBUG_SIGNALQUALITY
1383#ifdef DEBUG_SIGNALQUALITY
1388 if (ioctl(
fd_frontend, FE_READ_UNCORRECTED_BLOCKS, &Unc) != -1) {
1390#ifdef DEBUG_SIGNALQUALITY
1411 Unc >>=
min(t,
int(
sizeof(Unc) * 8 - 1));
1414#ifdef DEBUG_SIGNALQUALITY
1420 if (errno != EINTR) {
1422#ifdef DEBUG_SIGNALQUALITY
1428 uint16_t MinSnr = 0x0000;
1429 uint16_t MaxSnr = 0xFFFF;
1444 MaxSnr = 255;
break;
1446 int a = int(
constrain(Snr, MinSnr, MaxSnr)) * 100 / (MaxSnr - MinSnr);
1447 int b = 100 - (Unc * 10 + (Ber / 256) * 5);
1453#ifdef DEBUG_SIGNALQUALITY
1454 fprintf(stderr,
"FE %d/%d: API3 %08X Q = %04X %04X %d %5d %5d %3d%%\n",
adapter,
frontend,
dvbFrontend->
SubsystemId(), MaxSnr, Snr, HasSnr, HasBer ?
int(Ber) : -1, HasUnc ?
int(Unc) : -1, q);
1463 while (f && f < 1000000)
1484 if (Diseqc->
IsScr())
1486 struct dvb_diseqc_master_cmd cmd;
1487 const char *CurrentAction = NULL;
1490 for (
int i = 0; !Break; i++) {
1491 cmd.msg_len =
sizeof(cmd.msg);
1522 default:
esyslog(
"ERROR: unknown diseqc command %d", da);
1530 if (Diseqc->
IsScr())
1543 memset(&Props, 0,
sizeof(Props));
1544 dtv_properties CmdSeq;
1545 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1546 CmdSeq.props = Props;
1548 if (ioctl(
fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
1566 frequency -= diseqc->Lof();
1585 int tone = SEC_TONE_OFF;
1588 tone = SEC_TONE_OFF;
1596 tone = SEC_TONE_OFF;
1597 volt = SEC_VOLTAGE_13;
1602 frequency = abs(frequency);
1605 SETCMD(DTV_FREQUENCY, frequency * 1000UL);
1619 SETCMD(DTV_ROLLOFF, ROLLOFF_35);
1669 esyslog(
"ERROR: attempt to set channel with unknown DVB frontend type");
1673 if (ioctl(
fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
1683 bool LostLock =
false;
1684 fe_status_t Status = (fe_status_t)0;
1686 int WaitTime = 1000;
1687 fe_status_t NewStatus;
1728 if (Status & FE_REINIT) {
1736 else if (Status & FE_HAS_LOCK) {
1806#define ST(s) if (strchr(s, type))
1824 default:
return NULL;
1878int DvbOpen(
const char *Name,
int Adapter,
int Frontend,
int Mode,
bool ReportError)
1881 int fd = open(FileName, Mode);
1882 if (fd < 0 && ReportError)
1895 if (access(FileName, F_OK) == 0) {
1896 int f = open(FileName, O_RDONLY);
1901 else if (errno != ENODEV && errno != EINVAL)
1904 else if (errno != ENOENT)
1912 dsyslog(
"probing %s", *FileName);
1917 dsyslog(
"creating cDvbDevice");
1946 while ((a = DvbDir.
Next()) != NULL) {
1950 if (AdapterDir.
Ok()) {
1952 while ((f = AdapterDir.
Next()) != NULL) {
1967 if (Nodes.
Size() > 0) {
1969 for (
int i = 0; i < Nodes.
Size(); i++) {
1990 isyslog(
"found %d DVB device%s", Found, Found > 1 ?
"s" :
"");
1992 isyslog(
"using only %d DVB device%s", Used, Used != 1 ?
"s" :
"");
1995 isyslog(
"no DVB device found");
2007 int ErrorDevice = 0;
2012 if (!DvbDevice1->Bond(DvbDevice2))
2016 ErrorDevice = d + 1;
2019 ErrorDevice = i + 1;
2021 esyslog(
"ERROR: device '%d' in device bondings '%s' is not a cDvbDevice", ErrorDevice, Bondings);
2026 ErrorDevice = d + 1;
2029 ErrorDevice = i + 1;
2031 esyslog(
"ERROR: unknown device '%d' in device bondings '%s'", ErrorDevice, Bondings);
2052 if (Device !=
this) {
2079 while (d->bondedDevice !=
this)
2080 d = d->bondedDevice;
2082 d->bondedDevice = NULL;
2105 dmx_pes_filter_params pesFilterParams;
2106 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
2108 if (Handle->
handle < 0) {
2110 if (Handle->
handle < 0) {
2115 pesFilterParams.pid = Handle->
pid;
2116 pesFilterParams.input = DMX_IN_FRONTEND;
2117 pesFilterParams.output = DMX_OUT_TS_TAP;
2118 pesFilterParams.pes_type= DMX_PES_OTHER;
2119 pesFilterParams.flags = DMX_IMMEDIATE_START;
2120 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
2125 else if (!Handle->
used) {
2128 pesFilterParams.pid = 0x1FFF;
2129 pesFilterParams.input = DMX_IN_FRONTEND;
2130 pesFilterParams.output = DMX_OUT_DECODER;
2131 pesFilterParams.pes_type= DMX_PES_OTHER;
2132 pesFilterParams.flags = DMX_IMMEDIATE_START;
2133 CHECK(ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams));
2142#define RB_NUM_SECTIONS 8
2147 int f = open(FileName, O_RDWR | O_NONBLOCK);
2151 dsyslog(
"OpenFilter (pid=%d, tid=%02X): ioctl DMX_SET_BUFFER_SIZE failed", Pid, Tid);
2153 dmx_sct_filter_params sctFilterParams;
2154 memset(&sctFilterParams, 0,
sizeof(sctFilterParams));
2155 sctFilterParams.pid = Pid;
2156 sctFilterParams.timeout = 0;
2157 sctFilterParams.flags = DMX_IMMEDIATE_START;
2158 sctFilterParams.filter.filter[0] = Tid;
2159 sctFilterParams.filter.mask[0] = Mask;
2160 if (ioctl(f, DMX_SET_FILTER, &sctFilterParams) >= 0)
2163 esyslog(
"ERROR: can't set filter (pid=%d, tid=%02X, mask=%02X): %m", Pid, Tid, Mask);
2168 esyslog(
"ERROR: can't open filter handle on '%s'", *FileName);
2207 bool result =
false;
2209 bool needsDetachReceivers =
false;
2213 result = hasPriority;
2219 if (
CamSlot()->CanDecrypt(Channel))
2222 needsDetachReceivers =
true;
2242 needsDetachReceivers |= d->Receiving();
2250 if (NeedsDetachReceivers)
2251 *NeedsDetachReceivers = needsDetachReceivers;
2270bool cDvbDevice::SignalStats(
int &Valid,
double *Strength,
double *Cnr,
double *BerPre,
double *BerPost,
double *Per,
int *Status)
const
2342 if (cs->WantsTsData()) {
2347 Data = cs->Decrypt(Data, Available);
2364 d->cDevice::DetachAllReceivers();
2386 uint32_t SubsystemId = 0;
2389 if (stat(FileName, &st) == 0) {
2393 while ((e = d.
Next()) != NULL) {
2394 if (strstr(e->d_name,
"frontend")) {
2396 if (FILE *f = fopen(FileName,
"r")) {
2398 char *s = ReadLine.
Read(f);
2402 if (s && 2 == sscanf(s,
"%u:%u", &Major, &Minor)) {
2403 if (((Major << 8) | Minor) == st.st_rdev) {
2404 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_vendor", e->d_name);
2405 if ((f = fopen(FileName,
"r")) != NULL) {
2406 if (
char *s = ReadLine.
Read(f))
2407 SubsystemId = strtoul(s, NULL, 0) << 16;
2411 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idVendor", e->d_name);
2412 if ((f = fopen(FileName,
"r")) != NULL) {
2413 if (
char *s = ReadLine.
Read(f))
2414 SubsystemId = strtoul(s, NULL, 16) << 16;
2418 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_device", e->d_name);
2419 if ((f = fopen(FileName,
"r")) != NULL) {
2420 if (
char *s = ReadLine.
Read(f))
2421 SubsystemId |= strtoul(s, NULL, 0);
2425 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idProduct", e->d_name);
2426 if ((f = fopen(FileName,
"r")) != NULL) {
2427 if (
char *s = ReadLine.
Read(f))
2428 SubsystemId |= strtoul(s, NULL, 16);
const char * Name(void) const
const char * Parameters(void) const
int Ca(int Index=0) const
int Frequency(void) const
Returns the actual frequency, as given in 'channels.conf'.
bool SetTransponderData(int Source, int Frequency, int Srate, const char *Parameters, bool Quiet=false)
int Transponder(void) const
Returns the transponder frequency in MHz, plus the polarization in case of sat.
bool TimedWait(cMutex &Mutex, int TimeoutMs)
static int NextCardIndex(int n=0)
Calculates the next card index.
void StopSectionHandler(void)
A device that has called StartSectionHandler() must call this function (typically in its destructor) ...
static bool UseDevice(int n)
Tells whether the device with the given card index shall be used in this instance of VDR.
bool IsPrimaryDevice(void) const
void StartSectionHandler(void)
A derived device that provides section data must call this function (typically in its constructor) to...
bool HasPid(int Pid) const
Returns true if this device is currently receiving the given PID.
static cDevice * PrimaryDevice(void)
Returns the primary device.
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...
static cDevice * GetDevice(int Index)
Gets the device with the given Index.
bool DeviceHooksProvidesEIT(void) const
int DeviceNumber(void) const
Returns the number of this device (0 ... numDevices - 1).
bool Receiving(bool Dummy=false) const
Returns true if we are currently receiving. The parameter has no meaning (for backwards compatibility...
const cSdtFilter * SdtFilter(void) const
cSectionHandler * SectionHandler(void) const
static int NumDevices(void)
Returns the total number of devices.
int Priority(void) const
Returns the priority of the current receiving session (-MAXPRIORITY..MAXPRIORITY),...
cCamSlot * CamSlot(void) const
Returns the CAM slot that is currently used with this device, or NULL if no CAM slot is in use.
void DelLivePids(void)
Deletes the live viewing PIDs.
bool DeviceHooksProvidesTransponder(const cChannel *Channel) const
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.
int Position(void) const
Indicates which positioning mode to use in order to move the dish to a given satellite position.
bool IsScr(void) const
Returns true if this DiSEqC sequence uses Satellite Channel Routing.
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.
static cDvbCiAdapter * CreateCiAdapter(cDevice *Device, int Fd)
static uint32_t GetSubsystemId(int Adapter, int Frontend)
virtual ~cDvbDeviceProbe()
The cDvbDevice implements a DVB device which can be accessed through the Linux DVB driver API.
virtual cString DeviceType(void) const
Returns a string identifying the type of this device (like "DVB-S").
virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask)
Opens a file handle for the given filter data.
static void UnBondDevices(void)
Unbonds all devices.
virtual bool IsTunedToTransponder(const cChannel *Channel) const
Returns true if this device is currently tuned to the given Channel's transponder.
static void SetTransferModeForDolbyDigital(int Mode)
cDvbDevice(int Adapter, int Frontend)
virtual int SignalStrength(void) const
Returns the "strength" of the currently received signal.
virtual bool HasLock(int TimeoutMs=0) const
Returns true if the device has a lock on the requested transponder.
virtual void CloseFilter(int Handle)
Closes a file handle that has previously been opened by OpenFilter().
static bool Exists(int Adapter, int Frontend)
Checks whether the given adapter/frontend exists.
virtual bool SetPid(cPidHandle *Handle, int Type, bool On)
Does the actual PID setting on this device.
static bool BondDevices(const char *Bondings)
Bonds the devices as defined in the given Bondings string.
static bool useDvbDevices
virtual int NumProvidedSystems(void) const
Returns the number of individual "delivery systems" this device provides.
virtual void DetachAllReceivers(void)
Detaches all receivers from this device.
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...
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...
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...
virtual bool OpenDvr(void)
Opens the DVR of this device and prepares it to deliver a Transport Stream for use in a cReceiver.
virtual void CloseDvr(void)
Shuts down the DVR.
static bool Initialize(void)
Initializes the DVB devices.
void UnBond(void)
Removes this device from any bonding it might have with other devices.
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView)
Sets the device to the given channel (actual physical setup).
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 ...
cTSBuffer * tsBuffer
< Controls how the DVB device handles Transfer Mode when replaying Dolby Digital audio.
bool needsDetachBondedReceivers
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).
static int setTransferModeForDolbyDigital
virtual cString DeviceName(void) const
Returns a string identifying the name of this device.
virtual bool GetTSPacket(uchar *&Data)
Gets exactly one TS packet from the DVR of this device and returns a pointer to it in Data.
virtual const cChannel * GetCurrentlyTunedTransponder(void) const
Returns a pointer to the currently tuned transponder.
bool Bond(cDvbDevice *Device)
Bonds this device with the given Device, making both of them use the same satellite cable and LNB.
virtual bool ProvidesDeliverySystem(int DeliverySystem) const
virtual bool ProvidesChannel(const cChannel *Channel, int Priority=IDLEPRIORITY, bool *NeedsDetachReceivers=NULL) const
Returns true if this device can provide the given channel.
virtual bool ProvidesSource(int Source) const
Returns true if this device can provide the given source.
virtual bool HasCi(void)
Returns true if this device has a Common Interface.
cDvbDevice * bondedDevice
virtual int SignalQuality(void) const
Returns the "quality" of the currently received signal.
static bool Probe(int Adapter, int Frontend)
Probes for existing DVB devices.
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...
bool ProvidesModulation(int System, int StreamId, int Modulation) const
uint32_t SubsystemId(void) const
int NumDeliverySystems(void) const
const char * FrontendName(void)
cDvbFrontend(int Adapter, int Frontend)
int NumModulations(void) const
bool ProvidesDeliverySystem(int DeliverySystem) const
cVector< int > deliverySystems
bool QueryDeliverySystems(void)
dvb_frontend_info frontendInfo
cDvbSourceParam(char Source, const char *Description)
cDvbTransponderParameters dtp
virtual void SetData(cChannel *Channel)
Sets all source specific parameters to those of the given Channel.
virtual cOsdItem * GetOsdItem(void)
Returns all the OSD items necessary for editing the source specific parameters of the channel that wa...
virtual void GetData(cChannel *Channel)
Copies all source specific parameters to the given Channel.
cString ToString(char Type) const
const char * ParseParameter(const char *s, int &Value, const tDvbParameterMap *Map=NULL)
char Polarization(void) const
bool Parse(const char *s)
int PrintParameter(char *p, char Name, int Value) const
int CoderateL(void) const
int Transmission(void) const
int Bandwidth(void) const
int Inversion(void) const
cDvbTransponderParameters(const char *Parameters=NULL)
int Modulation(void) const
int Hierarchy(void) const
int CoderateH(void) const
void ExecuteDiseqc(const cDiseqc *Diseqc, int *Frequency)
bool Bond(cDvbTuner *Tuner)
void ClearEventQueue(void) const
int NumProvidedSystems(void) const
void SetChannel(const cChannel *Channel)
cDvbTuner(const cDvbDevice *Device, int Adapter, int Frontend)
bool BondingOk(const cChannel *Channel, bool ConsiderOccupied=false) const
void ResetToneAndVoltage(void)
cPositioner * GetPositioner(void)
cString GetBondingParams(const cChannel *Channel=NULL) const
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
bool Locked(int TimeoutMs=0)
int GetSignalQuality(void) const
bool ProvidesModulation(int System, int StreamId, int Modulation) const
const cPositioner * Positioner(void) const
cVector< cDvbFrontend * > dvbFrontends
bool IsBondedMaster(void) const
cDvbTuner * GetBondedMaster(void)
uint32_t SubsystemId(void) const
bool GetSignalStats(int &Valid, double *Strength=NULL, double *Cnr=NULL, double *BerPre=NULL, double *BerPost=NULL, double *Per=NULL, int *Status=NULL) const
bool ProvidesFrontend(const cChannel *Channel, bool Activate=false) const
int FrontendType(void) const
bool IsTunedTo(const cChannel *Channel) const
cDvbFrontend * dvbFrontend
const cDiseqc * lastDiseqc
const cDvbDevice * device
int GetSignalStrength(void) const
bool ProvidesDeliverySystem(int DeliverySystem) const
bool GetFrontendStatus(fe_status_t &Status) const
const cChannel * GetTransponder(void) const
const char * FrontendName(void)
bool Poll(int TimeoutMs=0)
A steerable satellite dish generally points to the south on the northern hemisphere,...
static cPositioner * GetPositioner(void)
Returns a previously created positioner.
void SetFrontend(int Frontend)
This function is called whenever the positioner is connected to a DVB frontend.
virtual bool IsMoving(void) const
Returns true if the dish is currently moving as a result of a call to GotoPosition() or GotoAngle().
virtual void GotoPosition(uint Number, int Longitude)
Move the dish to the satellite position stored under the given Number.
virtual void GotoAngle(int Longitude)
Move the dish to the given angular position.
struct dirent * Next(void)
int FirstDeviceIndex(int DeviceIndex) const
Returns the first device index (starting at 0) that uses the same sat cable number as the device with...
bool TransponderWrong(void) const
int Position(void)
Returns the orbital position of the satellite in case this is a DVB-S source (zero otherwise).
static bool IsSat(int Code)
void Sort(bool IgnoreCase=false)
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Derived cDevice classes that can receive channels will have to provide Transport Stream (TS) packets ...
uchar * Get(int *Available=NULL, bool CheckAvailable=false)
Returns a pointer to the first TS packet in the buffer.
void Skip(int Count)
If after a call to Get() more or less than TS_SIZE of the available data has been processed,...
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
void SetDescription(const char *Description,...) __attribute__((format(printf
bool Running(void)
Returns false if a derived cThread object shall leave its Action() function.
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
void Set(int Ms=0)
Sets the timer.
bool TimedOut(void) const
virtual void Append(T Data)
#define DTV_STAT_HAS_NONE
#define DTV_STAT_HAS_VITERBI
#define DTV_STAT_VALID_STRENGTH
#define DTV_STAT_VALID_BERPRE
#define DTV_STAT_VALID_NONE
The cDevice class is the base from which actual devices can be derived.
#define DTV_STAT_VALID_PER
#define DTV_STAT_HAS_CARRIER
#define DTV_STAT_VALID_CNR
#define DTV_STAT_HAS_LOCK
#define DTV_STAT_VALID_BERPOST
#define DTV_STAT_HAS_SYNC
#define DTV_STAT_HAS_SIGNAL
#define DTV_STAT_VALID_STATUS
int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError)
int SignalToSQI(const cChannel *Channel, int Signal, int Ber, int FeModulation, int FeCoderateH, int FeFec)
static const int DeliverySystemNamesMax
const tDvbParameterMap CoderateValues[]
int dB1000toPercent(int dB1000, int Low, int High)
const tDvbParameterMap PilotValues[]
int StrengthToSSI(const cChannel *Channel, int Strength, int FeModulation, int FeCoderateH, int FeFec)
#define REF_T2(q1, q2, q3, q4)
const tDvbParameterMap GuardValues[]
#define DVBC_LOCK_TIMEOUT
const tDvbParameterMap SystemValuesSat[]
const tDvbParameterMap HierarchyValues[]
#define DVBC_TUNE_TIMEOUT
int DriverIndex(int Value, const tDvbParameterMap *Map)
#define REF_C1(q1, q2, q3, q4, q5)
cString DvbName(const char *Name, int Adapter, int Frontend)
#define SCR_RANDOM_TIMEOUT
#define REF_S2(q1, q2, q3, q4)
const tDvbParameterMap BandwidthValues[]
static const char * GetDeliverySystemName(int Index)
#define TUNER_POLL_TIMEOUT
cList< cDvbDeviceProbe > DvbDeviceProbes
const tDvbParameterMap TransmissionValues[]
const tDvbParameterMap InversionValues[]
static unsigned int FrequencyToHz(unsigned int f)
#define ATSC_TUNE_TIMEOUT
const tDvbParameterMap RollOffValues[]
const tDvbParameterMap ModulationValues[]
const tDvbParameterMap SystemValuesTerr[]
#define DVBT_TUNE_TIMEOUT
int UserIndex(int Value, const tDvbParameterMap *Map)
#define REF_T1(q1, q2, q3)
static int GetRequiredDeliverySystem(const cChannel *Channel, const cDvbTransponderParameters *Dtp)
int MapToUser(int Value, const tDvbParameterMap *Map, const char **String)
const char * MapToUserString(int Value, const tDvbParameterMap *Map)
#define ATSC_LOCK_TIMEOUT
#define DVBS_LOCK_TIMEOUT
const char * DeliverySystemNames[]
int MapToDriver(int Value, const tDvbParameterMap *Map)
#define DVBS_TUNE_TIMEOUT
#define DVBT_LOCK_TIMEOUT
const tDvbParameterMap CoderateValues[]
const tDvbParameterMap PilotValues[]
const tDvbParameterMap GuardValues[]
const tDvbParameterMap SystemValuesSat[]
int DvbOpen(const char *Name, int Adapter, int Frontend, int Mode, bool ReportError=false)
const tDvbParameterMap HierarchyValues[]
cString DvbName(const char *Name, int Adapter, int Frontend)
const tDvbParameterMap BandwidthValues[]
int MapToUser(int Value, const tDvbParameterMap *Map, const char **String=NULL)
cList< cDvbDeviceProbe > DvbDeviceProbes
const tDvbParameterMap TransmissionValues[]
const tDvbParameterMap InversionValues[]
const tDvbParameterMap RollOffValues[]
const tDvbParameterMap ModulationValues[]
#define DTV_DVBT2_PLP_ID_LEGACY
int MapToDriver(int Value, const tDvbParameterMap *Map)