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;
791 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
792 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
796 if (m_state != state)
799 m_stateChanged(this);
804 void eDVBFrontend::timeout()
807 if (m_state == stateTuning)
810 eDVBFrontend *sec_fe = this;
811 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
812 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
814 m_state = stateFailed;
815 m_stateChanged(this);
819 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
821 /* unsigned 32 bit division */
822 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
824 return (a + b / 2) / b;
827 int eDVBFrontend::readFrontendData(int type)
836 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
837 eDebug("FE_READ_BER failed (%m)");
842 case signalQualitydB: /* this will move into the driver */
844 int sat_max = 1600; // for stv0288 / bsbe2
845 int ret = 0x12345678;
849 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
850 eDebug("FE_READ_SNR failed (%m)");
851 else if (!strcmp(m_description, "BCM4501 (internal)"))
853 float SDS_SNRE = snr << 16;
856 eDVBFrontendParametersSatellite sparm;
857 oparm.getDVBS(sparm);
859 if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
861 static float SNR_COEFF[6] = {
864 197418.0 / 4194304.0,
865 -2602183.0 / 4194304.0,
866 20377212.0 / 4194304.0,
867 -37791203.0 / 4194304.0,
869 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
870 fval2 = pow(10.0, fval1)-1;
871 fval1 = 10.0 * log10(fval2);
875 fval2 = SNR_COEFF[0];
876 for (int i=1; i<6; ++i)
879 fval2 += SNR_COEFF[i];
885 #if HAVE_DVB_API_VERSION >= 3
888 float fval1 = SDS_SNRE / 268435456.0,
891 if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
902 fval4 = -10.0 * log10(fval1);
904 for (int i=0; i < 5; ++i)
905 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
910 ret = (int)(snr_in_db * 100);
912 else if (strstr(m_description, "Alps BSBE1 C01A") ||
913 strstr(m_description, "Alps -S(STV0288)"))
917 else if (snr == 0xFFFF) // i think this should not happen
921 enum { REALVAL, REGVAL };
922 const long CN_lookup[31][2] = {
923 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
924 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
925 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
926 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
927 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
928 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
931 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
932 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
936 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
941 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
946 ret = (((regval - CN_lookup[Imin][REGVAL])
947 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
948 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
949 + CN_lookup[Imin][REALVAL]) * 10;
955 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
956 !strcmp(m_description, "Alps -S") ||
957 !strcmp(m_description, "Philips -S") ||
958 !strcmp(m_description, "LG -S") )
961 ret = (int)((snr-39075)/17.647);
962 } else if (!strcmp(m_description, "Alps BSBE2"))
964 ret = (int)((snr >> 7) * 10);
965 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
967 int mse = (~snr) & 0xFF;
968 switch (parm_u_qam_modulation) {
969 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
970 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
971 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
972 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
973 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
976 } else if (!strcmp(m_description, "Philips TU1216"))
978 snr = 0xFF - (snr & 0xFF);
980 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
982 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
983 ret = (snr * 100) >> 8;
984 else if (!strcmp(m_description, "CXD1981"))
986 int mse = (~snr) & 0xFF;
987 switch (parm_u_qam_modulation) {
990 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
992 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
998 if (type == signalQuality)
1000 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
1004 oparm.getSystem(type);
1008 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
1009 case feCable: // we assume a max of 42db here
1010 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
1011 case feTerrestrial: // we assume a max of 24db here
1012 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
1016 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
1021 uint16_t strength=0;
1024 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
1025 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1031 #if HAVE_DVB_API_VERSION < 3
1032 FrontendStatus status=0;
1038 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1039 eDebug("FE_READ_STATUS failed (%m)");
1040 return !!(status&FE_HAS_LOCK);
1046 #if HAVE_DVB_API_VERSION < 3
1047 FrontendStatus status=0;
1053 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1054 eDebug("FE_READ_STATUS failed (%m)");
1055 return !!(status&FE_HAS_SYNC);
1059 case frontendNumber:
1065 void PutToDict(ePyObject &dict, const char*key, long value)
1067 ePyObject item = PyInt_FromLong(value);
1070 if (PyDict_SetItemString(dict, key, item))
1071 eDebug("put %s to dict failed", key);
1075 eDebug("could not create PyObject for %s", key);
1078 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1082 if (PyDict_SetItemString(dict, key, item))
1083 eDebug("put %s to dict failed", key);
1087 eDebug("invalid PyObject for %s", key);
1090 void PutToDict(ePyObject &dict, const char*key, const char *value)
1092 ePyObject item = PyString_FromString(value);
1095 if (PyDict_SetItemString(dict, key, item))
1096 eDebug("put %s to dict failed", key);
1100 eDebug("could not create PyObject for %s", key);
1103 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1105 PutToDict(dict, "tuner_type", "DVB-S");
1106 PutToDict(dict, "frequency", feparm.frequency);
1107 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1108 PutToDict(dict, "orbital_position", feparm.orbital_position);
1109 PutToDict(dict, "inversion", feparm.inversion);
1110 PutToDict(dict, "fec_inner", feparm.fec);
1111 PutToDict(dict, "modulation", feparm.modulation);
1112 PutToDict(dict, "polarization", feparm.polarisation);
1113 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1115 PutToDict(dict, "rolloff", feparm.rolloff);
1116 PutToDict(dict, "pilot", feparm.pilot);
1118 PutToDict(dict, "system", feparm.system);
1121 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1123 PutToDict(dict, "tuner_type", "DVB-T");
1124 PutToDict(dict, "frequency", feparm.frequency);
1125 PutToDict(dict, "bandwidth", feparm.bandwidth);
1126 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1127 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1128 PutToDict(dict, "constellation", feparm.modulation);
1129 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1130 PutToDict(dict, "guard_interval", feparm.guard_interval);
1131 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1132 PutToDict(dict, "inversion", feparm.inversion);
1133 PutToDict(dict, "system", feparm.system);
1134 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1136 PutToDict(dict, "plp_id", feparm.plpid);
1140 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1142 PutToDict(dict, "tuner_type", "DVB-C");
1143 PutToDict(dict, "frequency", feparm.frequency);
1144 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1145 PutToDict(dict, "modulation", feparm.modulation);
1146 PutToDict(dict, "inversion", feparm.inversion);
1147 PutToDict(dict, "fec_inner", feparm.fec_inner);
1150 #if HAVE_DVB_API_VERSION >= 5
1151 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1154 int frequency = parm_frequency + freq_offset;
1155 PutToDict(dict, "frequency", frequency);
1156 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1157 PutToDict(dict, "orbital_position", orb_pos);
1158 PutToDict(dict, "polarization", polarization);
1160 switch(parm_u_qpsk_fec_inner)
1162 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1163 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1164 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1165 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1166 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1167 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1168 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1169 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1170 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1171 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1172 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1173 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1175 PutToDict(dict, "fec_inner", tmp);
1177 switch (p[0].u.data)
1179 default: eDebug("got unsupported system from frontend! report as DVBS!");
1180 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1183 switch (p[2].u.data)
1185 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1186 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1187 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1188 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1190 PutToDict(dict, "rolloff", tmp);
1192 switch (p[3].u.data)
1194 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1195 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1196 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1198 PutToDict(dict, "pilot", tmp);
1200 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1203 PutToDict(dict, "system", tmp);
1205 switch (p[1].u.data)
1207 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1208 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1209 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1211 PutToDict(dict, "modulation", tmp);
1213 switch(parm_inversion & 3)
1215 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1216 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1217 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1219 PutToDict(dict, "inversion", tmp);
1222 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1226 tmp = p[1].u.data/1000;
1227 PutToDict(dict, "frequency", tmp);
1229 PutToDict(dict, "symbol_rate", p[2].u.data);
1231 switch (p[3].u.data)
1233 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1234 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1235 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1236 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1237 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1238 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1239 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1241 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1243 PutToDict(dict, "fec_inner", tmp);
1245 switch (p[4].u.data)
1247 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1248 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1249 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1250 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1251 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1253 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1255 PutToDict(dict, "modulation", tmp);
1257 switch (p[5].u.data)
1259 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1260 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1262 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1264 PutToDict(dict, "inversion", tmp);
1267 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1271 switch (p[0].u.data)
1273 default: eDebug("got unsupported system from frontend! report as DVBT!");
1274 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1277 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1279 PutToDict(dict, "plp_id", tmp);
1281 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1284 PutToDict(dict, "system", tmp);
1287 PutToDict(dict, "frequency", tmp);
1289 switch (p[2].u.data)
1291 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1292 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1293 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1294 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1295 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1296 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1298 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1300 PutToDict(dict, "bandwidth", tmp);
1302 switch (p[3].u.data)
1304 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1305 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1306 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1307 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1308 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1309 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1310 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1311 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1313 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1315 PutToDict(dict, "code_rate_lp", tmp);
1317 switch (p[4].u.data)
1319 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1320 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1321 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1322 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1323 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1324 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1325 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1326 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1328 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1330 PutToDict(dict, "code_rate_hp", tmp);
1332 switch (p[5].u.data)
1334 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1335 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1336 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1337 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1339 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1341 PutToDict(dict, "constellation", tmp);
1344 switch (p[6].u.data)
1346 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1347 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1348 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1349 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1350 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1351 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1353 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1355 PutToDict(dict, "transmission_mode", tmp);
1357 switch (p[7].u.data)
1359 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1360 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1361 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1362 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1363 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1364 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1365 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1367 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1369 PutToDict(dict, "guard_interval", tmp);
1371 switch (p[8].u.data)
1373 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1374 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1375 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1376 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1378 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1380 PutToDict(dict, "hierarchy_information", tmp);
1382 switch (p[9].u.data)
1384 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1385 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1387 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1389 PutToDict(dict, "inversion", tmp);
1392 #else // #if HAVE_DVB_API_VERSION >= 5
1393 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1396 int frequency = parm_frequency + freq_offset;
1397 PutToDict(dict, "frequency", frequency);
1398 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1399 PutToDict(dict, "orbital_position", orb_pos);
1400 PutToDict(dict, "polarization", polarization);
1402 switch((int)parm_u_qpsk_fec_inner)
1404 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1405 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1406 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1407 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1408 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1409 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1411 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1412 #if HAVE_DVB_API_VERSION >=3
1413 case FEC_S2_8PSK_1_2:
1414 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1415 case FEC_S2_8PSK_2_3:
1416 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1417 case FEC_S2_8PSK_3_4:
1418 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1419 case FEC_S2_8PSK_5_6:
1420 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1421 case FEC_S2_8PSK_7_8:
1422 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1423 case FEC_S2_8PSK_8_9:
1424 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1425 case FEC_S2_8PSK_3_5:
1426 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1427 case FEC_S2_8PSK_4_5:
1428 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1429 case FEC_S2_8PSK_9_10:
1430 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1433 PutToDict(dict, "fec_inner", tmp);
1434 #if HAVE_DVB_API_VERSION >=3
1435 PutToDict(dict, "modulation",
1436 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1437 eDVBFrontendParametersSatellite::Modulation_8PSK :
1438 eDVBFrontendParametersSatellite::Modulation_QPSK );
1439 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1441 switch(parm_inversion & 0xc)
1443 default: // unknown rolloff
1444 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1445 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1446 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1448 PutToDict(dict, "rolloff", tmp);
1449 switch(parm_inversion & 0x30)
1451 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1452 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1453 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1455 PutToDict(dict, "pilot", tmp);
1456 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1459 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1461 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1462 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1464 PutToDict(dict, "system", tmp);
1467 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1470 #if HAVE_DVB_API_VERSION < 3
1471 PutToDict(dict, "frequency", parm_frequency);
1473 PutToDict(dict, "frequency", parm_frequency/1000);
1475 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1476 switch(parm_u_qam_fec_inner)
1478 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1479 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1480 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1481 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1482 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1483 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1484 #if HAVE_DVB_API_VERSION >= 3
1485 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1488 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1490 PutToDict(dict, "fec_inner", tmp);
1491 switch(parm_u_qam_modulation)
1493 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1494 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1495 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1496 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1497 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1499 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1501 PutToDict(dict, "modulation", tmp);
1504 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1507 PutToDict(dict, "frequency", parm_frequency);
1508 switch (parm_u_ofdm_bandwidth)
1510 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1511 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1512 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1514 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1516 PutToDict(dict, "bandwidth", tmp);
1517 switch (parm_u_ofdm_code_rate_LP)
1519 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1520 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1521 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1522 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1523 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1525 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1527 PutToDict(dict, "code_rate_lp", tmp);
1528 switch (parm_u_ofdm_code_rate_HP)
1530 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1531 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1532 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1533 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1534 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1536 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1538 PutToDict(dict, "code_rate_hp", tmp);
1539 switch (parm_u_ofdm_constellation)
1541 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1542 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1543 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1545 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1547 PutToDict(dict, "constellation", tmp);
1548 switch (parm_u_ofdm_transmission_mode)
1550 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1551 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1553 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1555 PutToDict(dict, "transmission_mode", tmp);
1556 switch (parm_u_ofdm_guard_interval)
1558 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1559 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1560 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1561 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1563 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1565 PutToDict(dict, "guard_interval", tmp);
1566 switch (parm_u_ofdm_hierarchy_information)
1568 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1569 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1570 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1571 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1573 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1575 PutToDict(dict, "hierarchy_information", tmp);
1578 #endif // #if HAVE_DVB_API_VERSION >= 5
1580 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1582 if (dest && PyDict_Check(dest))
1584 const char *tmp = "UNKNOWN";
1605 PutToDict(dest, "tuner_state", tmp);
1606 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1607 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1608 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1609 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1610 int sigQualitydB = readFrontendData(signalQualitydB);
1611 if (sigQualitydB == 0x12345678) // not support yet
1613 ePyObject obj=Py_None;
1615 PutToDict(dest, "tuner_signal_quality_db", obj);
1618 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1619 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1623 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1625 if (dest && PyDict_Check(dest))
1628 FRONTENDPARAMETERS front;
1629 #if HAVE_DVB_API_VERSION >= 5
1630 struct dtv_property p[16];
1631 struct dtv_properties cmdseq;
1634 oparm.getSystem(type);
1638 p[0].cmd = DTV_DELIVERY_SYSTEM;
1639 p[1].cmd = DTV_MODULATION;
1640 p[2].cmd = DTV_ROLLOFF;
1641 p[3].cmd = DTV_PILOT;
1645 p[0].cmd = DTV_DELIVERY_SYSTEM;
1646 p[1].cmd = DTV_FREQUENCY;
1647 p[2].cmd = DTV_SYMBOL_RATE;
1648 p[3].cmd = DTV_INNER_FEC;
1649 p[4].cmd = DTV_MODULATION;
1650 p[5].cmd = DTV_INVERSION;
1654 p[0].cmd = DTV_DELIVERY_SYSTEM;
1655 p[1].cmd = DTV_FREQUENCY;
1656 p[2].cmd = DTV_BANDWIDTH_HZ;
1657 p[3].cmd = DTV_CODE_RATE_LP;
1658 p[4].cmd = DTV_CODE_RATE_HP;
1659 p[5].cmd = DTV_MODULATION;
1660 p[6].cmd = DTV_TRANSMISSION_MODE;
1661 p[7].cmd = DTV_GUARD_INTERVAL;
1662 p[8].cmd = DTV_HIERARCHY;
1663 p[9].cmd = DTV_INVERSION;
1664 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
1665 p[10].cmd = DTV_STREAM_ID;
1667 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1668 p[10].cmd = DTV_DVBT2_PLP_ID;
1676 if (m_simulate || m_fd == -1 || original)
1680 #if HAVE_DVB_API_VERSION >= 5
1681 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1683 eDebug("FE_GET_PROPERTY failed (%m)");
1686 else if (type == feSatellite && // use for DVB-S(2) only
1687 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1689 eDebug("FE_GET_FRONTEND failed (%m)");
1693 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1695 eDebug("FE_GET_FRONTEND failed (%m)");
1704 eDVBFrontendParametersSatellite sparm;
1705 oparm.getDVBS(sparm);
1706 PutSatelliteDataToDict(dest, sparm);
1709 eDVBFrontendParametersCable cparm;
1710 oparm.getDVBC(cparm);
1711 PutCableDataToDict(dest, cparm);
1714 eDVBFrontendParametersTerrestrial tparm;
1715 oparm.getDVBT(tparm);
1716 PutTerrestrialDataToDict(dest, tparm);
1722 FRONTENDPARAMETERS &parm = front;
1723 #if HAVE_DVB_API_VERSION >= 5
1727 eDVBFrontendParametersSatellite sparm;
1728 oparm.getDVBS(sparm);
1729 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1732 fillDictWithCableData(dest, p);
1735 fillDictWithTerrestrialData(dest, p);
1739 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1740 switch(parm_inversion & 3)
1743 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1746 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1750 PutToDict(dest, "inversion", tmp);
1753 eDVBFrontendParametersSatellite sparm;
1754 oparm.getDVBS(sparm);
1756 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1759 fillDictWithCableData(dest, parm);
1762 fillDictWithTerrestrialData(dest, parm);
1770 void eDVBFrontend::getFrontendData(ePyObject dest)
1772 if (dest && PyDict_Check(dest))
1775 PutToDict(dest, "tuner_number", m_slotid);
1777 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
1781 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
1782 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1784 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1789 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1797 PutToDict(dest, "tuner_type", tmp);
1801 #ifndef FP_IOCTL_GET_ID
1802 #define FP_IOCTL_GET_ID 0
1804 int eDVBFrontend::readInputpower()
1808 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1810 char proc_name2[64];
1811 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1812 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1814 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1816 if (fscanf(f, "%d", &power) != 1)
1817 eDebug("read %s failed!! (%m)", proc_name);
1819 eDebug("%s is %d\n", proc_name, power);
1824 // open front prozessor
1825 int fp=::open("/dev/dbox/fp0", O_RDWR);
1828 eDebug("couldn't open fp");
1831 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1832 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1834 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1843 bool eDVBFrontend::setSecSequencePos(int steps)
1845 eDebugNoSimulate("set sequence pos %d", steps);
1850 if (m_sec_sequence.current() != m_sec_sequence.end())
1851 ++m_sec_sequence.current();
1856 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1857 --m_sec_sequence.current();
1863 void eDVBFrontend::tuneLoop()
1868 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1871 eDVBFrontend *sec_fe = this;
1872 eDVBRegisteredFrontend *regFE = 0;
1873 long tmp = m_data[LINKED_PREV_PTR];
1876 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1877 sec_fe = prev->m_frontend;
1878 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1879 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1880 int state = sec_fe->m_state;
1881 // workaround to put the kernel frontend thread into idle state!
1882 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1884 sec_fe->closeFrontend(true);
1885 state = sec_fe->m_state;
1887 // sec_fe is closed... we must reopen it here..
1888 if (state == stateClosed)
1896 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1898 long *sec_fe_data = sec_fe->m_data;
1899 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1901 switch (m_sec_sequence.current()->cmd)
1903 case eSecCommand::SLEEP:
1904 delay = m_sec_sequence.current()++->msec;
1905 eDebugNoSimulate("[SEC] sleep %dms", delay);
1907 case eSecCommand::GOTO:
1908 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1909 ++m_sec_sequence.current();
1911 case eSecCommand::SET_VOLTAGE:
1913 int voltage = m_sec_sequence.current()++->voltage;
1914 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1915 sec_fe->setVoltage(voltage);
1918 case eSecCommand::IF_VOLTAGE_GOTO:
1920 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1921 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1923 ++m_sec_sequence.current();
1926 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1928 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1929 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1931 ++m_sec_sequence.current();
1934 case eSecCommand::IF_TONE_GOTO:
1936 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1937 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1939 ++m_sec_sequence.current();
1942 case eSecCommand::IF_NOT_TONE_GOTO:
1944 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1945 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1947 ++m_sec_sequence.current();
1950 case eSecCommand::SET_TONE:
1951 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1952 sec_fe->setTone(m_sec_sequence.current()++->tone);
1954 case eSecCommand::SEND_DISEQC:
1955 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1956 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1957 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1958 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1959 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1960 eDebugNoSimulate("(DiSEqC reset)");
1961 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1962 eDebugNoSimulate("(DiSEqC peripherial power on)");
1964 eDebugNoSimulate("");
1965 ++m_sec_sequence.current();
1967 case eSecCommand::SEND_TONEBURST:
1968 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1969 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1971 case eSecCommand::SET_FRONTEND:
1973 int enableEvents = (m_sec_sequence.current()++)->val;
1974 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1975 setFrontend(enableEvents);
1978 case eSecCommand::START_TUNE_TIMEOUT:
1980 int tuneTimeout = m_sec_sequence.current()->timeout;
1981 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1983 m_timeout->start(tuneTimeout, 1);
1984 ++m_sec_sequence.current();
1987 case eSecCommand::SET_TIMEOUT:
1988 m_timeoutCount = m_sec_sequence.current()++->val;
1989 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1991 case eSecCommand::IF_TIMEOUT_GOTO:
1992 if (!m_timeoutCount)
1994 eDebugNoSimulate("[SEC] rotor timout");
1995 setSecSequencePos(m_sec_sequence.current()->steps);
1998 ++m_sec_sequence.current();
2000 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
2002 int idx = m_sec_sequence.current()++->val;
2003 if ( idx == 0 || idx == 1 )
2005 m_idleInputpower[idx] = sec_fe->readInputpower();
2006 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
2009 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
2012 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
2014 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
2015 int idx = compare.val;
2016 if ( !m_simulate && (idx == 0 || idx == 1) )
2018 int idle = sec_fe->readInputpower();
2019 int diff = abs(idle-m_idleInputpower[idx]);
2022 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
2023 setSecSequencePos(compare.steps);
2027 ++m_sec_sequence.current();
2030 case eSecCommand::IF_TUNER_LOCKED_GOTO:
2032 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2035 setSecSequencePos(cmd.steps);
2039 int isLocked = readFrontendData(locked);
2040 m_idleInputpower[0] = m_idleInputpower[1] = 0;
2042 if (!m_timeoutCount && m_retryCount > 0)
2044 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
2047 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2050 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2052 cmd.lastSignal = signal;
2055 if (cmd.okcount > 4)
2057 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2058 setSecSequencePos(cmd.steps);
2059 m_state = stateLock;
2060 m_stateChanged(this);
2061 feEvent(-1); // flush events
2069 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2071 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2075 ++m_sec_sequence.current();
2078 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2079 m_runningInputpower = sec_fe->readInputpower();
2080 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2081 ++m_sec_sequence.current();
2083 case eSecCommand::SET_ROTOR_MOVING:
2085 m_sec->setRotorMoving(m_slotid, true);
2086 ++m_sec_sequence.current();
2088 case eSecCommand::SET_ROTOR_STOPPED:
2090 m_sec->setRotorMoving(m_slotid, false);
2091 ++m_sec_sequence.current();
2093 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2095 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2098 setSecSequencePos(cmd.steps);
2101 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2102 const char *txt = cmd.direction ? "running" : "stopped";
2104 if (!m_timeoutCount && m_retryCount > 0)
2106 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2108 m_runningInputpower,
2111 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2112 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2115 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2116 if ( cmd.okcount > 6 )
2118 eDebugNoSimulate("[SEC] rotor is %s", txt);
2119 if (setSecSequencePos(cmd.steps))
2125 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2128 ++m_sec_sequence.current();
2131 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2132 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2133 setSecSequencePos(m_sec_sequence.current()->steps);
2135 ++m_sec_sequence.current();
2137 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2138 eDebugNoSimulate("[SEC] invalidate current switch params");
2139 sec_fe_data[CSW] = -1;
2140 sec_fe_data[UCSW] = -1;
2141 sec_fe_data[TONEBURST] = -1;
2142 ++m_sec_sequence.current();
2144 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2145 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2146 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2147 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2148 eDebugNoSimulate("[SEC] update current switch params");
2149 ++m_sec_sequence.current();
2151 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2152 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2153 sec_fe_data[ROTOR_CMD] = -1;
2154 sec_fe_data[ROTOR_POS] = -1;
2155 ++m_sec_sequence.current();
2157 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2158 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2159 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2160 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2161 ++m_sec_sequence.current();
2163 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2164 m_retryCount = m_sec_sequence.current()++->val;
2165 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2167 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2170 eDebugNoSimulate("[SEC] no more rotor retrys");
2171 setSecSequencePos(m_sec_sequence.current()->steps);
2174 ++m_sec_sequence.current();
2176 case eSecCommand::SET_POWER_LIMITING_MODE:
2181 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2182 FILE *f=fopen(proc_name, "w");
2183 if (f) // new interface exist?
2185 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2186 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2187 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2189 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2192 else if (sec_fe->m_need_rotor_workaround)
2195 int slotid = sec_fe->m_slotid;
2196 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2198 sprintf(dev, "/dev/i2c-%d", slotid);
2199 else if (slotid == 2)
2200 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2201 else if (slotid == 3)
2202 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2203 int fd = ::open(dev, O_RDWR);
2205 unsigned char data[2];
2206 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2207 if(::read(fd, data, 1) != 1)
2208 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2209 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2211 data[0] |= 0x80; // enable static current limiting
2212 eDebugNoSimulate("[SEC] set static current limiting");
2216 data[0] &= ~0x80; // enable dynamic current limiting
2217 eDebugNoSimulate("[SEC] set dynamic current limiting");
2219 if(::write(fd, data, 1) != 1)
2220 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2224 ++m_sec_sequence.current();
2227 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2229 eDebugNoSimulate("[SEC] delayed close frontend");
2230 closeFrontend(false, true);
2231 ++m_sec_sequence.current();
2235 eDebugNoSimulate("[SEC] unhandled sec command %d",
2236 ++m_sec_sequence.current()->cmd);
2237 ++m_sec_sequence.current();
2240 m_tuneTimer->start(delay,true);
2244 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2249 void eDVBFrontend::setFrontend(bool recvEvents)
2253 eDebug("setting frontend %d", m_dvbid);
2256 oparm.getSystem(type);
2260 feEvent(-1); // flush events
2261 #if HAVE_DVB_API_VERSION >= 5
2262 if (type == iDVBFrontend::feSatellite)
2264 fe_rolloff_t rolloff = ROLLOFF_35;
2265 fe_pilot_t pilot = PILOT_OFF;
2266 fe_modulation_t modulation = QPSK;
2267 fe_delivery_system_t system = SYS_DVBS;
2268 eDVBFrontendParametersSatellite sparm;
2269 oparm.getDVBS(sparm);
2270 switch(sparm.system)
2272 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2273 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2275 switch(sparm.modulation)
2277 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2278 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2279 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2283 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2284 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2285 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2287 switch(sparm.rolloff)
2289 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2290 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2291 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2293 struct dtv_property p[10];
2294 struct dtv_properties cmdseq;
2296 p[0].cmd = DTV_CLEAR;
2297 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2298 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2299 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2300 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2301 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2302 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2303 if (system == SYS_DVBS2)
2305 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2306 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2307 p[9].cmd = DTV_TUNE;
2312 p[7].cmd = DTV_TUNE;
2315 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2317 perror("FE_SET_PROPERTY failed");
2321 else if (type == iDVBFrontend::feCable)
2323 struct dtv_property p[8];
2324 struct dtv_properties cmdseq;
2326 p[0].cmd = DTV_CLEAR;
2327 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2328 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2330 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2332 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2333 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2334 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2335 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2336 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2337 p[7].cmd = DTV_TUNE;
2339 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2341 perror("FE_SET_PROPERTY failed");
2345 else if (type == iDVBFrontend::feTerrestrial)
2347 fe_delivery_system_t system = SYS_DVBT;
2348 eDVBFrontendParametersTerrestrial tparm;
2349 oparm.getDVBT(tparm);
2350 switch (tparm.system)
2353 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2354 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2357 switch (tparm.bandwidth)
2359 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2360 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2361 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2363 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2364 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2365 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2366 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2368 struct dtv_property p[13];
2369 struct dtv_properties cmdseq;
2372 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2373 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2374 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2375 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2376 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2377 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2378 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2379 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2380 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2381 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2382 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2383 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
2384 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2385 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
2386 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2388 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2389 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2391 perror("FE_SET_PROPERTY failed");
2396 #endif /* HAVE_DVB_API_VERSION >= 5 */
2398 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2400 perror("FE_SET_FRONTEND failed");
2407 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2412 eWarning("no SEC module active!");
2415 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2418 #if HAVE_DVB_API_VERSION >= 3
2419 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",
2422 feparm.polarisation,
2426 feparm.orbital_position,
2432 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2435 feparm.polarisation,
2439 feparm.orbital_position);
2441 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2442 switch (feparm.inversion)
2444 case eDVBFrontendParametersSatellite::Inversion_On:
2445 parm_inversion = INVERSION_ON;
2447 case eDVBFrontendParametersSatellite::Inversion_Off:
2448 parm_inversion = INVERSION_OFF;
2451 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2452 parm_inversion = INVERSION_AUTO;
2455 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2459 case eDVBFrontendParametersSatellite::FEC_None:
2460 parm_u_qpsk_fec_inner = FEC_NONE;
2462 case eDVBFrontendParametersSatellite::FEC_1_2:
2463 parm_u_qpsk_fec_inner = FEC_1_2;
2465 case eDVBFrontendParametersSatellite::FEC_2_3:
2466 parm_u_qpsk_fec_inner = FEC_2_3;
2468 case eDVBFrontendParametersSatellite::FEC_3_4:
2469 parm_u_qpsk_fec_inner = FEC_3_4;
2471 case eDVBFrontendParametersSatellite::FEC_5_6:
2472 parm_u_qpsk_fec_inner = FEC_5_6;
2474 case eDVBFrontendParametersSatellite::FEC_7_8:
2475 parm_u_qpsk_fec_inner = FEC_7_8;
2478 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2479 case eDVBFrontendParametersSatellite::FEC_Auto:
2480 parm_u_qpsk_fec_inner = FEC_AUTO;
2484 #if HAVE_DVB_API_VERSION >= 3
2489 case eDVBFrontendParametersSatellite::FEC_1_2:
2490 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2492 case eDVBFrontendParametersSatellite::FEC_2_3:
2493 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2495 case eDVBFrontendParametersSatellite::FEC_3_4:
2496 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2498 case eDVBFrontendParametersSatellite::FEC_3_5:
2499 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2501 case eDVBFrontendParametersSatellite::FEC_4_5:
2502 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2504 case eDVBFrontendParametersSatellite::FEC_5_6:
2505 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2507 case eDVBFrontendParametersSatellite::FEC_7_8:
2508 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2510 case eDVBFrontendParametersSatellite::FEC_8_9:
2511 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2513 case eDVBFrontendParametersSatellite::FEC_9_10:
2514 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2517 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2520 #if HAVE_DVB_API_VERSION < 5
2521 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2522 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2523 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2525 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2526 // 8PSK fec driver values are decimal 9 bigger
2531 // FIXME !!! get frequency range from tuner
2532 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2534 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2537 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2539 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2543 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2545 #if HAVE_DVB_API_VERSION < 3
2546 parm_frequency = feparm.frequency;
2548 parm_frequency = feparm.frequency * 1000;
2550 parm_u_qam_symbol_rate = feparm.symbol_rate;
2551 switch (feparm.modulation)
2553 case eDVBFrontendParametersCable::Modulation_QAM16:
2554 parm_u_qam_modulation = QAM_16;
2556 case eDVBFrontendParametersCable::Modulation_QAM32:
2557 parm_u_qam_modulation = QAM_32;
2559 case eDVBFrontendParametersCable::Modulation_QAM64:
2560 parm_u_qam_modulation = QAM_64;
2562 case eDVBFrontendParametersCable::Modulation_QAM128:
2563 parm_u_qam_modulation = QAM_128;
2565 case eDVBFrontendParametersCable::Modulation_QAM256:
2566 parm_u_qam_modulation = QAM_256;
2569 case eDVBFrontendParametersCable::Modulation_Auto:
2570 parm_u_qam_modulation = QAM_AUTO;
2573 switch (feparm.inversion)
2575 case eDVBFrontendParametersCable::Inversion_On:
2576 parm_inversion = INVERSION_ON;
2578 case eDVBFrontendParametersCable::Inversion_Off:
2579 parm_inversion = INVERSION_OFF;
2582 case eDVBFrontendParametersCable::Inversion_Unknown:
2583 parm_inversion = INVERSION_AUTO;
2586 switch (feparm.fec_inner)
2588 case eDVBFrontendParametersCable::FEC_None:
2589 parm_u_qam_fec_inner = FEC_NONE;
2591 case eDVBFrontendParametersCable::FEC_1_2:
2592 parm_u_qam_fec_inner = FEC_1_2;
2594 case eDVBFrontendParametersCable::FEC_2_3:
2595 parm_u_qam_fec_inner = FEC_2_3;
2597 case eDVBFrontendParametersCable::FEC_3_4:
2598 parm_u_qam_fec_inner = FEC_3_4;
2600 case eDVBFrontendParametersCable::FEC_5_6:
2601 parm_u_qam_fec_inner = FEC_5_6;
2603 case eDVBFrontendParametersCable::FEC_7_8:
2604 parm_u_qam_fec_inner = FEC_7_8;
2606 #if HAVE_DVB_API_VERSION >= 3
2607 case eDVBFrontendParametersCable::FEC_8_9:
2608 parm_u_qam_fec_inner = FEC_8_9;
2612 case eDVBFrontendParametersCable::FEC_Auto:
2613 parm_u_qam_fec_inner = FEC_AUTO;
2616 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2617 parm_frequency/1000,
2618 parm_u_qam_symbol_rate,
2619 parm_u_qam_fec_inner,
2620 parm_u_qam_modulation,
2622 oparm.setDVBC(feparm);
2626 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2628 parm_frequency = feparm.frequency;
2630 switch (feparm.bandwidth)
2632 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2633 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2635 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2636 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2638 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2639 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2641 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2642 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2644 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2645 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2647 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2648 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2651 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2652 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2655 switch (feparm.code_rate_LP)
2657 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2658 parm_u_ofdm_code_rate_LP = FEC_1_2;
2660 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2661 parm_u_ofdm_code_rate_LP = FEC_2_3;
2663 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2664 parm_u_ofdm_code_rate_LP = FEC_3_4;
2666 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2667 parm_u_ofdm_code_rate_LP = FEC_5_6;
2669 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2670 parm_u_ofdm_code_rate_LP = FEC_7_8;
2672 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2673 parm_u_ofdm_code_rate_LP = FEC_6_7;
2675 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2676 parm_u_ofdm_code_rate_LP = FEC_8_9;
2679 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2680 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2683 switch (feparm.code_rate_HP)
2685 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2686 parm_u_ofdm_code_rate_HP = FEC_1_2;
2688 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2689 parm_u_ofdm_code_rate_HP = FEC_2_3;
2691 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2692 parm_u_ofdm_code_rate_HP = FEC_3_4;
2694 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2695 parm_u_ofdm_code_rate_HP = FEC_5_6;
2697 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2698 parm_u_ofdm_code_rate_HP = FEC_7_8;
2700 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2701 parm_u_ofdm_code_rate_HP = FEC_6_7;
2703 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2704 parm_u_ofdm_code_rate_HP = FEC_8_9;
2707 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2708 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2711 switch (feparm.modulation)
2713 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2714 parm_u_ofdm_constellation = QPSK;
2716 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2717 parm_u_ofdm_constellation = QAM_16;
2719 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2720 parm_u_ofdm_constellation = QAM_64;
2722 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2723 parm_u_ofdm_constellation = QAM_256;
2726 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2727 parm_u_ofdm_constellation = QAM_AUTO;
2730 switch (feparm.transmission_mode)
2732 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2733 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2735 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2736 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2738 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2739 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2741 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2742 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2744 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2745 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2747 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2748 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2751 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2752 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2755 switch (feparm.guard_interval)
2757 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2758 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2760 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2761 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2763 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2764 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2766 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2767 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2769 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2770 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2772 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2773 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2775 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2776 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2779 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2780 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2783 switch (feparm.hierarchy)
2785 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2786 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2788 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2789 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2791 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2792 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2794 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2795 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2798 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2799 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2802 switch (feparm.inversion)
2804 case eDVBFrontendParametersTerrestrial::Inversion_On:
2805 parm_inversion = INVERSION_ON;
2807 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2808 parm_inversion = INVERSION_OFF;
2811 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2812 parm_inversion = INVERSION_AUTO;
2815 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",
2816 parm_frequency/1000,
2817 parm_u_ofdm_bandwidth,
2818 parm_u_ofdm_code_rate_LP,
2819 parm_u_ofdm_code_rate_HP,
2820 parm_u_ofdm_constellation,
2821 parm_u_ofdm_transmission_mode,
2822 parm_u_ofdm_guard_interval,
2823 parm_u_ofdm_hierarchy_information,
2827 oparm.setDVBT(feparm);
2831 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2833 unsigned int timeout = 5000;
2834 eDebugNoSimulate("(%d)tune", m_dvbid);
2841 if (where.getSystem(type) < 0)
2847 if (!m_sn && !m_simulate)
2849 eDebug("no frontend device opened... do not try to tune !!!");
2857 m_sec_sequence.clear();
2859 where.calcLockTimeout(timeout);
2865 eDVBFrontendParametersSatellite feparm;
2866 if (where.getDVBS(feparm))
2868 eDebug("no dvbs data!");
2872 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2874 eDVBFrontend *sec_fe = this;
2875 long tmp = m_data[LINKED_PREV_PTR];
2878 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2879 sec_fe = linked_fe->m_frontend;
2880 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2882 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2883 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
2885 m_rotor_mode = feparm.no_rotor_command_on_tune;
2887 m_sec->setRotorMoving(m_slotid, false);
2888 res=prepare_sat(feparm, timeout);
2896 eDVBFrontendParametersCable feparm;
2897 if (where.getDVBC(feparm))
2902 res=prepare_cable(feparm);
2906 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2907 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2912 eDVBFrontendParametersTerrestrial feparm;
2913 if (where.getDVBT(feparm))
2915 eDebug("no -T data");
2919 res=prepare_terrestrial(feparm);
2923 std::string enable_5V;
2924 char configStr[255];
2925 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2926 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2927 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2928 if (enable_5V == "True")
2929 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2931 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2932 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2943 m_sec_sequence.current() = m_sec_sequence.begin();
2947 m_tuneTimer->start(0,true);
2949 if (m_state != stateTuning)
2951 m_state = stateTuning;
2952 m_stateChanged(this);
2961 m_tuneTimer->stop();
2965 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2967 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2971 RESULT eDVBFrontend::setVoltage(int voltage)
2973 #if HAVE_DVB_API_VERSION < 3
2976 bool increased=false;
2977 fe_sec_voltage_t vlt;
2979 m_data[CUR_VOLTAGE]=voltage;
2983 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2984 vlt = SEC_VOLTAGE_OFF;
2987 #if HAVE_DVB_API_VERSION < 3
2988 vlt = SEC_VOLTAGE_13_5;
2994 vlt = SEC_VOLTAGE_13;
2997 #if HAVE_DVB_API_VERSION < 3
2998 vlt = SEC_VOLTAGE_18_5;
3004 vlt = SEC_VOLTAGE_18;
3011 #if HAVE_DVB_API_VERSION < 3
3012 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
3014 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
3015 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
3019 RESULT eDVBFrontend::getState(int &state)
3025 RESULT eDVBFrontend::setTone(int t)
3027 #if HAVE_DVB_API_VERSION < 3
3030 fe_sec_tone_mode_t tone;
3039 tone = SEC_TONE_OFF;
3046 #if HAVE_DVB_API_VERSION < 3
3047 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
3049 return ::ioctl(m_fd, FE_SET_TONE, tone);
3053 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3054 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3057 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3062 #if HAVE_DVB_API_VERSION < 3
3063 struct secCommand cmd;
3064 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3065 cmd.u.diseqc.cmdtype = diseqc.data[0];
3066 cmd.u.diseqc.addr = diseqc.data[1];
3067 cmd.u.diseqc.cmd = diseqc.data[2];
3068 cmd.u.diseqc.numParams = diseqc.len-3;
3069 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3070 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3072 struct dvb_diseqc_master_cmd cmd;
3073 memcpy(cmd.msg, diseqc.data, diseqc.len);
3074 cmd.msg_len = diseqc.len;
3075 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3081 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3082 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3084 RESULT eDVBFrontend::sendToneburst(int burst)
3088 #if HAVE_DVB_API_VERSION < 3
3089 secMiniCmd cmd = SEC_MINI_NONE;
3091 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3093 if ( burst == eDVBSatelliteDiseqcParameters::A )
3095 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3097 #if HAVE_DVB_API_VERSION < 3
3098 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3101 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3107 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3113 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3115 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3116 m_sec_sequence.push_back(list);
3118 m_sec_sequence = list;
3122 bool eDVBFrontend::isScheduledSendDiseqc()
3124 bool has_senddiseqc = false;
3125 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
3127 eSecCommandList::iterator cur = m_sec_sequence.current();
3128 while(cur != m_sec_sequence.end())
3130 if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
3132 has_senddiseqc = true;
3137 return has_senddiseqc;
3140 RESULT eDVBFrontend::getData(int num, long &data)
3142 if ( num < NUM_DATA_ENTRIES )
3150 RESULT eDVBFrontend::setData(int num, long val)
3152 if ( num < NUM_DATA_ENTRIES )
3160 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3164 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3166 if (feparm->getSystem(type) || !m_enabled)
3169 if (type == eDVBFrontend::feSatellite)
3171 eDVBFrontendParametersSatellite sat_parm;
3172 bool can_handle_dvbs, can_handle_dvbs2;
3173 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
3174 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
3175 if (feparm->getDVBS(sat_parm) < 0)
3179 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
3183 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
3187 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3188 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
3190 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3195 else if (type == eDVBFrontend::feCable)
3197 eDVBFrontendParametersCable cab_parm;
3198 if (feparm->getDVBC(cab_parm) < 0)
3202 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
3203 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
3208 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
3216 else if (type == eDVBFrontend::feTerrestrial)
3218 eDVBFrontendParametersTerrestrial ter_parm;
3219 bool can_handle_dvbt, can_handle_dvbt2;
3220 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
3221 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
3222 if (feparm->getDVBT(ter_parm) < 0)
3226 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
3230 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
3235 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
3237 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3242 if (score && preferred)
3244 /* make 'sure' we always prefer this frontend */
3251 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
3253 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
3254 if (it != m_delsys.end() && it->second)
3256 if (obeywhitelist && !m_delsys_whitelist.empty())
3258 it = m_delsys_whitelist.find(sys);
3259 if (it == m_delsys_whitelist.end() || !it->second) return false;
3266 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
3268 m_delsys_whitelist.clear();
3269 for (unsigned int i = 0; i < whitelist.size(); i++)
3271 m_delsys_whitelist[whitelist[i]] = true;
3275 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
3279 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3281 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3282 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3284 Id = PyTuple_GET_ITEM(obj, 0);
3285 Descr = PyTuple_GET_ITEM(obj, 1);
3286 Enabled = PyTuple_GET_ITEM(obj, 2);
3287 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3288 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3289 frontendId = PyTuple_GET_ITEM(obj, 5);
3290 m_slotid = PyInt_AsLong(Id);
3291 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3293 strcpy(m_description, PyString_AS_STRING(Descr));
3294 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3295 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3296 // m_slotid, m_description);
3299 m_enabled = (Enabled == Py_True);
3300 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3301 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3302 !!strstr(m_description, "Alps BSBE2") ||
3303 !!strstr(m_description, "Alps -S") ||
3304 !!strstr(m_description, "BCM4501");
3305 if (IsDVBS2 == Py_True)
3307 /* HACK for legacy dvb api without DELSYS support */
3308 m_delsys[SYS_DVBS2] = true;
3310 if (IsDVBT2 == Py_True)
3312 /* HACK for legacy dvb api without DELSYS support */
3313 m_delsys[SYS_DVBT2] = true;
3316 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3317 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" );
3320 PyErr_SetString(PyExc_StandardError,
3321 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");