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)
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, m_data[SATCR]);
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;
785 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
788 if (m_state != state)
791 m_stateChanged(this);
796 void eDVBFrontend::timeout()
799 if (m_state == stateTuning)
802 eDVBFrontend *sec_fe = this;
803 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
805 m_state = stateFailed;
806 m_stateChanged(this);
810 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
812 /* unsigned 32 bit division */
813 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
815 return (a + b / 2) / b;
818 int eDVBFrontend::readFrontendData(int type)
827 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
828 eDebug("FE_READ_BER failed (%m)");
833 case signalQualitydB: /* this will move into the driver */
835 int sat_max = 1600; // for stv0288 / bsbe2
836 int ret = 0x12345678;
840 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
841 eDebug("FE_READ_SNR failed (%m)");
842 else if (!strcmp(m_description, "BCM4501 (internal)"))
844 float SDS_SNRE = snr << 16;
847 eDVBFrontendParametersSatellite sparm;
848 oparm.getDVBS(sparm);
850 if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
852 static float SNR_COEFF[6] = {
855 197418.0 / 4194304.0,
856 -2602183.0 / 4194304.0,
857 20377212.0 / 4194304.0,
858 -37791203.0 / 4194304.0,
860 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
861 fval2 = pow(10.0, fval1)-1;
862 fval1 = 10.0 * log10(fval2);
866 fval2 = SNR_COEFF[0];
867 for (int i=1; i<6; ++i)
870 fval2 += SNR_COEFF[i];
876 #if HAVE_DVB_API_VERSION >= 3
879 float fval1 = SDS_SNRE / 268435456.0,
882 if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
893 fval4 = -10.0 * log10(fval1);
895 for (int i=0; i < 5; ++i)
896 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
901 ret = (int)(snr_in_db * 100);
903 else if (strstr(m_description, "Alps BSBE1 C01A") ||
904 strstr(m_description, "Alps -S(STV0288)"))
908 else if (snr == 0xFFFF) // i think this should not happen
912 enum { REALVAL, REGVAL };
913 const long CN_lookup[31][2] = {
914 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
915 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
916 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
917 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
918 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
919 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
922 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
923 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
927 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
932 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
937 ret = (((regval - CN_lookup[Imin][REGVAL])
938 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
939 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
940 + CN_lookup[Imin][REALVAL]) * 10;
946 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
947 !strcmp(m_description, "Alps -S") ||
948 !strcmp(m_description, "Philips -S") ||
949 !strcmp(m_description, "LG -S") )
952 ret = (int)((snr-39075)/17.647);
953 } else if (!strcmp(m_description, "Alps BSBE2"))
955 ret = (int)((snr >> 7) * 10);
956 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
958 int mse = (~snr) & 0xFF;
959 switch (parm_u_qam_modulation) {
960 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
961 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
962 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
963 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
964 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
967 } else if (!strcmp(m_description, "Philips TU1216"))
969 snr = 0xFF - (snr & 0xFF);
971 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
973 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
974 ret = (snr * 100) >> 8;
975 else if (!strcmp(m_description, "CXD1981"))
977 int mse = (~snr) & 0xFF;
978 switch (parm_u_qam_modulation) {
981 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
983 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
989 if (type == signalQuality)
991 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
995 oparm.getSystem(type);
999 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
1000 case feCable: // we assume a max of 42db here
1001 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
1002 case feTerrestrial: // we assume a max of 24db here
1003 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
1007 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
1012 uint16_t strength=0;
1015 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
1016 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1022 #if HAVE_DVB_API_VERSION < 3
1023 FrontendStatus status=0;
1029 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1030 eDebug("FE_READ_STATUS failed (%m)");
1031 return !!(status&FE_HAS_LOCK);
1037 #if HAVE_DVB_API_VERSION < 3
1038 FrontendStatus status=0;
1044 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1045 eDebug("FE_READ_STATUS failed (%m)");
1046 return !!(status&FE_HAS_SYNC);
1050 case frontendNumber:
1056 void PutToDict(ePyObject &dict, const char*key, long value)
1058 ePyObject item = PyInt_FromLong(value);
1061 if (PyDict_SetItemString(dict, key, item))
1062 eDebug("put %s to dict failed", key);
1066 eDebug("could not create PyObject for %s", key);
1069 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1073 if (PyDict_SetItemString(dict, key, item))
1074 eDebug("put %s to dict failed", key);
1078 eDebug("invalid PyObject for %s", key);
1081 void PutToDict(ePyObject &dict, const char*key, const char *value)
1083 ePyObject item = PyString_FromString(value);
1086 if (PyDict_SetItemString(dict, key, item))
1087 eDebug("put %s to dict failed", key);
1091 eDebug("could not create PyObject for %s", key);
1094 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1096 PutToDict(dict, "tuner_type", "DVB-S");
1097 PutToDict(dict, "frequency", feparm.frequency);
1098 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1099 PutToDict(dict, "orbital_position", feparm.orbital_position);
1100 PutToDict(dict, "inversion", feparm.inversion);
1101 PutToDict(dict, "fec_inner", feparm.fec);
1102 PutToDict(dict, "modulation", feparm.modulation);
1103 PutToDict(dict, "polarization", feparm.polarisation);
1104 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1106 PutToDict(dict, "rolloff", feparm.rolloff);
1107 PutToDict(dict, "pilot", feparm.pilot);
1109 PutToDict(dict, "system", feparm.system);
1112 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1114 PutToDict(dict, "tuner_type", "DVB-T");
1115 PutToDict(dict, "frequency", feparm.frequency);
1116 PutToDict(dict, "bandwidth", feparm.bandwidth);
1117 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1118 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1119 PutToDict(dict, "constellation", feparm.modulation);
1120 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1121 PutToDict(dict, "guard_interval", feparm.guard_interval);
1122 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1123 PutToDict(dict, "inversion", feparm.inversion);
1124 PutToDict(dict, "system", feparm.system);
1125 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1127 PutToDict(dict, "plp_id", feparm.plpid);
1131 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1133 PutToDict(dict, "tuner_type", "DVB-C");
1134 PutToDict(dict, "frequency", feparm.frequency);
1135 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1136 PutToDict(dict, "modulation", feparm.modulation);
1137 PutToDict(dict, "inversion", feparm.inversion);
1138 PutToDict(dict, "fec_inner", feparm.fec_inner);
1141 #if HAVE_DVB_API_VERSION >= 5
1142 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1145 int frequency = parm_frequency + freq_offset;
1146 PutToDict(dict, "frequency", frequency);
1147 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1148 PutToDict(dict, "orbital_position", orb_pos);
1149 PutToDict(dict, "polarization", polarization);
1151 switch(parm_u_qpsk_fec_inner)
1153 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1154 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1155 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1156 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1157 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1158 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1159 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1160 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1161 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1162 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1163 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1164 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1166 PutToDict(dict, "fec_inner", tmp);
1168 switch (p[0].u.data)
1170 default: eDebug("got unsupported system from frontend! report as DVBS!");
1171 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1174 switch (p[2].u.data)
1176 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1177 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1178 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1179 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1181 PutToDict(dict, "rolloff", tmp);
1183 switch (p[3].u.data)
1185 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1186 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1187 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1189 PutToDict(dict, "pilot", tmp);
1191 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1194 PutToDict(dict, "system", tmp);
1196 switch (p[1].u.data)
1198 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1199 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1200 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1202 PutToDict(dict, "modulation", tmp);
1204 switch(parm_inversion & 3)
1206 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1207 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1208 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1210 PutToDict(dict, "inversion", tmp);
1213 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1217 tmp = p[1].u.data/1000;
1218 PutToDict(dict, "frequency", tmp);
1220 PutToDict(dict, "symbol_rate", p[2].u.data);
1222 switch (p[3].u.data)
1224 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1225 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1226 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1227 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1228 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1229 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1230 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1232 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1234 PutToDict(dict, "fec_inner", tmp);
1236 switch (p[4].u.data)
1238 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1239 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1240 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1241 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1242 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1244 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1246 PutToDict(dict, "modulation", tmp);
1248 switch (p[5].u.data)
1250 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1251 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1253 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1255 PutToDict(dict, "inversion", tmp);
1258 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1262 switch (p[0].u.data)
1264 default: eDebug("got unsupported system from frontend! report as DVBT!");
1265 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1268 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1270 PutToDict(dict, "plp_id", tmp);
1272 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1275 PutToDict(dict, "system", tmp);
1278 PutToDict(dict, "frequency", tmp);
1280 switch (p[2].u.data)
1282 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1283 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1284 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1285 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1286 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1287 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1289 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1291 PutToDict(dict, "bandwidth", tmp);
1293 switch (p[3].u.data)
1295 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1296 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1297 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1298 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1299 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1300 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1301 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1302 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1304 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1306 PutToDict(dict, "code_rate_lp", tmp);
1308 switch (p[4].u.data)
1310 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1311 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1312 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1313 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1314 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1315 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1316 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1317 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1319 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1321 PutToDict(dict, "code_rate_hp", tmp);
1323 switch (p[5].u.data)
1325 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1326 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1327 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1328 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1330 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1332 PutToDict(dict, "constellation", tmp);
1335 switch (p[6].u.data)
1337 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1338 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1339 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1340 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1341 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1342 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1344 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1346 PutToDict(dict, "transmission_mode", tmp);
1348 switch (p[7].u.data)
1350 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1351 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1352 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1353 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1354 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1355 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1356 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1358 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1360 PutToDict(dict, "guard_interval", tmp);
1362 switch (p[8].u.data)
1364 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1365 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1366 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1367 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1369 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1371 PutToDict(dict, "hierarchy_information", tmp);
1373 switch (p[9].u.data)
1375 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1376 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1378 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1380 PutToDict(dict, "inversion", tmp);
1383 #else // #if HAVE_DVB_API_VERSION >= 5
1384 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1387 int frequency = parm_frequency + freq_offset;
1388 PutToDict(dict, "frequency", frequency);
1389 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1390 PutToDict(dict, "orbital_position", orb_pos);
1391 PutToDict(dict, "polarization", polarization);
1393 switch((int)parm_u_qpsk_fec_inner)
1395 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1396 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1397 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1398 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1399 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1400 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1402 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1403 #if HAVE_DVB_API_VERSION >=3
1404 case FEC_S2_8PSK_1_2:
1405 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1406 case FEC_S2_8PSK_2_3:
1407 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1408 case FEC_S2_8PSK_3_4:
1409 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1410 case FEC_S2_8PSK_5_6:
1411 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1412 case FEC_S2_8PSK_7_8:
1413 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1414 case FEC_S2_8PSK_8_9:
1415 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1416 case FEC_S2_8PSK_3_5:
1417 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1418 case FEC_S2_8PSK_4_5:
1419 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1420 case FEC_S2_8PSK_9_10:
1421 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1424 PutToDict(dict, "fec_inner", tmp);
1425 #if HAVE_DVB_API_VERSION >=3
1426 PutToDict(dict, "modulation",
1427 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1428 eDVBFrontendParametersSatellite::Modulation_8PSK :
1429 eDVBFrontendParametersSatellite::Modulation_QPSK );
1430 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1432 switch(parm_inversion & 0xc)
1434 default: // unknown rolloff
1435 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1436 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1437 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1439 PutToDict(dict, "rolloff", tmp);
1440 switch(parm_inversion & 0x30)
1442 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1443 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1444 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1446 PutToDict(dict, "pilot", tmp);
1447 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1450 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1452 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1453 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1455 PutToDict(dict, "system", tmp);
1458 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1461 #if HAVE_DVB_API_VERSION < 3
1462 PutToDict(dict, "frequency", parm_frequency);
1464 PutToDict(dict, "frequency", parm_frequency/1000);
1466 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1467 switch(parm_u_qam_fec_inner)
1469 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1470 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1471 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1472 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1473 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1474 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1475 #if HAVE_DVB_API_VERSION >= 3
1476 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1479 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1481 PutToDict(dict, "fec_inner", tmp);
1482 switch(parm_u_qam_modulation)
1484 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1485 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1486 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1487 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1488 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1490 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1492 PutToDict(dict, "modulation", tmp);
1495 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1498 PutToDict(dict, "frequency", parm_frequency);
1499 switch (parm_u_ofdm_bandwidth)
1501 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1502 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1503 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1505 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1507 PutToDict(dict, "bandwidth", tmp);
1508 switch (parm_u_ofdm_code_rate_LP)
1510 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1511 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1512 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1513 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1514 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1516 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1518 PutToDict(dict, "code_rate_lp", tmp);
1519 switch (parm_u_ofdm_code_rate_HP)
1521 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1522 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1523 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1524 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1525 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1527 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1529 PutToDict(dict, "code_rate_hp", tmp);
1530 switch (parm_u_ofdm_constellation)
1532 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1533 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1534 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1536 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1538 PutToDict(dict, "constellation", tmp);
1539 switch (parm_u_ofdm_transmission_mode)
1541 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1542 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1544 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1546 PutToDict(dict, "transmission_mode", tmp);
1547 switch (parm_u_ofdm_guard_interval)
1549 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1550 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1551 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1552 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1554 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1556 PutToDict(dict, "guard_interval", tmp);
1557 switch (parm_u_ofdm_hierarchy_information)
1559 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1560 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1561 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1562 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1564 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1566 PutToDict(dict, "hierarchy_information", tmp);
1569 #endif // #if HAVE_DVB_API_VERSION >= 5
1571 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1573 if (dest && PyDict_Check(dest))
1575 const char *tmp = "UNKNOWN";
1596 PutToDict(dest, "tuner_state", tmp);
1597 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1598 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1599 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1600 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1601 int sigQualitydB = readFrontendData(signalQualitydB);
1602 if (sigQualitydB == 0x12345678) // not support yet
1604 ePyObject obj=Py_None;
1606 PutToDict(dest, "tuner_signal_quality_db", obj);
1609 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1610 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1614 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1616 if (dest && PyDict_Check(dest))
1619 FRONTENDPARAMETERS front;
1620 #if HAVE_DVB_API_VERSION >= 5
1621 struct dtv_property p[16];
1622 struct dtv_properties cmdseq;
1625 oparm.getSystem(type);
1629 p[0].cmd = DTV_DELIVERY_SYSTEM;
1630 p[1].cmd = DTV_MODULATION;
1631 p[2].cmd = DTV_ROLLOFF;
1632 p[3].cmd = DTV_PILOT;
1636 p[0].cmd = DTV_DELIVERY_SYSTEM;
1637 p[1].cmd = DTV_FREQUENCY;
1638 p[2].cmd = DTV_SYMBOL_RATE;
1639 p[3].cmd = DTV_INNER_FEC;
1640 p[4].cmd = DTV_MODULATION;
1641 p[5].cmd = DTV_INVERSION;
1645 p[0].cmd = DTV_DELIVERY_SYSTEM;
1646 p[1].cmd = DTV_FREQUENCY;
1647 p[2].cmd = DTV_BANDWIDTH_HZ;
1648 p[3].cmd = DTV_CODE_RATE_LP;
1649 p[4].cmd = DTV_CODE_RATE_HP;
1650 p[5].cmd = DTV_MODULATION;
1651 p[6].cmd = DTV_TRANSMISSION_MODE;
1652 p[7].cmd = DTV_GUARD_INTERVAL;
1653 p[8].cmd = DTV_HIERARCHY;
1654 p[9].cmd = DTV_INVERSION;
1655 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
1656 p[10].cmd = DTV_STREAM_ID;
1658 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1659 p[10].cmd = DTV_DVBT2_PLP_ID;
1667 if (m_simulate || m_fd == -1 || original)
1671 #if HAVE_DVB_API_VERSION >= 5
1672 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1674 eDebug("FE_GET_PROPERTY failed (%m)");
1677 else if (type == feSatellite && // use for DVB-S(2) only
1678 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1680 eDebug("FE_GET_FRONTEND failed (%m)");
1684 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1686 eDebug("FE_GET_FRONTEND failed (%m)");
1695 eDVBFrontendParametersSatellite sparm;
1696 oparm.getDVBS(sparm);
1697 PutSatelliteDataToDict(dest, sparm);
1700 eDVBFrontendParametersCable cparm;
1701 oparm.getDVBC(cparm);
1702 PutCableDataToDict(dest, cparm);
1705 eDVBFrontendParametersTerrestrial tparm;
1706 oparm.getDVBT(tparm);
1707 PutTerrestrialDataToDict(dest, tparm);
1713 FRONTENDPARAMETERS &parm = front;
1714 #if HAVE_DVB_API_VERSION >= 5
1718 eDVBFrontendParametersSatellite sparm;
1719 oparm.getDVBS(sparm);
1720 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1723 fillDictWithCableData(dest, p);
1726 fillDictWithTerrestrialData(dest, p);
1730 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1731 switch(parm_inversion & 3)
1734 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1737 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1741 PutToDict(dest, "inversion", tmp);
1744 eDVBFrontendParametersSatellite sparm;
1745 oparm.getDVBS(sparm);
1747 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1750 fillDictWithCableData(dest, parm);
1753 fillDictWithTerrestrialData(dest, parm);
1761 void eDVBFrontend::getFrontendData(ePyObject dest)
1763 if (dest && PyDict_Check(dest))
1766 PutToDict(dest, "tuner_number", m_slotid);
1768 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
1772 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
1773 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1775 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1780 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1788 PutToDict(dest, "tuner_type", tmp);
1792 #ifndef FP_IOCTL_GET_ID
1793 #define FP_IOCTL_GET_ID 0
1795 int eDVBFrontend::readInputpower()
1799 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1801 char proc_name2[64];
1802 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1803 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1805 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1807 if (fscanf(f, "%d", &power) != 1)
1808 eDebug("read %s failed!! (%m)", proc_name);
1810 eDebug("%s is %d\n", proc_name, power);
1815 // open front prozessor
1816 int fp=::open("/dev/dbox/fp0", O_RDWR);
1819 eDebug("couldn't open fp");
1822 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1823 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1825 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1834 bool eDVBFrontend::setSecSequencePos(int steps)
1836 eDebugNoSimulate("set sequence pos %d", steps);
1841 if (m_sec_sequence.current() != m_sec_sequence.end())
1842 ++m_sec_sequence.current();
1847 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1848 --m_sec_sequence.current();
1854 void eDVBFrontend::tuneLoop()
1859 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1862 eDVBFrontend *sec_fe = this;
1863 eDVBRegisteredFrontend *regFE = 0;
1864 long tmp = m_data[LINKED_PREV_PTR];
1867 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1868 sec_fe = prev->m_frontend;
1869 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1870 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1871 int state = sec_fe->m_state;
1872 // workaround to put the kernel frontend thread into idle state!
1873 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1875 sec_fe->closeFrontend(true);
1876 state = sec_fe->m_state;
1878 // sec_fe is closed... we must reopen it here..
1879 if (state == stateClosed)
1887 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1889 long *sec_fe_data = sec_fe->m_data;
1890 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1892 switch (m_sec_sequence.current()->cmd)
1894 case eSecCommand::SLEEP:
1895 delay = m_sec_sequence.current()++->msec;
1896 eDebugNoSimulate("[SEC] sleep %dms", delay);
1898 case eSecCommand::GOTO:
1899 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1900 ++m_sec_sequence.current();
1902 case eSecCommand::SET_VOLTAGE:
1904 int voltage = m_sec_sequence.current()++->voltage;
1905 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1906 sec_fe->setVoltage(voltage);
1909 case eSecCommand::IF_VOLTAGE_GOTO:
1911 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1912 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1914 ++m_sec_sequence.current();
1917 case eSecCommand::IF_NOT_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_TONE_GOTO:
1927 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1928 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1930 ++m_sec_sequence.current();
1933 case eSecCommand::IF_NOT_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::SET_TONE:
1942 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1943 sec_fe->setTone(m_sec_sequence.current()++->tone);
1945 case eSecCommand::SEND_DISEQC:
1946 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1947 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1948 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1949 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1950 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1951 eDebugNoSimulate("(DiSEqC reset)");
1952 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1953 eDebugNoSimulate("(DiSEqC peripherial power on)");
1955 eDebugNoSimulate("");
1956 ++m_sec_sequence.current();
1958 case eSecCommand::SEND_TONEBURST:
1959 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1960 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1962 case eSecCommand::SET_FRONTEND:
1964 int enableEvents = (m_sec_sequence.current()++)->val;
1965 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1966 setFrontend(enableEvents);
1969 case eSecCommand::START_TUNE_TIMEOUT:
1971 int tuneTimeout = m_sec_sequence.current()->timeout;
1972 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1974 m_timeout->start(tuneTimeout, 1);
1975 ++m_sec_sequence.current();
1978 case eSecCommand::SET_TIMEOUT:
1979 m_timeoutCount = m_sec_sequence.current()++->val;
1980 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1982 case eSecCommand::IF_TIMEOUT_GOTO:
1983 if (!m_timeoutCount)
1985 eDebugNoSimulate("[SEC] rotor timout");
1986 setSecSequencePos(m_sec_sequence.current()->steps);
1989 ++m_sec_sequence.current();
1991 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1993 int idx = m_sec_sequence.current()++->val;
1994 if ( idx == 0 || idx == 1 )
1996 m_idleInputpower[idx] = sec_fe->readInputpower();
1997 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
2000 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
2003 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
2005 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
2006 int idx = compare.val;
2007 if ( !m_simulate && (idx == 0 || idx == 1) )
2009 int idle = sec_fe->readInputpower();
2010 int diff = abs(idle-m_idleInputpower[idx]);
2013 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
2014 setSecSequencePos(compare.steps);
2018 ++m_sec_sequence.current();
2021 case eSecCommand::IF_TUNER_LOCKED_GOTO:
2023 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2026 setSecSequencePos(cmd.steps);
2030 int isLocked = readFrontendData(locked);
2031 m_idleInputpower[0] = m_idleInputpower[1] = 0;
2033 if (!m_timeoutCount && m_retryCount > 0)
2035 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
2038 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2041 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2043 cmd.lastSignal = signal;
2046 if (cmd.okcount > 4)
2048 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2049 setSecSequencePos(cmd.steps);
2050 m_state = stateLock;
2051 m_stateChanged(this);
2052 feEvent(-1); // flush events
2060 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2062 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2066 ++m_sec_sequence.current();
2069 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2070 m_runningInputpower = sec_fe->readInputpower();
2071 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2072 ++m_sec_sequence.current();
2074 case eSecCommand::SET_ROTOR_MOVING:
2076 m_sec->setRotorMoving(m_slotid, true);
2077 ++m_sec_sequence.current();
2079 case eSecCommand::SET_ROTOR_STOPPED:
2081 m_sec->setRotorMoving(m_slotid, false);
2082 ++m_sec_sequence.current();
2084 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2086 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2089 setSecSequencePos(cmd.steps);
2092 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2093 const char *txt = cmd.direction ? "running" : "stopped";
2095 if (!m_timeoutCount && m_retryCount > 0)
2097 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2099 m_runningInputpower,
2102 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2103 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2106 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2107 if ( cmd.okcount > 6 )
2109 eDebugNoSimulate("[SEC] rotor is %s", txt);
2110 if (setSecSequencePos(cmd.steps))
2116 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2119 ++m_sec_sequence.current();
2122 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2123 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2124 setSecSequencePos(m_sec_sequence.current()->steps);
2126 ++m_sec_sequence.current();
2128 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2129 eDebugNoSimulate("[SEC] invalidate current switch params");
2130 sec_fe_data[CSW] = -1;
2131 sec_fe_data[UCSW] = -1;
2132 sec_fe_data[TONEBURST] = -1;
2133 ++m_sec_sequence.current();
2135 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2136 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2137 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2138 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2139 eDebugNoSimulate("[SEC] update current switch params");
2140 ++m_sec_sequence.current();
2142 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2143 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2144 sec_fe_data[ROTOR_CMD] = -1;
2145 sec_fe_data[ROTOR_POS] = -1;
2146 ++m_sec_sequence.current();
2148 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2149 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2150 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2151 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2152 ++m_sec_sequence.current();
2154 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2155 m_retryCount = m_sec_sequence.current()++->val;
2156 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2158 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2161 eDebugNoSimulate("[SEC] no more rotor retrys");
2162 setSecSequencePos(m_sec_sequence.current()->steps);
2165 ++m_sec_sequence.current();
2167 case eSecCommand::SET_POWER_LIMITING_MODE:
2172 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2173 FILE *f=fopen(proc_name, "w");
2174 if (f) // new interface exist?
2176 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2177 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2178 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2180 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2183 else if (sec_fe->m_need_rotor_workaround)
2186 int slotid = sec_fe->m_slotid;
2187 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2189 sprintf(dev, "/dev/i2c-%d", slotid);
2190 else if (slotid == 2)
2191 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2192 else if (slotid == 3)
2193 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2194 int fd = ::open(dev, O_RDWR);
2196 unsigned char data[2];
2197 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2198 if(::read(fd, data, 1) != 1)
2199 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2200 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2202 data[0] |= 0x80; // enable static current limiting
2203 eDebugNoSimulate("[SEC] set static current limiting");
2207 data[0] &= ~0x80; // enable dynamic current limiting
2208 eDebugNoSimulate("[SEC] set dynamic current limiting");
2210 if(::write(fd, data, 1) != 1)
2211 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2215 ++m_sec_sequence.current();
2218 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2220 eDebugNoSimulate("[SEC] delayed close frontend");
2221 closeFrontend(false, true);
2222 ++m_sec_sequence.current();
2226 eDebugNoSimulate("[SEC] unhandled sec command %d",
2227 ++m_sec_sequence.current()->cmd);
2228 ++m_sec_sequence.current();
2231 m_tuneTimer->start(delay,true);
2235 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2240 void eDVBFrontend::setFrontend(bool recvEvents)
2244 eDebug("setting frontend %d", m_dvbid);
2247 oparm.getSystem(type);
2251 feEvent(-1); // flush events
2252 #if HAVE_DVB_API_VERSION >= 5
2253 if (type == iDVBFrontend::feSatellite)
2255 fe_rolloff_t rolloff = ROLLOFF_35;
2256 fe_pilot_t pilot = PILOT_OFF;
2257 fe_modulation_t modulation = QPSK;
2258 fe_delivery_system_t system = SYS_DVBS;
2259 eDVBFrontendParametersSatellite sparm;
2260 oparm.getDVBS(sparm);
2261 switch(sparm.system)
2263 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2264 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2266 switch(sparm.modulation)
2268 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2269 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2270 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2274 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2275 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2276 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2278 switch(sparm.rolloff)
2280 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2281 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2282 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2284 struct dtv_property p[10];
2285 struct dtv_properties cmdseq;
2287 p[0].cmd = DTV_CLEAR;
2288 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2289 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2290 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2291 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2292 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2293 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2294 if (system == SYS_DVBS2)
2296 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2297 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2298 p[9].cmd = DTV_TUNE;
2303 p[7].cmd = DTV_TUNE;
2306 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2308 perror("FE_SET_PROPERTY failed");
2312 else if (type == iDVBFrontend::feCable)
2314 struct dtv_property p[8];
2315 struct dtv_properties cmdseq;
2317 p[0].cmd = DTV_CLEAR;
2318 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2319 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2321 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2323 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2324 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2325 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2326 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2327 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2328 p[7].cmd = DTV_TUNE;
2330 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2332 perror("FE_SET_PROPERTY failed");
2336 else if (type == iDVBFrontend::feTerrestrial)
2338 fe_delivery_system_t system = SYS_DVBT;
2339 eDVBFrontendParametersTerrestrial tparm;
2340 oparm.getDVBT(tparm);
2341 switch (tparm.system)
2344 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2345 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2348 switch (tparm.bandwidth)
2350 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2351 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2352 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2354 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2355 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2356 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2357 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2359 struct dtv_property p[13];
2360 struct dtv_properties cmdseq;
2363 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2364 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2365 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2366 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2367 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2368 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2369 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2370 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2371 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2372 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2373 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2374 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
2375 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2376 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
2377 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2379 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2380 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2382 perror("FE_SET_PROPERTY failed");
2387 #endif /* HAVE_DVB_API_VERSION >= 5 */
2389 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2391 perror("FE_SET_FRONTEND failed");
2398 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2403 eWarning("no SEC module active!");
2406 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2409 #if HAVE_DVB_API_VERSION >= 3
2410 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",
2413 feparm.polarisation,
2417 feparm.orbital_position,
2423 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2426 feparm.polarisation,
2430 feparm.orbital_position);
2432 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2433 switch (feparm.inversion)
2435 case eDVBFrontendParametersSatellite::Inversion_On:
2436 parm_inversion = INVERSION_ON;
2438 case eDVBFrontendParametersSatellite::Inversion_Off:
2439 parm_inversion = INVERSION_OFF;
2442 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2443 parm_inversion = INVERSION_AUTO;
2446 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2450 case eDVBFrontendParametersSatellite::FEC_None:
2451 parm_u_qpsk_fec_inner = FEC_NONE;
2453 case eDVBFrontendParametersSatellite::FEC_1_2:
2454 parm_u_qpsk_fec_inner = FEC_1_2;
2456 case eDVBFrontendParametersSatellite::FEC_2_3:
2457 parm_u_qpsk_fec_inner = FEC_2_3;
2459 case eDVBFrontendParametersSatellite::FEC_3_4:
2460 parm_u_qpsk_fec_inner = FEC_3_4;
2462 case eDVBFrontendParametersSatellite::FEC_5_6:
2463 parm_u_qpsk_fec_inner = FEC_5_6;
2465 case eDVBFrontendParametersSatellite::FEC_7_8:
2466 parm_u_qpsk_fec_inner = FEC_7_8;
2469 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2470 case eDVBFrontendParametersSatellite::FEC_Auto:
2471 parm_u_qpsk_fec_inner = FEC_AUTO;
2475 #if HAVE_DVB_API_VERSION >= 3
2480 case eDVBFrontendParametersSatellite::FEC_1_2:
2481 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2483 case eDVBFrontendParametersSatellite::FEC_2_3:
2484 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2486 case eDVBFrontendParametersSatellite::FEC_3_4:
2487 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2489 case eDVBFrontendParametersSatellite::FEC_3_5:
2490 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2492 case eDVBFrontendParametersSatellite::FEC_4_5:
2493 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2495 case eDVBFrontendParametersSatellite::FEC_5_6:
2496 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2498 case eDVBFrontendParametersSatellite::FEC_7_8:
2499 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2501 case eDVBFrontendParametersSatellite::FEC_8_9:
2502 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2504 case eDVBFrontendParametersSatellite::FEC_9_10:
2505 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2508 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2511 #if HAVE_DVB_API_VERSION < 5
2512 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2513 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2514 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2516 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2517 // 8PSK fec driver values are decimal 9 bigger
2522 // FIXME !!! get frequency range from tuner
2523 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2525 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2528 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2530 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2534 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2536 #if HAVE_DVB_API_VERSION < 3
2537 parm_frequency = feparm.frequency;
2539 parm_frequency = feparm.frequency * 1000;
2541 parm_u_qam_symbol_rate = feparm.symbol_rate;
2542 switch (feparm.modulation)
2544 case eDVBFrontendParametersCable::Modulation_QAM16:
2545 parm_u_qam_modulation = QAM_16;
2547 case eDVBFrontendParametersCable::Modulation_QAM32:
2548 parm_u_qam_modulation = QAM_32;
2550 case eDVBFrontendParametersCable::Modulation_QAM64:
2551 parm_u_qam_modulation = QAM_64;
2553 case eDVBFrontendParametersCable::Modulation_QAM128:
2554 parm_u_qam_modulation = QAM_128;
2556 case eDVBFrontendParametersCable::Modulation_QAM256:
2557 parm_u_qam_modulation = QAM_256;
2560 case eDVBFrontendParametersCable::Modulation_Auto:
2561 parm_u_qam_modulation = QAM_AUTO;
2564 switch (feparm.inversion)
2566 case eDVBFrontendParametersCable::Inversion_On:
2567 parm_inversion = INVERSION_ON;
2569 case eDVBFrontendParametersCable::Inversion_Off:
2570 parm_inversion = INVERSION_OFF;
2573 case eDVBFrontendParametersCable::Inversion_Unknown:
2574 parm_inversion = INVERSION_AUTO;
2577 switch (feparm.fec_inner)
2579 case eDVBFrontendParametersCable::FEC_None:
2580 parm_u_qam_fec_inner = FEC_NONE;
2582 case eDVBFrontendParametersCable::FEC_1_2:
2583 parm_u_qam_fec_inner = FEC_1_2;
2585 case eDVBFrontendParametersCable::FEC_2_3:
2586 parm_u_qam_fec_inner = FEC_2_3;
2588 case eDVBFrontendParametersCable::FEC_3_4:
2589 parm_u_qam_fec_inner = FEC_3_4;
2591 case eDVBFrontendParametersCable::FEC_5_6:
2592 parm_u_qam_fec_inner = FEC_5_6;
2594 case eDVBFrontendParametersCable::FEC_7_8:
2595 parm_u_qam_fec_inner = FEC_7_8;
2597 #if HAVE_DVB_API_VERSION >= 3
2598 case eDVBFrontendParametersCable::FEC_8_9:
2599 parm_u_qam_fec_inner = FEC_8_9;
2603 case eDVBFrontendParametersCable::FEC_Auto:
2604 parm_u_qam_fec_inner = FEC_AUTO;
2607 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2608 parm_frequency/1000,
2609 parm_u_qam_symbol_rate,
2610 parm_u_qam_fec_inner,
2611 parm_u_qam_modulation,
2613 oparm.setDVBC(feparm);
2617 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2619 parm_frequency = feparm.frequency;
2621 switch (feparm.bandwidth)
2623 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2624 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2626 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2627 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2629 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2630 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2632 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2633 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2635 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2636 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2638 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2639 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2642 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2643 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2646 switch (feparm.code_rate_LP)
2648 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2649 parm_u_ofdm_code_rate_LP = FEC_1_2;
2651 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2652 parm_u_ofdm_code_rate_LP = FEC_2_3;
2654 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2655 parm_u_ofdm_code_rate_LP = FEC_3_4;
2657 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2658 parm_u_ofdm_code_rate_LP = FEC_5_6;
2660 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2661 parm_u_ofdm_code_rate_LP = FEC_7_8;
2663 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2664 parm_u_ofdm_code_rate_LP = FEC_6_7;
2666 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2667 parm_u_ofdm_code_rate_LP = FEC_8_9;
2670 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2671 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2674 switch (feparm.code_rate_HP)
2676 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2677 parm_u_ofdm_code_rate_HP = FEC_1_2;
2679 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2680 parm_u_ofdm_code_rate_HP = FEC_2_3;
2682 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2683 parm_u_ofdm_code_rate_HP = FEC_3_4;
2685 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2686 parm_u_ofdm_code_rate_HP = FEC_5_6;
2688 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2689 parm_u_ofdm_code_rate_HP = FEC_7_8;
2691 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2692 parm_u_ofdm_code_rate_HP = FEC_6_7;
2694 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2695 parm_u_ofdm_code_rate_HP = FEC_8_9;
2698 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2699 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2702 switch (feparm.modulation)
2704 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2705 parm_u_ofdm_constellation = QPSK;
2707 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2708 parm_u_ofdm_constellation = QAM_16;
2710 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2711 parm_u_ofdm_constellation = QAM_64;
2713 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2714 parm_u_ofdm_constellation = QAM_256;
2717 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2718 parm_u_ofdm_constellation = QAM_AUTO;
2721 switch (feparm.transmission_mode)
2723 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2724 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2726 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2727 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2729 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2730 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2732 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2733 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2735 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2736 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2738 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2739 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2742 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2743 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2746 switch (feparm.guard_interval)
2748 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2749 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2751 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2752 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2754 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2755 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2757 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2758 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2760 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2761 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2763 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2764 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2766 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2767 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2770 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2771 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2774 switch (feparm.hierarchy)
2776 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2777 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2779 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2780 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2782 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2783 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2785 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2786 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2789 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2790 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2793 switch (feparm.inversion)
2795 case eDVBFrontendParametersTerrestrial::Inversion_On:
2796 parm_inversion = INVERSION_ON;
2798 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2799 parm_inversion = INVERSION_OFF;
2802 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2803 parm_inversion = INVERSION_AUTO;
2806 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",
2807 parm_frequency/1000,
2808 parm_u_ofdm_bandwidth,
2809 parm_u_ofdm_code_rate_LP,
2810 parm_u_ofdm_code_rate_HP,
2811 parm_u_ofdm_constellation,
2812 parm_u_ofdm_transmission_mode,
2813 parm_u_ofdm_guard_interval,
2814 parm_u_ofdm_hierarchy_information,
2818 oparm.setDVBT(feparm);
2822 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2824 unsigned int timeout = 5000;
2825 eDebugNoSimulate("(%d)tune", m_dvbid);
2832 if (where.getSystem(type) < 0)
2838 if (!m_sn && !m_simulate)
2840 eDebug("no frontend device opened... do not try to tune !!!");
2848 m_sec_sequence.clear();
2850 where.calcLockTimeout(timeout);
2856 eDVBFrontendParametersSatellite feparm;
2857 if (where.getDVBS(feparm))
2859 eDebug("no dvbs data!");
2863 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2865 eDVBFrontend *sec_fe = this;
2866 long tmp = m_data[LINKED_PREV_PTR];
2869 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2870 sec_fe = linked_fe->m_frontend;
2871 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2873 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2874 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
2876 m_rotor_mode = feparm.no_rotor_command_on_tune;
2878 m_sec->setRotorMoving(m_slotid, false);
2879 res=prepare_sat(feparm, timeout);
2887 eDVBFrontendParametersCable feparm;
2888 if (where.getDVBC(feparm))
2893 res=prepare_cable(feparm);
2897 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2898 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2903 eDVBFrontendParametersTerrestrial feparm;
2904 if (where.getDVBT(feparm))
2906 eDebug("no -T data");
2910 res=prepare_terrestrial(feparm);
2914 std::string enable_5V;
2915 char configStr[255];
2916 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2917 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2918 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2919 if (enable_5V == "True")
2920 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2922 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2923 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2934 m_sec_sequence.current() = m_sec_sequence.begin();
2938 m_tuneTimer->start(0,true);
2940 if (m_state != stateTuning)
2942 m_state = stateTuning;
2943 m_stateChanged(this);
2952 m_tuneTimer->stop();
2956 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2958 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2962 RESULT eDVBFrontend::setVoltage(int voltage)
2965 #if HAVE_DVB_API_VERSION < 3
2968 bool increased=false;
2969 fe_sec_voltage_t vlt;
2971 m_data[CUR_VOLTAGE]=voltage;
2975 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2976 vlt = SEC_VOLTAGE_OFF;
2979 #if HAVE_DVB_API_VERSION < 3
2980 vlt = SEC_VOLTAGE_13_5;
2986 vlt = SEC_VOLTAGE_13;
2989 #if HAVE_DVB_API_VERSION < 3
2990 vlt = SEC_VOLTAGE_18_5;
2996 vlt = SEC_VOLTAGE_18;
3003 #if HAVE_DVB_API_VERSION < 3
3004 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
3006 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
3007 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
3011 RESULT eDVBFrontend::getState(int &state)
3017 RESULT eDVBFrontend::setTone(int t)
3019 #if HAVE_DVB_API_VERSION < 3
3022 fe_sec_tone_mode_t tone;
3031 tone = SEC_TONE_OFF;
3038 #if HAVE_DVB_API_VERSION < 3
3039 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
3041 return ::ioctl(m_fd, FE_SET_TONE, tone);
3045 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3046 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3049 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3053 #if HAVE_DVB_API_VERSION < 3
3054 struct secCommand cmd;
3055 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3056 cmd.u.diseqc.cmdtype = diseqc.data[0];
3057 cmd.u.diseqc.addr = diseqc.data[1];
3058 cmd.u.diseqc.cmd = diseqc.data[2];
3059 cmd.u.diseqc.numParams = diseqc.len-3;
3060 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3061 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3063 struct dvb_diseqc_master_cmd cmd;
3064 memcpy(cmd.msg, diseqc.data, diseqc.len);
3065 cmd.msg_len = diseqc.len;
3066 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3072 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3073 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3075 RESULT eDVBFrontend::sendToneburst(int burst)
3079 #if HAVE_DVB_API_VERSION < 3
3080 secMiniCmd cmd = SEC_MINI_NONE;
3082 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3084 if ( burst == eDVBSatelliteDiseqcParameters::A )
3086 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3088 #if HAVE_DVB_API_VERSION < 3
3089 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3092 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3098 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3104 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3106 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3107 m_sec_sequence.push_back(list);
3109 m_sec_sequence = list;
3113 RESULT eDVBFrontend::getData(int num, long &data)
3115 if ( num < NUM_DATA_ENTRIES )
3123 RESULT eDVBFrontend::setData(int num, long val)
3125 if ( num < NUM_DATA_ENTRIES )
3133 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3137 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3139 if (feparm->getSystem(type) || !m_enabled)
3142 if (type == eDVBFrontend::feSatellite)
3144 eDVBFrontendParametersSatellite sat_parm;
3145 bool can_handle_dvbs, can_handle_dvbs2;
3146 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
3147 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
3148 if (feparm->getDVBS(sat_parm) < 0)
3152 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
3156 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
3160 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3161 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
3163 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3168 else if (type == eDVBFrontend::feCable)
3170 eDVBFrontendParametersCable cab_parm;
3171 if (feparm->getDVBC(cab_parm) < 0)
3175 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
3176 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
3181 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
3189 else if (type == eDVBFrontend::feTerrestrial)
3191 eDVBFrontendParametersTerrestrial ter_parm;
3192 bool can_handle_dvbt, can_handle_dvbt2;
3193 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
3194 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
3195 if (feparm->getDVBT(ter_parm) < 0)
3199 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
3203 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
3208 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
3210 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3215 if (score && preferred)
3217 /* make 'sure' we always prefer this frontend */
3224 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
3226 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
3227 if (it != m_delsys.end() && it->second)
3229 if (obeywhitelist && !m_delsys_whitelist.empty())
3231 it = m_delsys_whitelist.find(sys);
3232 if (it == m_delsys_whitelist.end() || !it->second) return false;
3239 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
3241 m_delsys_whitelist.clear();
3242 for (unsigned int i = 0; i < whitelist.size(); i++)
3244 m_delsys_whitelist[whitelist[i]] = true;
3248 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
3252 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3254 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3255 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3257 Id = PyTuple_GET_ITEM(obj, 0);
3258 Descr = PyTuple_GET_ITEM(obj, 1);
3259 Enabled = PyTuple_GET_ITEM(obj, 2);
3260 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3261 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3262 frontendId = PyTuple_GET_ITEM(obj, 5);
3263 m_slotid = PyInt_AsLong(Id);
3264 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3266 strcpy(m_description, PyString_AS_STRING(Descr));
3267 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3268 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3269 // m_slotid, m_description);
3272 m_enabled = Enabled == Py_True;
3273 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3274 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3275 !!strstr(m_description, "Alps BSBE2") ||
3276 !!strstr(m_description, "Alps -S") ||
3277 !!strstr(m_description, "BCM4501");
3278 if (IsDVBS2 == Py_True)
3280 /* HACK for legacy dvb api without DELSYS support */
3281 m_delsys[SYS_DVBS2] = true;
3283 if (IsDVBT2 == Py_True)
3285 /* HACK for legacy dvb api without DELSYS support */
3286 m_delsys[SYS_DVBT2] = true;
3288 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3289 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled == Py_True ? "Yes" : "No", IsDVBS2 == Py_True ? "Yes" : "No", IsDVBT2 == Py_True ? "Yes" : "No" );
3292 PyErr_SetString(PyExc_StandardError,
3293 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");