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 #if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
1882 // workaround to put the kernel frontend thread into idle state!
1883 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1885 sec_fe->closeFrontend(true);
1886 state = sec_fe->m_state;
1889 // sec_fe is closed... we must reopen it here..
1890 if (state == stateClosed)
1898 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1900 long *sec_fe_data = sec_fe->m_data;
1901 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1903 switch (m_sec_sequence.current()->cmd)
1905 case eSecCommand::SLEEP:
1906 delay = m_sec_sequence.current()++->msec;
1907 eDebugNoSimulate("[SEC] sleep %dms", delay);
1909 case eSecCommand::GOTO:
1910 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1911 ++m_sec_sequence.current();
1913 case eSecCommand::SET_VOLTAGE:
1915 int voltage = m_sec_sequence.current()++->voltage;
1916 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1917 sec_fe->setVoltage(voltage);
1920 case eSecCommand::IF_VOLTAGE_GOTO:
1922 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1923 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1925 ++m_sec_sequence.current();
1928 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1930 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1931 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1933 ++m_sec_sequence.current();
1936 case eSecCommand::IF_TONE_GOTO:
1938 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1939 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1941 ++m_sec_sequence.current();
1944 case eSecCommand::IF_NOT_TONE_GOTO:
1946 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1947 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1949 ++m_sec_sequence.current();
1952 case eSecCommand::SET_TONE:
1953 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1954 sec_fe->setTone(m_sec_sequence.current()++->tone);
1956 case eSecCommand::SEND_DISEQC:
1957 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1958 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1959 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1960 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1961 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1962 eDebugNoSimulate("(DiSEqC reset)");
1963 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1964 eDebugNoSimulate("(DiSEqC peripherial power on)");
1966 eDebugNoSimulate("");
1967 ++m_sec_sequence.current();
1969 case eSecCommand::SEND_TONEBURST:
1970 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1971 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1973 case eSecCommand::SET_FRONTEND:
1975 int enableEvents = (m_sec_sequence.current()++)->val;
1976 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1977 setFrontend(enableEvents);
1980 case eSecCommand::START_TUNE_TIMEOUT:
1982 int tuneTimeout = m_sec_sequence.current()->timeout;
1983 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1985 m_timeout->start(tuneTimeout, 1);
1986 ++m_sec_sequence.current();
1989 case eSecCommand::SET_TIMEOUT:
1990 m_timeoutCount = m_sec_sequence.current()++->val;
1991 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1993 case eSecCommand::IF_TIMEOUT_GOTO:
1994 if (!m_timeoutCount)
1996 eDebugNoSimulate("[SEC] rotor timout");
1997 setSecSequencePos(m_sec_sequence.current()->steps);
2000 ++m_sec_sequence.current();
2002 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
2004 int idx = m_sec_sequence.current()++->val;
2005 if ( idx == 0 || idx == 1 )
2007 m_idleInputpower[idx] = sec_fe->readInputpower();
2008 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
2011 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
2014 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
2016 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
2017 int idx = compare.val;
2018 if ( !m_simulate && (idx == 0 || idx == 1) )
2020 int idle = sec_fe->readInputpower();
2021 int diff = abs(idle-m_idleInputpower[idx]);
2024 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
2025 setSecSequencePos(compare.steps);
2029 ++m_sec_sequence.current();
2032 case eSecCommand::IF_TUNER_LOCKED_GOTO:
2034 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2037 setSecSequencePos(cmd.steps);
2041 int isLocked = readFrontendData(locked);
2042 m_idleInputpower[0] = m_idleInputpower[1] = 0;
2044 if (!m_timeoutCount && m_retryCount > 0)
2046 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
2049 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2052 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2054 cmd.lastSignal = signal;
2057 if (cmd.okcount > 4)
2059 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2060 setSecSequencePos(cmd.steps);
2061 m_state = stateLock;
2062 m_stateChanged(this);
2063 feEvent(-1); // flush events
2071 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2073 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2077 ++m_sec_sequence.current();
2080 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2081 m_runningInputpower = sec_fe->readInputpower();
2082 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2083 ++m_sec_sequence.current();
2085 case eSecCommand::SET_ROTOR_MOVING:
2087 m_sec->setRotorMoving(m_slotid, true);
2088 ++m_sec_sequence.current();
2090 case eSecCommand::SET_ROTOR_STOPPED:
2092 m_sec->setRotorMoving(m_slotid, false);
2093 ++m_sec_sequence.current();
2095 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2097 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2100 setSecSequencePos(cmd.steps);
2103 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2104 const char *txt = cmd.direction ? "running" : "stopped";
2106 if (!m_timeoutCount && m_retryCount > 0)
2108 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2110 m_runningInputpower,
2113 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2114 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2117 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2118 if ( cmd.okcount > 6 )
2120 eDebugNoSimulate("[SEC] rotor is %s", txt);
2121 if (setSecSequencePos(cmd.steps))
2127 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2130 ++m_sec_sequence.current();
2133 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2134 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2135 setSecSequencePos(m_sec_sequence.current()->steps);
2137 ++m_sec_sequence.current();
2139 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2140 eDebugNoSimulate("[SEC] invalidate current switch params");
2141 sec_fe_data[CSW] = -1;
2142 sec_fe_data[UCSW] = -1;
2143 sec_fe_data[TONEBURST] = -1;
2144 ++m_sec_sequence.current();
2146 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2147 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2148 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2149 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2150 eDebugNoSimulate("[SEC] update current switch params");
2151 ++m_sec_sequence.current();
2153 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2154 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2155 sec_fe_data[ROTOR_CMD] = -1;
2156 sec_fe_data[ROTOR_POS] = -1;
2157 ++m_sec_sequence.current();
2159 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2160 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2161 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2162 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2163 ++m_sec_sequence.current();
2165 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2166 m_retryCount = m_sec_sequence.current()++->val;
2167 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2169 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2172 eDebugNoSimulate("[SEC] no more rotor retrys");
2173 setSecSequencePos(m_sec_sequence.current()->steps);
2176 ++m_sec_sequence.current();
2178 case eSecCommand::SET_POWER_LIMITING_MODE:
2183 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2184 FILE *f=fopen(proc_name, "w");
2185 if (f) // new interface exist?
2187 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2188 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2189 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2191 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2194 else if (sec_fe->m_need_rotor_workaround)
2197 int slotid = sec_fe->m_slotid;
2198 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2200 sprintf(dev, "/dev/i2c-%d", slotid);
2201 else if (slotid == 2)
2202 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2203 else if (slotid == 3)
2204 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2205 int fd = ::open(dev, O_RDWR);
2207 unsigned char data[2];
2208 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2209 if(::read(fd, data, 1) != 1)
2210 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2211 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2213 data[0] |= 0x80; // enable static current limiting
2214 eDebugNoSimulate("[SEC] set static current limiting");
2218 data[0] &= ~0x80; // enable dynamic current limiting
2219 eDebugNoSimulate("[SEC] set dynamic current limiting");
2221 if(::write(fd, data, 1) != 1)
2222 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2226 ++m_sec_sequence.current();
2229 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2231 eDebugNoSimulate("[SEC] delayed close frontend");
2232 closeFrontend(false, true);
2233 ++m_sec_sequence.current();
2237 eDebugNoSimulate("[SEC] unhandled sec command %d",
2238 ++m_sec_sequence.current()->cmd);
2239 ++m_sec_sequence.current();
2242 m_tuneTimer->start(delay,true);
2246 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2251 void eDVBFrontend::setFrontend(bool recvEvents)
2255 eDebug("setting frontend %d", m_dvbid);
2258 oparm.getSystem(type);
2262 feEvent(-1); // flush events
2263 #if HAVE_DVB_API_VERSION >= 5
2264 if (type == iDVBFrontend::feSatellite)
2266 fe_rolloff_t rolloff = ROLLOFF_35;
2267 fe_pilot_t pilot = PILOT_OFF;
2268 fe_modulation_t modulation = QPSK;
2269 fe_delivery_system_t system = SYS_DVBS;
2270 eDVBFrontendParametersSatellite sparm;
2271 oparm.getDVBS(sparm);
2272 switch(sparm.system)
2274 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2275 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2277 switch(sparm.modulation)
2279 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2280 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2281 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2285 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2286 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2287 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2289 switch(sparm.rolloff)
2291 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2292 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2293 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2295 struct dtv_property p[10];
2296 struct dtv_properties cmdseq;
2298 p[0].cmd = DTV_CLEAR;
2299 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2300 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2301 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2302 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2303 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2304 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2305 if (system == SYS_DVBS2)
2307 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2308 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2309 p[9].cmd = DTV_TUNE;
2314 p[7].cmd = DTV_TUNE;
2317 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2319 perror("FE_SET_PROPERTY failed");
2323 else if (type == iDVBFrontend::feCable)
2325 struct dtv_property p[8];
2326 struct dtv_properties cmdseq;
2328 p[0].cmd = DTV_CLEAR;
2329 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2330 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2332 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2334 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2335 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2336 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2337 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2338 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2339 p[7].cmd = DTV_TUNE;
2341 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2343 perror("FE_SET_PROPERTY failed");
2347 else if (type == iDVBFrontend::feTerrestrial)
2349 fe_delivery_system_t system = SYS_DVBT;
2350 eDVBFrontendParametersTerrestrial tparm;
2351 oparm.getDVBT(tparm);
2352 switch (tparm.system)
2355 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2356 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2359 switch (tparm.bandwidth)
2361 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2362 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2363 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2365 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2366 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2367 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2368 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2370 struct dtv_property p[13];
2371 struct dtv_properties cmdseq;
2374 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2375 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2376 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2377 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2378 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2379 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2380 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2381 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2382 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2383 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2384 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2385 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
2386 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2387 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
2388 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2390 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2391 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2393 perror("FE_SET_PROPERTY failed");
2398 #endif /* HAVE_DVB_API_VERSION >= 5 */
2400 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2402 perror("FE_SET_FRONTEND failed");
2409 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2414 eWarning("no SEC module active!");
2417 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2420 #if HAVE_DVB_API_VERSION >= 3
2421 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",
2424 feparm.polarisation,
2428 feparm.orbital_position,
2434 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2437 feparm.polarisation,
2441 feparm.orbital_position);
2443 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2444 switch (feparm.inversion)
2446 case eDVBFrontendParametersSatellite::Inversion_On:
2447 parm_inversion = INVERSION_ON;
2449 case eDVBFrontendParametersSatellite::Inversion_Off:
2450 parm_inversion = INVERSION_OFF;
2453 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2454 parm_inversion = INVERSION_AUTO;
2457 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2461 case eDVBFrontendParametersSatellite::FEC_None:
2462 parm_u_qpsk_fec_inner = FEC_NONE;
2464 case eDVBFrontendParametersSatellite::FEC_1_2:
2465 parm_u_qpsk_fec_inner = FEC_1_2;
2467 case eDVBFrontendParametersSatellite::FEC_2_3:
2468 parm_u_qpsk_fec_inner = FEC_2_3;
2470 case eDVBFrontendParametersSatellite::FEC_3_4:
2471 parm_u_qpsk_fec_inner = FEC_3_4;
2473 case eDVBFrontendParametersSatellite::FEC_5_6:
2474 parm_u_qpsk_fec_inner = FEC_5_6;
2476 case eDVBFrontendParametersSatellite::FEC_7_8:
2477 parm_u_qpsk_fec_inner = FEC_7_8;
2480 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2481 case eDVBFrontendParametersSatellite::FEC_Auto:
2482 parm_u_qpsk_fec_inner = FEC_AUTO;
2486 #if HAVE_DVB_API_VERSION >= 3
2491 case eDVBFrontendParametersSatellite::FEC_1_2:
2492 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2494 case eDVBFrontendParametersSatellite::FEC_2_3:
2495 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2497 case eDVBFrontendParametersSatellite::FEC_3_4:
2498 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2500 case eDVBFrontendParametersSatellite::FEC_3_5:
2501 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2503 case eDVBFrontendParametersSatellite::FEC_4_5:
2504 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2506 case eDVBFrontendParametersSatellite::FEC_5_6:
2507 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2509 case eDVBFrontendParametersSatellite::FEC_7_8:
2510 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2512 case eDVBFrontendParametersSatellite::FEC_8_9:
2513 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2515 case eDVBFrontendParametersSatellite::FEC_9_10:
2516 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2519 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2522 #if HAVE_DVB_API_VERSION < 5
2523 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2524 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2525 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2527 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2528 // 8PSK fec driver values are decimal 9 bigger
2533 // FIXME !!! get frequency range from tuner
2534 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2536 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2539 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2541 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2545 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2547 #if HAVE_DVB_API_VERSION < 3
2548 parm_frequency = feparm.frequency;
2550 parm_frequency = feparm.frequency * 1000;
2552 parm_u_qam_symbol_rate = feparm.symbol_rate;
2553 switch (feparm.modulation)
2555 case eDVBFrontendParametersCable::Modulation_QAM16:
2556 parm_u_qam_modulation = QAM_16;
2558 case eDVBFrontendParametersCable::Modulation_QAM32:
2559 parm_u_qam_modulation = QAM_32;
2561 case eDVBFrontendParametersCable::Modulation_QAM64:
2562 parm_u_qam_modulation = QAM_64;
2564 case eDVBFrontendParametersCable::Modulation_QAM128:
2565 parm_u_qam_modulation = QAM_128;
2567 case eDVBFrontendParametersCable::Modulation_QAM256:
2568 parm_u_qam_modulation = QAM_256;
2571 case eDVBFrontendParametersCable::Modulation_Auto:
2572 parm_u_qam_modulation = QAM_AUTO;
2575 switch (feparm.inversion)
2577 case eDVBFrontendParametersCable::Inversion_On:
2578 parm_inversion = INVERSION_ON;
2580 case eDVBFrontendParametersCable::Inversion_Off:
2581 parm_inversion = INVERSION_OFF;
2584 case eDVBFrontendParametersCable::Inversion_Unknown:
2585 parm_inversion = INVERSION_AUTO;
2588 switch (feparm.fec_inner)
2590 case eDVBFrontendParametersCable::FEC_None:
2591 parm_u_qam_fec_inner = FEC_NONE;
2593 case eDVBFrontendParametersCable::FEC_1_2:
2594 parm_u_qam_fec_inner = FEC_1_2;
2596 case eDVBFrontendParametersCable::FEC_2_3:
2597 parm_u_qam_fec_inner = FEC_2_3;
2599 case eDVBFrontendParametersCable::FEC_3_4:
2600 parm_u_qam_fec_inner = FEC_3_4;
2602 case eDVBFrontendParametersCable::FEC_5_6:
2603 parm_u_qam_fec_inner = FEC_5_6;
2605 case eDVBFrontendParametersCable::FEC_7_8:
2606 parm_u_qam_fec_inner = FEC_7_8;
2608 #if HAVE_DVB_API_VERSION >= 3
2609 case eDVBFrontendParametersCable::FEC_8_9:
2610 parm_u_qam_fec_inner = FEC_8_9;
2614 case eDVBFrontendParametersCable::FEC_Auto:
2615 parm_u_qam_fec_inner = FEC_AUTO;
2618 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2619 parm_frequency/1000,
2620 parm_u_qam_symbol_rate,
2621 parm_u_qam_fec_inner,
2622 parm_u_qam_modulation,
2624 oparm.setDVBC(feparm);
2628 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2630 parm_frequency = feparm.frequency;
2632 switch (feparm.bandwidth)
2634 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2635 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2637 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2638 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2640 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2641 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2643 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2644 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2646 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2647 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2649 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2650 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2653 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2654 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2657 switch (feparm.code_rate_LP)
2659 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2660 parm_u_ofdm_code_rate_LP = FEC_1_2;
2662 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2663 parm_u_ofdm_code_rate_LP = FEC_2_3;
2665 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2666 parm_u_ofdm_code_rate_LP = FEC_3_4;
2668 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2669 parm_u_ofdm_code_rate_LP = FEC_5_6;
2671 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2672 parm_u_ofdm_code_rate_LP = FEC_7_8;
2674 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2675 parm_u_ofdm_code_rate_LP = FEC_6_7;
2677 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2678 parm_u_ofdm_code_rate_LP = FEC_8_9;
2681 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2682 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2685 switch (feparm.code_rate_HP)
2687 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2688 parm_u_ofdm_code_rate_HP = FEC_1_2;
2690 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2691 parm_u_ofdm_code_rate_HP = FEC_2_3;
2693 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2694 parm_u_ofdm_code_rate_HP = FEC_3_4;
2696 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2697 parm_u_ofdm_code_rate_HP = FEC_5_6;
2699 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2700 parm_u_ofdm_code_rate_HP = FEC_7_8;
2702 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2703 parm_u_ofdm_code_rate_HP = FEC_6_7;
2705 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2706 parm_u_ofdm_code_rate_HP = FEC_8_9;
2709 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2710 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2713 switch (feparm.modulation)
2715 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2716 parm_u_ofdm_constellation = QPSK;
2718 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2719 parm_u_ofdm_constellation = QAM_16;
2721 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2722 parm_u_ofdm_constellation = QAM_64;
2724 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2725 parm_u_ofdm_constellation = QAM_256;
2728 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2729 parm_u_ofdm_constellation = QAM_AUTO;
2732 switch (feparm.transmission_mode)
2734 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2735 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2737 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2738 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2740 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2741 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2743 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2744 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2746 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2747 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2749 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2750 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2753 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2754 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2757 switch (feparm.guard_interval)
2759 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2760 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2762 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2763 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2765 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2766 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2768 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2769 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2771 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2772 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2774 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2775 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2777 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2778 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2781 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2782 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2785 switch (feparm.hierarchy)
2787 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2788 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2790 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2791 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2793 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2794 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2796 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2797 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2800 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2801 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2804 switch (feparm.inversion)
2806 case eDVBFrontendParametersTerrestrial::Inversion_On:
2807 parm_inversion = INVERSION_ON;
2809 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2810 parm_inversion = INVERSION_OFF;
2813 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2814 parm_inversion = INVERSION_AUTO;
2817 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",
2818 parm_frequency/1000,
2819 parm_u_ofdm_bandwidth,
2820 parm_u_ofdm_code_rate_LP,
2821 parm_u_ofdm_code_rate_HP,
2822 parm_u_ofdm_constellation,
2823 parm_u_ofdm_transmission_mode,
2824 parm_u_ofdm_guard_interval,
2825 parm_u_ofdm_hierarchy_information,
2829 oparm.setDVBT(feparm);
2833 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2835 unsigned int timeout = 5000;
2836 eDebugNoSimulate("(%d)tune", m_dvbid);
2843 if (where.getSystem(type) < 0)
2849 if (!m_sn && !m_simulate)
2851 eDebug("no frontend device opened... do not try to tune !!!");
2859 m_sec_sequence.clear();
2861 where.calcLockTimeout(timeout);
2867 eDVBFrontendParametersSatellite feparm;
2868 if (where.getDVBS(feparm))
2870 eDebug("no dvbs data!");
2874 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2876 eDVBFrontend *sec_fe = this;
2877 long tmp = m_data[LINKED_PREV_PTR];
2880 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2881 sec_fe = linked_fe->m_frontend;
2882 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2884 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2885 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
2887 m_rotor_mode = feparm.no_rotor_command_on_tune;
2889 m_sec->setRotorMoving(m_slotid, false);
2890 res=prepare_sat(feparm, timeout);
2898 eDVBFrontendParametersCable feparm;
2899 if (where.getDVBC(feparm))
2904 res=prepare_cable(feparm);
2908 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2909 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2914 eDVBFrontendParametersTerrestrial feparm;
2915 if (where.getDVBT(feparm))
2917 eDebug("no -T data");
2921 res=prepare_terrestrial(feparm);
2925 std::string enable_5V;
2926 char configStr[255];
2927 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2928 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2929 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2930 if (enable_5V == "True")
2931 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2933 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2934 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2945 m_sec_sequence.current() = m_sec_sequence.begin();
2949 m_tuneTimer->start(0,true);
2951 if (m_state != stateTuning)
2953 m_state = stateTuning;
2954 m_stateChanged(this);
2963 m_tuneTimer->stop();
2967 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2969 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2973 RESULT eDVBFrontend::setVoltage(int voltage)
2975 #if HAVE_DVB_API_VERSION < 3
2978 bool increased=false;
2979 fe_sec_voltage_t vlt;
2981 m_data[CUR_VOLTAGE]=voltage;
2985 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2986 vlt = SEC_VOLTAGE_OFF;
2989 #if HAVE_DVB_API_VERSION < 3
2990 vlt = SEC_VOLTAGE_13_5;
2996 vlt = SEC_VOLTAGE_13;
2999 #if HAVE_DVB_API_VERSION < 3
3000 vlt = SEC_VOLTAGE_18_5;
3006 vlt = SEC_VOLTAGE_18;
3013 #if HAVE_DVB_API_VERSION < 3
3014 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
3016 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
3017 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
3021 RESULT eDVBFrontend::getState(int &state)
3027 RESULT eDVBFrontend::setTone(int t)
3029 #if HAVE_DVB_API_VERSION < 3
3032 fe_sec_tone_mode_t tone;
3041 tone = SEC_TONE_OFF;
3048 #if HAVE_DVB_API_VERSION < 3
3049 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
3051 return ::ioctl(m_fd, FE_SET_TONE, tone);
3055 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3056 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3059 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3064 #if HAVE_DVB_API_VERSION < 3
3065 struct secCommand cmd;
3066 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3067 cmd.u.diseqc.cmdtype = diseqc.data[0];
3068 cmd.u.diseqc.addr = diseqc.data[1];
3069 cmd.u.diseqc.cmd = diseqc.data[2];
3070 cmd.u.diseqc.numParams = diseqc.len-3;
3071 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3072 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3074 struct dvb_diseqc_master_cmd cmd;
3075 memcpy(cmd.msg, diseqc.data, diseqc.len);
3076 cmd.msg_len = diseqc.len;
3077 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3083 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3084 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3086 RESULT eDVBFrontend::sendToneburst(int burst)
3090 #if HAVE_DVB_API_VERSION < 3
3091 secMiniCmd cmd = SEC_MINI_NONE;
3093 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3095 if ( burst == eDVBSatelliteDiseqcParameters::A )
3097 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3099 #if HAVE_DVB_API_VERSION < 3
3100 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3103 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3109 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3115 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3117 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3118 m_sec_sequence.push_back(list);
3120 m_sec_sequence = list;
3124 bool eDVBFrontend::isScheduledSendDiseqc()
3126 bool has_senddiseqc = false;
3127 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
3129 eSecCommandList::iterator cur = m_sec_sequence.current();
3130 while(cur != m_sec_sequence.end())
3132 if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
3134 has_senddiseqc = true;
3139 return has_senddiseqc;
3142 RESULT eDVBFrontend::getData(int num, long &data)
3144 if ( num < NUM_DATA_ENTRIES )
3152 RESULT eDVBFrontend::setData(int num, long val)
3154 if ( num < NUM_DATA_ENTRIES )
3162 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3166 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3168 if (feparm->getSystem(type) || !m_enabled)
3171 if (type == eDVBFrontend::feSatellite)
3173 eDVBFrontendParametersSatellite sat_parm;
3174 bool can_handle_dvbs, can_handle_dvbs2;
3175 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
3176 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
3177 if (feparm->getDVBS(sat_parm) < 0)
3181 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
3185 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
3189 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3190 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
3192 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3197 else if (type == eDVBFrontend::feCable)
3199 eDVBFrontendParametersCable cab_parm;
3200 if (feparm->getDVBC(cab_parm) < 0)
3204 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
3205 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
3210 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
3218 else if (type == eDVBFrontend::feTerrestrial)
3220 eDVBFrontendParametersTerrestrial ter_parm;
3221 bool can_handle_dvbt, can_handle_dvbt2;
3222 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
3223 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
3224 if (feparm->getDVBT(ter_parm) < 0)
3228 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
3232 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
3237 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
3239 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3244 if (score && preferred)
3246 /* make 'sure' we always prefer this frontend */
3253 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
3255 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
3256 if (it != m_delsys.end() && it->second)
3258 if (obeywhitelist && !m_delsys_whitelist.empty())
3260 it = m_delsys_whitelist.find(sys);
3261 if (it == m_delsys_whitelist.end() || !it->second) return false;
3268 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
3270 m_delsys_whitelist.clear();
3271 for (unsigned int i = 0; i < whitelist.size(); i++)
3273 m_delsys_whitelist[whitelist[i]] = true;
3277 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
3281 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3283 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3284 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3286 Id = PyTuple_GET_ITEM(obj, 0);
3287 Descr = PyTuple_GET_ITEM(obj, 1);
3288 Enabled = PyTuple_GET_ITEM(obj, 2);
3289 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3290 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3291 frontendId = PyTuple_GET_ITEM(obj, 5);
3292 m_slotid = PyInt_AsLong(Id);
3293 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3295 strcpy(m_description, PyString_AS_STRING(Descr));
3296 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3297 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3298 // m_slotid, m_description);
3301 m_enabled = (Enabled == Py_True);
3302 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3303 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3304 !!strstr(m_description, "Alps BSBE2") ||
3305 !!strstr(m_description, "Alps -S") ||
3306 !!strstr(m_description, "BCM4501");
3307 if (IsDVBS2 == Py_True)
3309 /* HACK for legacy dvb api without DELSYS support */
3310 m_delsys[SYS_DVBS2] = true;
3312 if (IsDVBT2 == Py_True)
3314 /* HACK for legacy dvb api without DELSYS support */
3315 m_delsys[SYS_DVBT2] = true;
3318 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3319 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" );
3322 PyErr_SetString(PyExc_StandardError,
3323 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");