1 #include <linux/dvb/version.h>
3 #include <lib/dvb/dvb.h>
4 #include <lib/dvb/frontendparms.h>
5 #include <lib/base/eerror.h>
6 #include <lib/base/nconfig.h> // access to python config
10 #include <sys/ioctl.h>
12 #ifndef I2C_SLAVE_FORCE
13 #define I2C_SLAVE_FORCE 0x0706
16 #if HAVE_DVB_API_VERSION < 3
17 #include <ost/frontend.h>
19 #define QAM_AUTO (Modulation)6
20 #define TRANSMISSION_MODE_AUTO (TransmitMode)2
21 #define BANDWIDTH_AUTO (BandWidth)3
22 #define GUARD_INTERVAL_AUTO (GuardInterval)4
23 #define HIERARCHY_AUTO (Hierarchy)4
24 #define parm_frequency parm.Frequency
25 #define parm_inversion parm.Inversion
26 #define parm_u_qpsk_symbol_rate parm.u.qpsk.SymbolRate
27 #define parm_u_qpsk_fec_inner parm.u.qpsk.FEC_inner
28 #define parm_u_qam_symbol_rate parm.u.qam.SymbolRate
29 #define parm_u_qam_fec_inner parm.u.qam.FEC_inner
30 #define parm_u_qam_modulation parm.u.qam.QAM
31 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandWidth
32 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.LP_CodeRate
33 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.HP_CodeRate
34 #define parm_u_ofdm_constellation parm.u.ofdm.Constellation
35 #define parm_u_ofdm_transmission_mode parm.u.ofdm.TransmissionMode
36 #define parm_u_ofdm_guard_interval parm.u.ofdm.guardInterval
37 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.HierarchyInformation
39 #include <linux/dvb/frontend.h>
40 #define parm_frequency parm.frequency
41 #define parm_inversion parm.inversion
42 #define parm_u_qpsk_symbol_rate parm.u.qpsk.symbol_rate
43 #define parm_u_qpsk_fec_inner parm.u.qpsk.fec_inner
44 #define parm_u_qam_symbol_rate parm.u.qam.symbol_rate
45 #define parm_u_qam_fec_inner parm.u.qam.fec_inner
46 #define parm_u_qam_modulation parm.u.qam.modulation
47 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandwidth
48 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.code_rate_LP
49 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.code_rate_HP
50 #define parm_u_ofdm_constellation parm.u.ofdm.constellation
51 #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode
52 #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval
53 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information
54 #if HAVE_DVB_API_VERSION < 5
55 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1)
56 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1)
57 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_S2_QPSK_2_3+1)
58 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_S2_QPSK_3_4+1)
59 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_S2_QPSK_5_6+1)
60 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_S2_QPSK_7_8+1)
61 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_S2_QPSK_8_9+1)
62 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_S2_QPSK_3_5+1)
63 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_S2_QPSK_4_5+1)
64 #define FEC_S2_8PSK_1_2 (fe_code_rate_t)(FEC_S2_QPSK_9_10+1)
65 #define FEC_S2_8PSK_2_3 (fe_code_rate_t)(FEC_S2_8PSK_1_2+1)
66 #define FEC_S2_8PSK_3_4 (fe_code_rate_t)(FEC_S2_8PSK_2_3+1)
67 #define FEC_S2_8PSK_5_6 (fe_code_rate_t)(FEC_S2_8PSK_3_4+1)
68 #define FEC_S2_8PSK_7_8 (fe_code_rate_t)(FEC_S2_8PSK_5_6+1)
69 #define FEC_S2_8PSK_8_9 (fe_code_rate_t)(FEC_S2_8PSK_7_8+1)
70 #define FEC_S2_8PSK_3_5 (fe_code_rate_t)(FEC_S2_8PSK_8_9+1)
71 #define FEC_S2_8PSK_4_5 (fe_code_rate_t)(FEC_S2_8PSK_3_5+1)
72 #define FEC_S2_8PSK_9_10 (fe_code_rate_t)(FEC_S2_8PSK_4_5+1)
74 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2)
75 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3)
76 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4)
77 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6)
78 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8)
79 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9)
80 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5)
81 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5)
82 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10)
86 #include <dvbsi++/satellite_delivery_system_descriptor.h>
87 #include <dvbsi++/cable_delivery_system_descriptor.h>
88 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
90 #define eDebugNoSimulate(x...) \
98 eDebugNoNewLine("SIMULATE:"); \
103 #define eDebugNoSimulateNoNewLine(x...) \
106 eDebugNoNewLine(x); \
111 eDebugNoNewLine("SIMULATE:"); \
112 eDebugNoNewLine(x); \
116 void eDVBDiseqcCommand::setCommandString(const char *str)
121 int slen = strlen(str);
124 eDebug("invalid diseqc command string length (not 2 byte aligned)");
127 if (slen > MAX_DISEQC_LENGTH*2)
129 eDebug("invalid diseqc command string length (string is to long)");
133 for (int i=0; i < slen; ++i)
135 unsigned char c = str[i];
138 case '0' ... '9': c-=48; break;
139 case 'a' ... 'f': c-=87; break;
140 case 'A' ... 'F': c-=55; break;
142 eDebug("invalid character in hex string..ignore complete diseqc command !");
156 void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescriptor &descriptor)
158 frequency = descriptor.getFrequency() * 10;
159 symbol_rate = descriptor.getSymbolRate() * 100;
160 polarisation = descriptor.getPolarization();
161 fec = descriptor.getFecInner();
162 if ( fec != eDVBFrontendParametersSatellite::FEC_None && fec > eDVBFrontendParametersSatellite::FEC_9_10 )
163 fec = eDVBFrontendParametersSatellite::FEC_Auto;
164 inversion = eDVBFrontendParametersSatellite::Inversion_Unknown;
165 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
166 orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
167 orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
168 orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
169 orbital_position += ((descriptor.getOrbitalPosition()) & 0xF);
170 if (orbital_position && (!descriptor.getWestEastFlag()))
171 orbital_position = 3600 - orbital_position;
172 system = descriptor.getModulationSystem();
173 modulation = descriptor.getModulation();
174 if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
176 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
177 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
179 rolloff = descriptor.getRollOff();
180 if (system == eDVBFrontendParametersSatellite::System_DVB_S2)
182 eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
184 polarisation ? "hor" : "vert",
192 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
194 polarisation ? "hor" : "vert",
200 void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descriptor)
202 frequency = descriptor.getFrequency() / 10;
203 symbol_rate = descriptor.getSymbolRate() * 100;
204 fec_inner = descriptor.getFecInner();
205 if ( fec_inner != eDVBFrontendParametersCable::FEC_None && fec_inner > eDVBFrontendParametersCable::FEC_8_9 )
206 fec_inner = eDVBFrontendParametersCable::FEC_Auto;
207 modulation = descriptor.getModulation();
208 if ( modulation > 0x5 )
209 modulation = eDVBFrontendParametersCable::Modulation_Auto;
210 inversion = eDVBFrontendParametersCable::Inversion_Unknown;
211 eDebug("Cable freq %d, mod %d, sr %d, fec %d",
213 modulation, symbol_rate, fec_inner);
216 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
218 /* EN 300 468 V1.11.1 DVB-SI SPEC */
219 frequency = descriptor.getCentreFrequency() * 10;
220 switch (descriptor.getBandwidth())
222 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
223 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
224 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
225 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
226 case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
227 case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
228 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
230 switch (descriptor.getCodeRateHpStream())
232 case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
233 case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
234 case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
235 case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
236 case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
237 default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
239 switch (descriptor.getCodeRateLpStream())
241 case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
242 case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
243 case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
244 case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
245 case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
246 default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
248 switch (descriptor.getTransmissionMode())
250 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
251 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
252 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
253 case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
254 case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
255 case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
256 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
258 switch (descriptor.getGuardInterval())
260 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
261 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
262 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
263 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
264 case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
265 case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
266 case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
267 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
269 // hierarchy = descriptor.getHierarchyInformation();
270 hierarchy = descriptor.getHierarchyInformation()&3;
271 if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
272 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
273 modulation = descriptor.getConstellation();
274 if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
275 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
276 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
277 system = eDVBFrontendParametersTerrestrial::System_DVB_T;
279 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
280 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
281 guard_interval, hierarchy, modulation);
284 eDVBFrontendParameters::eDVBFrontendParameters()
285 :m_type(-1), m_flags(0)
289 DEFINE_REF(eDVBFrontendParameters);
291 RESULT eDVBFrontendParameters::getSystem(int &t) const
294 return (m_type == -1) ? -1 : 0;
297 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
299 if (m_type != iDVBFrontend::feSatellite)
305 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
307 if (m_type != iDVBFrontend::feCable)
313 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
315 if (m_type != iDVBFrontend::feTerrestrial)
321 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
324 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
325 m_type = iDVBFrontend::feSatellite;
329 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
332 m_type = iDVBFrontend::feCable;
336 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
339 m_type = iDVBFrontend::feTerrestrial;
343 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
348 if (parm->getSystem(type))
352 diff = 1<<30; // big difference
358 case iDVBFrontend::feSatellite:
360 eDVBFrontendParametersSatellite osat;
361 if (parm->getDVBS(osat))
364 if (sat.orbital_position != osat.orbital_position)
366 else if (sat.polarisation != osat.polarisation)
368 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
370 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
374 diff = abs(sat.frequency - osat.frequency);
375 diff += abs(sat.symbol_rate - osat.symbol_rate);
379 case iDVBFrontend::feCable:
380 eDVBFrontendParametersCable ocable;
381 if (parm->getDVBC(ocable))
384 if (exact && cable.modulation != ocable.modulation
385 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
386 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
388 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
392 diff = abs(cable.frequency - ocable.frequency);
393 diff += abs(cable.symbol_rate - ocable.symbol_rate);
396 case iDVBFrontend::feTerrestrial:
397 eDVBFrontendParametersTerrestrial oterrestrial;
398 if (parm->getDVBT(oterrestrial))
400 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
401 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
402 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
404 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
405 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
406 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
408 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
409 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
410 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
412 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
413 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
414 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
416 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
417 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
418 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
420 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
421 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
422 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
424 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
425 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
426 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
428 else if (oterrestrial.system != terrestrial.system)
430 else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
431 oterrestrial.plpid != terrestrial.plpid)
434 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
442 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
446 case iDVBFrontend::feSatellite:
448 hash = (sat.orbital_position << 16);
449 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
452 case iDVBFrontend::feCable:
454 hash |= (cable.frequency/1000)&0xFFFF;
456 case iDVBFrontend::feTerrestrial:
458 hash |= (terrestrial.frequency/1000000)&0xFFFF;
465 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
469 case iDVBFrontend::feSatellite:
471 /* high symbol rate transponders tune faster, due to
472 requiring less zigzag and giving more symbols faster.
474 5s are definitely not enough on really low SR when
475 zigzag has to find the exact frequency first.
477 if (sat.symbol_rate > 20000000)
479 else if (sat.symbol_rate > 10000000)
485 case iDVBFrontend::feCable:
488 case iDVBFrontend::feTerrestrial:
496 DEFINE_REF(eDVBFrontend);
498 int eDVBFrontend::PriorityOrder=0;
499 int eDVBFrontend::PreferredFrontendIndex=-1;
502 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
503 :m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
504 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false)
505 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false)
506 #if HAVE_DVB_API_VERSION < 3
510 #if HAVE_DVB_API_VERSION < 3
511 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
512 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
514 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
517 m_timeout = eTimer::create(eApp);
518 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
520 m_tuneTimer = eTimer::create(eApp);
521 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
523 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
526 m_idleInputpower[0]=m_idleInputpower[1]=0;
528 ok = !openFrontend();
532 void eDVBFrontend::reopenFrontend()
539 int eDVBFrontend::openFrontend()
541 if (m_state != stateClosed)
542 return -1; // already opened
547 #if HAVE_DVB_API_VERSION < 3
548 FrontendInfo fe_info;
550 dvb_frontend_info fe_info;
554 eDebug("opening frontend %d", m_dvbid);
557 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
560 eWarning("failed! (%s) %m", m_filename);
565 eWarning("frontend %d already opened", m_dvbid);
567 if (m_delsys.empty())
569 #ifdef DTV_ENUM_DELSYS
570 struct dtv_property p[1];
571 p[0].cmd = DTV_ENUM_DELSYS;
572 struct dtv_properties cmdseq;
575 if (::ioctl(m_fd, FE_GET_PROPERTY, &cmdseq) >= 0)
579 for (i = 0; i < p[0].u.buffer.len ; i++)
581 fe_delivery_system_t delsys = (fe_delivery_system_t)p[0].u.buffer.data[i];
582 m_delsys[delsys] = true;
586 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
588 eWarning("ioctl FE_GET_INFO failed");
593 /* old DVB API, fill delsys map with some defaults */
594 switch (fe_info.type)
598 m_delsys[SYS_DVBS] = true;
599 #if DVB_API_VERSION >= 5
600 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
606 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
607 m_delsys[SYS_DVBC_ANNEX_A] = true;
609 m_delsys[SYS_DVBC_ANNEX_AC] = true;
615 m_delsys[SYS_DVBT] = true;
616 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
617 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
621 case FE_ATSC: // placeholder to prevent warning
631 m_simulate_fe->m_delsys = m_delsys;
634 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
635 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
638 setTone(iDVBFrontend::toneOff);
639 setVoltage(iDVBFrontend::voltageOff);
644 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
646 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
648 long tmp = m_data[LINKED_NEXT_PTR];
651 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
652 if (linked_fe->m_inuse)
654 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
655 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
658 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
664 eDebugNoSimulate("close frontend %d", m_dvbid);
665 if (m_data[SATCR] != -1)
669 m_sec->prepareTurnOffSatCR(*this);
670 m_tuneTimer->start(0, true);
671 if(!m_tuneTimer->isActive())
674 eDebug("[turnOffSatCR] no mainloop");
677 timeout = tuneLoopInt();
680 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
684 eDebug("[turnOffSatCR] running mainloop");
688 m_data[ROTOR_CMD] = -1;
691 setTone(iDVBFrontend::toneOff);
692 setVoltage(iDVBFrontend::voltageOff);
695 if (m_sec && !m_simulate)
696 m_sec->setRotorMoving(m_slotid, false);
700 eWarning("couldnt close frontend %d", m_dvbid);
704 setTone(iDVBFrontend::toneOff);
705 setVoltage(iDVBFrontend::voltageOff);
707 #if HAVE_DVB_API_VERSION < 3
710 if (!::close(m_secfd))
713 eWarning("couldnt close sec %d", m_dvbid);
717 m_state = stateClosed;
722 eDVBFrontend::~eDVBFrontend()
724 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
728 void eDVBFrontend::feEvent(int w)
730 eDVBFrontend *sec_fe = this;
731 long tmp = m_data[LINKED_PREV_PTR];
734 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
735 sec_fe = linked_fe->m_frontend;
736 sec_fe->getData(LINKED_NEXT_PTR, tmp);
740 #if HAVE_DVB_API_VERSION < 3
743 dvb_frontend_event event;
747 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
749 if (res && (errno == EAGAIN))
755 #if HAVE_DVB_API_VERSION < 3
756 if (event.type == FE_COMPLETION_EV)
758 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
759 if (event.status & FE_HAS_LOCK)
767 #if HAVE_DVB_API_VERSION >= 3
768 if (event.status & FE_TIMEDOUT) {
769 eDebug("FE_TIMEDOUT! ..abort");
782 eDebug("stateLostLock");
783 state = stateLostLock;
786 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
787 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
791 if (m_state != state)
794 m_stateChanged(this);
799 void eDVBFrontend::timeout()
802 if (m_state == stateTuning)
805 eDVBFrontend *sec_fe = this;
806 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
807 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
809 m_state = stateFailed;
810 m_stateChanged(this);
814 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
816 /* unsigned 32 bit division */
817 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
819 return (a + b / 2) / b;
822 int eDVBFrontend::readFrontendData(int type)
831 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
832 eDebug("FE_READ_BER failed (%m)");
837 case signalQualitydB: /* this will move into the driver */
839 int sat_max = 1600; // for stv0288 / bsbe2
840 int ret = 0x12345678;
844 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
845 eDebug("FE_READ_SNR failed (%m)");
846 else if (!strcmp(m_description, "BCM4501 (internal)"))
848 float SDS_SNRE = snr << 16;
851 eDVBFrontendParametersSatellite sparm;
852 oparm.getDVBS(sparm);
854 if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
856 static float SNR_COEFF[6] = {
859 197418.0 / 4194304.0,
860 -2602183.0 / 4194304.0,
861 20377212.0 / 4194304.0,
862 -37791203.0 / 4194304.0,
864 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
865 fval2 = pow(10.0, fval1)-1;
866 fval1 = 10.0 * log10(fval2);
870 fval2 = SNR_COEFF[0];
871 for (int i=1; i<6; ++i)
874 fval2 += SNR_COEFF[i];
880 #if HAVE_DVB_API_VERSION >= 3
883 float fval1 = SDS_SNRE / 268435456.0,
886 if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
897 fval4 = -10.0 * log10(fval1);
899 for (int i=0; i < 5; ++i)
900 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
905 ret = (int)(snr_in_db * 100);
907 else if (strstr(m_description, "Alps BSBE1 C01A") ||
908 strstr(m_description, "Alps -S(STV0288)"))
912 else if (snr == 0xFFFF) // i think this should not happen
916 enum { REALVAL, REGVAL };
917 const long CN_lookup[31][2] = {
918 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
919 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
920 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
921 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
922 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
923 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
926 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
927 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
931 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
936 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
941 ret = (((regval - CN_lookup[Imin][REGVAL])
942 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
943 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
944 + CN_lookup[Imin][REALVAL]) * 10;
950 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
951 !strcmp(m_description, "Alps -S") ||
952 !strcmp(m_description, "Philips -S") ||
953 !strcmp(m_description, "LG -S") )
956 ret = (int)((snr-39075)/17.647);
957 } else if (!strcmp(m_description, "Alps BSBE2"))
959 ret = (int)((snr >> 7) * 10);
960 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
962 int mse = (~snr) & 0xFF;
963 switch (parm_u_qam_modulation) {
964 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
965 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
966 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
967 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
968 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
971 } else if (!strcmp(m_description, "Philips TU1216"))
973 snr = 0xFF - (snr & 0xFF);
975 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
977 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
978 ret = (snr * 100) >> 8;
979 else if (!strcmp(m_description, "CXD1981"))
981 int mse = (~snr) & 0xFF;
982 switch (parm_u_qam_modulation) {
985 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
987 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
993 if (type == signalQuality)
995 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
999 oparm.getSystem(type);
1003 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
1004 case feCable: // we assume a max of 42db here
1005 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
1006 case feTerrestrial: // we assume a max of 24db here
1007 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
1011 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
1016 uint16_t strength=0;
1019 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
1020 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1026 #if HAVE_DVB_API_VERSION < 3
1027 FrontendStatus status=0;
1033 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1034 eDebug("FE_READ_STATUS failed (%m)");
1035 return !!(status&FE_HAS_LOCK);
1041 #if HAVE_DVB_API_VERSION < 3
1042 FrontendStatus status=0;
1048 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1049 eDebug("FE_READ_STATUS failed (%m)");
1050 return !!(status&FE_HAS_SYNC);
1054 case frontendNumber:
1060 void PutToDict(ePyObject &dict, const char*key, long value)
1062 ePyObject item = PyInt_FromLong(value);
1065 if (PyDict_SetItemString(dict, key, item))
1066 eDebug("put %s to dict failed", key);
1070 eDebug("could not create PyObject for %s", key);
1073 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1077 if (PyDict_SetItemString(dict, key, item))
1078 eDebug("put %s to dict failed", key);
1082 eDebug("invalid PyObject for %s", key);
1085 void PutToDict(ePyObject &dict, const char*key, const char *value)
1087 ePyObject item = PyString_FromString(value);
1090 if (PyDict_SetItemString(dict, key, item))
1091 eDebug("put %s to dict failed", key);
1095 eDebug("could not create PyObject for %s", key);
1098 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1100 PutToDict(dict, "tuner_type", "DVB-S");
1101 PutToDict(dict, "frequency", feparm.frequency);
1102 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1103 PutToDict(dict, "orbital_position", feparm.orbital_position);
1104 PutToDict(dict, "inversion", feparm.inversion);
1105 PutToDict(dict, "fec_inner", feparm.fec);
1106 PutToDict(dict, "modulation", feparm.modulation);
1107 PutToDict(dict, "polarization", feparm.polarisation);
1108 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1110 PutToDict(dict, "rolloff", feparm.rolloff);
1111 PutToDict(dict, "pilot", feparm.pilot);
1113 PutToDict(dict, "system", feparm.system);
1116 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1118 PutToDict(dict, "tuner_type", "DVB-T");
1119 PutToDict(dict, "frequency", feparm.frequency);
1120 PutToDict(dict, "bandwidth", feparm.bandwidth);
1121 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1122 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1123 PutToDict(dict, "constellation", feparm.modulation);
1124 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1125 PutToDict(dict, "guard_interval", feparm.guard_interval);
1126 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1127 PutToDict(dict, "inversion", feparm.inversion);
1128 PutToDict(dict, "system", feparm.system);
1129 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1131 PutToDict(dict, "plp_id", feparm.plpid);
1135 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1137 PutToDict(dict, "tuner_type", "DVB-C");
1138 PutToDict(dict, "frequency", feparm.frequency);
1139 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1140 PutToDict(dict, "modulation", feparm.modulation);
1141 PutToDict(dict, "inversion", feparm.inversion);
1142 PutToDict(dict, "fec_inner", feparm.fec_inner);
1145 #if HAVE_DVB_API_VERSION >= 5
1146 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1149 int frequency = parm_frequency + freq_offset;
1150 PutToDict(dict, "frequency", frequency);
1151 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1152 PutToDict(dict, "orbital_position", orb_pos);
1153 PutToDict(dict, "polarization", polarization);
1155 switch(parm_u_qpsk_fec_inner)
1157 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1158 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1159 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1160 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1161 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1162 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1163 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1164 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1165 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1166 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1167 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1168 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1170 PutToDict(dict, "fec_inner", tmp);
1172 switch (p[0].u.data)
1174 default: eDebug("got unsupported system from frontend! report as DVBS!");
1175 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1178 switch (p[2].u.data)
1180 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1181 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1182 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1183 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1185 PutToDict(dict, "rolloff", tmp);
1187 switch (p[3].u.data)
1189 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1190 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1191 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1193 PutToDict(dict, "pilot", tmp);
1195 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1198 PutToDict(dict, "system", tmp);
1200 switch (p[1].u.data)
1202 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1203 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1204 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1206 PutToDict(dict, "modulation", tmp);
1208 switch(parm_inversion & 3)
1210 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1211 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1212 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1214 PutToDict(dict, "inversion", tmp);
1217 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1221 tmp = p[1].u.data/1000;
1222 PutToDict(dict, "frequency", tmp);
1224 PutToDict(dict, "symbol_rate", p[2].u.data);
1226 switch (p[3].u.data)
1228 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1229 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1230 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1231 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1232 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1233 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1234 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1236 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1238 PutToDict(dict, "fec_inner", tmp);
1240 switch (p[4].u.data)
1242 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1243 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1244 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1245 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1246 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1248 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1250 PutToDict(dict, "modulation", tmp);
1252 switch (p[5].u.data)
1254 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1255 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1257 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1259 PutToDict(dict, "inversion", tmp);
1262 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1266 switch (p[0].u.data)
1268 default: eDebug("got unsupported system from frontend! report as DVBT!");
1269 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1272 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1274 PutToDict(dict, "plp_id", tmp);
1276 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1279 PutToDict(dict, "system", tmp);
1282 PutToDict(dict, "frequency", tmp);
1284 switch (p[2].u.data)
1286 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1287 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1288 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1289 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1290 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1291 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1293 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1295 PutToDict(dict, "bandwidth", tmp);
1297 switch (p[3].u.data)
1299 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1300 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1301 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1302 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1303 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1304 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1305 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1306 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1308 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1310 PutToDict(dict, "code_rate_lp", tmp);
1312 switch (p[4].u.data)
1314 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1315 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1316 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1317 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1318 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1319 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1320 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1321 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1323 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1325 PutToDict(dict, "code_rate_hp", tmp);
1327 switch (p[5].u.data)
1329 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1330 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1331 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1332 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1334 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1336 PutToDict(dict, "constellation", tmp);
1339 switch (p[6].u.data)
1341 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1342 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1343 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1344 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1345 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1346 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1348 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1350 PutToDict(dict, "transmission_mode", tmp);
1352 switch (p[7].u.data)
1354 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1355 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1356 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1357 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1358 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1359 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1360 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1362 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1364 PutToDict(dict, "guard_interval", tmp);
1366 switch (p[8].u.data)
1368 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1369 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1370 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1371 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1373 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1375 PutToDict(dict, "hierarchy_information", tmp);
1377 switch (p[9].u.data)
1379 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1380 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1382 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1384 PutToDict(dict, "inversion", tmp);
1387 #else // #if HAVE_DVB_API_VERSION >= 5
1388 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1391 int frequency = parm_frequency + freq_offset;
1392 PutToDict(dict, "frequency", frequency);
1393 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1394 PutToDict(dict, "orbital_position", orb_pos);
1395 PutToDict(dict, "polarization", polarization);
1397 switch((int)parm_u_qpsk_fec_inner)
1399 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1400 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1401 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1402 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1403 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1404 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1406 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1407 #if HAVE_DVB_API_VERSION >=3
1408 case FEC_S2_8PSK_1_2:
1409 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1410 case FEC_S2_8PSK_2_3:
1411 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1412 case FEC_S2_8PSK_3_4:
1413 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1414 case FEC_S2_8PSK_5_6:
1415 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1416 case FEC_S2_8PSK_7_8:
1417 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1418 case FEC_S2_8PSK_8_9:
1419 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1420 case FEC_S2_8PSK_3_5:
1421 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1422 case FEC_S2_8PSK_4_5:
1423 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1424 case FEC_S2_8PSK_9_10:
1425 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1428 PutToDict(dict, "fec_inner", tmp);
1429 #if HAVE_DVB_API_VERSION >=3
1430 PutToDict(dict, "modulation",
1431 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1432 eDVBFrontendParametersSatellite::Modulation_8PSK :
1433 eDVBFrontendParametersSatellite::Modulation_QPSK );
1434 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1436 switch(parm_inversion & 0xc)
1438 default: // unknown rolloff
1439 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1440 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1441 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1443 PutToDict(dict, "rolloff", tmp);
1444 switch(parm_inversion & 0x30)
1446 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1447 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1448 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1450 PutToDict(dict, "pilot", tmp);
1451 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1454 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1456 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1457 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1459 PutToDict(dict, "system", tmp);
1462 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1465 #if HAVE_DVB_API_VERSION < 3
1466 PutToDict(dict, "frequency", parm_frequency);
1468 PutToDict(dict, "frequency", parm_frequency/1000);
1470 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1471 switch(parm_u_qam_fec_inner)
1473 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1474 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1475 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1476 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1477 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1478 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1479 #if HAVE_DVB_API_VERSION >= 3
1480 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1483 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1485 PutToDict(dict, "fec_inner", tmp);
1486 switch(parm_u_qam_modulation)
1488 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1489 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1490 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1491 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1492 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1494 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1496 PutToDict(dict, "modulation", tmp);
1499 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1502 PutToDict(dict, "frequency", parm_frequency);
1503 switch (parm_u_ofdm_bandwidth)
1505 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1506 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1507 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1509 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1511 PutToDict(dict, "bandwidth", tmp);
1512 switch (parm_u_ofdm_code_rate_LP)
1514 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1515 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1516 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1517 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1518 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1520 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1522 PutToDict(dict, "code_rate_lp", tmp);
1523 switch (parm_u_ofdm_code_rate_HP)
1525 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1526 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1527 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1528 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1529 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1531 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1533 PutToDict(dict, "code_rate_hp", tmp);
1534 switch (parm_u_ofdm_constellation)
1536 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1537 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1538 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1540 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1542 PutToDict(dict, "constellation", tmp);
1543 switch (parm_u_ofdm_transmission_mode)
1545 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1546 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1548 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1550 PutToDict(dict, "transmission_mode", tmp);
1551 switch (parm_u_ofdm_guard_interval)
1553 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1554 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1555 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1556 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1558 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1560 PutToDict(dict, "guard_interval", tmp);
1561 switch (parm_u_ofdm_hierarchy_information)
1563 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1564 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1565 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1566 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1568 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1570 PutToDict(dict, "hierarchy_information", tmp);
1573 #endif // #if HAVE_DVB_API_VERSION >= 5
1575 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1577 if (dest && PyDict_Check(dest))
1579 const char *tmp = "UNKNOWN";
1600 PutToDict(dest, "tuner_state", tmp);
1601 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1602 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1603 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1604 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1605 int sigQualitydB = readFrontendData(signalQualitydB);
1606 if (sigQualitydB == 0x12345678) // not support yet
1608 ePyObject obj=Py_None;
1610 PutToDict(dest, "tuner_signal_quality_db", obj);
1613 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1614 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1618 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1620 if (dest && PyDict_Check(dest))
1623 FRONTENDPARAMETERS front;
1624 #if HAVE_DVB_API_VERSION >= 5
1625 struct dtv_property p[16];
1626 struct dtv_properties cmdseq;
1629 oparm.getSystem(type);
1633 p[0].cmd = DTV_DELIVERY_SYSTEM;
1634 p[1].cmd = DTV_MODULATION;
1635 p[2].cmd = DTV_ROLLOFF;
1636 p[3].cmd = DTV_PILOT;
1640 p[0].cmd = DTV_DELIVERY_SYSTEM;
1641 p[1].cmd = DTV_FREQUENCY;
1642 p[2].cmd = DTV_SYMBOL_RATE;
1643 p[3].cmd = DTV_INNER_FEC;
1644 p[4].cmd = DTV_MODULATION;
1645 p[5].cmd = DTV_INVERSION;
1649 p[0].cmd = DTV_DELIVERY_SYSTEM;
1650 p[1].cmd = DTV_FREQUENCY;
1651 p[2].cmd = DTV_BANDWIDTH_HZ;
1652 p[3].cmd = DTV_CODE_RATE_LP;
1653 p[4].cmd = DTV_CODE_RATE_HP;
1654 p[5].cmd = DTV_MODULATION;
1655 p[6].cmd = DTV_TRANSMISSION_MODE;
1656 p[7].cmd = DTV_GUARD_INTERVAL;
1657 p[8].cmd = DTV_HIERARCHY;
1658 p[9].cmd = DTV_INVERSION;
1659 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
1660 p[10].cmd = DTV_STREAM_ID;
1662 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1663 p[10].cmd = DTV_DVBT2_PLP_ID;
1671 if (m_simulate || m_fd == -1 || original)
1675 #if HAVE_DVB_API_VERSION >= 5
1676 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1678 eDebug("FE_GET_PROPERTY failed (%m)");
1681 else if (type == feSatellite && // use for DVB-S(2) only
1682 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1684 eDebug("FE_GET_FRONTEND failed (%m)");
1688 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1690 eDebug("FE_GET_FRONTEND failed (%m)");
1699 eDVBFrontendParametersSatellite sparm;
1700 oparm.getDVBS(sparm);
1701 PutSatelliteDataToDict(dest, sparm);
1704 eDVBFrontendParametersCable cparm;
1705 oparm.getDVBC(cparm);
1706 PutCableDataToDict(dest, cparm);
1709 eDVBFrontendParametersTerrestrial tparm;
1710 oparm.getDVBT(tparm);
1711 PutTerrestrialDataToDict(dest, tparm);
1717 FRONTENDPARAMETERS &parm = front;
1718 #if HAVE_DVB_API_VERSION >= 5
1722 eDVBFrontendParametersSatellite sparm;
1723 oparm.getDVBS(sparm);
1724 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1727 fillDictWithCableData(dest, p);
1730 fillDictWithTerrestrialData(dest, p);
1734 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1735 switch(parm_inversion & 3)
1738 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1741 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1745 PutToDict(dest, "inversion", tmp);
1748 eDVBFrontendParametersSatellite sparm;
1749 oparm.getDVBS(sparm);
1751 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1754 fillDictWithCableData(dest, parm);
1757 fillDictWithTerrestrialData(dest, parm);
1765 void eDVBFrontend::getFrontendData(ePyObject dest)
1767 if (dest && PyDict_Check(dest))
1770 PutToDict(dest, "tuner_number", m_slotid);
1772 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
1776 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
1777 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1779 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1784 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1792 PutToDict(dest, "tuner_type", tmp);
1796 #ifndef FP_IOCTL_GET_ID
1797 #define FP_IOCTL_GET_ID 0
1799 int eDVBFrontend::readInputpower()
1803 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1805 char proc_name2[64];
1806 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1807 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1809 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1811 if (fscanf(f, "%d", &power) != 1)
1812 eDebug("read %s failed!! (%m)", proc_name);
1814 eDebug("%s is %d\n", proc_name, power);
1819 // open front prozessor
1820 int fp=::open("/dev/dbox/fp0", O_RDWR);
1823 eDebug("couldn't open fp");
1826 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1827 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1829 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1838 bool eDVBFrontend::setSecSequencePos(int steps)
1840 eDebugNoSimulate("set sequence pos %d", steps);
1845 if (m_sec_sequence.current() != m_sec_sequence.end())
1846 ++m_sec_sequence.current();
1851 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1852 --m_sec_sequence.current();
1858 void eDVBFrontend::tuneLoop()
1863 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1866 eDVBFrontend *sec_fe = this;
1867 eDVBRegisteredFrontend *regFE = 0;
1868 long tmp = m_data[LINKED_PREV_PTR];
1871 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1872 sec_fe = prev->m_frontend;
1873 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1874 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1875 int state = sec_fe->m_state;
1876 #if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
1877 // workaround to put the kernel frontend thread into idle state!
1878 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1880 sec_fe->closeFrontend(true);
1881 state = sec_fe->m_state;
1884 // sec_fe is closed... we must reopen it here..
1885 if (state == stateClosed)
1893 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1895 long *sec_fe_data = sec_fe->m_data;
1896 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1898 switch (m_sec_sequence.current()->cmd)
1900 case eSecCommand::SLEEP:
1901 delay = m_sec_sequence.current()++->msec;
1902 eDebugNoSimulate("[SEC] sleep %dms", delay);
1904 case eSecCommand::GOTO:
1905 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1906 ++m_sec_sequence.current();
1908 case eSecCommand::SET_VOLTAGE:
1910 int voltage = m_sec_sequence.current()++->voltage;
1911 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1912 sec_fe->setVoltage(voltage);
1915 case eSecCommand::IF_VOLTAGE_GOTO:
1917 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1918 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1920 ++m_sec_sequence.current();
1923 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1925 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1926 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1928 ++m_sec_sequence.current();
1931 case eSecCommand::IF_TONE_GOTO:
1933 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1934 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1936 ++m_sec_sequence.current();
1939 case eSecCommand::IF_NOT_TONE_GOTO:
1941 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1942 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1944 ++m_sec_sequence.current();
1947 case eSecCommand::SET_TONE:
1948 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1949 sec_fe->setTone(m_sec_sequence.current()++->tone);
1951 case eSecCommand::SEND_DISEQC:
1952 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1953 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1954 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1955 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1956 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1957 eDebugNoSimulate("(DiSEqC reset)");
1958 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1959 eDebugNoSimulate("(DiSEqC peripherial power on)");
1961 eDebugNoSimulate("");
1962 ++m_sec_sequence.current();
1964 case eSecCommand::SEND_TONEBURST:
1965 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1966 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1968 case eSecCommand::SET_FRONTEND:
1970 int enableEvents = (m_sec_sequence.current()++)->val;
1971 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1972 setFrontend(enableEvents);
1975 case eSecCommand::START_TUNE_TIMEOUT:
1977 int tuneTimeout = m_sec_sequence.current()->timeout;
1978 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1980 m_timeout->start(tuneTimeout, 1);
1981 ++m_sec_sequence.current();
1984 case eSecCommand::SET_TIMEOUT:
1985 m_timeoutCount = m_sec_sequence.current()++->val;
1986 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1988 case eSecCommand::IF_TIMEOUT_GOTO:
1989 if (!m_timeoutCount)
1991 eDebugNoSimulate("[SEC] rotor timout");
1992 setSecSequencePos(m_sec_sequence.current()->steps);
1995 ++m_sec_sequence.current();
1997 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1999 int idx = m_sec_sequence.current()++->val;
2000 if ( idx == 0 || idx == 1 )
2002 m_idleInputpower[idx] = sec_fe->readInputpower();
2003 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
2006 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
2009 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
2011 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
2012 int idx = compare.val;
2013 if ( !m_simulate && (idx == 0 || idx == 1) )
2015 int idle = sec_fe->readInputpower();
2016 int diff = abs(idle-m_idleInputpower[idx]);
2019 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
2020 setSecSequencePos(compare.steps);
2024 ++m_sec_sequence.current();
2027 case eSecCommand::IF_TUNER_LOCKED_GOTO:
2029 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2032 setSecSequencePos(cmd.steps);
2036 int isLocked = readFrontendData(locked);
2037 m_idleInputpower[0] = m_idleInputpower[1] = 0;
2039 if (!m_timeoutCount && m_retryCount > 0)
2041 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
2044 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2047 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2049 cmd.lastSignal = signal;
2052 if (cmd.okcount > 4)
2054 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2055 setSecSequencePos(cmd.steps);
2056 m_state = stateLock;
2057 m_stateChanged(this);
2058 feEvent(-1); // flush events
2066 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2068 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2072 ++m_sec_sequence.current();
2075 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2076 m_runningInputpower = sec_fe->readInputpower();
2077 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2078 ++m_sec_sequence.current();
2080 case eSecCommand::SET_ROTOR_MOVING:
2082 m_sec->setRotorMoving(m_slotid, true);
2083 ++m_sec_sequence.current();
2085 case eSecCommand::SET_ROTOR_STOPPED:
2087 m_sec->setRotorMoving(m_slotid, false);
2088 ++m_sec_sequence.current();
2090 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2092 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2095 setSecSequencePos(cmd.steps);
2098 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2099 const char *txt = cmd.direction ? "running" : "stopped";
2101 if (!m_timeoutCount && m_retryCount > 0)
2103 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2105 m_runningInputpower,
2108 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2109 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2112 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2113 if ( cmd.okcount > 6 )
2115 eDebugNoSimulate("[SEC] rotor is %s", txt);
2116 if (setSecSequencePos(cmd.steps))
2122 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2125 ++m_sec_sequence.current();
2128 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2129 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2130 setSecSequencePos(m_sec_sequence.current()->steps);
2132 ++m_sec_sequence.current();
2134 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2135 eDebugNoSimulate("[SEC] invalidate current switch params");
2136 sec_fe_data[CSW] = -1;
2137 sec_fe_data[UCSW] = -1;
2138 sec_fe_data[TONEBURST] = -1;
2139 ++m_sec_sequence.current();
2141 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2142 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2143 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2144 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2145 eDebugNoSimulate("[SEC] update current switch params");
2146 ++m_sec_sequence.current();
2148 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2149 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2150 sec_fe_data[ROTOR_CMD] = -1;
2151 sec_fe_data[ROTOR_POS] = -1;
2152 ++m_sec_sequence.current();
2154 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2155 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2156 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2157 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2158 ++m_sec_sequence.current();
2160 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2161 m_retryCount = m_sec_sequence.current()++->val;
2162 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2164 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2167 eDebugNoSimulate("[SEC] no more rotor retrys");
2168 setSecSequencePos(m_sec_sequence.current()->steps);
2171 ++m_sec_sequence.current();
2173 case eSecCommand::SET_POWER_LIMITING_MODE:
2178 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2179 FILE *f=fopen(proc_name, "w");
2180 if (f) // new interface exist?
2182 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2183 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2184 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2186 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2189 else if (sec_fe->m_need_rotor_workaround)
2192 int slotid = sec_fe->m_slotid;
2193 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2195 sprintf(dev, "/dev/i2c-%d", slotid);
2196 else if (slotid == 2)
2197 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2198 else if (slotid == 3)
2199 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2200 int fd = ::open(dev, O_RDWR);
2202 unsigned char data[2];
2203 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2204 if(::read(fd, data, 1) != 1)
2205 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2206 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2208 data[0] |= 0x80; // enable static current limiting
2209 eDebugNoSimulate("[SEC] set static current limiting");
2213 data[0] &= ~0x80; // enable dynamic current limiting
2214 eDebugNoSimulate("[SEC] set dynamic current limiting");
2216 if(::write(fd, data, 1) != 1)
2217 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2221 ++m_sec_sequence.current();
2224 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2226 eDebugNoSimulate("[SEC] delayed close frontend");
2227 closeFrontend(false, true);
2228 ++m_sec_sequence.current();
2232 eDebugNoSimulate("[SEC] unhandled sec command %d",
2233 ++m_sec_sequence.current()->cmd);
2234 ++m_sec_sequence.current();
2237 m_tuneTimer->start(delay,true);
2241 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2246 void eDVBFrontend::setFrontend(bool recvEvents)
2250 eDebug("setting frontend %d", m_dvbid);
2253 oparm.getSystem(type);
2257 feEvent(-1); // flush events
2258 #if HAVE_DVB_API_VERSION >= 5
2259 if (type == iDVBFrontend::feSatellite)
2261 fe_rolloff_t rolloff = ROLLOFF_35;
2262 fe_pilot_t pilot = PILOT_OFF;
2263 fe_modulation_t modulation = QPSK;
2264 fe_delivery_system_t system = SYS_DVBS;
2265 eDVBFrontendParametersSatellite sparm;
2266 oparm.getDVBS(sparm);
2267 switch(sparm.system)
2269 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2270 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2272 switch(sparm.modulation)
2274 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2275 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2276 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2280 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2281 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2282 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2284 switch(sparm.rolloff)
2286 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2287 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2288 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2290 struct dtv_property p[10];
2291 struct dtv_properties cmdseq;
2293 p[0].cmd = DTV_CLEAR;
2294 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2295 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2296 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2297 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2298 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2299 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2300 if (system == SYS_DVBS2)
2302 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2303 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2304 p[9].cmd = DTV_TUNE;
2309 p[7].cmd = DTV_TUNE;
2312 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2314 perror("FE_SET_PROPERTY failed");
2318 else if (type == iDVBFrontend::feCable)
2320 struct dtv_property p[8];
2321 struct dtv_properties cmdseq;
2323 p[0].cmd = DTV_CLEAR;
2324 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2325 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2327 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2329 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2330 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2331 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2332 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2333 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2334 p[7].cmd = DTV_TUNE;
2336 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2338 perror("FE_SET_PROPERTY failed");
2342 else if (type == iDVBFrontend::feTerrestrial)
2344 fe_delivery_system_t system = SYS_DVBT;
2345 eDVBFrontendParametersTerrestrial tparm;
2346 oparm.getDVBT(tparm);
2347 switch (tparm.system)
2350 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2351 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2354 switch (tparm.bandwidth)
2356 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2357 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2358 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2360 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2361 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2362 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2363 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2365 struct dtv_property p[13];
2366 struct dtv_properties cmdseq;
2369 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2370 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2371 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2372 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2373 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2374 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2375 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2376 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2377 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2378 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2379 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2380 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
2381 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2382 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
2383 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2385 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2386 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2388 perror("FE_SET_PROPERTY failed");
2393 #endif /* HAVE_DVB_API_VERSION >= 5 */
2395 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2397 perror("FE_SET_FRONTEND failed");
2404 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2409 eWarning("no SEC module active!");
2412 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2415 #if HAVE_DVB_API_VERSION >= 3
2416 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d",
2419 feparm.polarisation,
2423 feparm.orbital_position,
2429 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2432 feparm.polarisation,
2436 feparm.orbital_position);
2438 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2439 switch (feparm.inversion)
2441 case eDVBFrontendParametersSatellite::Inversion_On:
2442 parm_inversion = INVERSION_ON;
2444 case eDVBFrontendParametersSatellite::Inversion_Off:
2445 parm_inversion = INVERSION_OFF;
2448 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2449 parm_inversion = INVERSION_AUTO;
2452 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2456 case eDVBFrontendParametersSatellite::FEC_None:
2457 parm_u_qpsk_fec_inner = FEC_NONE;
2459 case eDVBFrontendParametersSatellite::FEC_1_2:
2460 parm_u_qpsk_fec_inner = FEC_1_2;
2462 case eDVBFrontendParametersSatellite::FEC_2_3:
2463 parm_u_qpsk_fec_inner = FEC_2_3;
2465 case eDVBFrontendParametersSatellite::FEC_3_4:
2466 parm_u_qpsk_fec_inner = FEC_3_4;
2468 case eDVBFrontendParametersSatellite::FEC_5_6:
2469 parm_u_qpsk_fec_inner = FEC_5_6;
2471 case eDVBFrontendParametersSatellite::FEC_7_8:
2472 parm_u_qpsk_fec_inner = FEC_7_8;
2475 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2476 case eDVBFrontendParametersSatellite::FEC_Auto:
2477 parm_u_qpsk_fec_inner = FEC_AUTO;
2481 #if HAVE_DVB_API_VERSION >= 3
2486 case eDVBFrontendParametersSatellite::FEC_1_2:
2487 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2489 case eDVBFrontendParametersSatellite::FEC_2_3:
2490 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2492 case eDVBFrontendParametersSatellite::FEC_3_4:
2493 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2495 case eDVBFrontendParametersSatellite::FEC_3_5:
2496 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2498 case eDVBFrontendParametersSatellite::FEC_4_5:
2499 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2501 case eDVBFrontendParametersSatellite::FEC_5_6:
2502 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2504 case eDVBFrontendParametersSatellite::FEC_7_8:
2505 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2507 case eDVBFrontendParametersSatellite::FEC_8_9:
2508 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2510 case eDVBFrontendParametersSatellite::FEC_9_10:
2511 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2514 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2517 #if HAVE_DVB_API_VERSION < 5
2518 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2519 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2520 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2522 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2523 // 8PSK fec driver values are decimal 9 bigger
2528 // FIXME !!! get frequency range from tuner
2529 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2531 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2534 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2536 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2540 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2542 #if HAVE_DVB_API_VERSION < 3
2543 parm_frequency = feparm.frequency;
2545 parm_frequency = feparm.frequency * 1000;
2547 parm_u_qam_symbol_rate = feparm.symbol_rate;
2548 switch (feparm.modulation)
2550 case eDVBFrontendParametersCable::Modulation_QAM16:
2551 parm_u_qam_modulation = QAM_16;
2553 case eDVBFrontendParametersCable::Modulation_QAM32:
2554 parm_u_qam_modulation = QAM_32;
2556 case eDVBFrontendParametersCable::Modulation_QAM64:
2557 parm_u_qam_modulation = QAM_64;
2559 case eDVBFrontendParametersCable::Modulation_QAM128:
2560 parm_u_qam_modulation = QAM_128;
2562 case eDVBFrontendParametersCable::Modulation_QAM256:
2563 parm_u_qam_modulation = QAM_256;
2566 case eDVBFrontendParametersCable::Modulation_Auto:
2567 parm_u_qam_modulation = QAM_AUTO;
2570 switch (feparm.inversion)
2572 case eDVBFrontendParametersCable::Inversion_On:
2573 parm_inversion = INVERSION_ON;
2575 case eDVBFrontendParametersCable::Inversion_Off:
2576 parm_inversion = INVERSION_OFF;
2579 case eDVBFrontendParametersCable::Inversion_Unknown:
2580 parm_inversion = INVERSION_AUTO;
2583 switch (feparm.fec_inner)
2585 case eDVBFrontendParametersCable::FEC_None:
2586 parm_u_qam_fec_inner = FEC_NONE;
2588 case eDVBFrontendParametersCable::FEC_1_2:
2589 parm_u_qam_fec_inner = FEC_1_2;
2591 case eDVBFrontendParametersCable::FEC_2_3:
2592 parm_u_qam_fec_inner = FEC_2_3;
2594 case eDVBFrontendParametersCable::FEC_3_4:
2595 parm_u_qam_fec_inner = FEC_3_4;
2597 case eDVBFrontendParametersCable::FEC_5_6:
2598 parm_u_qam_fec_inner = FEC_5_6;
2600 case eDVBFrontendParametersCable::FEC_7_8:
2601 parm_u_qam_fec_inner = FEC_7_8;
2603 #if HAVE_DVB_API_VERSION >= 3
2604 case eDVBFrontendParametersCable::FEC_8_9:
2605 parm_u_qam_fec_inner = FEC_8_9;
2609 case eDVBFrontendParametersCable::FEC_Auto:
2610 parm_u_qam_fec_inner = FEC_AUTO;
2613 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2614 parm_frequency/1000,
2615 parm_u_qam_symbol_rate,
2616 parm_u_qam_fec_inner,
2617 parm_u_qam_modulation,
2619 oparm.setDVBC(feparm);
2623 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2625 parm_frequency = feparm.frequency;
2627 switch (feparm.bandwidth)
2629 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2630 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2632 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2633 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2635 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2636 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2638 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2639 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2641 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2642 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2644 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2645 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2648 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2649 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2652 switch (feparm.code_rate_LP)
2654 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2655 parm_u_ofdm_code_rate_LP = FEC_1_2;
2657 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2658 parm_u_ofdm_code_rate_LP = FEC_2_3;
2660 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2661 parm_u_ofdm_code_rate_LP = FEC_3_4;
2663 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2664 parm_u_ofdm_code_rate_LP = FEC_5_6;
2666 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2667 parm_u_ofdm_code_rate_LP = FEC_7_8;
2669 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2670 parm_u_ofdm_code_rate_LP = FEC_6_7;
2672 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2673 parm_u_ofdm_code_rate_LP = FEC_8_9;
2676 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2677 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2680 switch (feparm.code_rate_HP)
2682 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2683 parm_u_ofdm_code_rate_HP = FEC_1_2;
2685 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2686 parm_u_ofdm_code_rate_HP = FEC_2_3;
2688 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2689 parm_u_ofdm_code_rate_HP = FEC_3_4;
2691 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2692 parm_u_ofdm_code_rate_HP = FEC_5_6;
2694 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2695 parm_u_ofdm_code_rate_HP = FEC_7_8;
2697 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2698 parm_u_ofdm_code_rate_HP = FEC_6_7;
2700 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2701 parm_u_ofdm_code_rate_HP = FEC_8_9;
2704 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2705 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2708 switch (feparm.modulation)
2710 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2711 parm_u_ofdm_constellation = QPSK;
2713 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2714 parm_u_ofdm_constellation = QAM_16;
2716 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2717 parm_u_ofdm_constellation = QAM_64;
2719 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2720 parm_u_ofdm_constellation = QAM_256;
2723 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2724 parm_u_ofdm_constellation = QAM_AUTO;
2727 switch (feparm.transmission_mode)
2729 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2730 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2732 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2733 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2735 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2736 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2738 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2739 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2741 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2742 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2744 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2745 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2748 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2749 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2752 switch (feparm.guard_interval)
2754 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2755 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2757 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2758 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2760 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2761 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2763 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2764 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2766 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2767 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2769 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2770 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2772 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2773 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2776 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2777 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2780 switch (feparm.hierarchy)
2782 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2783 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2785 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2786 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2788 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2789 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2791 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2792 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2795 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2796 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2799 switch (feparm.inversion)
2801 case eDVBFrontendParametersTerrestrial::Inversion_On:
2802 parm_inversion = INVERSION_ON;
2804 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2805 parm_inversion = INVERSION_OFF;
2808 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2809 parm_inversion = INVERSION_AUTO;
2812 eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d, system %d, plpid %d",
2813 parm_frequency/1000,
2814 parm_u_ofdm_bandwidth,
2815 parm_u_ofdm_code_rate_LP,
2816 parm_u_ofdm_code_rate_HP,
2817 parm_u_ofdm_constellation,
2818 parm_u_ofdm_transmission_mode,
2819 parm_u_ofdm_guard_interval,
2820 parm_u_ofdm_hierarchy_information,
2824 oparm.setDVBT(feparm);
2828 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2830 unsigned int timeout = 5000;
2831 eDebugNoSimulate("(%d)tune", m_dvbid);
2838 if (where.getSystem(type) < 0)
2844 if (!m_sn && !m_simulate)
2846 eDebug("no frontend device opened... do not try to tune !!!");
2854 m_sec_sequence.clear();
2856 where.calcLockTimeout(timeout);
2862 eDVBFrontendParametersSatellite feparm;
2863 if (where.getDVBS(feparm))
2865 eDebug("no dvbs data!");
2869 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2871 eDVBFrontend *sec_fe = this;
2872 long tmp = m_data[LINKED_PREV_PTR];
2875 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2876 sec_fe = linked_fe->m_frontend;
2877 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2879 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2880 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = sec_fe->m_data[ROTOR_CMD] = sec_fe->m_data[ROTOR_POS] = -1; // reset diseqc
2882 m_rotor_mode = feparm.no_rotor_command_on_tune;
2884 m_sec->setRotorMoving(m_slotid, false);
2885 res=prepare_sat(feparm, timeout);
2893 eDVBFrontendParametersCable feparm;
2894 if (where.getDVBC(feparm))
2899 res=prepare_cable(feparm);
2903 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2904 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2909 eDVBFrontendParametersTerrestrial feparm;
2910 if (where.getDVBT(feparm))
2912 eDebug("no -T data");
2916 res=prepare_terrestrial(feparm);
2920 std::string enable_5V;
2921 char configStr[255];
2922 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2923 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2924 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2925 if (enable_5V == "True")
2926 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2928 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2929 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2940 m_sec_sequence.current() = m_sec_sequence.begin();
2944 m_tuneTimer->start(0,true);
2946 if (m_state != stateTuning)
2948 m_state = stateTuning;
2949 m_stateChanged(this);
2958 m_tuneTimer->stop();
2962 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2964 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2968 RESULT eDVBFrontend::setVoltage(int voltage)
2970 #if HAVE_DVB_API_VERSION < 3
2973 bool increased=false;
2974 fe_sec_voltage_t vlt;
2976 m_data[CUR_VOLTAGE]=voltage;
2980 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2981 vlt = SEC_VOLTAGE_OFF;
2984 #if HAVE_DVB_API_VERSION < 3
2985 vlt = SEC_VOLTAGE_13_5;
2991 vlt = SEC_VOLTAGE_13;
2994 #if HAVE_DVB_API_VERSION < 3
2995 vlt = SEC_VOLTAGE_18_5;
3001 vlt = SEC_VOLTAGE_18;
3008 #if HAVE_DVB_API_VERSION < 3
3009 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
3011 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
3012 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
3016 RESULT eDVBFrontend::getState(int &state)
3022 RESULT eDVBFrontend::setTone(int t)
3024 #if HAVE_DVB_API_VERSION < 3
3027 fe_sec_tone_mode_t tone;
3036 tone = SEC_TONE_OFF;
3043 #if HAVE_DVB_API_VERSION < 3
3044 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
3046 return ::ioctl(m_fd, FE_SET_TONE, tone);
3050 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3051 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3054 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3059 #if HAVE_DVB_API_VERSION < 3
3060 struct secCommand cmd;
3061 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3062 cmd.u.diseqc.cmdtype = diseqc.data[0];
3063 cmd.u.diseqc.addr = diseqc.data[1];
3064 cmd.u.diseqc.cmd = diseqc.data[2];
3065 cmd.u.diseqc.numParams = diseqc.len-3;
3066 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3067 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3069 struct dvb_diseqc_master_cmd cmd;
3070 memcpy(cmd.msg, diseqc.data, diseqc.len);
3071 cmd.msg_len = diseqc.len;
3072 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3078 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3079 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3081 RESULT eDVBFrontend::sendToneburst(int burst)
3085 #if HAVE_DVB_API_VERSION < 3
3086 secMiniCmd cmd = SEC_MINI_NONE;
3088 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3090 if ( burst == eDVBSatelliteDiseqcParameters::A )
3092 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3094 #if HAVE_DVB_API_VERSION < 3
3095 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3098 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3104 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3110 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3112 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3113 m_sec_sequence.push_back(list);
3115 m_sec_sequence = list;
3119 bool eDVBFrontend::isScheduledSendDiseqc()
3121 bool has_senddiseqc = false;
3122 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
3124 eSecCommandList::iterator cur = m_sec_sequence.current();
3125 while(cur != m_sec_sequence.end())
3127 if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
3129 has_senddiseqc = true;
3134 return has_senddiseqc;
3137 RESULT eDVBFrontend::getData(int num, long &data)
3139 if ( num < NUM_DATA_ENTRIES )
3147 RESULT eDVBFrontend::setData(int num, long val)
3149 if ( num < NUM_DATA_ENTRIES )
3157 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3161 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3163 if (feparm->getSystem(type) || !m_enabled)
3166 if (type == eDVBFrontend::feSatellite)
3168 eDVBFrontendParametersSatellite sat_parm;
3169 bool can_handle_dvbs, can_handle_dvbs2;
3170 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
3171 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
3172 if (feparm->getDVBS(sat_parm) < 0)
3176 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
3180 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
3184 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3185 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
3187 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3192 else if (type == eDVBFrontend::feCable)
3194 eDVBFrontendParametersCable cab_parm;
3195 if (feparm->getDVBC(cab_parm) < 0)
3199 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
3200 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
3205 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
3213 else if (type == eDVBFrontend::feTerrestrial)
3215 eDVBFrontendParametersTerrestrial ter_parm;
3216 bool can_handle_dvbt, can_handle_dvbt2;
3217 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
3218 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
3219 if (feparm->getDVBT(ter_parm) < 0)
3223 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
3227 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
3232 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
3234 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3239 if (score && preferred)
3241 /* make 'sure' we always prefer this frontend */
3248 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
3250 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
3251 if (it != m_delsys.end() && it->second)
3253 if (obeywhitelist && !m_delsys_whitelist.empty())
3255 it = m_delsys_whitelist.find(sys);
3256 if (it == m_delsys_whitelist.end() || !it->second) return false;
3263 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
3265 m_delsys_whitelist.clear();
3266 for (unsigned int i = 0; i < whitelist.size(); i++)
3268 m_delsys_whitelist[whitelist[i]] = true;
3272 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
3276 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3278 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3279 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3281 Id = PyTuple_GET_ITEM(obj, 0);
3282 Descr = PyTuple_GET_ITEM(obj, 1);
3283 Enabled = PyTuple_GET_ITEM(obj, 2);
3284 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3285 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3286 frontendId = PyTuple_GET_ITEM(obj, 5);
3287 m_slotid = PyInt_AsLong(Id);
3288 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3290 strcpy(m_description, PyString_AS_STRING(Descr));
3291 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3292 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3293 // m_slotid, m_description);
3296 m_enabled = (Enabled == Py_True);
3297 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3298 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3299 !!strstr(m_description, "Alps BSBE2") ||
3300 !!strstr(m_description, "Alps -S") ||
3301 !!strstr(m_description, "BCM4501");
3302 if (IsDVBS2 == Py_True)
3304 /* HACK for legacy dvb api without DELSYS support */
3305 m_delsys[SYS_DVBS2] = true;
3307 if (IsDVBT2 == Py_True)
3309 /* HACK for legacy dvb api without DELSYS support */
3310 m_delsys[SYS_DVBT2] = true;
3313 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3314 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", Enabled == Py_True ? "Yes" : "No", IsDVBS2 == Py_True ? "Yes" : "No", IsDVBT2 == Py_True ? "Yes" : "No" );
3317 PyErr_SetString(PyExc_StandardError,
3318 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");