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), m_is_usbtuner(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:
1057 return m_is_usbtuner;
1062 void PutToDict(ePyObject &dict, const char*key, long value)
1064 ePyObject item = PyInt_FromLong(value);
1067 if (PyDict_SetItemString(dict, key, item))
1068 eDebug("put %s to dict failed", key);
1072 eDebug("could not create PyObject for %s", key);
1075 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1079 if (PyDict_SetItemString(dict, key, item))
1080 eDebug("put %s to dict failed", key);
1084 eDebug("invalid PyObject for %s", key);
1087 void PutToDict(ePyObject &dict, const char*key, const char *value)
1089 ePyObject item = PyString_FromString(value);
1092 if (PyDict_SetItemString(dict, key, item))
1093 eDebug("put %s to dict failed", key);
1097 eDebug("could not create PyObject for %s", key);
1100 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1102 PutToDict(dict, "tuner_type", "DVB-S");
1103 PutToDict(dict, "frequency", feparm.frequency);
1104 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1105 PutToDict(dict, "orbital_position", feparm.orbital_position);
1106 PutToDict(dict, "inversion", feparm.inversion);
1107 PutToDict(dict, "fec_inner", feparm.fec);
1108 PutToDict(dict, "modulation", feparm.modulation);
1109 PutToDict(dict, "polarization", feparm.polarisation);
1110 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1112 PutToDict(dict, "rolloff", feparm.rolloff);
1113 PutToDict(dict, "pilot", feparm.pilot);
1115 PutToDict(dict, "system", feparm.system);
1118 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1120 PutToDict(dict, "tuner_type", "DVB-T");
1121 PutToDict(dict, "frequency", feparm.frequency);
1122 PutToDict(dict, "bandwidth", feparm.bandwidth);
1123 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1124 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1125 PutToDict(dict, "constellation", feparm.modulation);
1126 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1127 PutToDict(dict, "guard_interval", feparm.guard_interval);
1128 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1129 PutToDict(dict, "inversion", feparm.inversion);
1130 PutToDict(dict, "system", feparm.system);
1131 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1133 PutToDict(dict, "plp_id", feparm.plpid);
1137 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1139 PutToDict(dict, "tuner_type", "DVB-C");
1140 PutToDict(dict, "frequency", feparm.frequency);
1141 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1142 PutToDict(dict, "modulation", feparm.modulation);
1143 PutToDict(dict, "inversion", feparm.inversion);
1144 PutToDict(dict, "fec_inner", feparm.fec_inner);
1147 #if HAVE_DVB_API_VERSION >= 5
1148 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1151 int frequency = parm_frequency + freq_offset;
1152 PutToDict(dict, "frequency", frequency);
1153 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1154 PutToDict(dict, "orbital_position", orb_pos);
1155 PutToDict(dict, "polarization", polarization);
1157 switch(parm_u_qpsk_fec_inner)
1159 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1160 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1161 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1162 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1163 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1164 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1165 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1166 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1167 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1168 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1169 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1170 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1172 PutToDict(dict, "fec_inner", tmp);
1174 switch (p[0].u.data)
1176 default: eDebug("got unsupported system from frontend! report as DVBS!");
1177 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1180 switch (p[2].u.data)
1182 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1183 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1184 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1185 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1187 PutToDict(dict, "rolloff", tmp);
1189 switch (p[3].u.data)
1191 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1192 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1193 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1195 PutToDict(dict, "pilot", tmp);
1197 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1200 PutToDict(dict, "system", tmp);
1202 switch (p[1].u.data)
1204 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1205 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1206 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1208 PutToDict(dict, "modulation", tmp);
1210 switch(parm_inversion & 3)
1212 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1213 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1214 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1216 PutToDict(dict, "inversion", tmp);
1219 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1223 tmp = p[1].u.data/1000;
1224 PutToDict(dict, "frequency", tmp);
1226 PutToDict(dict, "symbol_rate", p[2].u.data);
1228 switch (p[3].u.data)
1230 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1231 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1232 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1233 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1234 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1235 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1236 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1238 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1240 PutToDict(dict, "fec_inner", tmp);
1242 switch (p[4].u.data)
1244 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1245 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1246 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1247 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1248 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1250 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1252 PutToDict(dict, "modulation", tmp);
1254 switch (p[5].u.data)
1256 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1257 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1259 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1261 PutToDict(dict, "inversion", tmp);
1264 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1268 switch (p[0].u.data)
1270 default: eDebug("got unsupported system from frontend! report as DVBT!");
1271 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1274 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1276 PutToDict(dict, "plp_id", tmp);
1278 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1281 PutToDict(dict, "system", tmp);
1284 PutToDict(dict, "frequency", tmp);
1286 switch (p[2].u.data)
1288 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1289 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1290 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1291 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1292 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1293 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1295 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1297 PutToDict(dict, "bandwidth", tmp);
1299 switch (p[3].u.data)
1301 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1302 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1303 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1304 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1305 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1306 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1307 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1308 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1310 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1312 PutToDict(dict, "code_rate_lp", tmp);
1314 switch (p[4].u.data)
1316 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1317 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1318 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1319 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1320 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1321 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1322 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1323 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1325 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1327 PutToDict(dict, "code_rate_hp", tmp);
1329 switch (p[5].u.data)
1331 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1332 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1333 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1334 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1336 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1338 PutToDict(dict, "constellation", tmp);
1341 switch (p[6].u.data)
1343 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1344 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1345 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1346 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1347 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1348 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1350 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1352 PutToDict(dict, "transmission_mode", tmp);
1354 switch (p[7].u.data)
1356 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1357 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1358 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1359 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1360 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1361 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1362 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1364 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1366 PutToDict(dict, "guard_interval", tmp);
1368 switch (p[8].u.data)
1370 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1371 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1372 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1373 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1375 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1377 PutToDict(dict, "hierarchy_information", tmp);
1379 switch (p[9].u.data)
1381 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1382 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1384 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1386 PutToDict(dict, "inversion", tmp);
1389 #else // #if HAVE_DVB_API_VERSION >= 5
1390 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1393 int frequency = parm_frequency + freq_offset;
1394 PutToDict(dict, "frequency", frequency);
1395 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1396 PutToDict(dict, "orbital_position", orb_pos);
1397 PutToDict(dict, "polarization", polarization);
1399 switch((int)parm_u_qpsk_fec_inner)
1401 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1402 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1403 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1404 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1405 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1406 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1408 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1409 #if HAVE_DVB_API_VERSION >=3
1410 case FEC_S2_8PSK_1_2:
1411 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1412 case FEC_S2_8PSK_2_3:
1413 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1414 case FEC_S2_8PSK_3_4:
1415 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1416 case FEC_S2_8PSK_5_6:
1417 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1418 case FEC_S2_8PSK_7_8:
1419 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1420 case FEC_S2_8PSK_8_9:
1421 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1422 case FEC_S2_8PSK_3_5:
1423 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1424 case FEC_S2_8PSK_4_5:
1425 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1426 case FEC_S2_8PSK_9_10:
1427 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1430 PutToDict(dict, "fec_inner", tmp);
1431 #if HAVE_DVB_API_VERSION >=3
1432 PutToDict(dict, "modulation",
1433 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1434 eDVBFrontendParametersSatellite::Modulation_8PSK :
1435 eDVBFrontendParametersSatellite::Modulation_QPSK );
1436 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1438 switch(parm_inversion & 0xc)
1440 default: // unknown rolloff
1441 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1442 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1443 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1445 PutToDict(dict, "rolloff", tmp);
1446 switch(parm_inversion & 0x30)
1448 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1449 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1450 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1452 PutToDict(dict, "pilot", tmp);
1453 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1456 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1458 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1459 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1461 PutToDict(dict, "system", tmp);
1464 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1467 #if HAVE_DVB_API_VERSION < 3
1468 PutToDict(dict, "frequency", parm_frequency);
1470 PutToDict(dict, "frequency", parm_frequency/1000);
1472 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1473 switch(parm_u_qam_fec_inner)
1475 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1476 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1477 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1478 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1479 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1480 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1481 #if HAVE_DVB_API_VERSION >= 3
1482 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1485 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1487 PutToDict(dict, "fec_inner", tmp);
1488 switch(parm_u_qam_modulation)
1490 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1491 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1492 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1493 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1494 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1496 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1498 PutToDict(dict, "modulation", tmp);
1501 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1504 PutToDict(dict, "frequency", parm_frequency);
1505 switch (parm_u_ofdm_bandwidth)
1507 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1508 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1509 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1511 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1513 PutToDict(dict, "bandwidth", tmp);
1514 switch (parm_u_ofdm_code_rate_LP)
1516 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1517 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1518 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1519 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1520 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1522 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1524 PutToDict(dict, "code_rate_lp", tmp);
1525 switch (parm_u_ofdm_code_rate_HP)
1527 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1528 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1529 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1530 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1531 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1533 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1535 PutToDict(dict, "code_rate_hp", tmp);
1536 switch (parm_u_ofdm_constellation)
1538 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1539 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1540 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1542 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1544 PutToDict(dict, "constellation", tmp);
1545 switch (parm_u_ofdm_transmission_mode)
1547 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1548 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1550 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1552 PutToDict(dict, "transmission_mode", tmp);
1553 switch (parm_u_ofdm_guard_interval)
1555 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1556 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1557 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1558 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1560 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1562 PutToDict(dict, "guard_interval", tmp);
1563 switch (parm_u_ofdm_hierarchy_information)
1565 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1566 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1567 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1568 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1570 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1572 PutToDict(dict, "hierarchy_information", tmp);
1575 #endif // #if HAVE_DVB_API_VERSION >= 5
1577 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1579 if (dest && PyDict_Check(dest))
1581 const char *tmp = "UNKNOWN";
1602 PutToDict(dest, "tuner_state", tmp);
1603 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1604 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1605 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1606 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1607 int sigQualitydB = readFrontendData(signalQualitydB);
1608 if (sigQualitydB == 0x12345678) // not support yet
1610 ePyObject obj=Py_None;
1612 PutToDict(dest, "tuner_signal_quality_db", obj);
1615 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1616 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1620 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1622 if (dest && PyDict_Check(dest))
1625 FRONTENDPARAMETERS front;
1626 #if HAVE_DVB_API_VERSION >= 5
1627 struct dtv_property p[16];
1628 struct dtv_properties cmdseq;
1631 oparm.getSystem(type);
1635 p[0].cmd = DTV_DELIVERY_SYSTEM;
1636 p[1].cmd = DTV_MODULATION;
1637 p[2].cmd = DTV_ROLLOFF;
1638 p[3].cmd = DTV_PILOT;
1642 p[0].cmd = DTV_DELIVERY_SYSTEM;
1643 p[1].cmd = DTV_FREQUENCY;
1644 p[2].cmd = DTV_SYMBOL_RATE;
1645 p[3].cmd = DTV_INNER_FEC;
1646 p[4].cmd = DTV_MODULATION;
1647 p[5].cmd = DTV_INVERSION;
1651 p[0].cmd = DTV_DELIVERY_SYSTEM;
1652 p[1].cmd = DTV_FREQUENCY;
1653 p[2].cmd = DTV_BANDWIDTH_HZ;
1654 p[3].cmd = DTV_CODE_RATE_LP;
1655 p[4].cmd = DTV_CODE_RATE_HP;
1656 p[5].cmd = DTV_MODULATION;
1657 p[6].cmd = DTV_TRANSMISSION_MODE;
1658 p[7].cmd = DTV_GUARD_INTERVAL;
1659 p[8].cmd = DTV_HIERARCHY;
1660 p[9].cmd = DTV_INVERSION;
1661 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
1662 p[10].cmd = DTV_STREAM_ID;
1664 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1665 p[10].cmd = DTV_DVBT2_PLP_ID;
1673 if (m_simulate || m_fd == -1 || original)
1677 #if HAVE_DVB_API_VERSION >= 5
1678 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1680 eDebug("FE_GET_PROPERTY failed (%m)");
1683 else if (type == feSatellite && // use for DVB-S(2) only
1684 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1686 eDebug("FE_GET_FRONTEND failed (%m)");
1690 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1692 eDebug("FE_GET_FRONTEND failed (%m)");
1701 eDVBFrontendParametersSatellite sparm;
1702 oparm.getDVBS(sparm);
1703 PutSatelliteDataToDict(dest, sparm);
1706 eDVBFrontendParametersCable cparm;
1707 oparm.getDVBC(cparm);
1708 PutCableDataToDict(dest, cparm);
1711 eDVBFrontendParametersTerrestrial tparm;
1712 oparm.getDVBT(tparm);
1713 PutTerrestrialDataToDict(dest, tparm);
1719 FRONTENDPARAMETERS &parm = front;
1720 #if HAVE_DVB_API_VERSION >= 5
1724 eDVBFrontendParametersSatellite sparm;
1725 oparm.getDVBS(sparm);
1726 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1729 fillDictWithCableData(dest, p);
1732 fillDictWithTerrestrialData(dest, p);
1736 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1737 switch(parm_inversion & 3)
1740 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1743 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1747 PutToDict(dest, "inversion", tmp);
1750 eDVBFrontendParametersSatellite sparm;
1751 oparm.getDVBS(sparm);
1753 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1756 fillDictWithCableData(dest, parm);
1759 fillDictWithTerrestrialData(dest, parm);
1767 void eDVBFrontend::getFrontendData(ePyObject dest)
1769 if (dest && PyDict_Check(dest))
1772 PutToDict(dest, "tuner_number", m_slotid);
1774 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
1778 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
1779 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1781 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1786 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1794 PutToDict(dest, "tuner_type", tmp);
1798 #ifndef FP_IOCTL_GET_ID
1799 #define FP_IOCTL_GET_ID 0
1801 int eDVBFrontend::readInputpower()
1805 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1807 char proc_name2[64];
1808 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1809 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1811 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1813 if (fscanf(f, "%d", &power) != 1)
1814 eDebug("read %s failed!! (%m)", proc_name);
1816 eDebug("%s is %d\n", proc_name, power);
1821 // open front prozessor
1822 int fp=::open("/dev/dbox/fp0", O_RDWR);
1825 eDebug("couldn't open fp");
1828 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1829 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1831 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1840 bool eDVBFrontend::setSecSequencePos(int steps)
1842 eDebugNoSimulate("set sequence pos %d", steps);
1847 if (m_sec_sequence.current() != m_sec_sequence.end())
1848 ++m_sec_sequence.current();
1853 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1854 --m_sec_sequence.current();
1860 void eDVBFrontend::tuneLoop()
1865 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1868 eDVBFrontend *sec_fe = this;
1869 eDVBRegisteredFrontend *regFE = 0;
1870 long tmp = m_data[LINKED_PREV_PTR];
1873 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1874 sec_fe = prev->m_frontend;
1875 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1876 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1877 int state = sec_fe->m_state;
1878 #if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
1879 // workaround to put the kernel frontend thread into idle state!
1880 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1882 sec_fe->closeFrontend(true);
1883 state = sec_fe->m_state;
1886 // sec_fe is closed... we must reopen it here..
1887 if (state == stateClosed)
1895 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1897 long *sec_fe_data = sec_fe->m_data;
1898 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1900 switch (m_sec_sequence.current()->cmd)
1902 case eSecCommand::SLEEP:
1903 delay = m_sec_sequence.current()++->msec;
1904 eDebugNoSimulate("[SEC] sleep %dms", delay);
1906 case eSecCommand::GOTO:
1907 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1908 ++m_sec_sequence.current();
1910 case eSecCommand::SET_VOLTAGE:
1912 int voltage = m_sec_sequence.current()++->voltage;
1913 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1914 sec_fe->setVoltage(voltage);
1917 case eSecCommand::IF_VOLTAGE_GOTO:
1919 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1920 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1922 ++m_sec_sequence.current();
1925 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1927 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1928 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1930 ++m_sec_sequence.current();
1933 case eSecCommand::IF_TONE_GOTO:
1935 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1936 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1938 ++m_sec_sequence.current();
1941 case eSecCommand::IF_NOT_TONE_GOTO:
1943 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1944 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1946 ++m_sec_sequence.current();
1949 case eSecCommand::SET_TONE:
1950 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1951 sec_fe->setTone(m_sec_sequence.current()++->tone);
1953 case eSecCommand::SEND_DISEQC:
1954 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1955 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1956 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1957 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1958 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1959 eDebugNoSimulate("(DiSEqC reset)");
1960 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1961 eDebugNoSimulate("(DiSEqC peripherial power on)");
1963 eDebugNoSimulate("");
1964 ++m_sec_sequence.current();
1966 case eSecCommand::SEND_TONEBURST:
1967 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1968 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1970 case eSecCommand::SET_FRONTEND:
1972 int enableEvents = (m_sec_sequence.current()++)->val;
1973 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1974 setFrontend(enableEvents);
1977 case eSecCommand::START_TUNE_TIMEOUT:
1979 int tuneTimeout = m_sec_sequence.current()->timeout;
1980 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1982 m_timeout->start(tuneTimeout, 1);
1983 ++m_sec_sequence.current();
1986 case eSecCommand::SET_TIMEOUT:
1987 m_timeoutCount = m_sec_sequence.current()++->val;
1988 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1990 case eSecCommand::IF_TIMEOUT_GOTO:
1991 if (!m_timeoutCount)
1993 eDebugNoSimulate("[SEC] rotor timout");
1994 setSecSequencePos(m_sec_sequence.current()->steps);
1997 ++m_sec_sequence.current();
1999 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
2001 int idx = m_sec_sequence.current()++->val;
2002 if ( idx == 0 || idx == 1 )
2004 m_idleInputpower[idx] = sec_fe->readInputpower();
2005 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
2008 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
2011 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
2013 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
2014 int idx = compare.val;
2015 if ( !m_simulate && (idx == 0 || idx == 1) )
2017 int idle = sec_fe->readInputpower();
2018 int diff = abs(idle-m_idleInputpower[idx]);
2021 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
2022 setSecSequencePos(compare.steps);
2026 ++m_sec_sequence.current();
2029 case eSecCommand::IF_TUNER_LOCKED_GOTO:
2031 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2034 setSecSequencePos(cmd.steps);
2038 int isLocked = readFrontendData(locked);
2039 m_idleInputpower[0] = m_idleInputpower[1] = 0;
2041 if (!m_timeoutCount && m_retryCount > 0)
2043 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
2046 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2049 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2051 cmd.lastSignal = signal;
2054 if (cmd.okcount > 4)
2056 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2057 setSecSequencePos(cmd.steps);
2058 m_state = stateLock;
2059 m_stateChanged(this);
2060 feEvent(-1); // flush events
2068 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2070 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2074 ++m_sec_sequence.current();
2077 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2078 m_runningInputpower = sec_fe->readInputpower();
2079 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2080 ++m_sec_sequence.current();
2082 case eSecCommand::SET_ROTOR_MOVING:
2084 m_sec->setRotorMoving(m_slotid, true);
2085 ++m_sec_sequence.current();
2087 case eSecCommand::SET_ROTOR_STOPPED:
2089 m_sec->setRotorMoving(m_slotid, false);
2090 ++m_sec_sequence.current();
2092 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2094 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2097 setSecSequencePos(cmd.steps);
2100 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2101 const char *txt = cmd.direction ? "running" : "stopped";
2103 if (!m_timeoutCount && m_retryCount > 0)
2105 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2107 m_runningInputpower,
2110 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2111 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2114 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2115 if ( cmd.okcount > 6 )
2117 eDebugNoSimulate("[SEC] rotor is %s", txt);
2118 if (setSecSequencePos(cmd.steps))
2124 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2127 ++m_sec_sequence.current();
2130 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2131 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2132 setSecSequencePos(m_sec_sequence.current()->steps);
2134 ++m_sec_sequence.current();
2136 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2137 eDebugNoSimulate("[SEC] invalidate current switch params");
2138 sec_fe_data[CSW] = -1;
2139 sec_fe_data[UCSW] = -1;
2140 sec_fe_data[TONEBURST] = -1;
2141 ++m_sec_sequence.current();
2143 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2144 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2145 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2146 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2147 eDebugNoSimulate("[SEC] update current switch params");
2148 ++m_sec_sequence.current();
2150 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2151 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2152 sec_fe_data[ROTOR_CMD] = -1;
2153 sec_fe_data[ROTOR_POS] = -1;
2154 ++m_sec_sequence.current();
2156 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2157 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2158 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2159 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2160 ++m_sec_sequence.current();
2162 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2163 m_retryCount = m_sec_sequence.current()++->val;
2164 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2166 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2169 eDebugNoSimulate("[SEC] no more rotor retrys");
2170 setSecSequencePos(m_sec_sequence.current()->steps);
2173 ++m_sec_sequence.current();
2175 case eSecCommand::SET_POWER_LIMITING_MODE:
2180 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2181 FILE *f=fopen(proc_name, "w");
2182 if (f) // new interface exist?
2184 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2185 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2186 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2188 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2191 else if (sec_fe->m_need_rotor_workaround)
2194 int slotid = sec_fe->m_slotid;
2195 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2197 sprintf(dev, "/dev/i2c-%d", slotid);
2198 else if (slotid == 2)
2199 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2200 else if (slotid == 3)
2201 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2202 int fd = ::open(dev, O_RDWR);
2204 unsigned char data[2];
2205 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2206 if(::read(fd, data, 1) != 1)
2207 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2208 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2210 data[0] |= 0x80; // enable static current limiting
2211 eDebugNoSimulate("[SEC] set static current limiting");
2215 data[0] &= ~0x80; // enable dynamic current limiting
2216 eDebugNoSimulate("[SEC] set dynamic current limiting");
2218 if(::write(fd, data, 1) != 1)
2219 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2223 ++m_sec_sequence.current();
2226 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2228 eDebugNoSimulate("[SEC] delayed close frontend");
2229 closeFrontend(false, true);
2230 ++m_sec_sequence.current();
2234 eDebugNoSimulate("[SEC] unhandled sec command %d",
2235 ++m_sec_sequence.current()->cmd);
2236 ++m_sec_sequence.current();
2239 m_tuneTimer->start(delay,true);
2243 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2248 void eDVBFrontend::setFrontend(bool recvEvents)
2252 eDebug("setting frontend %d", m_dvbid);
2255 oparm.getSystem(type);
2259 feEvent(-1); // flush events
2260 #if HAVE_DVB_API_VERSION >= 5
2261 if (type == iDVBFrontend::feSatellite)
2263 fe_rolloff_t rolloff = ROLLOFF_35;
2264 fe_pilot_t pilot = PILOT_OFF;
2265 fe_modulation_t modulation = QPSK;
2266 fe_delivery_system_t system = SYS_DVBS;
2267 eDVBFrontendParametersSatellite sparm;
2268 oparm.getDVBS(sparm);
2269 switch(sparm.system)
2271 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2272 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2274 switch(sparm.modulation)
2276 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2277 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2278 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2282 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2283 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2284 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2286 switch(sparm.rolloff)
2288 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2289 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2290 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2292 struct dtv_property p[10];
2293 struct dtv_properties cmdseq;
2295 p[0].cmd = DTV_CLEAR;
2296 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2297 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2298 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2299 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2300 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2301 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2302 if (system == SYS_DVBS2)
2304 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2305 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2306 p[9].cmd = DTV_TUNE;
2311 p[7].cmd = DTV_TUNE;
2314 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2316 perror("FE_SET_PROPERTY failed");
2320 else if (type == iDVBFrontend::feCable)
2322 struct dtv_property p[8];
2323 struct dtv_properties cmdseq;
2325 p[0].cmd = DTV_CLEAR;
2326 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2327 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2329 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2331 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2332 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2333 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2334 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2335 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2336 p[7].cmd = DTV_TUNE;
2338 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2340 perror("FE_SET_PROPERTY failed");
2344 else if (type == iDVBFrontend::feTerrestrial)
2346 fe_delivery_system_t system = SYS_DVBT;
2347 eDVBFrontendParametersTerrestrial tparm;
2348 oparm.getDVBT(tparm);
2349 switch (tparm.system)
2352 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2353 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2356 switch (tparm.bandwidth)
2358 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2359 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2360 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2362 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2363 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2364 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2365 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2367 struct dtv_property p[13];
2368 struct dtv_properties cmdseq;
2371 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2372 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2373 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2374 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2375 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2376 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2377 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2378 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2379 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2380 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2381 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2382 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
2383 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2384 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
2385 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2387 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2388 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2390 perror("FE_SET_PROPERTY failed");
2395 #endif /* HAVE_DVB_API_VERSION >= 5 */
2397 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2399 perror("FE_SET_FRONTEND failed");
2406 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2411 eWarning("no SEC module active!");
2414 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2417 #if HAVE_DVB_API_VERSION >= 3
2418 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",
2421 feparm.polarisation,
2425 feparm.orbital_position,
2431 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2434 feparm.polarisation,
2438 feparm.orbital_position);
2440 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2441 switch (feparm.inversion)
2443 case eDVBFrontendParametersSatellite::Inversion_On:
2444 parm_inversion = INVERSION_ON;
2446 case eDVBFrontendParametersSatellite::Inversion_Off:
2447 parm_inversion = INVERSION_OFF;
2450 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2451 parm_inversion = INVERSION_AUTO;
2454 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2458 case eDVBFrontendParametersSatellite::FEC_None:
2459 parm_u_qpsk_fec_inner = FEC_NONE;
2461 case eDVBFrontendParametersSatellite::FEC_1_2:
2462 parm_u_qpsk_fec_inner = FEC_1_2;
2464 case eDVBFrontendParametersSatellite::FEC_2_3:
2465 parm_u_qpsk_fec_inner = FEC_2_3;
2467 case eDVBFrontendParametersSatellite::FEC_3_4:
2468 parm_u_qpsk_fec_inner = FEC_3_4;
2470 case eDVBFrontendParametersSatellite::FEC_5_6:
2471 parm_u_qpsk_fec_inner = FEC_5_6;
2473 case eDVBFrontendParametersSatellite::FEC_7_8:
2474 parm_u_qpsk_fec_inner = FEC_7_8;
2477 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2478 case eDVBFrontendParametersSatellite::FEC_Auto:
2479 parm_u_qpsk_fec_inner = FEC_AUTO;
2483 #if HAVE_DVB_API_VERSION >= 3
2488 case eDVBFrontendParametersSatellite::FEC_1_2:
2489 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2491 case eDVBFrontendParametersSatellite::FEC_2_3:
2492 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2494 case eDVBFrontendParametersSatellite::FEC_3_4:
2495 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2497 case eDVBFrontendParametersSatellite::FEC_3_5:
2498 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2500 case eDVBFrontendParametersSatellite::FEC_4_5:
2501 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2503 case eDVBFrontendParametersSatellite::FEC_5_6:
2504 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2506 case eDVBFrontendParametersSatellite::FEC_7_8:
2507 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2509 case eDVBFrontendParametersSatellite::FEC_8_9:
2510 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2512 case eDVBFrontendParametersSatellite::FEC_9_10:
2513 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2516 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2519 #if HAVE_DVB_API_VERSION < 5
2520 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2521 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2522 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2524 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2525 // 8PSK fec driver values are decimal 9 bigger
2530 // FIXME !!! get frequency range from tuner
2531 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2533 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2536 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2538 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2542 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2544 #if HAVE_DVB_API_VERSION < 3
2545 parm_frequency = feparm.frequency;
2547 parm_frequency = feparm.frequency * 1000;
2549 parm_u_qam_symbol_rate = feparm.symbol_rate;
2550 switch (feparm.modulation)
2552 case eDVBFrontendParametersCable::Modulation_QAM16:
2553 parm_u_qam_modulation = QAM_16;
2555 case eDVBFrontendParametersCable::Modulation_QAM32:
2556 parm_u_qam_modulation = QAM_32;
2558 case eDVBFrontendParametersCable::Modulation_QAM64:
2559 parm_u_qam_modulation = QAM_64;
2561 case eDVBFrontendParametersCable::Modulation_QAM128:
2562 parm_u_qam_modulation = QAM_128;
2564 case eDVBFrontendParametersCable::Modulation_QAM256:
2565 parm_u_qam_modulation = QAM_256;
2568 case eDVBFrontendParametersCable::Modulation_Auto:
2569 parm_u_qam_modulation = QAM_AUTO;
2572 switch (feparm.inversion)
2574 case eDVBFrontendParametersCable::Inversion_On:
2575 parm_inversion = INVERSION_ON;
2577 case eDVBFrontendParametersCable::Inversion_Off:
2578 parm_inversion = INVERSION_OFF;
2581 case eDVBFrontendParametersCable::Inversion_Unknown:
2582 parm_inversion = INVERSION_AUTO;
2585 switch (feparm.fec_inner)
2587 case eDVBFrontendParametersCable::FEC_None:
2588 parm_u_qam_fec_inner = FEC_NONE;
2590 case eDVBFrontendParametersCable::FEC_1_2:
2591 parm_u_qam_fec_inner = FEC_1_2;
2593 case eDVBFrontendParametersCable::FEC_2_3:
2594 parm_u_qam_fec_inner = FEC_2_3;
2596 case eDVBFrontendParametersCable::FEC_3_4:
2597 parm_u_qam_fec_inner = FEC_3_4;
2599 case eDVBFrontendParametersCable::FEC_5_6:
2600 parm_u_qam_fec_inner = FEC_5_6;
2602 case eDVBFrontendParametersCable::FEC_7_8:
2603 parm_u_qam_fec_inner = FEC_7_8;
2605 #if HAVE_DVB_API_VERSION >= 3
2606 case eDVBFrontendParametersCable::FEC_8_9:
2607 parm_u_qam_fec_inner = FEC_8_9;
2611 case eDVBFrontendParametersCable::FEC_Auto:
2612 parm_u_qam_fec_inner = FEC_AUTO;
2615 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2616 parm_frequency/1000,
2617 parm_u_qam_symbol_rate,
2618 parm_u_qam_fec_inner,
2619 parm_u_qam_modulation,
2621 oparm.setDVBC(feparm);
2625 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2627 parm_frequency = feparm.frequency;
2629 switch (feparm.bandwidth)
2631 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2632 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2634 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2635 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2637 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2638 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2640 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2641 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2643 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2644 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2646 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2647 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2650 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2651 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2654 switch (feparm.code_rate_LP)
2656 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2657 parm_u_ofdm_code_rate_LP = FEC_1_2;
2659 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2660 parm_u_ofdm_code_rate_LP = FEC_2_3;
2662 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2663 parm_u_ofdm_code_rate_LP = FEC_3_4;
2665 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2666 parm_u_ofdm_code_rate_LP = FEC_5_6;
2668 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2669 parm_u_ofdm_code_rate_LP = FEC_7_8;
2671 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2672 parm_u_ofdm_code_rate_LP = FEC_6_7;
2674 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2675 parm_u_ofdm_code_rate_LP = FEC_8_9;
2678 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2679 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2682 switch (feparm.code_rate_HP)
2684 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2685 parm_u_ofdm_code_rate_HP = FEC_1_2;
2687 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2688 parm_u_ofdm_code_rate_HP = FEC_2_3;
2690 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2691 parm_u_ofdm_code_rate_HP = FEC_3_4;
2693 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2694 parm_u_ofdm_code_rate_HP = FEC_5_6;
2696 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2697 parm_u_ofdm_code_rate_HP = FEC_7_8;
2699 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2700 parm_u_ofdm_code_rate_HP = FEC_6_7;
2702 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2703 parm_u_ofdm_code_rate_HP = FEC_8_9;
2706 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2707 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2710 switch (feparm.modulation)
2712 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2713 parm_u_ofdm_constellation = QPSK;
2715 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2716 parm_u_ofdm_constellation = QAM_16;
2718 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2719 parm_u_ofdm_constellation = QAM_64;
2721 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2722 parm_u_ofdm_constellation = QAM_256;
2725 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2726 parm_u_ofdm_constellation = QAM_AUTO;
2729 switch (feparm.transmission_mode)
2731 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2732 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2734 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2735 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2737 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2738 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2740 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2741 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2743 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2744 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2746 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2747 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2750 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2751 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2754 switch (feparm.guard_interval)
2756 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2757 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2759 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2760 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2762 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2763 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2765 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2766 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2768 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2769 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2771 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2772 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2774 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2775 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2778 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2779 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2782 switch (feparm.hierarchy)
2784 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2785 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2787 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2788 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2790 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2791 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2793 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2794 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2797 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2798 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2801 switch (feparm.inversion)
2803 case eDVBFrontendParametersTerrestrial::Inversion_On:
2804 parm_inversion = INVERSION_ON;
2806 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2807 parm_inversion = INVERSION_OFF;
2810 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2811 parm_inversion = INVERSION_AUTO;
2814 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",
2815 parm_frequency/1000,
2816 parm_u_ofdm_bandwidth,
2817 parm_u_ofdm_code_rate_LP,
2818 parm_u_ofdm_code_rate_HP,
2819 parm_u_ofdm_constellation,
2820 parm_u_ofdm_transmission_mode,
2821 parm_u_ofdm_guard_interval,
2822 parm_u_ofdm_hierarchy_information,
2826 oparm.setDVBT(feparm);
2830 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2832 unsigned int timeout = 5000;
2833 eDebugNoSimulate("(%d)tune", m_dvbid);
2840 if (where.getSystem(type) < 0)
2846 if (!m_sn && !m_simulate)
2848 eDebug("no frontend device opened... do not try to tune !!!");
2856 m_sec_sequence.clear();
2858 where.calcLockTimeout(timeout);
2864 eDVBFrontendParametersSatellite feparm;
2865 if (where.getDVBS(feparm))
2867 eDebug("no dvbs data!");
2871 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2873 eDVBFrontend *sec_fe = this;
2874 long tmp = m_data[LINKED_PREV_PTR];
2877 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2878 sec_fe = linked_fe->m_frontend;
2879 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2881 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2882 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
2884 m_rotor_mode = feparm.no_rotor_command_on_tune;
2886 m_sec->setRotorMoving(m_slotid, false);
2887 res=prepare_sat(feparm, timeout);
2895 eDVBFrontendParametersCable feparm;
2896 if (where.getDVBC(feparm))
2901 res=prepare_cable(feparm);
2905 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2906 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2911 eDVBFrontendParametersTerrestrial feparm;
2912 if (where.getDVBT(feparm))
2914 eDebug("no -T data");
2918 res=prepare_terrestrial(feparm);
2922 std::string enable_5V;
2923 char configStr[255];
2924 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2925 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2926 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2927 if (enable_5V == "True")
2928 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2930 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2931 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2942 m_sec_sequence.current() = m_sec_sequence.begin();
2946 m_tuneTimer->start(0,true);
2948 if (m_state != stateTuning)
2950 m_state = stateTuning;
2951 m_stateChanged(this);
2960 m_tuneTimer->stop();
2964 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2966 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2970 RESULT eDVBFrontend::setVoltage(int voltage)
2972 #if HAVE_DVB_API_VERSION < 3
2975 bool increased=false;
2976 fe_sec_voltage_t vlt;
2978 m_data[CUR_VOLTAGE]=voltage;
2982 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2983 vlt = SEC_VOLTAGE_OFF;
2986 #if HAVE_DVB_API_VERSION < 3
2987 vlt = SEC_VOLTAGE_13_5;
2993 vlt = SEC_VOLTAGE_13;
2996 #if HAVE_DVB_API_VERSION < 3
2997 vlt = SEC_VOLTAGE_18_5;
3003 vlt = SEC_VOLTAGE_18;
3010 #if HAVE_DVB_API_VERSION < 3
3011 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
3013 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
3014 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
3018 RESULT eDVBFrontend::getState(int &state)
3024 RESULT eDVBFrontend::setTone(int t)
3026 #if HAVE_DVB_API_VERSION < 3
3029 fe_sec_tone_mode_t tone;
3038 tone = SEC_TONE_OFF;
3045 #if HAVE_DVB_API_VERSION < 3
3046 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
3048 return ::ioctl(m_fd, FE_SET_TONE, tone);
3052 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3053 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3056 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3061 #if HAVE_DVB_API_VERSION < 3
3062 struct secCommand cmd;
3063 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3064 cmd.u.diseqc.cmdtype = diseqc.data[0];
3065 cmd.u.diseqc.addr = diseqc.data[1];
3066 cmd.u.diseqc.cmd = diseqc.data[2];
3067 cmd.u.diseqc.numParams = diseqc.len-3;
3068 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3069 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3071 struct dvb_diseqc_master_cmd cmd;
3072 memcpy(cmd.msg, diseqc.data, diseqc.len);
3073 cmd.msg_len = diseqc.len;
3074 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3080 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3081 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3083 RESULT eDVBFrontend::sendToneburst(int burst)
3087 #if HAVE_DVB_API_VERSION < 3
3088 secMiniCmd cmd = SEC_MINI_NONE;
3090 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3092 if ( burst == eDVBSatelliteDiseqcParameters::A )
3094 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3096 #if HAVE_DVB_API_VERSION < 3
3097 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3100 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3106 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3112 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3114 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3115 m_sec_sequence.push_back(list);
3117 m_sec_sequence = list;
3121 bool eDVBFrontend::isScheduledSendDiseqc()
3123 bool has_senddiseqc = false;
3124 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
3126 eSecCommandList::iterator cur = m_sec_sequence.current();
3127 while(cur != m_sec_sequence.end())
3129 if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
3131 has_senddiseqc = true;
3136 return has_senddiseqc;
3139 RESULT eDVBFrontend::getData(int num, long &data)
3141 if ( num < NUM_DATA_ENTRIES )
3149 RESULT eDVBFrontend::setData(int num, long val)
3151 if ( num < NUM_DATA_ENTRIES )
3159 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3163 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3165 if (feparm->getSystem(type) || !m_enabled)
3168 if (type == eDVBFrontend::feSatellite)
3170 eDVBFrontendParametersSatellite sat_parm;
3171 bool can_handle_dvbs, can_handle_dvbs2;
3172 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
3173 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
3174 if (feparm->getDVBS(sat_parm) < 0)
3178 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
3182 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
3186 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3187 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
3189 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3194 else if (type == eDVBFrontend::feCable)
3196 eDVBFrontendParametersCable cab_parm;
3197 if (feparm->getDVBC(cab_parm) < 0)
3201 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
3202 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
3207 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
3215 else if (type == eDVBFrontend::feTerrestrial)
3217 eDVBFrontendParametersTerrestrial ter_parm;
3218 bool can_handle_dvbt, can_handle_dvbt2;
3219 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
3220 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
3221 if (feparm->getDVBT(ter_parm) < 0)
3225 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
3229 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
3234 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
3236 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3241 if (score && preferred)
3243 /* make 'sure' we always prefer this frontend */
3250 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
3252 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
3253 if (it != m_delsys.end() && it->second)
3255 if (obeywhitelist && !m_delsys_whitelist.empty())
3257 it = m_delsys_whitelist.find(sys);
3258 if (it == m_delsys_whitelist.end() || !it->second) return false;
3265 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
3267 m_delsys_whitelist.clear();
3268 for (unsigned int i = 0; i < whitelist.size(); i++)
3270 m_delsys_whitelist[whitelist[i]] = true;
3274 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
3278 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3280 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3281 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3283 Id = PyTuple_GET_ITEM(obj, 0);
3284 Descr = PyTuple_GET_ITEM(obj, 1);
3285 Enabled = PyTuple_GET_ITEM(obj, 2);
3286 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3287 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3288 frontendId = PyTuple_GET_ITEM(obj, 5);
3289 m_slotid = PyInt_AsLong(Id);
3290 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3292 strcpy(m_description, PyString_AS_STRING(Descr));
3293 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3294 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3295 // m_slotid, m_description);
3298 m_enabled = (Enabled == Py_True);
3299 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3300 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3301 !!strstr(m_description, "Alps BSBE2") ||
3302 !!strstr(m_description, "Alps -S") ||
3303 !!strstr(m_description, "BCM4501");
3304 if (IsDVBS2 == Py_True)
3306 /* HACK for legacy dvb api without DELSYS support */
3307 m_delsys[SYS_DVBS2] = true;
3309 if (IsDVBT2 == Py_True)
3311 /* HACK for legacy dvb api without DELSYS support */
3312 m_delsys[SYS_DVBT2] = true;
3315 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3316 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" );
3319 PyErr_SetString(PyExc_StandardError,
3320 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");