14 #include <linux/dvb/dmx.h>
15 #include <linux/dvb/frontend.h>
16 #include <sys/ioctl.h>
26 #define BANDWIDTH_HZ_AUTO 0
28 #define DVBS_TUNE_TIMEOUT 9000
29 #define DVBS_LOCK_TIMEOUT 2000
30 #define DVBC_TUNE_TIMEOUT 9000
31 #define DVBC_LOCK_TIMEOUT 2000
32 #define DVBT_TUNE_TIMEOUT 9000
33 #define DVBT_LOCK_TIMEOUT 2000
34 #define ATSC_TUNE_TIMEOUT 9000
35 #define ATSC_LOCK_TIMEOUT 2000
37 #define SCR_RANDOM_TIMEOUT 500
39 #define TSBUFFERSIZE MEGABYTE(16)
44 { 0, PILOT_OFF,
trNOOP(
"off") },
45 { 1, PILOT_ON,
trNOOP(
"on") },
46 { 999, PILOT_AUTO,
trNOOP(
"auto") },
51 { 0, INVERSION_OFF,
trNOOP(
"off") },
52 { 1, INVERSION_ON,
trNOOP(
"on") },
53 { 999, INVERSION_AUTO,
trNOOP(
"auto") },
58 { 5, 5000000,
"5 MHz" },
59 { 6, 6000000,
"6 MHz" },
60 { 7, 7000000,
"7 MHz" },
61 { 8, 8000000,
"8 MHz" },
62 { 10, 10000000,
"10 MHz" },
63 { 1712, 1712000,
"1.712 MHz" },
69 { 0, FEC_NONE,
trNOOP(
"none") },
70 { 12, FEC_1_2,
"1/2" },
71 { 23, FEC_2_3,
"2/3" },
72 { 34, FEC_3_4,
"3/4" },
73 { 35, FEC_3_5,
"3/5" },
74 { 45, FEC_4_5,
"4/5" },
75 { 56, FEC_5_6,
"5/6" },
76 { 67, FEC_6_7,
"6/7" },
77 { 78, FEC_7_8,
"7/8" },
78 { 89, FEC_8_9,
"8/9" },
79 { 910, FEC_9_10,
"9/10" },
80 { 999, FEC_AUTO,
trNOOP(
"auto") },
85 { 16, QAM_16,
"QAM16" },
86 { 32, QAM_32,
"QAM32" },
87 { 64, QAM_64,
"QAM64" },
88 { 128, QAM_128,
"QAM128" },
89 { 256, QAM_256,
"QAM256" },
92 { 6, APSK_16,
"16APSK" },
93 { 7, APSK_32,
"32APSK" },
94 { 10, VSB_8,
"VSB8" },
95 { 11, VSB_16,
"VSB16" },
96 { 12, DQPSK,
"DQPSK" },
97 { 999, QAM_AUTO,
trNOOP(
"auto") },
101 #define DVB_SYSTEM_1 0
102 #define DVB_SYSTEM_2 1
118 { 2, TRANSMISSION_MODE_2K,
"2K" },
120 { 8, TRANSMISSION_MODE_8K,
"8K" },
123 { 999, TRANSMISSION_MODE_AUTO,
trNOOP(
"auto") },
128 { 4, GUARD_INTERVAL_1_4,
"1/4" },
129 { 8, GUARD_INTERVAL_1_8,
"1/8" },
130 { 16, GUARD_INTERVAL_1_16,
"1/16" },
131 { 32, GUARD_INTERVAL_1_32,
"1/32" },
135 { 999, GUARD_INTERVAL_AUTO,
trNOOP(
"auto") },
140 { 0, HIERARCHY_NONE,
trNOOP(
"none") },
141 { 1, HIERARCHY_1,
"1" },
142 { 2, HIERARCHY_2,
"2" },
143 { 4, HIERARCHY_4,
"4" },
144 { 999, HIERARCHY_AUTO,
trNOOP(
"auto") },
149 { 0, ROLLOFF_AUTO,
trNOOP(
"auto") },
150 { 20, ROLLOFF_20,
"0.20" },
151 { 25, ROLLOFF_25,
"0.25" },
152 { 35, ROLLOFF_35,
"0.35" },
183 *String =
tr(Map[n].userString);
214 return Value >= 0 && Value != 999 ? sprintf(p,
"%c%d", Name, Value) : 0;
219 #define ST(s) if (strchr(s, Type) && (strchr(s, '0' + system + 1) || strchr(s, '*')))
247 int n = strtol(s, &p, 10);
248 if (!errno && p != s) {
254 esyslog(
"ERROR: invalid value for parameter '%c'", *(s - 1));
268 guard = GUARD_INTERVAL_AUTO;
277 switch (toupper(*s)) {
297 default:
esyslog(
"ERROR: unknown parameter key '%c'", *s);
339 #define MAXFRONTENDCMDS 16
340 #define SETCMD(c, d) { Props[CmdSeq.num].cmd = (c);\
341 Props[CmdSeq.num].u.data = (d);\
342 if (CmdSeq.num++ > MAXFRONTENDCMDS) {\
343 esyslog("ERROR: too many tuning commands on frontend %d/%d", adapter, frontend);\
418 if (Modulation == QPSK && !(
frontendInfo.caps & FE_CAN_QPSK) ||
419 Modulation == QAM_16 && !(
frontendInfo.caps & FE_CAN_QAM_16) ||
420 Modulation == QAM_32 && !(
frontendInfo.caps & FE_CAN_QAM_32) ||
421 Modulation == QAM_64 && !(
frontendInfo.caps & FE_CAN_QAM_64) ||
422 Modulation == QAM_128 && !(
frontendInfo.caps & FE_CAN_QAM_128) ||
423 Modulation == QAM_256 && !(
frontendInfo.caps & FE_CAN_QAM_256) ||
424 Modulation == QAM_AUTO && !(
frontendInfo.caps & FE_CAN_QAM_AUTO) ||
425 Modulation == VSB_8 && !(
frontendInfo.caps & FE_CAN_8VSB) ||
426 Modulation == VSB_16 && !(
frontendInfo.caps & FE_CAN_16VSB) ||
440 dtv_property Props[1];
441 dtv_properties CmdSeq;
444 memset(&Props, 0,
sizeof(Props));
445 memset(&CmdSeq, 0,
sizeof(CmdSeq));
446 CmdSeq.props = Props;
447 SETCMD(DTV_API_VERSION, 0);
448 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
456 bool LegacyMode =
true;
458 memset(&Props, 0,
sizeof(Props));
459 memset(&CmdSeq, 0,
sizeof(CmdSeq));
460 CmdSeq.props = Props;
462 int Result = ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq);
464 for (uint i = 0; i < Props[0].u.buffer.len; i++) {
472 esyslog(
"ERROR: can't query delivery systems on frontend %d/%d - falling back to legacy mode",
adapter,
frontend);
506 ms =
"unknown modulations";
517 #define TUNER_POLL_TIMEOUT 10
521 int ds = SYS_UNDEFINED;
525 ds = SYS_DVBC_ANNEX_AC;
526 else if (Channel->
IsSat())
528 else if (Channel->
IsTerr())
531 esyslog(
"ERROR: can't determine frontend type for channel %d (%s)", Channel->
Number(), Channel->
Name());
576 virtual void Action(
void);
594 bool Locked(
int TimeoutMs = 0);
596 bool GetSignalStats(
int &Valid,
double *Strength = NULL,
double *Cnr = NULL,
double *BerPre = NULL,
double *BerPost = NULL,
double *Per = NULL,
int *Status = NULL)
const;
634 for (
int i = 1; ; i++) {
737 while (t->bondedTuner !=
this)
740 t->bondedTuner = NULL;
755 return diseqc->Commands();
771 if (t->device->Priority() >
IDLEPRIORITY || ConsiderOccupied && t->device->Occupied()) {
772 if (strcmp(BondingParams, t->GetBondedMaster()->GetBondingParams()) != 0)
818 if (BondedMaster ==
this) {
848 if (isLocked || !TimeoutMs)
861 dvb_frontend_event Event;
862 while (ioctl(
fd_frontend, FE_GET_EVENT, &Event) == 0)
872 Status = (fe_status_t)0;
874 if (ioctl(
fd_frontend, FE_READ_STATUS, &Status) != -1)
886 bool cDvbTuner::GetSignalStats(
int &Valid,
double *Strength,
double *Cnr,
double *BerPre,
double *BerPost,
double *Per,
int *Status)
const
891 fe_status_t FeStatus = (fe_status_t)0;
893 dtv_properties CmdSeq;
894 memset(&Props, 0,
sizeof(Props));
895 memset(&CmdSeq, 0,
sizeof(CmdSeq));
896 CmdSeq.props = Props;
898 if (ioctl(
fd_frontend, FE_READ_STATUS, &FeStatus) != 0) {
911 if (Strength)
SETCMD(DTV_STAT_SIGNAL_STRENGTH, 0);
912 if (Cnr)
SETCMD(DTV_STAT_CNR, 0);
913 if (BerPre) {
SETCMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0);
914 SETCMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0); }
915 if (BerPost) {
SETCMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0);
916 SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0); }
917 if (Per) {
SETCMD(DTV_STAT_ERROR_BLOCK_COUNT, 0);
918 SETCMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0); }
919 if (CmdSeq.num && ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
925 if (Props[i].u.st.len > 0) {
926 switch (Props[i].u.st.stat[0].scale) {
927 case FE_SCALE_DECIBEL: *Strength = double(Props[i].u.st.stat[0].svalue) / 1000;
936 if (Props[i].u.st.len > 0) {
937 switch (Props[i].u.st.stat[0].scale) {
938 case FE_SCALE_DECIBEL: *Cnr = double(Props[i].u.st.stat[0].svalue) / 1000;
947 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
948 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
949 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
950 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
952 *BerPre = double(ebc) / tbc;
960 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
961 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
962 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
963 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
965 *BerPost = double(ebc) / tbc;
973 if (Props[i].u.st.len > 0 && Props[i + 1].u.st.len > 0) {
974 if (Props[i].u.st.stat[0].scale == FE_SCALE_COUNTER && Props[i + 1].u.st.stat[0].scale == FE_SCALE_COUNTER) {
975 uint64_t ebc = Props[i].u.st.stat[0].uvalue;
976 uint64_t tbc = Props[i + 1].u.st.stat[0].uvalue;
978 *Per = double(ebc) / tbc;
985 #ifdef DEBUG_SIGNALSTATS
993 fprintf(stderr,
"\n");
1009 double v = 10.0 * (dB1000 - High) / (Low - High);
1013 #define REF_S1(q1) (mod == QPSK) ? q1 : 0
1014 #define REF_S2(q1, q2, q3, q4) (mod == QPSK) ? q1 : (mod == PSK_8) ? q2 : (mod == APSK_16) ? q3 : (mod == APSK_32) ? q4 : 0
1015 #define REF_T1(q1, q2, q3) (mod == QPSK) ? q1 : (mod == QAM_16) ? q2 : (mod == QAM_64) ? q3 : 0
1016 #define REF_T2(q1, q2, q3, q4) (mod == QPSK) ? q1 : (mod == QAM_16) ? q2 : (mod == QAM_64) ? q3 : (mod == QAM_256) ? q4 : 0
1017 #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
1024 int mod = (FeModulation >= 0) ? FeModulation : dtp.
Modulation();
1025 int cod = (FeCoderateH >= 0) ? FeCoderateH : dtp.
CoderateH();
1026 int fec = (FeFec >= 0) ? FeFec : dtp.
CoderateH();
1033 if (mod == QAM_AUTO) mod = QPSK;
1035 case FEC_1_2: pref =
REF_T1(-93, -87, -82);
break;
1037 case FEC_2_3: pref =
REF_T1(-91, -85, -80);
break;
1038 case FEC_3_4: pref =
REF_T1(-90, -84, -78);
break;
1039 case FEC_5_6: pref =
REF_T1(-89, -83, -77);
break;
1040 case FEC_7_8: pref =
REF_T1(-88, -82, -76);
break;
1044 if (mod == QAM_AUTO) mod = QAM_64;
1046 case FEC_1_2: pref =
REF_T2(-96, -91, -86, -82);
break;
1048 case FEC_3_5: pref =
REF_T2(-95, -89, -85, -80);
break;
1049 case FEC_2_3: pref =
REF_T2(-94, -88, -83, -78);
break;
1050 case FEC_3_4: pref =
REF_T2(-93, -87, -82, -76);
break;
1051 case FEC_4_5: pref =
REF_T2(-92, -86, -81, -75);
break;
1052 case FEC_5_6: pref =
REF_T2(-92, -86, -80, -74);
break;
1056 int prel = (Strength / 1000) - pref;
1057 ssi = (prel < -15) ? 0 :
1058 (prel < 0) ? (prel + 15) * 2 / 3 :
1059 (prel < 20) ? prel * 4 + 10 :
1060 (prel < 35) ? (prel - 20) * 2 / 3 + 90 :
1062 #ifdef DEBUG_SIGNALSTRENGTH
1063 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);
1067 else if (Channel->
IsCable()) {
1072 if (mod == QAM_AUTO) mod = QAM_256;
1074 int pref =
REF_C1(-79, -76, -73, -70, -67);
1076 int prel = (Strength / 1000) - pref;
1077 ssi = (prel < -15) ? 0 :
1078 (prel < 0) ? (prel + 15) * 2 / 3 :
1079 (prel < 20) ? prel * 4 + 10 :
1080 (prel < 35) ? (prel - 20) * 2 / 3 + 90 :
1082 #ifdef DEBUG_SIGNALSTRENGTH
1083 fprintf(stderr,
"SSI-C: STR:%d, Pref:%d, Prel:%d, ssi:%d%%(mod:%d)\n", Strength, pref, prel, ssi, mod);
1087 else if (Channel->
IsSat())
1093 #define IGNORE_BER 1
1094 #define BER_ERROR_FREE (1000*1000*1000)
1104 int mod = (FeModulation >= 0) ? FeModulation : dtp.
Modulation();
1105 int cod = (FeCoderateH >= 0) ? FeCoderateH : dtp.
CoderateH();
1106 int fec = (FeFec >= 0) ? FeFec : dtp.
CoderateH();
1113 if (mod == QAM_AUTO) mod = QPSK;
1115 case FEC_1_2: cnref =
REF_T1(51, 108, 165);
break;
1117 case FEC_2_3: cnref =
REF_T1(69, 131, 187);
break;
1118 case FEC_3_4: cnref =
REF_T1(79, 146, 202);
break;
1119 case FEC_5_6: cnref =
REF_T1(89, 156, 216);
break;
1120 case FEC_7_8: cnref =
REF_T1(97, 160, 225);
break;
1124 if (mod == QAM_AUTO) mod = QAM_64;
1126 case FEC_1_2: cnref =
REF_T2(35, 87, 130, 170);
break;
1128 case FEC_3_5: cnref =
REF_T2(47, 101, 148, 194);
break;
1129 case FEC_2_3: cnref =
REF_T2(56, 114, 162, 208);
break;
1130 case FEC_3_4: cnref =
REF_T2(66, 125, 177, 229);
break;
1131 case FEC_4_5: cnref =
REF_T2(72, 133, 187, 243);
break;
1132 case FEC_5_6: cnref =
REF_T2(77, 138, 194, 251);
break;
1136 int cnrel = (Signal/100) - cnref;
1140 ber_sqi = (Ber < 1000) ? 0 :
1141 (Ber >= 10000000) ? 100 :
1142 (int)(20 * log10(Ber)) - 40;
1144 cnr_sqi = (cnrel < -70) ? 0 :
1145 (cnrel < +30) ? (100 + (cnrel - 30)) :
1147 sqi = (cnr_sqi * ber_sqi) / 100;
1152 ber_sqi = (Ber < 10000) ? 0 :
1153 (Ber >= 10000000) ? 100 * 100 / 6 :
1156 sqi = (cnrel < -30) ? 0 :
1157 (cnrel <= +30) ? (cnrel + 30) * ber_sqi / 1000 :
1162 #ifdef DEBUG_SIGNALQUALITY
1163 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);
1167 else if (Channel->
IsCable()) {
1168 if (mod == QAM_AUTO) mod = QAM_256;
1170 int cnref =
REF_C1(200, 230, 260, 290, 320);
1172 int cnrel = (Signal / 100) - cnref;
1173 int ber_sqi = (Ber < 1000) ? 0 :
1174 (Ber >= 10000000) ? 100 :
1175 (int)(20 * log10(Ber)) - 40;
1177 int cnr_sqi = (cnrel < -70) ? 0 :
1178 (cnrel < +30) ? (100 + (cnrel - 30)) :
1180 sqi = (cnr_sqi * ber_sqi) / 100;
1183 #ifdef DEBUG_SIGNALQUALITY
1184 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);
1188 else if (Channel->
IsSat()) {
1191 if (mod == QAM_AUTO) mod = QPSK;
1193 case FEC_1_2: cnref =
REF_S1(38);
break;
1195 case FEC_2_3: cnref =
REF_S1(56);
break;
1196 case FEC_3_4: cnref =
REF_S1(67);
break;
1197 case FEC_5_6: cnref =
REF_S1(77);
break;
1198 case FEC_7_8: cnref =
REF_S1(84);
break;
1204 #ifdef DEBUG_SIGNALQUALITY
1205 dsyslog(
"SQI-S1: SIG:%d, BER:%d, CNref:%d, sqi:%d%%(mod:%d, fec:%d)\n", Signal, Ber, cnref, sqi, mod, fec);
1210 if (mod == QAM_AUTO) mod = QAM_64;
1214 case FEC_2_5: cnref =
REF_S2( 7, 65, 90, 126);
break;
1215 case FEC_1_2: cnref =
REF_S2( 20, 65, 90, 126);
break;
1216 case FEC_3_5: cnref =
REF_S2( 32, 65, 90, 126);
break;
1218 case FEC_2_3: cnref =
REF_S2( 41, 76, 90, 126);
break;
1219 case FEC_3_4: cnref =
REF_S2( 50, 66, 102, 126);
break;
1220 case FEC_4_5: cnref =
REF_S2( 57, 89, 110, 136);
break;
1221 case FEC_5_6: cnref =
REF_S2( 62, 104, 116, 143);
break;
1222 case FEC_8_9: cnref =
REF_S2( 72, 117, 129, 157);
break;
1223 case FEC_9_10: cnref =
REF_S2( 74, 120, 131, 161);
break;
1229 #ifdef DEBUG_SIGNALQUALITY
1230 dsyslog(
"SQI-S2: SIG:%d, BER:%d, CNref:%d, sqi:%d%%(mod:%d, fec:%d)\n", Signal, Ber, cnref, sqi, mod, fec);
1244 for (
int i = 0; i < 1; i++) {
1246 dtv_properties CmdSeq;
1247 memset(&Props, 0,
sizeof(Props));
1248 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1249 CmdSeq.props = Props;
1250 SETCMD(DTV_STAT_SIGNAL_STRENGTH, 0);
1251 SETCMD(DTV_MODULATION, 0);
1252 SETCMD(DTV_CODE_RATE_HP, 0);
1253 SETCMD(DTV_INNER_FEC, 0);
1254 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
1258 int FeMod = (Props[1].u.st.len > 0) ? (
int)Props[1].u.data : -1;
1259 int FeCod = (Props[2].u.st.len > 0) ? (
int)Props[2].u.data : -1;
1260 int FeFec = (Props[3].u.st.len > 0) ? (
int)Props[3].u.data : -1;
1262 if (Props[0].u.st.len > 0) {
1263 switch (Props[0].u.st.stat[0].scale) {
1264 case FE_SCALE_DECIBEL: Signal =
StrengthToSSI(&
channel, Props[0].u.st.stat[0].svalue, FeMod, FeCod, FeFec);
1266 case FE_SCALE_RELATIVE: Signal = 100 * Props[0].u.st.stat[0].uvalue / 0xFFFF;
1270 #ifdef DEBUG_SIGNALSTRENGTH
1271 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);
1281 if (ioctl(
fd_frontend, FE_READ_SIGNAL_STRENGTH, &Signal) != -1)
1286 uint16_t MaxSignal = 0xFFFF;
1292 MaxSignal = 670;
break;
1294 int s = int(Signal) * 100 / MaxSignal;
1297 #ifdef DEBUG_SIGNALSTRENGTH
1303 #define LOCK_THRESHOLD 5
1310 for (
int i = 0; i < 1; i++) {
1312 dtv_properties CmdSeq;
1313 memset(&Props, 0,
sizeof(Props));
1314 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1315 CmdSeq.props = Props;
1317 SETCMD(DTV_MODULATION, 0);
1318 SETCMD(DTV_CODE_RATE_HP, 0);
1319 SETCMD(DTV_INNER_FEC, 0);
1320 SETCMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0);
1321 SETCMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0);
1322 if (ioctl(
fd_frontend, FE_GET_PROPERTY, &CmdSeq) != 0) {
1326 int FeMod = (Props[1].u.st.len > 0) ? (
int)Props[1].u.data : -1;
1327 int FeCod = (Props[2].u.st.len > 0) ? (
int)Props[2].u.data : -1;
1328 int FeFec = (Props[3].u.st.len > 0) ? (
int)Props[3].u.data : -1;
1330 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) {
1331 uint64_t ebc = Props[4].u.st.stat[0].uvalue;
1332 uint64_t tbc = Props[5].u.st.stat[0].uvalue;
1334 uint64_t BerRev = tbc / ebc;
1340 if (Props[0].u.st.len > 0) {
1341 switch (Props[0].u.st.stat[0].scale) {
1342 case FE_SCALE_DECIBEL: Cnr =
SignalToSQI(&
channel, Props[0].u.st.stat[0].svalue, Ber, FeMod, FeCod, FeFec);
1344 case FE_SCALE_RELATIVE: Cnr = 100 * Props[0].u.st.stat[0].uvalue / 0xFFFF;
1348 #ifdef DEBUG_SIGNALQUALITY
1349 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);
1360 if ((Status & FE_HAS_LOCK) == 0) {
1361 if ((Status & FE_HAS_SIGNAL) == 0)
1363 if ((Status & FE_HAS_CARRIER) == 0)
1365 if ((Status & FE_HAS_VITERBI) == 0)
1367 if ((Status & FE_HAS_SYNC) == 0)
1371 #ifdef DEBUG_SIGNALQUALITY
1378 if (errno != EINTR) {
1380 #ifdef DEBUG_SIGNALQUALITY
1386 #ifdef DEBUG_SIGNALQUALITY
1393 if (errno != EINTR) {
1395 #ifdef DEBUG_SIGNALQUALITY
1401 #ifdef DEBUG_SIGNALQUALITY
1406 if (ioctl(
fd_frontend, FE_READ_UNCORRECTED_BLOCKS, &Unc) != -1) {
1408 #ifdef DEBUG_SIGNALQUALITY
1429 Unc >>=
min(t,
int(
sizeof(Unc) * 8 - 1));
1432 #ifdef DEBUG_SIGNALQUALITY
1438 if (errno != EINTR) {
1440 #ifdef DEBUG_SIGNALQUALITY
1446 uint16_t MinSnr = 0x0000;
1447 uint16_t MaxSnr = 0xFFFF;
1462 MaxSnr = 255;
break;
1464 int a = int(
constrain(Snr, MinSnr, MaxSnr)) * 100 / (MaxSnr - MinSnr);
1465 int b = 100 - (Unc * 10 + (Ber / 256) * 5);
1471 #ifdef DEBUG_SIGNALQUALITY
1472 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);
1481 while (f && f < 1000000)
1502 if (Diseqc->
IsScr())
1504 struct dvb_diseqc_master_cmd cmd;
1505 const char *CurrentAction = NULL;
1508 for (
int i = 0; !Break; i++) {
1509 cmd.msg_len =
sizeof(cmd.msg);
1540 default:
esyslog(
"ERROR: unknown diseqc command %d", da);
1548 if (Diseqc->
IsScr())
1563 memset(&Props, 0,
sizeof(Props));
1564 dtv_properties CmdSeq;
1565 memset(&CmdSeq, 0,
sizeof(CmdSeq));
1566 CmdSeq.props = Props;
1568 if (ioctl(
fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
1586 frequency -= diseqc->Lof();
1605 int tone = SEC_TONE_OFF;
1608 tone = SEC_TONE_OFF;
1616 tone = SEC_TONE_OFF;
1617 volt = SEC_VOLTAGE_13;
1622 frequency = abs(frequency);
1625 SETCMD(DTV_FREQUENCY, frequency * 1000UL);
1639 SETCMD(DTV_ROLLOFF, ROLLOFF_35);
1689 esyslog(
"ERROR: attempt to set channel with unknown DVB frontend type");
1693 if (ioctl(
fd_frontend, FE_SET_PROPERTY, &CmdSeq) < 0) {
1703 bool LostLock =
false;
1704 fe_status_t Status = (fe_status_t)0;
1706 int WaitTime = 1000;
1707 fe_status_t NewStatus;
1748 if (Status & FE_REINIT) {
1756 else if (Status & FE_HAS_LOCK) {
1852 #define ST(s) if (strchr(s, type))
1870 default:
return NULL;
1924 int DvbOpen(
const char *Name,
int Adapter,
int Frontend,
int Mode,
bool ReportError)
1927 int fd = open(FileName, Mode);
1928 if (fd < 0 && ReportError)
1941 if (access(FileName, F_OK) == 0) {
1942 int f = open(FileName, O_RDONLY);
1947 else if (errno != ENODEV && errno != EINVAL)
1950 else if (errno != ENOENT)
1958 dsyslog(
"probing %s", *FileName);
1963 dsyslog(
"creating cDvbDevice");
1992 while ((a = DvbDir.
Next()) != NULL) {
1996 if (AdapterDir.
Ok()) {
1998 while ((f = AdapterDir.
Next()) != NULL) {
2013 if (Nodes.
Size() > 0) {
2015 for (
int i = 0; i < Nodes.
Size(); i++) {
2036 isyslog(
"found %d DVB device%s", Found, Found > 1 ?
"s" :
"");
2038 isyslog(
"using only %d DVB device%s", Used, Used != 1 ?
"s" :
"");
2041 isyslog(
"no DVB device found");
2053 int ErrorDevice = 0;
2058 if (!DvbDevice1->Bond(DvbDevice2))
2062 ErrorDevice = d + 1;
2065 ErrorDevice = i + 1;
2067 esyslog(
"ERROR: device '%d' in device bondings '%s' is not a cDvbDevice", ErrorDevice, Bondings);
2072 ErrorDevice = d + 1;
2075 ErrorDevice = i + 1;
2077 esyslog(
"ERROR: unknown device '%d' in device bondings '%s'", ErrorDevice, Bondings);
2098 if (Device !=
this) {
2125 while (d->bondedDevice !=
this)
2126 d = d->bondedDevice;
2128 d->bondedDevice = NULL;
2151 dmx_pes_filter_params pesFilterParams;
2152 memset(&pesFilterParams, 0,
sizeof(pesFilterParams));
2154 if (Handle->
handle < 0) {
2156 if (Handle->
handle < 0) {
2161 pesFilterParams.pid = Handle->
pid;
2162 pesFilterParams.input = DMX_IN_FRONTEND;
2163 pesFilterParams.output = DMX_OUT_TS_TAP;
2164 pesFilterParams.pes_type= DMX_PES_OTHER;
2165 pesFilterParams.flags = DMX_IMMEDIATE_START;
2166 if (ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
2171 else if (!Handle->
used) {
2174 pesFilterParams.pid = 0x1FFF;
2175 pesFilterParams.input = DMX_IN_FRONTEND;
2176 pesFilterParams.output = DMX_OUT_DECODER;
2177 pesFilterParams.pes_type= DMX_PES_OTHER;
2178 pesFilterParams.flags = DMX_IMMEDIATE_START;
2179 CHECK(ioctl(Handle->
handle, DMX_SET_PES_FILTER, &pesFilterParams));
2188 #define RB_NUM_SECTIONS 8
2193 int f = open(FileName, O_RDWR | O_NONBLOCK);
2197 dsyslog(
"OpenFilter (pid=%d, tid=%02X): ioctl DMX_SET_BUFFER_SIZE failed", Pid, Tid);
2199 dmx_sct_filter_params sctFilterParams;
2200 memset(&sctFilterParams, 0,
sizeof(sctFilterParams));
2201 sctFilterParams.pid = Pid;
2202 sctFilterParams.timeout = 0;
2203 sctFilterParams.flags = DMX_IMMEDIATE_START;
2204 sctFilterParams.filter.filter[0] = Tid;
2205 sctFilterParams.filter.mask[0] = Mask;
2206 if (ioctl(f, DMX_SET_FILTER, &sctFilterParams) >= 0)
2209 esyslog(
"ERROR: can't set filter (pid=%d, tid=%02X, mask=%02X): %m", Pid, Tid, Mask);
2214 esyslog(
"ERROR: can't open filter handle on '%s'", *FileName);
2253 bool result =
false;
2255 bool needsDetachReceivers =
false;
2259 result = hasPriority;
2265 if (
CamSlot()->CanDecrypt(Channel))
2268 needsDetachReceivers =
true;
2288 needsDetachReceivers |= d->Receiving();
2296 if (NeedsDetachReceivers)
2297 *NeedsDetachReceivers = needsDetachReceivers;
2316 bool cDvbDevice::SignalStats(
int &Valid,
double *Strength,
double *Cnr,
double *BerPre,
double *BerPost,
double *Per,
int *Status)
const
2393 if (cs->WantsTsData()) {
2398 Data = cs->Decrypt(Data, Available);
2415 d->cDevice::DetachAllReceivers();
2437 uint32_t SubsystemId = 0;
2440 if (stat(FileName, &st) == 0) {
2444 while ((e = d.
Next()) != NULL) {
2445 if (strstr(e->d_name,
"frontend")) {
2447 if (FILE *f = fopen(FileName,
"r")) {
2449 char *s = ReadLine.
Read(f);
2453 if (s && 2 == sscanf(s,
"%u:%u", &Major, &Minor)) {
2454 if (((Major << 8) | Minor) == st.st_rdev) {
2455 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_vendor", e->d_name);
2456 if ((f = fopen(FileName,
"r")) != NULL) {
2457 if (
char *s = ReadLine.
Read(f))
2458 SubsystemId = strtoul(s, NULL, 0) << 16;
2462 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idVendor", e->d_name);
2463 if ((f = fopen(FileName,
"r")) != NULL) {
2464 if (
char *s = ReadLine.
Read(f))
2465 SubsystemId = strtoul(s, NULL, 16) << 16;
2469 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/subsystem_device", e->d_name);
2470 if ((f = fopen(FileName,
"r")) != NULL) {
2471 if (
char *s = ReadLine.
Read(f))
2472 SubsystemId |= strtoul(s, NULL, 0);
2476 FileName =
cString::sprintf(
"/sys/class/dvb/%s/device/idProduct", e->d_name);
2477 if ((f = fopen(FileName,
"r")) != NULL) {
2478 if (
char *s = ReadLine.
Read(f))
2479 SubsystemId |= strtoul(s, NULL, 16);
const char * Name(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)
const char * Parameters(void) const
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) ...
int Priority(bool IgnoreOccupied=false) const
Returns the priority of the current receiving session (-MAXPRIORITY..MAXPRIORITY),...
static bool UseDevice(int n)
Tells whether the device with the given card index shall be used in this instance of VDR.
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.
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 IsPrimaryDevice(bool CheckDecoder=true) const
bool Receiving(bool Dummy=false) const
Returns true if we are currently receiving. The parameter has no meaning (for backwards compatibility...
cSectionHandler * SectionHandler(void) const
static int NumDevices(void)
Returns the total number of devices.
static cDevice * PrimaryDevice(void)
Returns the primary device.
const cSdtFilter * SdtFilter(void) const
void DelLivePids(void)
Deletes the live viewing PIDs.
bool DeviceHooksProvidesTransponder(const cChannel *Channel) const
cCamSlot * CamSlot(void) const
Returns the CAM slot that is currently used with this device, or NULL if no CAM slot is in use.
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 void SetPowerSaveMode(bool On)
Puts the device into power save mode, if applicable.
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...
const char * FrontendName(void)
bool ProvidesModulation(int System, int StreamId, int Modulation) const
uint32_t SubsystemId(void) const
int NumDeliverySystems(void) const
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
const cPositioner * Positioner(void) 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
cVector< cDvbFrontend * > dvbFrontends
const cChannel * GetTransponder(void) const
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
const char * FrontendName(void)
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
void SetPowerSaveMode(bool On)
int GetSignalStrength(void) const
bool ProvidesDeliverySystem(int DeliverySystem) const
bool GetFrontendStatus(fe_status_t &Status) const
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 char * MapToUserString(int Value, const tDvbParameterMap *Map)
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 BANDWIDTH_HZ_AUTO
#define REF_S2(q1, q2, q3, q4)
const tDvbParameterMap BandwidthValues[]
#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[]
static const char * GetDeliverySystemName(int Index)
#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)
#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
#define DTV_DVBT2_PLP_ID_LEGACY