1 #include <linux/dvb/version.h>
3 #include <lib/dvb/dvb.h>
4 #include <lib/dvb/frontendparms.h>
5 #include <lib/base/eerror.h>
6 #include <lib/base/nconfig.h> // access to python config
10 #include <sys/ioctl.h>
12 #ifndef I2C_SLAVE_FORCE
13 #define I2C_SLAVE_FORCE 0x0706
16 #if HAVE_DVB_API_VERSION < 3
17 #include <ost/frontend.h>
19 #define QAM_AUTO (Modulation)6
20 #define TRANSMISSION_MODE_AUTO (TransmitMode)2
21 #define BANDWIDTH_AUTO (BandWidth)3
22 #define GUARD_INTERVAL_AUTO (GuardInterval)4
23 #define HIERARCHY_AUTO (Hierarchy)4
24 #define parm_frequency parm.Frequency
25 #define parm_inversion parm.Inversion
26 #define parm_u_qpsk_symbol_rate parm.u.qpsk.SymbolRate
27 #define parm_u_qpsk_fec_inner parm.u.qpsk.FEC_inner
28 #define parm_u_qam_symbol_rate parm.u.qam.SymbolRate
29 #define parm_u_qam_fec_inner parm.u.qam.FEC_inner
30 #define parm_u_qam_modulation parm.u.qam.QAM
31 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandWidth
32 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.LP_CodeRate
33 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.HP_CodeRate
34 #define parm_u_ofdm_constellation parm.u.ofdm.Constellation
35 #define parm_u_ofdm_transmission_mode parm.u.ofdm.TransmissionMode
36 #define parm_u_ofdm_guard_interval parm.u.ofdm.guardInterval
37 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.HierarchyInformation
39 #include <linux/dvb/frontend.h>
40 #define parm_frequency parm.frequency
41 #define parm_inversion parm.inversion
42 #define parm_u_qpsk_symbol_rate parm.u.qpsk.symbol_rate
43 #define parm_u_qpsk_fec_inner parm.u.qpsk.fec_inner
44 #define parm_u_qam_symbol_rate parm.u.qam.symbol_rate
45 #define parm_u_qam_fec_inner parm.u.qam.fec_inner
46 #define parm_u_qam_modulation parm.u.qam.modulation
47 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandwidth
48 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.code_rate_LP
49 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.code_rate_HP
50 #define parm_u_ofdm_constellation parm.u.ofdm.constellation
51 #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode
52 #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval
53 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information
54 #if HAVE_DVB_API_VERSION < 5
55 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1)
56 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1)
57 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_S2_QPSK_2_3+1)
58 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_S2_QPSK_3_4+1)
59 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_S2_QPSK_5_6+1)
60 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_S2_QPSK_7_8+1)
61 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_S2_QPSK_8_9+1)
62 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_S2_QPSK_3_5+1)
63 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_S2_QPSK_4_5+1)
64 #define FEC_S2_8PSK_1_2 (fe_code_rate_t)(FEC_S2_QPSK_9_10+1)
65 #define FEC_S2_8PSK_2_3 (fe_code_rate_t)(FEC_S2_8PSK_1_2+1)
66 #define FEC_S2_8PSK_3_4 (fe_code_rate_t)(FEC_S2_8PSK_2_3+1)
67 #define FEC_S2_8PSK_5_6 (fe_code_rate_t)(FEC_S2_8PSK_3_4+1)
68 #define FEC_S2_8PSK_7_8 (fe_code_rate_t)(FEC_S2_8PSK_5_6+1)
69 #define FEC_S2_8PSK_8_9 (fe_code_rate_t)(FEC_S2_8PSK_7_8+1)
70 #define FEC_S2_8PSK_3_5 (fe_code_rate_t)(FEC_S2_8PSK_8_9+1)
71 #define FEC_S2_8PSK_4_5 (fe_code_rate_t)(FEC_S2_8PSK_3_5+1)
72 #define FEC_S2_8PSK_9_10 (fe_code_rate_t)(FEC_S2_8PSK_4_5+1)
74 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2)
75 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3)
76 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4)
77 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6)
78 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8)
79 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9)
80 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5)
81 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5)
82 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10)
86 #include <dvbsi++/satellite_delivery_system_descriptor.h>
87 #include <dvbsi++/cable_delivery_system_descriptor.h>
88 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
90 #define eDebugNoSimulate(x...) \
98 eDebugNoNewLine("SIMULATE:"); \
103 #define eDebugNoSimulateNoNewLine(x...) \
106 eDebugNoNewLine(x); \
111 eDebugNoNewLine("SIMULATE:"); \
112 eDebugNoNewLine(x); \
116 void eDVBDiseqcCommand::setCommandString(const char *str)
121 int slen = strlen(str);
124 eDebug("invalid diseqc command string length (not 2 byte aligned)");
127 if (slen > MAX_DISEQC_LENGTH*2)
129 eDebug("invalid diseqc command string length (string is to long)");
133 for (int i=0; i < slen; ++i)
135 unsigned char c = str[i];
138 case '0' ... '9': c-=48; break;
139 case 'a' ... 'f': c-=87; break;
140 case 'A' ... 'F': c-=55; break;
142 eDebug("invalid character in hex string..ignore complete diseqc command !");
156 void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescriptor &descriptor)
158 frequency = descriptor.getFrequency() * 10;
159 symbol_rate = descriptor.getSymbolRate() * 100;
160 polarisation = descriptor.getPolarization();
161 fec = descriptor.getFecInner();
162 if ( fec != eDVBFrontendParametersSatellite::FEC_None && fec > eDVBFrontendParametersSatellite::FEC_9_10 )
163 fec = eDVBFrontendParametersSatellite::FEC_Auto;
164 inversion = eDVBFrontendParametersSatellite::Inversion_Unknown;
165 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
166 orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
167 orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
168 orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
169 orbital_position += ((descriptor.getOrbitalPosition()) & 0xF);
170 if (orbital_position && (!descriptor.getWestEastFlag()))
171 orbital_position = 3600 - orbital_position;
172 system = descriptor.getModulationSystem();
173 modulation = descriptor.getModulation();
174 if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
176 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
177 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
179 rolloff = descriptor.getRollOff();
180 if (system == eDVBFrontendParametersSatellite::System_DVB_S2)
182 eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
184 polarisation ? "hor" : "vert",
192 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
194 polarisation ? "hor" : "vert",
200 void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descriptor)
202 frequency = descriptor.getFrequency() / 10;
203 symbol_rate = descriptor.getSymbolRate() * 100;
204 fec_inner = descriptor.getFecInner();
205 if ( fec_inner != eDVBFrontendParametersCable::FEC_None && fec_inner > eDVBFrontendParametersCable::FEC_8_9 )
206 fec_inner = eDVBFrontendParametersCable::FEC_Auto;
207 modulation = descriptor.getModulation();
208 if ( modulation > 0x5 )
209 modulation = eDVBFrontendParametersCable::Modulation_Auto;
210 inversion = eDVBFrontendParametersCable::Inversion_Unknown;
211 eDebug("Cable freq %d, mod %d, sr %d, fec %d",
213 modulation, symbol_rate, fec_inner);
216 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
218 /* EN 300 468 V1.11.1 DVB-SI SPEC */
219 frequency = descriptor.getCentreFrequency() * 10;
220 switch (descriptor.getBandwidth())
222 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
223 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
224 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
225 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
226 case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
227 case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
228 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
230 switch (descriptor.getCodeRateHpStream())
232 case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
233 case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
234 case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
235 case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
236 case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
237 default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
239 switch (descriptor.getCodeRateLpStream())
241 case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
242 case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
243 case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
244 case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
245 case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
246 default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
248 switch (descriptor.getTransmissionMode())
250 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
251 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
252 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
253 case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
254 case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
255 case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
256 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
258 switch (descriptor.getGuardInterval())
260 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
261 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
262 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
263 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
264 case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
265 case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
266 case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
267 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
269 // hierarchy = descriptor.getHierarchyInformation();
270 hierarchy = descriptor.getHierarchyInformation()&3;
271 if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
272 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
273 modulation = descriptor.getConstellation();
274 if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
275 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
276 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
277 system = eDVBFrontendParametersTerrestrial::System_DVB_T;
279 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
280 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
281 guard_interval, hierarchy, modulation);
284 eDVBFrontendParameters::eDVBFrontendParameters()
285 :m_type(-1), m_flags(0)
289 DEFINE_REF(eDVBFrontendParameters);
291 RESULT eDVBFrontendParameters::getSystem(int &t) const
294 return (m_type == -1) ? -1 : 0;
297 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
299 if (m_type != iDVBFrontend::feSatellite)
305 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
307 if (m_type != iDVBFrontend::feCable)
313 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
315 if (m_type != iDVBFrontend::feTerrestrial)
321 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
324 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
325 m_type = iDVBFrontend::feSatellite;
329 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
332 m_type = iDVBFrontend::feCable;
336 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
339 m_type = iDVBFrontend::feTerrestrial;
343 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
348 if (parm->getSystem(type))
352 diff = 1<<30; // big difference
358 case iDVBFrontend::feSatellite:
360 eDVBFrontendParametersSatellite osat;
361 if (parm->getDVBS(osat))
364 if (sat.orbital_position != osat.orbital_position)
366 else if (sat.polarisation != osat.polarisation)
368 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
370 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
374 diff = abs(sat.frequency - osat.frequency);
375 diff += abs(sat.symbol_rate - osat.symbol_rate);
379 case iDVBFrontend::feCable:
380 eDVBFrontendParametersCable ocable;
381 if (parm->getDVBC(ocable))
384 if (exact && cable.modulation != ocable.modulation
385 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
386 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
388 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
392 diff = abs(cable.frequency - ocable.frequency);
393 diff += abs(cable.symbol_rate - ocable.symbol_rate);
396 case iDVBFrontend::feTerrestrial:
397 eDVBFrontendParametersTerrestrial oterrestrial;
398 if (parm->getDVBT(oterrestrial))
400 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
401 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
402 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
404 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
405 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
406 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
408 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
409 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
410 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
412 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
413 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
414 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
416 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
417 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
418 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
420 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
421 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
422 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
424 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
425 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
426 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
428 else if (oterrestrial.system != terrestrial.system)
430 else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
431 oterrestrial.plpid != terrestrial.plpid)
434 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
442 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
446 case iDVBFrontend::feSatellite:
448 hash = (sat.orbital_position << 16);
449 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
452 case iDVBFrontend::feCable:
454 hash |= (cable.frequency/1000)&0xFFFF;
456 case iDVBFrontend::feTerrestrial:
458 hash |= (terrestrial.frequency/1000000)&0xFFFF;
465 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
469 case iDVBFrontend::feSatellite:
471 /* high symbol rate transponders tune faster, due to
472 requiring less zigzag and giving more symbols faster.
474 5s are definitely not enough on really low SR when
475 zigzag has to find the exact frequency first.
477 if (sat.symbol_rate > 20000000)
479 else if (sat.symbol_rate > 10000000)
485 case iDVBFrontend::feCable:
488 case iDVBFrontend::feTerrestrial:
496 DEFINE_REF(eDVBFrontend);
498 int eDVBFrontend::PriorityOrder=0;
499 int eDVBFrontend::PreferredFrontendIndex=-1;
502 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
503 :m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
504 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false)
505 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false)
506 #if HAVE_DVB_API_VERSION < 3
510 #if HAVE_DVB_API_VERSION < 3
511 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
512 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
514 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
517 m_timeout = eTimer::create(eApp);
518 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
520 m_tuneTimer = eTimer::create(eApp);
521 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
523 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
526 m_idleInputpower[0]=m_idleInputpower[1]=0;
528 char fileName[32] = {0};
529 sprintf(fileName, "/proc/stb/frontend/%d/fbc_id", m_slotid);
530 if (access(fileName, F_OK) == 0)
533 ok = !openFrontend();
537 void eDVBFrontend::reopenFrontend()
544 int eDVBFrontend::openFrontend()
546 if (m_state != stateClosed)
547 return -1; // already opened
552 #if HAVE_DVB_API_VERSION < 3
553 FrontendInfo fe_info;
555 dvb_frontend_info fe_info;
559 eDebug("opening frontend %d", m_dvbid);
562 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
565 eWarning("failed! (%s) %m", m_filename);
570 eWarning("frontend %d already opened", m_dvbid);
572 if (m_delsys.empty())
574 #ifdef DTV_ENUM_DELSYS
575 struct dtv_property p[1];
576 p[0].cmd = DTV_ENUM_DELSYS;
577 struct dtv_properties cmdseq;
580 if (::ioctl(m_fd, FE_GET_PROPERTY, &cmdseq) >= 0)
584 for (i = 0; i < p[0].u.buffer.len ; i++)
586 fe_delivery_system_t delsys = (fe_delivery_system_t)p[0].u.buffer.data[i];
587 m_delsys[delsys] = true;
591 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
593 eWarning("ioctl FE_GET_INFO failed");
598 /* old DVB API, fill delsys map with some defaults */
599 switch (fe_info.type)
603 m_delsys[SYS_DVBS] = true;
604 #if DVB_API_VERSION >= 5
605 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
611 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
612 m_delsys[SYS_DVBC_ANNEX_A] = true;
614 m_delsys[SYS_DVBC_ANNEX_AC] = true;
620 m_delsys[SYS_DVBT] = true;
621 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
622 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
626 case FE_ATSC: // placeholder to prevent warning
636 m_simulate_fe->m_delsys = m_delsys;
639 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
640 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
643 setTone(iDVBFrontend::toneOff);
644 setVoltage(iDVBFrontend::voltageOff);
649 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
651 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
653 long tmp = m_data[LINKED_NEXT_PTR];
656 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
657 if (linked_fe->m_inuse)
659 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
660 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
663 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
669 eDebugNoSimulate("close frontend %d", m_dvbid);
670 if (m_data[SATCR] != -1)
674 m_sec->prepareTurnOffSatCR(*this);
675 m_tuneTimer->start(0, true);
676 if(!m_tuneTimer->isActive())
679 eDebug("[turnOffSatCR] no mainloop");
682 timeout = tuneLoopInt();
685 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
689 eDebug("[turnOffSatCR] running mainloop");
693 m_data[ROTOR_CMD] = -1;
696 setTone(iDVBFrontend::toneOff);
697 setVoltage(iDVBFrontend::voltageOff);
700 if (m_sec && !m_simulate)
701 m_sec->setRotorMoving(m_slotid, false);
705 eWarning("couldnt close frontend %d", m_dvbid);
709 setTone(iDVBFrontend::toneOff);
710 setVoltage(iDVBFrontend::voltageOff);
712 #if HAVE_DVB_API_VERSION < 3
715 if (!::close(m_secfd))
718 eWarning("couldnt close sec %d", m_dvbid);
722 m_state = stateClosed;
727 eDVBFrontend::~eDVBFrontend()
729 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
733 void eDVBFrontend::feEvent(int w)
735 eDVBFrontend *sec_fe = this;
736 long tmp = m_data[LINKED_PREV_PTR];
739 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
740 sec_fe = linked_fe->m_frontend;
741 sec_fe->getData(LINKED_NEXT_PTR, tmp);
745 #if HAVE_DVB_API_VERSION < 3
748 dvb_frontend_event event;
752 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
754 if (res && (errno == EAGAIN))
760 #if HAVE_DVB_API_VERSION < 3
761 if (event.type == FE_COMPLETION_EV)
763 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
764 if (event.status & FE_HAS_LOCK)
772 #if HAVE_DVB_API_VERSION >= 3
773 if (event.status & FE_TIMEDOUT) {
774 eDebug("FE_TIMEDOUT! ..abort");
787 eDebug("stateLostLock");
788 state = stateLostLock;
790 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
793 if (m_state != state)
796 m_stateChanged(this);
801 void eDVBFrontend::timeout()
804 if (m_state == stateTuning)
807 eDVBFrontend *sec_fe = this;
808 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
810 m_state = stateFailed;
811 m_stateChanged(this);
815 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
817 /* unsigned 32 bit division */
818 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
820 return (a + b / 2) / b;
823 int eDVBFrontend::readFrontendData(int type)
832 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
833 eDebug("FE_READ_BER failed (%m)");
838 case signalQualitydB: /* this will move into the driver */
840 int sat_max = 1600; // for stv0288 / bsbe2
841 int ret = 0x12345678;
845 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
846 eDebug("FE_READ_SNR failed (%m)");
847 else if (!strcmp(m_description, "BCM4501 (internal)"))
849 float SDS_SNRE = snr << 16;
852 eDVBFrontendParametersSatellite sparm;
853 oparm.getDVBS(sparm);
855 if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
857 static float SNR_COEFF[6] = {
860 197418.0 / 4194304.0,
861 -2602183.0 / 4194304.0,
862 20377212.0 / 4194304.0,
863 -37791203.0 / 4194304.0,
865 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
866 fval2 = pow(10.0, fval1)-1;
867 fval1 = 10.0 * log10(fval2);
871 fval2 = SNR_COEFF[0];
872 for (int i=1; i<6; ++i)
875 fval2 += SNR_COEFF[i];
881 #if HAVE_DVB_API_VERSION >= 3
884 float fval1 = SDS_SNRE / 268435456.0,
887 if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
898 fval4 = -10.0 * log10(fval1);
900 for (int i=0; i < 5; ++i)
901 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
906 ret = (int)(snr_in_db * 100);
908 else if (strstr(m_description, "Alps BSBE1 C01A") ||
909 strstr(m_description, "Alps -S(STV0288)"))
913 else if (snr == 0xFFFF) // i think this should not happen
917 enum { REALVAL, REGVAL };
918 const long CN_lookup[31][2] = {
919 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
920 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
921 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
922 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
923 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
924 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
927 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
928 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
932 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
937 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
942 ret = (((regval - CN_lookup[Imin][REGVAL])
943 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
944 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
945 + CN_lookup[Imin][REALVAL]) * 10;
951 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
952 !strcmp(m_description, "Alps -S") ||
953 !strcmp(m_description, "Philips -S") ||
954 !strcmp(m_description, "LG -S") )
957 ret = (int)((snr-39075)/17.647);
958 } else if (!strcmp(m_description, "Alps BSBE2"))
960 ret = (int)((snr >> 7) * 10);
961 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
963 int mse = (~snr) & 0xFF;
964 switch (parm_u_qam_modulation) {
965 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
966 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
967 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
968 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
969 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
972 } else if (!strcmp(m_description, "Philips TU1216"))
974 snr = 0xFF - (snr & 0xFF);
976 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
978 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
979 ret = (snr * 100) >> 8;
980 else if (!strcmp(m_description, "CXD1981"))
982 int mse = (~snr) & 0xFF;
983 switch (parm_u_qam_modulation) {
986 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
988 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
994 if (type == signalQuality)
996 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
1000 oparm.getSystem(type);
1004 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
1005 case feCable: // we assume a max of 42db here
1006 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
1007 case feTerrestrial: // we assume a max of 24db here
1008 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
1012 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
1017 uint16_t strength=0;
1020 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
1021 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1027 #if HAVE_DVB_API_VERSION < 3
1028 FrontendStatus status=0;
1034 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1035 eDebug("FE_READ_STATUS failed (%m)");
1036 return !!(status&FE_HAS_LOCK);
1042 #if HAVE_DVB_API_VERSION < 3
1043 FrontendStatus status=0;
1049 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1050 eDebug("FE_READ_STATUS failed (%m)");
1051 return !!(status&FE_HAS_SYNC);
1055 case frontendNumber:
1061 void PutToDict(ePyObject &dict, const char*key, long value)
1063 ePyObject item = PyInt_FromLong(value);
1066 if (PyDict_SetItemString(dict, key, item))
1067 eDebug("put %s to dict failed", key);
1071 eDebug("could not create PyObject for %s", key);
1074 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1078 if (PyDict_SetItemString(dict, key, item))
1079 eDebug("put %s to dict failed", key);
1083 eDebug("invalid PyObject for %s", key);
1086 void PutToDict(ePyObject &dict, const char*key, const char *value)
1088 ePyObject item = PyString_FromString(value);
1091 if (PyDict_SetItemString(dict, key, item))
1092 eDebug("put %s to dict failed", key);
1096 eDebug("could not create PyObject for %s", key);
1099 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1101 PutToDict(dict, "tuner_type", "DVB-S");
1102 PutToDict(dict, "frequency", feparm.frequency);
1103 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1104 PutToDict(dict, "orbital_position", feparm.orbital_position);
1105 PutToDict(dict, "inversion", feparm.inversion);
1106 PutToDict(dict, "fec_inner", feparm.fec);
1107 PutToDict(dict, "modulation", feparm.modulation);
1108 PutToDict(dict, "polarization", feparm.polarisation);
1109 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1111 PutToDict(dict, "rolloff", feparm.rolloff);
1112 PutToDict(dict, "pilot", feparm.pilot);
1114 PutToDict(dict, "system", feparm.system);
1117 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1119 PutToDict(dict, "tuner_type", "DVB-T");
1120 PutToDict(dict, "frequency", feparm.frequency);
1121 PutToDict(dict, "bandwidth", feparm.bandwidth);
1122 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1123 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1124 PutToDict(dict, "constellation", feparm.modulation);
1125 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1126 PutToDict(dict, "guard_interval", feparm.guard_interval);
1127 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1128 PutToDict(dict, "inversion", feparm.inversion);
1129 PutToDict(dict, "system", feparm.system);
1130 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1132 PutToDict(dict, "plp_id", feparm.plpid);
1136 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1138 PutToDict(dict, "tuner_type", "DVB-C");
1139 PutToDict(dict, "frequency", feparm.frequency);
1140 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1141 PutToDict(dict, "modulation", feparm.modulation);
1142 PutToDict(dict, "inversion", feparm.inversion);
1143 PutToDict(dict, "fec_inner", feparm.fec_inner);
1146 #if HAVE_DVB_API_VERSION >= 5
1147 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1150 int frequency = parm_frequency + freq_offset;
1151 PutToDict(dict, "frequency", frequency);
1152 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1153 PutToDict(dict, "orbital_position", orb_pos);
1154 PutToDict(dict, "polarization", polarization);
1156 switch(parm_u_qpsk_fec_inner)
1158 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1159 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1160 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1161 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1162 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1163 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1164 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1165 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1166 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1167 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1168 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1169 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1171 PutToDict(dict, "fec_inner", tmp);
1173 switch (p[0].u.data)
1175 default: eDebug("got unsupported system from frontend! report as DVBS!");
1176 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1179 switch (p[2].u.data)
1181 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1182 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1183 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1184 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1186 PutToDict(dict, "rolloff", tmp);
1188 switch (p[3].u.data)
1190 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1191 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1192 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1194 PutToDict(dict, "pilot", tmp);
1196 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1199 PutToDict(dict, "system", tmp);
1201 switch (p[1].u.data)
1203 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1204 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1205 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1207 PutToDict(dict, "modulation", tmp);
1209 switch(parm_inversion & 3)
1211 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1212 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1213 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1215 PutToDict(dict, "inversion", tmp);
1218 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1222 tmp = p[1].u.data/1000;
1223 PutToDict(dict, "frequency", tmp);
1225 PutToDict(dict, "symbol_rate", p[2].u.data);
1227 switch (p[3].u.data)
1229 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1230 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1231 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1232 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1233 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1234 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1235 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1237 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1239 PutToDict(dict, "fec_inner", tmp);
1241 switch (p[4].u.data)
1243 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1244 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1245 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1246 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1247 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1249 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1251 PutToDict(dict, "modulation", tmp);
1253 switch (p[5].u.data)
1255 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1256 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1258 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1260 PutToDict(dict, "inversion", tmp);
1263 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1267 switch (p[0].u.data)
1269 default: eDebug("got unsupported system from frontend! report as DVBT!");
1270 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1273 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1275 PutToDict(dict, "plp_id", tmp);
1277 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1280 PutToDict(dict, "system", tmp);
1283 PutToDict(dict, "frequency", tmp);
1285 switch (p[2].u.data)
1287 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1288 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1289 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1290 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1291 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1292 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1294 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1296 PutToDict(dict, "bandwidth", tmp);
1298 switch (p[3].u.data)
1300 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1301 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1302 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1303 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1304 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1305 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1306 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1307 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1309 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1311 PutToDict(dict, "code_rate_lp", tmp);
1313 switch (p[4].u.data)
1315 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1316 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1317 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1318 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1319 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1320 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1321 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1322 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1324 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1326 PutToDict(dict, "code_rate_hp", tmp);
1328 switch (p[5].u.data)
1330 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1331 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1332 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1333 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1335 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1337 PutToDict(dict, "constellation", tmp);
1340 switch (p[6].u.data)
1342 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1343 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1344 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1345 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1346 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1347 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1349 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1351 PutToDict(dict, "transmission_mode", tmp);
1353 switch (p[7].u.data)
1355 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1356 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1357 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1358 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1359 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1360 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1361 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1363 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1365 PutToDict(dict, "guard_interval", tmp);
1367 switch (p[8].u.data)
1369 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1370 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1371 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1372 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1374 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1376 PutToDict(dict, "hierarchy_information", tmp);
1378 switch (p[9].u.data)
1380 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1381 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1383 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1385 PutToDict(dict, "inversion", tmp);
1388 #else // #if HAVE_DVB_API_VERSION >= 5
1389 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1392 int frequency = parm_frequency + freq_offset;
1393 PutToDict(dict, "frequency", frequency);
1394 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1395 PutToDict(dict, "orbital_position", orb_pos);
1396 PutToDict(dict, "polarization", polarization);
1398 switch((int)parm_u_qpsk_fec_inner)
1400 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1401 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1402 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1403 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1404 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1405 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1407 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1408 #if HAVE_DVB_API_VERSION >=3
1409 case FEC_S2_8PSK_1_2:
1410 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1411 case FEC_S2_8PSK_2_3:
1412 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1413 case FEC_S2_8PSK_3_4:
1414 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1415 case FEC_S2_8PSK_5_6:
1416 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1417 case FEC_S2_8PSK_7_8:
1418 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1419 case FEC_S2_8PSK_8_9:
1420 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1421 case FEC_S2_8PSK_3_5:
1422 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1423 case FEC_S2_8PSK_4_5:
1424 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1425 case FEC_S2_8PSK_9_10:
1426 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1429 PutToDict(dict, "fec_inner", tmp);
1430 #if HAVE_DVB_API_VERSION >=3
1431 PutToDict(dict, "modulation",
1432 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1433 eDVBFrontendParametersSatellite::Modulation_8PSK :
1434 eDVBFrontendParametersSatellite::Modulation_QPSK );
1435 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1437 switch(parm_inversion & 0xc)
1439 default: // unknown rolloff
1440 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1441 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1442 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1444 PutToDict(dict, "rolloff", tmp);
1445 switch(parm_inversion & 0x30)
1447 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1448 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1449 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1451 PutToDict(dict, "pilot", tmp);
1452 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1455 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1457 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1458 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1460 PutToDict(dict, "system", tmp);
1463 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1466 #if HAVE_DVB_API_VERSION < 3
1467 PutToDict(dict, "frequency", parm_frequency);
1469 PutToDict(dict, "frequency", parm_frequency/1000);
1471 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1472 switch(parm_u_qam_fec_inner)
1474 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1475 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1476 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1477 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1478 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1479 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1480 #if HAVE_DVB_API_VERSION >= 3
1481 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1484 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1486 PutToDict(dict, "fec_inner", tmp);
1487 switch(parm_u_qam_modulation)
1489 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1490 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1491 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1492 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1493 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1495 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1497 PutToDict(dict, "modulation", tmp);
1500 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1503 PutToDict(dict, "frequency", parm_frequency);
1504 switch (parm_u_ofdm_bandwidth)
1506 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1507 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1508 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1510 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1512 PutToDict(dict, "bandwidth", tmp);
1513 switch (parm_u_ofdm_code_rate_LP)
1515 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1516 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1517 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1518 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1519 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1521 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1523 PutToDict(dict, "code_rate_lp", tmp);
1524 switch (parm_u_ofdm_code_rate_HP)
1526 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1527 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1528 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1529 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1530 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1532 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1534 PutToDict(dict, "code_rate_hp", tmp);
1535 switch (parm_u_ofdm_constellation)
1537 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1538 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1539 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1541 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1543 PutToDict(dict, "constellation", tmp);
1544 switch (parm_u_ofdm_transmission_mode)
1546 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1547 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1549 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1551 PutToDict(dict, "transmission_mode", tmp);
1552 switch (parm_u_ofdm_guard_interval)
1554 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1555 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1556 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1557 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1559 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1561 PutToDict(dict, "guard_interval", tmp);
1562 switch (parm_u_ofdm_hierarchy_information)
1564 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1565 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1566 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1567 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1569 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1571 PutToDict(dict, "hierarchy_information", tmp);
1574 #endif // #if HAVE_DVB_API_VERSION >= 5
1576 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1578 if (dest && PyDict_Check(dest))
1580 const char *tmp = "UNKNOWN";
1601 PutToDict(dest, "tuner_state", tmp);
1602 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1603 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1604 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1605 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1606 int sigQualitydB = readFrontendData(signalQualitydB);
1607 if (sigQualitydB == 0x12345678) // not support yet
1609 ePyObject obj=Py_None;
1611 PutToDict(dest, "tuner_signal_quality_db", obj);
1614 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1615 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1619 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1621 if (dest && PyDict_Check(dest))
1624 FRONTENDPARAMETERS front;
1625 #if HAVE_DVB_API_VERSION >= 5
1626 struct dtv_property p[16];
1627 struct dtv_properties cmdseq;
1630 oparm.getSystem(type);
1634 p[0].cmd = DTV_DELIVERY_SYSTEM;
1635 p[1].cmd = DTV_MODULATION;
1636 p[2].cmd = DTV_ROLLOFF;
1637 p[3].cmd = DTV_PILOT;
1641 p[0].cmd = DTV_DELIVERY_SYSTEM;
1642 p[1].cmd = DTV_FREQUENCY;
1643 p[2].cmd = DTV_SYMBOL_RATE;
1644 p[3].cmd = DTV_INNER_FEC;
1645 p[4].cmd = DTV_MODULATION;
1646 p[5].cmd = DTV_INVERSION;
1650 p[0].cmd = DTV_DELIVERY_SYSTEM;
1651 p[1].cmd = DTV_FREQUENCY;
1652 p[2].cmd = DTV_BANDWIDTH_HZ;
1653 p[3].cmd = DTV_CODE_RATE_LP;
1654 p[4].cmd = DTV_CODE_RATE_HP;
1655 p[5].cmd = DTV_MODULATION;
1656 p[6].cmd = DTV_TRANSMISSION_MODE;
1657 p[7].cmd = DTV_GUARD_INTERVAL;
1658 p[8].cmd = DTV_HIERARCHY;
1659 p[9].cmd = DTV_INVERSION;
1660 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
1661 p[10].cmd = DTV_STREAM_ID;
1663 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1664 p[10].cmd = DTV_DVBT2_PLP_ID;
1672 if (m_simulate || m_fd == -1 || original)
1676 #if HAVE_DVB_API_VERSION >= 5
1677 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1679 eDebug("FE_GET_PROPERTY failed (%m)");
1682 else if (type == feSatellite && // use for DVB-S(2) only
1683 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1685 eDebug("FE_GET_FRONTEND failed (%m)");
1689 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1691 eDebug("FE_GET_FRONTEND failed (%m)");
1700 eDVBFrontendParametersSatellite sparm;
1701 oparm.getDVBS(sparm);
1702 PutSatelliteDataToDict(dest, sparm);
1705 eDVBFrontendParametersCable cparm;
1706 oparm.getDVBC(cparm);
1707 PutCableDataToDict(dest, cparm);
1710 eDVBFrontendParametersTerrestrial tparm;
1711 oparm.getDVBT(tparm);
1712 PutTerrestrialDataToDict(dest, tparm);
1718 FRONTENDPARAMETERS &parm = front;
1719 #if HAVE_DVB_API_VERSION >= 5
1723 eDVBFrontendParametersSatellite sparm;
1724 oparm.getDVBS(sparm);
1725 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1728 fillDictWithCableData(dest, p);
1731 fillDictWithTerrestrialData(dest, p);
1735 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1736 switch(parm_inversion & 3)
1739 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1742 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1746 PutToDict(dest, "inversion", tmp);
1749 eDVBFrontendParametersSatellite sparm;
1750 oparm.getDVBS(sparm);
1752 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1755 fillDictWithCableData(dest, parm);
1758 fillDictWithTerrestrialData(dest, parm);
1766 void eDVBFrontend::getFrontendData(ePyObject dest)
1768 if (dest && PyDict_Check(dest))
1771 PutToDict(dest, "tuner_number", m_slotid);
1773 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
1777 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
1778 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1780 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1785 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1793 PutToDict(dest, "tuner_type", tmp);
1797 #ifndef FP_IOCTL_GET_ID
1798 #define FP_IOCTL_GET_ID 0
1800 int eDVBFrontend::readInputpower()
1804 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1806 char proc_name2[64];
1807 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1808 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1810 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1812 if (fscanf(f, "%d", &power) != 1)
1813 eDebug("read %s failed!! (%m)", proc_name);
1815 eDebug("%s is %d\n", proc_name, power);
1820 // open front prozessor
1821 int fp=::open("/dev/dbox/fp0", O_RDWR);
1824 eDebug("couldn't open fp");
1827 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1828 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1830 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1839 bool eDVBFrontend::setSecSequencePos(int steps)
1841 eDebugNoSimulate("set sequence pos %d", steps);
1846 if (m_sec_sequence.current() != m_sec_sequence.end())
1847 ++m_sec_sequence.current();
1852 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1853 --m_sec_sequence.current();
1859 void eDVBFrontend::tuneLoop()
1864 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1867 eDVBFrontend *sec_fe = this;
1868 eDVBRegisteredFrontend *regFE = 0;
1869 long tmp = m_data[LINKED_PREV_PTR];
1872 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1873 sec_fe = prev->m_frontend;
1874 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1875 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1876 int state = sec_fe->m_state;
1877 // workaround to put the kernel frontend thread into idle state!
1878 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1880 sec_fe->closeFrontend(true);
1881 state = sec_fe->m_state;
1883 // sec_fe is closed... we must reopen it here..
1884 if (state == stateClosed)
1892 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1894 long *sec_fe_data = sec_fe->m_data;
1895 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1897 switch (m_sec_sequence.current()->cmd)
1899 case eSecCommand::SLEEP:
1900 delay = m_sec_sequence.current()++->msec;
1901 eDebugNoSimulate("[SEC] sleep %dms", delay);
1903 case eSecCommand::GOTO:
1904 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1905 ++m_sec_sequence.current();
1907 case eSecCommand::SET_VOLTAGE:
1909 int voltage = m_sec_sequence.current()++->voltage;
1910 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1911 sec_fe->setVoltage(voltage);
1914 case eSecCommand::IF_VOLTAGE_GOTO:
1916 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1917 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1919 ++m_sec_sequence.current();
1922 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1924 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1925 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1927 ++m_sec_sequence.current();
1930 case eSecCommand::IF_TONE_GOTO:
1932 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1933 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1935 ++m_sec_sequence.current();
1938 case eSecCommand::IF_NOT_TONE_GOTO:
1940 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1941 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1943 ++m_sec_sequence.current();
1946 case eSecCommand::SET_TONE:
1947 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1948 sec_fe->setTone(m_sec_sequence.current()++->tone);
1950 case eSecCommand::SEND_DISEQC:
1951 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1952 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1953 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1954 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1955 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1956 eDebugNoSimulate("(DiSEqC reset)");
1957 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1958 eDebugNoSimulate("(DiSEqC peripherial power on)");
1960 eDebugNoSimulate("");
1961 ++m_sec_sequence.current();
1963 case eSecCommand::SEND_TONEBURST:
1964 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1965 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1967 case eSecCommand::SET_FRONTEND:
1969 int enableEvents = (m_sec_sequence.current()++)->val;
1970 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1971 setFrontend(enableEvents);
1974 case eSecCommand::START_TUNE_TIMEOUT:
1976 int tuneTimeout = m_sec_sequence.current()->timeout;
1977 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1979 m_timeout->start(tuneTimeout, 1);
1980 ++m_sec_sequence.current();
1983 case eSecCommand::SET_TIMEOUT:
1984 m_timeoutCount = m_sec_sequence.current()++->val;
1985 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1987 case eSecCommand::IF_TIMEOUT_GOTO:
1988 if (!m_timeoutCount)
1990 eDebugNoSimulate("[SEC] rotor timout");
1991 setSecSequencePos(m_sec_sequence.current()->steps);
1994 ++m_sec_sequence.current();
1996 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1998 int idx = m_sec_sequence.current()++->val;
1999 if ( idx == 0 || idx == 1 )
2001 m_idleInputpower[idx] = sec_fe->readInputpower();
2002 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
2005 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
2008 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
2010 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
2011 int idx = compare.val;
2012 if ( !m_simulate && (idx == 0 || idx == 1) )
2014 int idle = sec_fe->readInputpower();
2015 int diff = abs(idle-m_idleInputpower[idx]);
2018 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
2019 setSecSequencePos(compare.steps);
2023 ++m_sec_sequence.current();
2026 case eSecCommand::IF_TUNER_LOCKED_GOTO:
2028 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2031 setSecSequencePos(cmd.steps);
2035 int isLocked = readFrontendData(locked);
2036 m_idleInputpower[0] = m_idleInputpower[1] = 0;
2038 if (!m_timeoutCount && m_retryCount > 0)
2040 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
2043 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2046 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2048 cmd.lastSignal = signal;
2051 if (cmd.okcount > 4)
2053 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2054 setSecSequencePos(cmd.steps);
2055 m_state = stateLock;
2056 m_stateChanged(this);
2057 feEvent(-1); // flush events
2065 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2067 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2071 ++m_sec_sequence.current();
2074 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2075 m_runningInputpower = sec_fe->readInputpower();
2076 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2077 ++m_sec_sequence.current();
2079 case eSecCommand::SET_ROTOR_MOVING:
2081 m_sec->setRotorMoving(m_slotid, true);
2082 ++m_sec_sequence.current();
2084 case eSecCommand::SET_ROTOR_STOPPED:
2086 m_sec->setRotorMoving(m_slotid, false);
2087 ++m_sec_sequence.current();
2089 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2091 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2094 setSecSequencePos(cmd.steps);
2097 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2098 const char *txt = cmd.direction ? "running" : "stopped";
2100 if (!m_timeoutCount && m_retryCount > 0)
2102 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2104 m_runningInputpower,
2107 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2108 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2111 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2112 if ( cmd.okcount > 6 )
2114 eDebugNoSimulate("[SEC] rotor is %s", txt);
2115 if (setSecSequencePos(cmd.steps))
2121 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2124 ++m_sec_sequence.current();
2127 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2128 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2129 setSecSequencePos(m_sec_sequence.current()->steps);
2131 ++m_sec_sequence.current();
2133 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2134 eDebugNoSimulate("[SEC] invalidate current switch params");
2135 sec_fe_data[CSW] = -1;
2136 sec_fe_data[UCSW] = -1;
2137 sec_fe_data[TONEBURST] = -1;
2138 ++m_sec_sequence.current();
2140 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2141 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2142 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2143 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2144 eDebugNoSimulate("[SEC] update current switch params");
2145 ++m_sec_sequence.current();
2147 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2148 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2149 sec_fe_data[ROTOR_CMD] = -1;
2150 sec_fe_data[ROTOR_POS] = -1;
2151 ++m_sec_sequence.current();
2153 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2154 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2155 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2156 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2157 ++m_sec_sequence.current();
2159 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2160 m_retryCount = m_sec_sequence.current()++->val;
2161 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2163 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2166 eDebugNoSimulate("[SEC] no more rotor retrys");
2167 setSecSequencePos(m_sec_sequence.current()->steps);
2170 ++m_sec_sequence.current();
2172 case eSecCommand::SET_POWER_LIMITING_MODE:
2177 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2178 FILE *f=fopen(proc_name, "w");
2179 if (f) // new interface exist?
2181 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2182 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2183 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2185 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2188 else if (sec_fe->m_need_rotor_workaround)
2191 int slotid = sec_fe->m_slotid;
2192 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2194 sprintf(dev, "/dev/i2c-%d", slotid);
2195 else if (slotid == 2)
2196 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2197 else if (slotid == 3)
2198 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2199 int fd = ::open(dev, O_RDWR);
2201 unsigned char data[2];
2202 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2203 if(::read(fd, data, 1) != 1)
2204 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2205 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2207 data[0] |= 0x80; // enable static current limiting
2208 eDebugNoSimulate("[SEC] set static current limiting");
2212 data[0] &= ~0x80; // enable dynamic current limiting
2213 eDebugNoSimulate("[SEC] set dynamic current limiting");
2215 if(::write(fd, data, 1) != 1)
2216 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2220 ++m_sec_sequence.current();
2223 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2225 eDebugNoSimulate("[SEC] delayed close frontend");
2226 closeFrontend(false, true);
2227 ++m_sec_sequence.current();
2231 eDebugNoSimulate("[SEC] unhandled sec command %d",
2232 ++m_sec_sequence.current()->cmd);
2233 ++m_sec_sequence.current();
2236 m_tuneTimer->start(delay,true);
2240 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2245 void eDVBFrontend::setFrontend(bool recvEvents)
2249 eDebug("setting frontend %d", m_dvbid);
2252 oparm.getSystem(type);
2256 feEvent(-1); // flush events
2257 #if HAVE_DVB_API_VERSION >= 5
2258 if (type == iDVBFrontend::feSatellite)
2260 fe_rolloff_t rolloff = ROLLOFF_35;
2261 fe_pilot_t pilot = PILOT_OFF;
2262 fe_modulation_t modulation = QPSK;
2263 fe_delivery_system_t system = SYS_DVBS;
2264 eDVBFrontendParametersSatellite sparm;
2265 oparm.getDVBS(sparm);
2266 switch(sparm.system)
2268 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2269 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2271 switch(sparm.modulation)
2273 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2274 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2275 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2279 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2280 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2281 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2283 switch(sparm.rolloff)
2285 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2286 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2287 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2289 struct dtv_property p[10];
2290 struct dtv_properties cmdseq;
2292 p[0].cmd = DTV_CLEAR;
2293 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2294 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2295 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2296 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2297 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2298 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2299 if (system == SYS_DVBS2)
2301 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2302 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2303 p[9].cmd = DTV_TUNE;
2308 p[7].cmd = DTV_TUNE;
2311 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2313 perror("FE_SET_PROPERTY failed");
2317 else if (type == iDVBFrontend::feCable)
2319 struct dtv_property p[8];
2320 struct dtv_properties cmdseq;
2322 p[0].cmd = DTV_CLEAR;
2323 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2324 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2326 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2328 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2329 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2330 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2331 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2332 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2333 p[7].cmd = DTV_TUNE;
2335 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2337 perror("FE_SET_PROPERTY failed");
2341 else if (type == iDVBFrontend::feTerrestrial)
2343 fe_delivery_system_t system = SYS_DVBT;
2344 eDVBFrontendParametersTerrestrial tparm;
2345 oparm.getDVBT(tparm);
2346 switch (tparm.system)
2349 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2350 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2353 switch (tparm.bandwidth)
2355 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2356 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2357 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2359 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2360 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2361 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2362 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2364 struct dtv_property p[13];
2365 struct dtv_properties cmdseq;
2368 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2369 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2370 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2371 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2372 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2373 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2374 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2375 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2376 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2377 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2378 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2379 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
2380 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2381 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
2382 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2384 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2385 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2387 perror("FE_SET_PROPERTY failed");
2392 #endif /* HAVE_DVB_API_VERSION >= 5 */
2394 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2396 perror("FE_SET_FRONTEND failed");
2403 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2408 eWarning("no SEC module active!");
2411 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2414 #if HAVE_DVB_API_VERSION >= 3
2415 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",
2418 feparm.polarisation,
2422 feparm.orbital_position,
2428 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2431 feparm.polarisation,
2435 feparm.orbital_position);
2437 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2438 switch (feparm.inversion)
2440 case eDVBFrontendParametersSatellite::Inversion_On:
2441 parm_inversion = INVERSION_ON;
2443 case eDVBFrontendParametersSatellite::Inversion_Off:
2444 parm_inversion = INVERSION_OFF;
2447 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2448 parm_inversion = INVERSION_AUTO;
2451 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2455 case eDVBFrontendParametersSatellite::FEC_None:
2456 parm_u_qpsk_fec_inner = FEC_NONE;
2458 case eDVBFrontendParametersSatellite::FEC_1_2:
2459 parm_u_qpsk_fec_inner = FEC_1_2;
2461 case eDVBFrontendParametersSatellite::FEC_2_3:
2462 parm_u_qpsk_fec_inner = FEC_2_3;
2464 case eDVBFrontendParametersSatellite::FEC_3_4:
2465 parm_u_qpsk_fec_inner = FEC_3_4;
2467 case eDVBFrontendParametersSatellite::FEC_5_6:
2468 parm_u_qpsk_fec_inner = FEC_5_6;
2470 case eDVBFrontendParametersSatellite::FEC_7_8:
2471 parm_u_qpsk_fec_inner = FEC_7_8;
2474 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2475 case eDVBFrontendParametersSatellite::FEC_Auto:
2476 parm_u_qpsk_fec_inner = FEC_AUTO;
2480 #if HAVE_DVB_API_VERSION >= 3
2485 case eDVBFrontendParametersSatellite::FEC_1_2:
2486 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2488 case eDVBFrontendParametersSatellite::FEC_2_3:
2489 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2491 case eDVBFrontendParametersSatellite::FEC_3_4:
2492 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2494 case eDVBFrontendParametersSatellite::FEC_3_5:
2495 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2497 case eDVBFrontendParametersSatellite::FEC_4_5:
2498 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2500 case eDVBFrontendParametersSatellite::FEC_5_6:
2501 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2503 case eDVBFrontendParametersSatellite::FEC_7_8:
2504 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2506 case eDVBFrontendParametersSatellite::FEC_8_9:
2507 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2509 case eDVBFrontendParametersSatellite::FEC_9_10:
2510 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2513 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2516 #if HAVE_DVB_API_VERSION < 5
2517 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2518 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2519 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2521 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2522 // 8PSK fec driver values are decimal 9 bigger
2527 // FIXME !!! get frequency range from tuner
2528 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2530 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2533 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2535 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2539 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2541 #if HAVE_DVB_API_VERSION < 3
2542 parm_frequency = feparm.frequency;
2544 parm_frequency = feparm.frequency * 1000;
2546 parm_u_qam_symbol_rate = feparm.symbol_rate;
2547 switch (feparm.modulation)
2549 case eDVBFrontendParametersCable::Modulation_QAM16:
2550 parm_u_qam_modulation = QAM_16;
2552 case eDVBFrontendParametersCable::Modulation_QAM32:
2553 parm_u_qam_modulation = QAM_32;
2555 case eDVBFrontendParametersCable::Modulation_QAM64:
2556 parm_u_qam_modulation = QAM_64;
2558 case eDVBFrontendParametersCable::Modulation_QAM128:
2559 parm_u_qam_modulation = QAM_128;
2561 case eDVBFrontendParametersCable::Modulation_QAM256:
2562 parm_u_qam_modulation = QAM_256;
2565 case eDVBFrontendParametersCable::Modulation_Auto:
2566 parm_u_qam_modulation = QAM_AUTO;
2569 switch (feparm.inversion)
2571 case eDVBFrontendParametersCable::Inversion_On:
2572 parm_inversion = INVERSION_ON;
2574 case eDVBFrontendParametersCable::Inversion_Off:
2575 parm_inversion = INVERSION_OFF;
2578 case eDVBFrontendParametersCable::Inversion_Unknown:
2579 parm_inversion = INVERSION_AUTO;
2582 switch (feparm.fec_inner)
2584 case eDVBFrontendParametersCable::FEC_None:
2585 parm_u_qam_fec_inner = FEC_NONE;
2587 case eDVBFrontendParametersCable::FEC_1_2:
2588 parm_u_qam_fec_inner = FEC_1_2;
2590 case eDVBFrontendParametersCable::FEC_2_3:
2591 parm_u_qam_fec_inner = FEC_2_3;
2593 case eDVBFrontendParametersCable::FEC_3_4:
2594 parm_u_qam_fec_inner = FEC_3_4;
2596 case eDVBFrontendParametersCable::FEC_5_6:
2597 parm_u_qam_fec_inner = FEC_5_6;
2599 case eDVBFrontendParametersCable::FEC_7_8:
2600 parm_u_qam_fec_inner = FEC_7_8;
2602 #if HAVE_DVB_API_VERSION >= 3
2603 case eDVBFrontendParametersCable::FEC_8_9:
2604 parm_u_qam_fec_inner = FEC_8_9;
2608 case eDVBFrontendParametersCable::FEC_Auto:
2609 parm_u_qam_fec_inner = FEC_AUTO;
2612 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2613 parm_frequency/1000,
2614 parm_u_qam_symbol_rate,
2615 parm_u_qam_fec_inner,
2616 parm_u_qam_modulation,
2618 oparm.setDVBC(feparm);
2622 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2624 parm_frequency = feparm.frequency;
2626 switch (feparm.bandwidth)
2628 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2629 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2631 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2632 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2634 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2635 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2637 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2638 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2640 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2641 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2643 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2644 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2647 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2648 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2651 switch (feparm.code_rate_LP)
2653 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2654 parm_u_ofdm_code_rate_LP = FEC_1_2;
2656 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2657 parm_u_ofdm_code_rate_LP = FEC_2_3;
2659 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2660 parm_u_ofdm_code_rate_LP = FEC_3_4;
2662 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2663 parm_u_ofdm_code_rate_LP = FEC_5_6;
2665 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2666 parm_u_ofdm_code_rate_LP = FEC_7_8;
2668 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2669 parm_u_ofdm_code_rate_LP = FEC_6_7;
2671 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2672 parm_u_ofdm_code_rate_LP = FEC_8_9;
2675 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2676 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2679 switch (feparm.code_rate_HP)
2681 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2682 parm_u_ofdm_code_rate_HP = FEC_1_2;
2684 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2685 parm_u_ofdm_code_rate_HP = FEC_2_3;
2687 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2688 parm_u_ofdm_code_rate_HP = FEC_3_4;
2690 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2691 parm_u_ofdm_code_rate_HP = FEC_5_6;
2693 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2694 parm_u_ofdm_code_rate_HP = FEC_7_8;
2696 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2697 parm_u_ofdm_code_rate_HP = FEC_6_7;
2699 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2700 parm_u_ofdm_code_rate_HP = FEC_8_9;
2703 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2704 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2707 switch (feparm.modulation)
2709 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2710 parm_u_ofdm_constellation = QPSK;
2712 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2713 parm_u_ofdm_constellation = QAM_16;
2715 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2716 parm_u_ofdm_constellation = QAM_64;
2718 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2719 parm_u_ofdm_constellation = QAM_256;
2722 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2723 parm_u_ofdm_constellation = QAM_AUTO;
2726 switch (feparm.transmission_mode)
2728 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2729 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2731 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2732 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2734 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2735 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2737 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2738 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2740 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2741 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2743 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2744 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2747 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2748 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2751 switch (feparm.guard_interval)
2753 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2754 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2756 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2757 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2759 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2760 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2762 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2763 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2765 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2766 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2768 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2769 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2771 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2772 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2775 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2776 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2779 switch (feparm.hierarchy)
2781 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2782 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2784 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2785 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2787 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2788 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2790 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2791 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2794 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2795 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2798 switch (feparm.inversion)
2800 case eDVBFrontendParametersTerrestrial::Inversion_On:
2801 parm_inversion = INVERSION_ON;
2803 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2804 parm_inversion = INVERSION_OFF;
2807 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2808 parm_inversion = INVERSION_AUTO;
2811 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",
2812 parm_frequency/1000,
2813 parm_u_ofdm_bandwidth,
2814 parm_u_ofdm_code_rate_LP,
2815 parm_u_ofdm_code_rate_HP,
2816 parm_u_ofdm_constellation,
2817 parm_u_ofdm_transmission_mode,
2818 parm_u_ofdm_guard_interval,
2819 parm_u_ofdm_hierarchy_information,
2823 oparm.setDVBT(feparm);
2827 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2829 unsigned int timeout = 5000;
2830 eDebugNoSimulate("(%d)tune", m_dvbid);
2837 if (where.getSystem(type) < 0)
2843 if (!m_sn && !m_simulate)
2845 eDebug("no frontend device opened... do not try to tune !!!");
2853 m_sec_sequence.clear();
2855 where.calcLockTimeout(timeout);
2861 eDVBFrontendParametersSatellite feparm;
2862 if (where.getDVBS(feparm))
2864 eDebug("no dvbs data!");
2868 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2870 eDVBFrontend *sec_fe = this;
2871 long tmp = m_data[LINKED_PREV_PTR];
2874 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2875 sec_fe = linked_fe->m_frontend;
2876 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2878 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2879 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
2881 m_rotor_mode = feparm.no_rotor_command_on_tune;
2883 m_sec->setRotorMoving(m_slotid, false);
2884 res=prepare_sat(feparm, timeout);
2892 eDVBFrontendParametersCable feparm;
2893 if (where.getDVBC(feparm))
2898 res=prepare_cable(feparm);
2902 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2903 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2908 eDVBFrontendParametersTerrestrial feparm;
2909 if (where.getDVBT(feparm))
2911 eDebug("no -T data");
2915 res=prepare_terrestrial(feparm);
2919 std::string enable_5V;
2920 char configStr[255];
2921 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2922 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2923 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2924 if (enable_5V == "True")
2925 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2927 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2928 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2939 m_sec_sequence.current() = m_sec_sequence.begin();
2943 m_tuneTimer->start(0,true);
2945 if (m_state != stateTuning)
2947 m_state = stateTuning;
2948 m_stateChanged(this);
2957 m_tuneTimer->stop();
2961 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2963 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2967 RESULT eDVBFrontend::setVoltage(int voltage)
2969 #if HAVE_DVB_API_VERSION < 3
2972 bool increased=false;
2973 fe_sec_voltage_t vlt;
2975 m_data[CUR_VOLTAGE]=voltage;
2979 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2980 vlt = SEC_VOLTAGE_OFF;
2983 #if HAVE_DVB_API_VERSION < 3
2984 vlt = SEC_VOLTAGE_13_5;
2990 vlt = SEC_VOLTAGE_13;
2993 #if HAVE_DVB_API_VERSION < 3
2994 vlt = SEC_VOLTAGE_18_5;
3000 vlt = SEC_VOLTAGE_18;
3007 #if HAVE_DVB_API_VERSION < 3
3008 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
3010 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
3011 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
3015 RESULT eDVBFrontend::getState(int &state)
3021 RESULT eDVBFrontend::setTone(int t)
3023 #if HAVE_DVB_API_VERSION < 3
3026 fe_sec_tone_mode_t tone;
3035 tone = SEC_TONE_OFF;
3042 #if HAVE_DVB_API_VERSION < 3
3043 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
3045 return ::ioctl(m_fd, FE_SET_TONE, tone);
3049 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3050 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3053 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3058 #if HAVE_DVB_API_VERSION < 3
3059 struct secCommand cmd;
3060 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3061 cmd.u.diseqc.cmdtype = diseqc.data[0];
3062 cmd.u.diseqc.addr = diseqc.data[1];
3063 cmd.u.diseqc.cmd = diseqc.data[2];
3064 cmd.u.diseqc.numParams = diseqc.len-3;
3065 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3066 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3068 struct dvb_diseqc_master_cmd cmd;
3069 memcpy(cmd.msg, diseqc.data, diseqc.len);
3070 cmd.msg_len = diseqc.len;
3071 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3077 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3078 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3080 RESULT eDVBFrontend::sendToneburst(int burst)
3084 #if HAVE_DVB_API_VERSION < 3
3085 secMiniCmd cmd = SEC_MINI_NONE;
3087 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3089 if ( burst == eDVBSatelliteDiseqcParameters::A )
3091 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3093 #if HAVE_DVB_API_VERSION < 3
3094 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3097 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3103 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3109 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3111 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3112 m_sec_sequence.push_back(list);
3114 m_sec_sequence = list;
3118 RESULT eDVBFrontend::getData(int num, long &data)
3120 if ( num < NUM_DATA_ENTRIES )
3128 RESULT eDVBFrontend::setData(int num, long val)
3130 if ( num < NUM_DATA_ENTRIES )
3138 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3142 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3144 if (feparm->getSystem(type) || !m_enabled)
3147 if (type == eDVBFrontend::feSatellite)
3149 eDVBFrontendParametersSatellite sat_parm;
3150 bool can_handle_dvbs, can_handle_dvbs2;
3151 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
3152 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
3153 if (feparm->getDVBS(sat_parm) < 0)
3157 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
3161 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
3165 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3166 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
3168 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3173 else if (type == eDVBFrontend::feCable)
3175 eDVBFrontendParametersCable cab_parm;
3176 if (feparm->getDVBC(cab_parm) < 0)
3180 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
3181 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
3186 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
3194 else if (type == eDVBFrontend::feTerrestrial)
3196 eDVBFrontendParametersTerrestrial ter_parm;
3197 bool can_handle_dvbt, can_handle_dvbt2;
3198 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
3199 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
3200 if (feparm->getDVBT(ter_parm) < 0)
3204 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
3208 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
3213 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
3215 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3220 if (score && preferred)
3222 /* make 'sure' we always prefer this frontend */
3229 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
3231 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
3232 if (it != m_delsys.end() && it->second)
3234 if (obeywhitelist && !m_delsys_whitelist.empty())
3236 it = m_delsys_whitelist.find(sys);
3237 if (it == m_delsys_whitelist.end() || !it->second) return false;
3244 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
3246 m_delsys_whitelist.clear();
3247 for (unsigned int i = 0; i < whitelist.size(); i++)
3249 m_delsys_whitelist[whitelist[i]] = true;
3253 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
3257 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3259 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3260 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3262 Id = PyTuple_GET_ITEM(obj, 0);
3263 Descr = PyTuple_GET_ITEM(obj, 1);
3264 Enabled = PyTuple_GET_ITEM(obj, 2);
3265 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3266 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3267 frontendId = PyTuple_GET_ITEM(obj, 5);
3268 m_slotid = PyInt_AsLong(Id);
3269 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3271 strcpy(m_description, PyString_AS_STRING(Descr));
3272 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3273 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3274 // m_slotid, m_description);
3277 m_enabled = (Enabled == Py_True);
3278 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3279 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3280 !!strstr(m_description, "Alps BSBE2") ||
3281 !!strstr(m_description, "Alps -S") ||
3282 !!strstr(m_description, "BCM4501");
3283 if (IsDVBS2 == Py_True)
3285 /* HACK for legacy dvb api without DELSYS support */
3286 m_delsys[SYS_DVBS2] = true;
3288 if (IsDVBT2 == Py_True)
3290 /* HACK for legacy dvb api without DELSYS support */
3291 m_delsys[SYS_DVBT2] = true;
3294 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3295 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", Enabled == Py_True ? "Yes" : "No", IsDVBS2 == Py_True ? "Yes" : "No", IsDVBT2 == Py_True ? "Yes" : "No" );
3298 PyErr_SetString(PyExc_StandardError,
3299 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");