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
299 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
301 if (m_type != iDVBFrontend::feSatellite)
307 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
309 if (m_type != iDVBFrontend::feCable)
315 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
317 if (m_type != iDVBFrontend::feTerrestrial)
323 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
326 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
327 m_type = iDVBFrontend::feSatellite;
331 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
334 m_type = iDVBFrontend::feCable;
338 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
341 m_type = iDVBFrontend::feTerrestrial;
345 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
350 if (parm->getSystem(type))
354 diff = 1<<30; // big difference
360 case iDVBFrontend::feSatellite:
362 eDVBFrontendParametersSatellite osat;
363 if (parm->getDVBS(osat))
366 if (sat.orbital_position != osat.orbital_position)
368 else if (sat.polarisation != osat.polarisation)
370 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
372 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
376 diff = abs(sat.frequency - osat.frequency);
377 diff += abs(sat.symbol_rate - osat.symbol_rate);
381 case iDVBFrontend::feCable:
382 eDVBFrontendParametersCable ocable;
383 if (parm->getDVBC(ocable))
386 if (exact && cable.modulation != ocable.modulation
387 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
388 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
390 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
394 diff = abs(cable.frequency - ocable.frequency);
395 diff += abs(cable.symbol_rate - ocable.symbol_rate);
398 case iDVBFrontend::feTerrestrial:
399 eDVBFrontendParametersTerrestrial oterrestrial;
400 if (parm->getDVBT(oterrestrial))
402 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
403 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
404 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
406 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
407 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
408 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
410 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
411 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
412 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
414 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
415 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
416 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
418 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
419 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
420 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
422 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
423 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
424 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
426 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
427 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
428 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
430 else if (oterrestrial.system != terrestrial.system)
432 else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
433 oterrestrial.plpid != terrestrial.plpid)
436 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
444 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
448 case iDVBFrontend::feSatellite:
450 hash = (sat.orbital_position << 16);
451 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
454 case iDVBFrontend::feCable:
456 hash |= (cable.frequency/1000)&0xFFFF;
458 case iDVBFrontend::feTerrestrial:
460 hash |= (terrestrial.frequency/1000000)&0xFFFF;
467 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
471 case iDVBFrontend::feSatellite:
473 /* high symbol rate transponders tune faster, due to
474 requiring less zigzag and giving more symbols faster.
476 5s are definitely not enough on really low SR when
477 zigzag has to find the exact frequency first.
479 if (sat.symbol_rate > 20000000)
481 else if (sat.symbol_rate > 10000000)
487 case iDVBFrontend::feCable:
490 case iDVBFrontend::feTerrestrial:
498 DEFINE_REF(eDVBFrontend);
500 int eDVBFrontend::PriorityOrder=0;
501 int eDVBFrontend::PreferredFrontendIndex=-1;
504 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
505 :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
506 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false), m_can_handle_dvbt2(false)
507 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
508 #if HAVE_DVB_API_VERSION < 3
512 #if HAVE_DVB_API_VERSION < 3
513 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
514 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
516 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
519 m_timeout = eTimer::create(eApp);
520 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
522 m_tuneTimer = eTimer::create(eApp);
523 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
525 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
528 m_idleInputpower[0]=m_idleInputpower[1]=0;
530 ok = !openFrontend();
534 void eDVBFrontend::reopenFrontend()
541 int eDVBFrontend::openFrontend()
543 if (m_state != stateClosed)
544 return -1; // already opened
549 #if HAVE_DVB_API_VERSION < 3
550 FrontendInfo fe_info;
552 dvb_frontend_info fe_info;
556 eDebug("opening frontend %d", m_dvbid);
559 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
562 eWarning("failed! (%s) %m", m_filename);
567 eWarning("frontend %d already opened", m_dvbid);
570 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
572 eWarning("ioctl FE_GET_INFO failed");
578 switch (fe_info.type)
581 m_type = iDVBFrontend::feSatellite;
584 m_type = iDVBFrontend::feCable;
587 m_type = iDVBFrontend::feTerrestrial;
590 eWarning("unknown frontend type.");
596 m_simulate_fe->m_type = m_type;
597 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
600 #if HAVE_DVB_API_VERSION < 3
601 if (m_type == iDVBFrontend::feSatellite)
607 m_secfd = ::open(m_sec_filename, O_RDWR);
610 eWarning("failed! (%s) %m", m_sec_filename);
618 eWarning("sec %d already opened", m_dvbid);
622 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
623 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
626 setTone(iDVBFrontend::toneOff);
627 setVoltage(iDVBFrontend::voltageOff);
632 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
634 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
636 long tmp = m_data[LINKED_NEXT_PTR];
639 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
640 if (linked_fe->m_inuse)
642 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
643 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
646 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
652 eDebugNoSimulate("close frontend %d", m_dvbid);
653 if (m_data[SATCR] != -1)
657 m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
658 m_tuneTimer->start(0, true);
659 if(!m_tuneTimer->isActive())
662 eDebug("[turnOffSatCR] no mainloop");
665 timeout = tuneLoopInt();
668 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
672 eDebug("[turnOffSatCR] running mainloop");
676 m_data[ROTOR_CMD] = -1;
679 setTone(iDVBFrontend::toneOff);
680 setVoltage(iDVBFrontend::voltageOff);
683 if (m_sec && !m_simulate)
684 m_sec->setRotorMoving(m_slotid, false);
688 eWarning("couldnt close frontend %d", m_dvbid);
692 setTone(iDVBFrontend::toneOff);
693 setVoltage(iDVBFrontend::voltageOff);
695 #if HAVE_DVB_API_VERSION < 3
698 if (!::close(m_secfd))
701 eWarning("couldnt close sec %d", m_dvbid);
705 m_state = stateClosed;
710 eDVBFrontend::~eDVBFrontend()
712 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
716 void eDVBFrontend::feEvent(int w)
718 eDVBFrontend *sec_fe = this;
719 long tmp = m_data[LINKED_PREV_PTR];
722 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
723 sec_fe = linked_fe->m_frontend;
724 sec_fe->getData(LINKED_NEXT_PTR, tmp);
728 #if HAVE_DVB_API_VERSION < 3
731 dvb_frontend_event event;
735 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
737 if (res && (errno == EAGAIN))
743 #if HAVE_DVB_API_VERSION < 3
744 if (event.type == FE_COMPLETION_EV)
746 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
747 if (event.status & FE_HAS_LOCK)
755 #if HAVE_DVB_API_VERSION >= 3
756 if (event.status & FE_TIMEDOUT) {
757 eDebug("FE_TIMEDOUT! ..abort");
770 eDebug("stateLostLock");
771 state = stateLostLock;
773 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
776 if (m_state != state)
779 m_stateChanged(this);
784 void eDVBFrontend::timeout()
787 if (m_state == stateTuning)
790 eDVBFrontend *sec_fe = this;
791 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
793 m_state = stateFailed;
794 m_stateChanged(this);
798 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
800 /* unsigned 32 bit division */
801 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
803 return (a + b / 2) / b;
806 int eDVBFrontend::readFrontendData(int type)
815 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
816 eDebug("FE_READ_BER failed (%m)");
821 case signalQualitydB: /* this will move into the driver */
823 int sat_max = 1600; // for stv0288 / bsbe2
824 int ret = 0x12345678;
828 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
829 eDebug("FE_READ_SNR failed (%m)");
830 else if (!strcmp(m_description, "BCM4501 (internal)"))
832 float SDS_SNRE = snr << 16;
835 if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
837 static float SNR_COEFF[6] = {
840 197418.0 / 4194304.0,
841 -2602183.0 / 4194304.0,
842 20377212.0 / 4194304.0,
843 -37791203.0 / 4194304.0,
845 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
846 fval2 = pow(10.0, fval1)-1;
847 fval1 = 10.0 * log10(fval2);
851 fval2 = SNR_COEFF[0];
852 for (int i=1; i<6; ++i)
855 fval2 += SNR_COEFF[i];
861 #if HAVE_DVB_API_VERSION >= 3
864 float fval1 = SDS_SNRE / 268435456.0,
867 if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
878 fval4 = -10.0 * log10(fval1);
880 for (int i=0; i < 5; ++i)
881 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
886 ret = (int)(snr_in_db * 100);
888 else if (strstr(m_description, "Alps BSBE1 C01A") ||
889 strstr(m_description, "Alps -S(STV0288)"))
893 else if (snr == 0xFFFF) // i think this should not happen
897 enum { REALVAL, REGVAL };
898 const long CN_lookup[31][2] = {
899 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
900 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
901 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
902 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
903 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
904 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
907 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
908 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
912 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
917 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
922 ret = (((regval - CN_lookup[Imin][REGVAL])
923 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
924 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
925 + CN_lookup[Imin][REALVAL]) * 10;
931 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
932 !strcmp(m_description, "Alps -S") ||
933 !strcmp(m_description, "Philips -S") ||
934 !strcmp(m_description, "LG -S") )
937 ret = (int)((snr-39075)/17.647);
938 } else if (!strcmp(m_description, "Alps BSBE2"))
940 ret = (int)((snr >> 7) * 10);
941 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
943 int mse = (~snr) & 0xFF;
944 switch (parm_u_qam_modulation) {
945 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
946 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
947 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
948 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
949 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
952 } else if (!strcmp(m_description, "Philips TU1216"))
954 snr = 0xFF - (snr & 0xFF);
956 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
958 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
959 ret = (snr * 100) >> 8;
960 else if (!strcmp(m_description, "CXD1981"))
962 int mse = (~snr) & 0xFF;
963 switch (parm_u_qam_modulation) {
966 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
968 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
974 if (type == signalQuality)
976 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
981 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
982 case feCable: // we assume a max of 42db here
983 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
984 case feTerrestrial: // we assume a max of 24db here
985 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
989 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
997 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
998 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1004 #if HAVE_DVB_API_VERSION < 3
1005 FrontendStatus status=0;
1011 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1012 eDebug("FE_READ_STATUS failed (%m)");
1013 return !!(status&FE_HAS_LOCK);
1019 #if HAVE_DVB_API_VERSION < 3
1020 FrontendStatus status=0;
1026 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1027 eDebug("FE_READ_STATUS failed (%m)");
1028 return !!(status&FE_HAS_SYNC);
1032 case frontendNumber:
1038 void PutToDict(ePyObject &dict, const char*key, long value)
1040 ePyObject item = PyInt_FromLong(value);
1043 if (PyDict_SetItemString(dict, key, item))
1044 eDebug("put %s to dict failed", key);
1048 eDebug("could not create PyObject for %s", key);
1051 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1055 if (PyDict_SetItemString(dict, key, item))
1056 eDebug("put %s to dict failed", key);
1060 eDebug("invalid PyObject for %s", key);
1063 void PutToDict(ePyObject &dict, const char*key, const char *value)
1065 ePyObject item = PyString_FromString(value);
1068 if (PyDict_SetItemString(dict, key, item))
1069 eDebug("put %s to dict failed", key);
1073 eDebug("could not create PyObject for %s", key);
1076 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1078 PutToDict(dict, "tuner_type", "DVB-S");
1079 PutToDict(dict, "frequency", feparm.frequency);
1080 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1081 PutToDict(dict, "orbital_position", feparm.orbital_position);
1082 PutToDict(dict, "inversion", feparm.inversion);
1083 PutToDict(dict, "fec_inner", feparm.fec);
1084 PutToDict(dict, "modulation", feparm.modulation);
1085 PutToDict(dict, "polarization", feparm.polarisation);
1086 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1088 PutToDict(dict, "rolloff", feparm.rolloff);
1089 PutToDict(dict, "pilot", feparm.pilot);
1091 PutToDict(dict, "system", feparm.system);
1094 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1096 PutToDict(dict, "tuner_type", "DVB-T");
1097 PutToDict(dict, "frequency", feparm.frequency);
1098 PutToDict(dict, "bandwidth", feparm.bandwidth);
1099 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1100 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1101 PutToDict(dict, "constellation", feparm.modulation);
1102 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1103 PutToDict(dict, "guard_interval", feparm.guard_interval);
1104 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1105 PutToDict(dict, "inversion", feparm.inversion);
1106 PutToDict(dict, "system", feparm.system);
1107 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1109 PutToDict(dict, "plp_id", feparm.plpid);
1113 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1115 PutToDict(dict, "tuner_type", "DVB-C");
1116 PutToDict(dict, "frequency", feparm.frequency);
1117 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1118 PutToDict(dict, "modulation", feparm.modulation);
1119 PutToDict(dict, "inversion", feparm.inversion);
1120 PutToDict(dict, "fec_inner", feparm.fec_inner);
1123 #if HAVE_DVB_API_VERSION >= 5
1124 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1127 int frequency = parm_frequency + freq_offset;
1128 PutToDict(dict, "frequency", frequency);
1129 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1130 PutToDict(dict, "orbital_position", orb_pos);
1131 PutToDict(dict, "polarization", polarization);
1133 switch(parm_u_qpsk_fec_inner)
1135 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1136 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1137 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1138 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1139 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1140 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1141 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1142 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1143 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1144 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1145 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1146 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1148 PutToDict(dict, "fec_inner", tmp);
1150 switch (p[0].u.data)
1152 default: eDebug("got unsupported system from frontend! report as DVBS!");
1153 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1156 switch (p[2].u.data)
1158 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1159 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1160 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1161 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1163 PutToDict(dict, "rolloff", tmp);
1165 switch (p[3].u.data)
1167 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1168 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1169 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1171 PutToDict(dict, "pilot", tmp);
1173 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1176 PutToDict(dict, "system", tmp);
1178 switch (p[1].u.data)
1180 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1181 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1182 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1184 PutToDict(dict, "modulation", tmp);
1186 switch(parm_inversion & 3)
1188 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1189 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1190 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1192 PutToDict(dict, "inversion", tmp);
1195 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1199 tmp = p[1].u.data/1000;
1200 PutToDict(dict, "frequency", tmp);
1202 PutToDict(dict, "symbol_rate", p[2].u.data);
1204 switch (p[3].u.data)
1206 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1207 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1208 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1209 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1210 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1211 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1212 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1214 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1216 PutToDict(dict, "fec_inner", tmp);
1218 switch (p[4].u.data)
1220 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1221 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1222 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1223 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1224 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1226 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1228 PutToDict(dict, "modulation", tmp);
1230 switch (p[5].u.data)
1232 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1233 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1235 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1237 PutToDict(dict, "inversion", tmp);
1240 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1244 switch (p[0].u.data)
1246 default: eDebug("got unsupported system from frontend! report as DVBT!");
1247 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1250 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1252 PutToDict(dict, "plp_id", tmp);
1254 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1257 PutToDict(dict, "system", tmp);
1260 PutToDict(dict, "frequency", tmp);
1262 switch (p[2].u.data)
1264 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1265 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1266 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1267 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1268 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1269 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1271 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1273 PutToDict(dict, "bandwidth", tmp);
1275 switch (p[3].u.data)
1277 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1278 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1279 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1280 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1281 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1282 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1283 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1284 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1286 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1288 PutToDict(dict, "code_rate_lp", tmp);
1290 switch (p[4].u.data)
1292 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1293 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1294 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1295 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1296 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1297 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1298 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1299 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1301 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1303 PutToDict(dict, "code_rate_hp", tmp);
1305 switch (p[5].u.data)
1307 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1308 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1309 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1310 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1312 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1314 PutToDict(dict, "constellation", tmp);
1317 switch (p[6].u.data)
1319 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1320 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1321 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1322 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1323 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1324 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1326 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1328 PutToDict(dict, "transmission_mode", tmp);
1330 switch (p[7].u.data)
1332 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1333 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1334 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1335 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1336 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1337 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1338 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1340 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1342 PutToDict(dict, "guard_interval", tmp);
1344 switch (p[8].u.data)
1346 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1347 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1348 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1349 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1351 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1353 PutToDict(dict, "hierarchy_information", tmp);
1355 switch (p[9].u.data)
1357 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1358 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1360 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1362 PutToDict(dict, "inversion", tmp);
1365 #else // #if HAVE_DVB_API_VERSION >= 5
1366 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1369 int frequency = parm_frequency + freq_offset;
1370 PutToDict(dict, "frequency", frequency);
1371 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1372 PutToDict(dict, "orbital_position", orb_pos);
1373 PutToDict(dict, "polarization", polarization);
1375 switch((int)parm_u_qpsk_fec_inner)
1377 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1378 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1379 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1380 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1381 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1382 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1384 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1385 #if HAVE_DVB_API_VERSION >=3
1386 case FEC_S2_8PSK_1_2:
1387 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1388 case FEC_S2_8PSK_2_3:
1389 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1390 case FEC_S2_8PSK_3_4:
1391 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1392 case FEC_S2_8PSK_5_6:
1393 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1394 case FEC_S2_8PSK_7_8:
1395 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1396 case FEC_S2_8PSK_8_9:
1397 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1398 case FEC_S2_8PSK_3_5:
1399 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1400 case FEC_S2_8PSK_4_5:
1401 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1402 case FEC_S2_8PSK_9_10:
1403 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1406 PutToDict(dict, "fec_inner", tmp);
1407 #if HAVE_DVB_API_VERSION >=3
1408 PutToDict(dict, "modulation",
1409 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1410 eDVBFrontendParametersSatellite::Modulation_8PSK :
1411 eDVBFrontendParametersSatellite::Modulation_QPSK );
1412 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1414 switch(parm_inversion & 0xc)
1416 default: // unknown rolloff
1417 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1418 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1419 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1421 PutToDict(dict, "rolloff", tmp);
1422 switch(parm_inversion & 0x30)
1424 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1425 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1426 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1428 PutToDict(dict, "pilot", tmp);
1429 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1432 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1434 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1435 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1437 PutToDict(dict, "system", tmp);
1440 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1443 #if HAVE_DVB_API_VERSION < 3
1444 PutToDict(dict, "frequency", parm_frequency);
1446 PutToDict(dict, "frequency", parm_frequency/1000);
1448 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1449 switch(parm_u_qam_fec_inner)
1451 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1452 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1453 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1454 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1455 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1456 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1457 #if HAVE_DVB_API_VERSION >= 3
1458 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1461 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1463 PutToDict(dict, "fec_inner", tmp);
1464 switch(parm_u_qam_modulation)
1466 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1467 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1468 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1469 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1470 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1472 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1474 PutToDict(dict, "modulation", tmp);
1477 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1480 PutToDict(dict, "frequency", parm_frequency);
1481 switch (parm_u_ofdm_bandwidth)
1483 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1484 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1485 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1487 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1489 PutToDict(dict, "bandwidth", tmp);
1490 switch (parm_u_ofdm_code_rate_LP)
1492 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1493 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1494 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1495 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1496 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1498 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1500 PutToDict(dict, "code_rate_lp", tmp);
1501 switch (parm_u_ofdm_code_rate_HP)
1503 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1504 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1505 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1506 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1507 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1509 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1511 PutToDict(dict, "code_rate_hp", tmp);
1512 switch (parm_u_ofdm_constellation)
1514 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1515 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1516 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1518 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1520 PutToDict(dict, "constellation", tmp);
1521 switch (parm_u_ofdm_transmission_mode)
1523 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1524 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1526 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1528 PutToDict(dict, "transmission_mode", tmp);
1529 switch (parm_u_ofdm_guard_interval)
1531 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1532 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1533 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1534 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1536 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1538 PutToDict(dict, "guard_interval", tmp);
1539 switch (parm_u_ofdm_hierarchy_information)
1541 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1542 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1543 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1544 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1546 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1548 PutToDict(dict, "hierarchy_information", tmp);
1551 #endif // #if HAVE_DVB_API_VERSION >= 5
1553 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1555 if (dest && PyDict_Check(dest))
1557 const char *tmp = "UNKNOWN";
1578 PutToDict(dest, "tuner_state", tmp);
1579 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1580 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1581 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1582 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1583 int sigQualitydB = readFrontendData(signalQualitydB);
1584 if (sigQualitydB == 0x12345678) // not support yet
1586 ePyObject obj=Py_None;
1588 PutToDict(dest, "tuner_signal_quality_db", obj);
1591 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1592 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1596 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1598 if (dest && PyDict_Check(dest))
1600 FRONTENDPARAMETERS front;
1601 #if HAVE_DVB_API_VERSION >= 5
1602 struct dtv_property p[16];
1603 struct dtv_properties cmdseq;
1609 p[0].cmd = DTV_DELIVERY_SYSTEM;
1610 p[1].cmd = DTV_MODULATION;
1611 p[2].cmd = DTV_ROLLOFF;
1612 p[3].cmd = DTV_PILOT;
1616 p[0].cmd = DTV_DELIVERY_SYSTEM;
1617 p[1].cmd = DTV_FREQUENCY;
1618 p[2].cmd = DTV_SYMBOL_RATE;
1619 p[3].cmd = DTV_INNER_FEC;
1620 p[4].cmd = DTV_MODULATION;
1621 p[5].cmd = DTV_INVERSION;
1625 p[0].cmd = DTV_DELIVERY_SYSTEM;
1626 p[1].cmd = DTV_FREQUENCY;
1627 p[2].cmd = DTV_BANDWIDTH_HZ;
1628 p[3].cmd = DTV_CODE_RATE_LP;
1629 p[4].cmd = DTV_CODE_RATE_HP;
1630 p[5].cmd = DTV_MODULATION;
1631 p[6].cmd = DTV_TRANSMISSION_MODE;
1632 p[7].cmd = DTV_GUARD_INTERVAL;
1633 p[8].cmd = DTV_HIERARCHY;
1634 p[9].cmd = DTV_INVERSION;
1635 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
1636 p[10].cmd = DTV_STREAM_ID;
1638 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
1639 p[10].cmd = DTV_DVBT2_PLP_ID;
1647 if (m_simulate || m_fd == -1 || original)
1651 #if HAVE_DVB_API_VERSION >= 5
1652 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1654 eDebug("FE_GET_PROPERTY failed (%m)");
1657 else if (m_type == feSatellite && // use for DVB-S(2) only
1658 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1660 eDebug("FE_GET_FRONTEND failed (%m)");
1664 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1666 eDebug("FE_GET_FRONTEND failed (%m)");
1675 PutSatelliteDataToDict(dest, oparm.sat);
1678 PutCableDataToDict(dest, oparm.cab);
1681 PutTerrestrialDataToDict(dest, oparm.ter);
1687 FRONTENDPARAMETERS &parm = front;
1688 #if HAVE_DVB_API_VERSION >= 5
1692 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1695 fillDictWithCableData(dest, p);
1698 fillDictWithTerrestrialData(dest, p);
1702 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1703 switch(parm_inversion & 3)
1706 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1709 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1713 PutToDict(dest, "inversion", tmp);
1717 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1720 fillDictWithCableData(dest, parm);
1723 fillDictWithTerrestrialData(dest, parm);
1731 void eDVBFrontend::getFrontendData(ePyObject dest)
1733 if (dest && PyDict_Check(dest))
1736 PutToDict(dest, "tuner_number", m_slotid);
1752 PutToDict(dest, "tuner_type", tmp);
1756 #ifndef FP_IOCTL_GET_ID
1757 #define FP_IOCTL_GET_ID 0
1759 int eDVBFrontend::readInputpower()
1763 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1765 char proc_name2[64];
1766 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1767 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1769 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1771 if (fscanf(f, "%d", &power) != 1)
1772 eDebug("read %s failed!! (%m)", proc_name);
1774 eDebug("%s is %d\n", proc_name, power);
1779 // open front prozessor
1780 int fp=::open("/dev/dbox/fp0", O_RDWR);
1783 eDebug("couldn't open fp");
1786 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1787 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1789 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1798 bool eDVBFrontend::setSecSequencePos(int steps)
1800 eDebugNoSimulate("set sequence pos %d", steps);
1805 if (m_sec_sequence.current() != m_sec_sequence.end())
1806 ++m_sec_sequence.current();
1811 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1812 --m_sec_sequence.current();
1818 void eDVBFrontend::tuneLoop()
1823 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1826 eDVBFrontend *sec_fe = this;
1827 eDVBRegisteredFrontend *regFE = 0;
1828 long tmp = m_data[LINKED_PREV_PTR];
1831 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1832 sec_fe = prev->m_frontend;
1833 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1834 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1835 int state = sec_fe->m_state;
1836 // workaround to put the kernel frontend thread into idle state!
1837 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1839 sec_fe->closeFrontend(true);
1840 state = sec_fe->m_state;
1842 // sec_fe is closed... we must reopen it here..
1843 if (state == stateClosed)
1851 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1853 long *sec_fe_data = sec_fe->m_data;
1854 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1856 switch (m_sec_sequence.current()->cmd)
1858 case eSecCommand::SLEEP:
1859 delay = m_sec_sequence.current()++->msec;
1860 eDebugNoSimulate("[SEC] sleep %dms", delay);
1862 case eSecCommand::GOTO:
1863 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1864 ++m_sec_sequence.current();
1866 case eSecCommand::SET_VOLTAGE:
1868 int voltage = m_sec_sequence.current()++->voltage;
1869 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1870 sec_fe->setVoltage(voltage);
1873 case eSecCommand::IF_VOLTAGE_GOTO:
1875 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1876 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1878 ++m_sec_sequence.current();
1881 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1883 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1884 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1886 ++m_sec_sequence.current();
1889 case eSecCommand::IF_TONE_GOTO:
1891 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1892 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1894 ++m_sec_sequence.current();
1897 case eSecCommand::IF_NOT_TONE_GOTO:
1899 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1900 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1902 ++m_sec_sequence.current();
1905 case eSecCommand::SET_TONE:
1906 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1907 sec_fe->setTone(m_sec_sequence.current()++->tone);
1909 case eSecCommand::SEND_DISEQC:
1910 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1911 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1912 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1913 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1914 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1915 eDebugNoSimulate("(DiSEqC reset)");
1916 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1917 eDebugNoSimulate("(DiSEqC peripherial power on)");
1919 eDebugNoSimulate("");
1920 ++m_sec_sequence.current();
1922 case eSecCommand::SEND_TONEBURST:
1923 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1924 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1926 case eSecCommand::SET_FRONTEND:
1928 int enableEvents = (m_sec_sequence.current()++)->val;
1929 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1930 setFrontend(enableEvents);
1933 case eSecCommand::START_TUNE_TIMEOUT:
1935 int tuneTimeout = m_sec_sequence.current()->timeout;
1936 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1938 m_timeout->start(tuneTimeout, 1);
1939 ++m_sec_sequence.current();
1942 case eSecCommand::SET_TIMEOUT:
1943 m_timeoutCount = m_sec_sequence.current()++->val;
1944 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1946 case eSecCommand::IF_TIMEOUT_GOTO:
1947 if (!m_timeoutCount)
1949 eDebugNoSimulate("[SEC] rotor timout");
1950 setSecSequencePos(m_sec_sequence.current()->steps);
1953 ++m_sec_sequence.current();
1955 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1957 int idx = m_sec_sequence.current()++->val;
1958 if ( idx == 0 || idx == 1 )
1960 m_idleInputpower[idx] = sec_fe->readInputpower();
1961 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1964 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1967 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1969 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1970 int idx = compare.val;
1971 if ( !m_simulate && (idx == 0 || idx == 1) )
1973 int idle = sec_fe->readInputpower();
1974 int diff = abs(idle-m_idleInputpower[idx]);
1977 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1978 setSecSequencePos(compare.steps);
1982 ++m_sec_sequence.current();
1985 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1987 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1990 setSecSequencePos(cmd.steps);
1994 int isLocked = readFrontendData(locked);
1995 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1997 if (!m_timeoutCount && m_retryCount > 0)
1999 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
2002 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2005 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2007 cmd.lastSignal = signal;
2010 if (cmd.okcount > 4)
2012 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2013 setSecSequencePos(cmd.steps);
2014 m_state = stateLock;
2015 m_stateChanged(this);
2016 feEvent(-1); // flush events
2024 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2026 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2030 ++m_sec_sequence.current();
2033 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2034 m_runningInputpower = sec_fe->readInputpower();
2035 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2036 ++m_sec_sequence.current();
2038 case eSecCommand::SET_ROTOR_MOVING:
2040 m_sec->setRotorMoving(m_slotid, true);
2041 ++m_sec_sequence.current();
2043 case eSecCommand::SET_ROTOR_STOPPED:
2045 m_sec->setRotorMoving(m_slotid, false);
2046 ++m_sec_sequence.current();
2048 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2050 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2053 setSecSequencePos(cmd.steps);
2056 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2057 const char *txt = cmd.direction ? "running" : "stopped";
2059 if (!m_timeoutCount && m_retryCount > 0)
2061 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2063 m_runningInputpower,
2066 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2067 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2070 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2071 if ( cmd.okcount > 6 )
2073 eDebugNoSimulate("[SEC] rotor is %s", txt);
2074 if (setSecSequencePos(cmd.steps))
2080 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2083 ++m_sec_sequence.current();
2086 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2087 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2088 setSecSequencePos(m_sec_sequence.current()->steps);
2090 ++m_sec_sequence.current();
2092 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2093 eDebugNoSimulate("[SEC] invalidate current switch params");
2094 sec_fe_data[CSW] = -1;
2095 sec_fe_data[UCSW] = -1;
2096 sec_fe_data[TONEBURST] = -1;
2097 ++m_sec_sequence.current();
2099 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2100 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2101 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2102 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2103 eDebugNoSimulate("[SEC] update current switch params");
2104 ++m_sec_sequence.current();
2106 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2107 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2108 sec_fe_data[ROTOR_CMD] = -1;
2109 sec_fe_data[ROTOR_POS] = -1;
2110 ++m_sec_sequence.current();
2112 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2113 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2114 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2115 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2116 ++m_sec_sequence.current();
2118 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2119 m_retryCount = m_sec_sequence.current()++->val;
2120 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2122 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2125 eDebugNoSimulate("[SEC] no more rotor retrys");
2126 setSecSequencePos(m_sec_sequence.current()->steps);
2129 ++m_sec_sequence.current();
2131 case eSecCommand::SET_POWER_LIMITING_MODE:
2136 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2137 FILE *f=fopen(proc_name, "w");
2138 if (f) // new interface exist?
2140 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2141 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2142 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2144 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2147 else if (sec_fe->m_need_rotor_workaround)
2150 int slotid = sec_fe->m_slotid;
2151 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2153 sprintf(dev, "/dev/i2c-%d", slotid);
2154 else if (slotid == 2)
2155 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2156 else if (slotid == 3)
2157 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2158 int fd = ::open(dev, O_RDWR);
2160 unsigned char data[2];
2161 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2162 if(::read(fd, data, 1) != 1)
2163 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2164 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2166 data[0] |= 0x80; // enable static current limiting
2167 eDebugNoSimulate("[SEC] set static current limiting");
2171 data[0] &= ~0x80; // enable dynamic current limiting
2172 eDebugNoSimulate("[SEC] set dynamic current limiting");
2174 if(::write(fd, data, 1) != 1)
2175 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2179 ++m_sec_sequence.current();
2182 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2184 eDebugNoSimulate("[SEC] delayed close frontend");
2185 closeFrontend(false, true);
2186 ++m_sec_sequence.current();
2190 eDebugNoSimulate("[SEC] unhandled sec command %d",
2191 ++m_sec_sequence.current()->cmd);
2192 ++m_sec_sequence.current();
2195 m_tuneTimer->start(delay,true);
2199 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2204 void eDVBFrontend::setFrontend(bool recvEvents)
2208 eDebug("setting frontend %d", m_dvbid);
2211 feEvent(-1); // flush events
2212 #if HAVE_DVB_API_VERSION >= 5
2213 if (m_type == iDVBFrontend::feSatellite)
2215 fe_rolloff_t rolloff = ROLLOFF_35;
2216 fe_pilot_t pilot = PILOT_OFF;
2217 fe_modulation_t modulation = QPSK;
2218 fe_delivery_system_t system = SYS_DVBS;
2219 switch(oparm.sat.system)
2221 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2222 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2224 switch(oparm.sat.modulation)
2226 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2227 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2228 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2230 switch(oparm.sat.pilot)
2232 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2233 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2234 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2236 switch(oparm.sat.rolloff)
2238 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2239 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2240 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2242 struct dtv_property p[10];
2243 struct dtv_properties cmdseq;
2245 p[0].cmd = DTV_CLEAR;
2246 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2247 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2248 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2249 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2250 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2251 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2252 if (system == SYS_DVBS2)
2254 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2255 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2256 p[9].cmd = DTV_TUNE;
2261 p[7].cmd = DTV_TUNE;
2264 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2266 perror("FE_SET_PROPERTY failed");
2270 else if (m_type == iDVBFrontend::feCable)
2272 struct dtv_property p[8];
2273 struct dtv_properties cmdseq;
2275 p[0].cmd = DTV_CLEAR;
2276 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2277 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2279 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2281 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2282 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2283 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2284 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2285 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2286 p[7].cmd = DTV_TUNE;
2288 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2290 perror("FE_SET_PROPERTY failed");
2294 else if (m_type == iDVBFrontend::feTerrestrial)
2296 fe_delivery_system_t system = SYS_DVBT;
2297 switch (oparm.ter.system)
2300 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2301 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2304 switch (oparm.ter.bandwidth)
2306 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2307 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2308 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2310 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2311 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2312 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2313 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2315 struct dtv_property p[13];
2316 struct dtv_properties cmdseq;
2319 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2320 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2321 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2322 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2323 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2324 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2325 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2326 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2327 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2328 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2329 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2330 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 9
2331 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
2332 #elif DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
2333 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
2335 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2336 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2338 perror("FE_SET_PROPERTY failed");
2345 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2347 perror("FE_SET_FRONTEND failed");
2354 RESULT eDVBFrontend::getFrontendType(int &t)
2362 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2367 eWarning("no SEC module active!");
2370 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2373 #if HAVE_DVB_API_VERSION >= 3
2374 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",
2377 feparm.polarisation,
2381 feparm.orbital_position,
2387 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2390 feparm.polarisation,
2394 feparm.orbital_position);
2396 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2397 switch (feparm.inversion)
2399 case eDVBFrontendParametersSatellite::Inversion_On:
2400 parm_inversion = INVERSION_ON;
2402 case eDVBFrontendParametersSatellite::Inversion_Off:
2403 parm_inversion = INVERSION_OFF;
2406 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2407 parm_inversion = INVERSION_AUTO;
2410 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2414 case eDVBFrontendParametersSatellite::FEC_None:
2415 parm_u_qpsk_fec_inner = FEC_NONE;
2417 case eDVBFrontendParametersSatellite::FEC_1_2:
2418 parm_u_qpsk_fec_inner = FEC_1_2;
2420 case eDVBFrontendParametersSatellite::FEC_2_3:
2421 parm_u_qpsk_fec_inner = FEC_2_3;
2423 case eDVBFrontendParametersSatellite::FEC_3_4:
2424 parm_u_qpsk_fec_inner = FEC_3_4;
2426 case eDVBFrontendParametersSatellite::FEC_5_6:
2427 parm_u_qpsk_fec_inner = FEC_5_6;
2429 case eDVBFrontendParametersSatellite::FEC_7_8:
2430 parm_u_qpsk_fec_inner = FEC_7_8;
2433 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2434 case eDVBFrontendParametersSatellite::FEC_Auto:
2435 parm_u_qpsk_fec_inner = FEC_AUTO;
2439 #if HAVE_DVB_API_VERSION >= 3
2444 case eDVBFrontendParametersSatellite::FEC_1_2:
2445 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2447 case eDVBFrontendParametersSatellite::FEC_2_3:
2448 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2450 case eDVBFrontendParametersSatellite::FEC_3_4:
2451 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2453 case eDVBFrontendParametersSatellite::FEC_3_5:
2454 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2456 case eDVBFrontendParametersSatellite::FEC_4_5:
2457 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2459 case eDVBFrontendParametersSatellite::FEC_5_6:
2460 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2462 case eDVBFrontendParametersSatellite::FEC_7_8:
2463 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2465 case eDVBFrontendParametersSatellite::FEC_8_9:
2466 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2468 case eDVBFrontendParametersSatellite::FEC_9_10:
2469 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2472 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2475 #if HAVE_DVB_API_VERSION < 5
2476 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2477 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2478 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2480 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2481 // 8PSK fec driver values are decimal 9 bigger
2486 // FIXME !!! get frequency range from tuner
2487 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2489 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2492 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2498 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2500 #if HAVE_DVB_API_VERSION < 3
2501 parm_frequency = feparm.frequency;
2503 parm_frequency = feparm.frequency * 1000;
2505 parm_u_qam_symbol_rate = feparm.symbol_rate;
2506 switch (feparm.modulation)
2508 case eDVBFrontendParametersCable::Modulation_QAM16:
2509 parm_u_qam_modulation = QAM_16;
2511 case eDVBFrontendParametersCable::Modulation_QAM32:
2512 parm_u_qam_modulation = QAM_32;
2514 case eDVBFrontendParametersCable::Modulation_QAM64:
2515 parm_u_qam_modulation = QAM_64;
2517 case eDVBFrontendParametersCable::Modulation_QAM128:
2518 parm_u_qam_modulation = QAM_128;
2520 case eDVBFrontendParametersCable::Modulation_QAM256:
2521 parm_u_qam_modulation = QAM_256;
2524 case eDVBFrontendParametersCable::Modulation_Auto:
2525 parm_u_qam_modulation = QAM_AUTO;
2528 switch (feparm.inversion)
2530 case eDVBFrontendParametersCable::Inversion_On:
2531 parm_inversion = INVERSION_ON;
2533 case eDVBFrontendParametersCable::Inversion_Off:
2534 parm_inversion = INVERSION_OFF;
2537 case eDVBFrontendParametersCable::Inversion_Unknown:
2538 parm_inversion = INVERSION_AUTO;
2541 switch (feparm.fec_inner)
2543 case eDVBFrontendParametersCable::FEC_None:
2544 parm_u_qam_fec_inner = FEC_NONE;
2546 case eDVBFrontendParametersCable::FEC_1_2:
2547 parm_u_qam_fec_inner = FEC_1_2;
2549 case eDVBFrontendParametersCable::FEC_2_3:
2550 parm_u_qam_fec_inner = FEC_2_3;
2552 case eDVBFrontendParametersCable::FEC_3_4:
2553 parm_u_qam_fec_inner = FEC_3_4;
2555 case eDVBFrontendParametersCable::FEC_5_6:
2556 parm_u_qam_fec_inner = FEC_5_6;
2558 case eDVBFrontendParametersCable::FEC_7_8:
2559 parm_u_qam_fec_inner = FEC_7_8;
2561 #if HAVE_DVB_API_VERSION >= 3
2562 case eDVBFrontendParametersCable::FEC_8_9:
2563 parm_u_qam_fec_inner = FEC_8_9;
2567 case eDVBFrontendParametersCable::FEC_Auto:
2568 parm_u_qam_fec_inner = FEC_AUTO;
2571 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2572 parm_frequency/1000,
2573 parm_u_qam_symbol_rate,
2574 parm_u_qam_fec_inner,
2575 parm_u_qam_modulation,
2581 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2583 parm_frequency = feparm.frequency;
2585 switch (feparm.bandwidth)
2587 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2588 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2590 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2591 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2593 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2594 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2596 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2597 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2599 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2600 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2602 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2603 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2606 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2607 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2610 switch (feparm.code_rate_LP)
2612 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2613 parm_u_ofdm_code_rate_LP = FEC_1_2;
2615 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2616 parm_u_ofdm_code_rate_LP = FEC_2_3;
2618 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2619 parm_u_ofdm_code_rate_LP = FEC_3_4;
2621 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2622 parm_u_ofdm_code_rate_LP = FEC_5_6;
2624 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2625 parm_u_ofdm_code_rate_LP = FEC_7_8;
2627 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2628 parm_u_ofdm_code_rate_LP = FEC_6_7;
2630 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2631 parm_u_ofdm_code_rate_LP = FEC_8_9;
2634 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2635 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2638 switch (feparm.code_rate_HP)
2640 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2641 parm_u_ofdm_code_rate_HP = FEC_1_2;
2643 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2644 parm_u_ofdm_code_rate_HP = FEC_2_3;
2646 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2647 parm_u_ofdm_code_rate_HP = FEC_3_4;
2649 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2650 parm_u_ofdm_code_rate_HP = FEC_5_6;
2652 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2653 parm_u_ofdm_code_rate_HP = FEC_7_8;
2655 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2656 parm_u_ofdm_code_rate_HP = FEC_6_7;
2658 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2659 parm_u_ofdm_code_rate_HP = FEC_8_9;
2662 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2663 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2666 switch (feparm.modulation)
2668 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2669 parm_u_ofdm_constellation = QPSK;
2671 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2672 parm_u_ofdm_constellation = QAM_16;
2674 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2675 parm_u_ofdm_constellation = QAM_64;
2677 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2678 parm_u_ofdm_constellation = QAM_256;
2681 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2682 parm_u_ofdm_constellation = QAM_AUTO;
2685 switch (feparm.transmission_mode)
2687 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2688 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2690 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2691 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2693 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2694 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2696 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2697 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2699 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2700 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2702 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2703 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2706 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2707 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2710 switch (feparm.guard_interval)
2712 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2713 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2715 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2716 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2718 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2719 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2721 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2722 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2724 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2725 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2727 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2728 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2730 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2731 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2734 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2735 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2738 switch (feparm.hierarchy)
2740 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2741 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2743 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2744 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2746 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2747 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2749 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2750 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2753 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2754 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2757 switch (feparm.inversion)
2759 case eDVBFrontendParametersTerrestrial::Inversion_On:
2760 parm_inversion = INVERSION_ON;
2762 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2763 parm_inversion = INVERSION_OFF;
2766 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2767 parm_inversion = INVERSION_AUTO;
2770 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",
2771 parm_frequency/1000,
2772 parm_u_ofdm_bandwidth,
2773 parm_u_ofdm_code_rate_LP,
2774 parm_u_ofdm_code_rate_HP,
2775 parm_u_ofdm_constellation,
2776 parm_u_ofdm_transmission_mode,
2777 parm_u_ofdm_guard_interval,
2778 parm_u_ofdm_hierarchy_information,
2786 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2788 unsigned int timeout = 5000;
2789 eDebugNoSimulate("(%d)tune", m_dvbid);
2795 if (!m_sn && !m_simulate)
2797 eDebug("no frontend device opened... do not try to tune !!!");
2811 m_sec_sequence.clear();
2813 where.calcLockTimeout(timeout);
2819 eDVBFrontendParametersSatellite feparm;
2820 if (where.getDVBS(feparm))
2822 eDebug("no dvbs data!");
2826 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2828 eDVBFrontend *sec_fe = this;
2829 long tmp = m_data[LINKED_PREV_PTR];
2832 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2833 sec_fe = linked_fe->m_frontend;
2834 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2836 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2837 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
2839 m_rotor_mode = feparm.no_rotor_command_on_tune;
2841 m_sec->setRotorMoving(m_slotid, false);
2842 res=prepare_sat(feparm, timeout);
2850 eDVBFrontendParametersCable feparm;
2851 if (where.getDVBC(feparm))
2856 res=prepare_cable(feparm);
2860 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2861 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2866 eDVBFrontendParametersTerrestrial feparm;
2867 if (where.getDVBT(feparm))
2869 eDebug("no -T data");
2873 res=prepare_terrestrial(feparm);
2877 std::string enable_5V;
2878 char configStr[255];
2879 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2880 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2881 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2882 if (enable_5V == "True")
2883 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2885 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2886 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2892 m_sec_sequence.current() = m_sec_sequence.begin();
2896 m_tuneTimer->start(0,true);
2898 if (m_state != stateTuning)
2900 m_state = stateTuning;
2901 m_stateChanged(this);
2910 m_tuneTimer->stop();
2914 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2916 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2920 RESULT eDVBFrontend::setVoltage(int voltage)
2922 if (m_type == feCable)
2924 #if HAVE_DVB_API_VERSION < 3
2927 bool increased=false;
2928 fe_sec_voltage_t vlt;
2930 m_data[CUR_VOLTAGE]=voltage;
2934 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2935 vlt = SEC_VOLTAGE_OFF;
2938 #if HAVE_DVB_API_VERSION < 3
2939 vlt = SEC_VOLTAGE_13_5;
2945 vlt = SEC_VOLTAGE_13;
2948 #if HAVE_DVB_API_VERSION < 3
2949 vlt = SEC_VOLTAGE_18_5;
2955 vlt = SEC_VOLTAGE_18;
2962 #if HAVE_DVB_API_VERSION < 3
2963 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2965 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2966 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2967 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2971 RESULT eDVBFrontend::getState(int &state)
2977 RESULT eDVBFrontend::setTone(int t)
2979 if (m_type != feSatellite)
2981 #if HAVE_DVB_API_VERSION < 3
2984 fe_sec_tone_mode_t tone;
2993 tone = SEC_TONE_OFF;
3000 #if HAVE_DVB_API_VERSION < 3
3001 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
3003 return ::ioctl(m_fd, FE_SET_TONE, tone);
3007 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3008 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3011 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3015 #if HAVE_DVB_API_VERSION < 3
3016 struct secCommand cmd;
3017 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3018 cmd.u.diseqc.cmdtype = diseqc.data[0];
3019 cmd.u.diseqc.addr = diseqc.data[1];
3020 cmd.u.diseqc.cmd = diseqc.data[2];
3021 cmd.u.diseqc.numParams = diseqc.len-3;
3022 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3023 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3025 struct dvb_diseqc_master_cmd cmd;
3026 memcpy(cmd.msg, diseqc.data, diseqc.len);
3027 cmd.msg_len = diseqc.len;
3028 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3034 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3035 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3037 RESULT eDVBFrontend::sendToneburst(int burst)
3041 #if HAVE_DVB_API_VERSION < 3
3042 secMiniCmd cmd = SEC_MINI_NONE;
3044 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3046 if ( burst == eDVBSatelliteDiseqcParameters::A )
3048 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3050 #if HAVE_DVB_API_VERSION < 3
3051 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3054 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3060 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3066 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3068 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3069 m_sec_sequence.push_back(list);
3071 m_sec_sequence = list;
3075 RESULT eDVBFrontend::getData(int num, long &data)
3077 if ( num < NUM_DATA_ENTRIES )
3085 RESULT eDVBFrontend::setData(int num, long val)
3087 if ( num < NUM_DATA_ENTRIES )
3095 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3099 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3101 if (feparm->getSystem(type) || type != m_type || !m_enabled)
3104 if (m_type == eDVBFrontend::feSatellite)
3106 eDVBFrontendParametersSatellite sat_parm;
3107 if (feparm->getDVBS(sat_parm) < 0)
3111 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
3115 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3116 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
3118 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3123 else if (m_type == eDVBFrontend::feCable)
3125 eDVBFrontendParametersCable cab_parm;
3126 if (feparm->getDVBC(cab_parm) < 0)
3133 else if (m_type == eDVBFrontend::feTerrestrial)
3135 eDVBFrontendParametersTerrestrial ter_parm;
3136 if (feparm->getDVBT(ter_parm) < 0)
3140 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !m_can_handle_dvbt2)
3145 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && m_can_handle_dvbt2)
3147 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3152 if (score && preferred)
3154 /* make 'sure' we always prefer this frontend */
3161 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3163 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3164 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3166 Id = PyTuple_GET_ITEM(obj, 0);
3167 Descr = PyTuple_GET_ITEM(obj, 1);
3168 Enabled = PyTuple_GET_ITEM(obj, 2);
3169 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3170 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3171 frontendId = PyTuple_GET_ITEM(obj, 5);
3172 m_slotid = PyInt_AsLong(Id);
3173 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3175 strcpy(m_description, PyString_AS_STRING(Descr));
3176 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3177 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3178 // m_slotid, m_description);
3181 m_enabled = Enabled == Py_True;
3182 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3183 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3184 !!strstr(m_description, "Alps BSBE2") ||
3185 !!strstr(m_description, "Alps -S") ||
3186 !!strstr(m_description, "BCM4501");
3187 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
3188 m_can_handle_dvbt2 = IsDVBT2 == Py_True;
3189 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3190 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No", m_can_handle_dvbt2 ? "Yes" : "No" );
3193 PyErr_SetString(PyExc_StandardError,
3194 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");