1 #include <lib/dvb/dvb.h>
2 #include <lib/dvb/frontendparms.h>
3 #include <lib/base/eerror.h>
4 #include <lib/base/nconfig.h> // access to python config
10 #ifndef I2C_SLAVE_FORCE
11 #define I2C_SLAVE_FORCE 0x0706
14 #if HAVE_DVB_API_VERSION < 3
15 #include <ost/frontend.h>
17 #define QAM_AUTO (Modulation)6
18 #define TRANSMISSION_MODE_AUTO (TransmitMode)2
19 #define BANDWIDTH_AUTO (BandWidth)3
20 #define GUARD_INTERVAL_AUTO (GuardInterval)4
21 #define HIERARCHY_AUTO (Hierarchy)4
22 #define parm_frequency parm.Frequency
23 #define parm_inversion parm.Inversion
24 #define parm_u_qpsk_symbol_rate parm.u.qpsk.SymbolRate
25 #define parm_u_qpsk_fec_inner parm.u.qpsk.FEC_inner
26 #define parm_u_qam_symbol_rate parm.u.qam.SymbolRate
27 #define parm_u_qam_fec_inner parm.u.qam.FEC_inner
28 #define parm_u_qam_modulation parm.u.qam.QAM
29 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandWidth
30 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.LP_CodeRate
31 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.HP_CodeRate
32 #define parm_u_ofdm_constellation parm.u.ofdm.Constellation
33 #define parm_u_ofdm_transmission_mode parm.u.ofdm.TransmissionMode
34 #define parm_u_ofdm_guard_interval parm.u.ofdm.guardInterval
35 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.HierarchyInformation
37 #include <linux/dvb/frontend.h>
38 #define parm_frequency parm.frequency
39 #define parm_inversion parm.inversion
40 #define parm_u_qpsk_symbol_rate parm.u.qpsk.symbol_rate
41 #define parm_u_qpsk_fec_inner parm.u.qpsk.fec_inner
42 #define parm_u_qam_symbol_rate parm.u.qam.symbol_rate
43 #define parm_u_qam_fec_inner parm.u.qam.fec_inner
44 #define parm_u_qam_modulation parm.u.qam.modulation
45 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandwidth
46 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.code_rate_LP
47 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.code_rate_HP
48 #define parm_u_ofdm_constellation parm.u.ofdm.constellation
49 #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode
50 #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval
51 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information
52 #if HAVE_DVB_API_VERSION < 5
53 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1)
54 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1)
55 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_S2_QPSK_2_3+1)
56 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_S2_QPSK_3_4+1)
57 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_S2_QPSK_5_6+1)
58 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_S2_QPSK_7_8+1)
59 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_S2_QPSK_8_9+1)
60 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_S2_QPSK_3_5+1)
61 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_S2_QPSK_4_5+1)
62 #define FEC_S2_8PSK_1_2 (fe_code_rate_t)(FEC_S2_QPSK_9_10+1)
63 #define FEC_S2_8PSK_2_3 (fe_code_rate_t)(FEC_S2_8PSK_1_2+1)
64 #define FEC_S2_8PSK_3_4 (fe_code_rate_t)(FEC_S2_8PSK_2_3+1)
65 #define FEC_S2_8PSK_5_6 (fe_code_rate_t)(FEC_S2_8PSK_3_4+1)
66 #define FEC_S2_8PSK_7_8 (fe_code_rate_t)(FEC_S2_8PSK_5_6+1)
67 #define FEC_S2_8PSK_8_9 (fe_code_rate_t)(FEC_S2_8PSK_7_8+1)
68 #define FEC_S2_8PSK_3_5 (fe_code_rate_t)(FEC_S2_8PSK_8_9+1)
69 #define FEC_S2_8PSK_4_5 (fe_code_rate_t)(FEC_S2_8PSK_3_5+1)
70 #define FEC_S2_8PSK_9_10 (fe_code_rate_t)(FEC_S2_8PSK_4_5+1)
72 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2)
73 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3)
74 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4)
75 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6)
76 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8)
77 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9)
78 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5)
79 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5)
80 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10)
84 #include <dvbsi++/satellite_delivery_system_descriptor.h>
85 #include <dvbsi++/cable_delivery_system_descriptor.h>
86 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
88 #define eDebugNoSimulate(x...) \
96 eDebugNoNewLine("SIMULATE:"); \
101 #define eDebugNoSimulateNoNewLine(x...) \
104 eDebugNoNewLine(x); \
109 eDebugNoNewLine("SIMULATE:"); \
110 eDebugNoNewLine(x); \
114 void eDVBDiseqcCommand::setCommandString(const char *str)
119 int slen = strlen(str);
122 eDebug("invalid diseqc command string length (not 2 byte aligned)");
125 if (slen > MAX_DISEQC_LENGTH*2)
127 eDebug("invalid diseqc command string length (string is to long)");
131 for (int i=0; i < slen; ++i)
133 unsigned char c = str[i];
136 case '0' ... '9': c-=48; break;
137 case 'a' ... 'f': c-=87; break;
138 case 'A' ... 'F': c-=55; break;
140 eDebug("invalid character in hex string..ignore complete diseqc command !");
154 void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescriptor &descriptor)
156 frequency = descriptor.getFrequency() * 10;
157 symbol_rate = descriptor.getSymbolRate() * 100;
158 polarisation = descriptor.getPolarization();
159 fec = descriptor.getFecInner();
160 if ( fec != eDVBFrontendParametersSatellite::FEC_None && fec > eDVBFrontendParametersSatellite::FEC_9_10 )
161 fec = eDVBFrontendParametersSatellite::FEC_Auto;
162 inversion = eDVBFrontendParametersSatellite::Inversion_Unknown;
163 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
164 orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
165 orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
166 orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
167 orbital_position += ((descriptor.getOrbitalPosition()) & 0xF);
168 if (orbital_position && (!descriptor.getWestEastFlag()))
169 orbital_position = 3600 - orbital_position;
170 system = descriptor.getModulationSystem();
171 modulation = descriptor.getModulation();
172 if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
174 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
175 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
177 rolloff = descriptor.getRollOff();
178 if (system == eDVBFrontendParametersSatellite::System_DVB_S2)
180 eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
182 polarisation ? "hor" : "vert",
190 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
192 polarisation ? "hor" : "vert",
198 void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descriptor)
200 frequency = descriptor.getFrequency() / 10;
201 symbol_rate = descriptor.getSymbolRate() * 100;
202 fec_inner = descriptor.getFecInner();
203 if ( fec_inner != eDVBFrontendParametersCable::FEC_None && fec_inner > eDVBFrontendParametersCable::FEC_8_9 )
204 fec_inner = eDVBFrontendParametersCable::FEC_Auto;
205 modulation = descriptor.getModulation();
206 if ( modulation > 0x5 )
207 modulation = eDVBFrontendParametersCable::Modulation_Auto;
208 inversion = eDVBFrontendParametersCable::Inversion_Unknown;
209 eDebug("Cable freq %d, mod %d, sr %d, fec %d",
211 modulation, symbol_rate, fec_inner);
214 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
216 frequency = descriptor.getCentreFrequency() * 10;
217 bandwidth = descriptor.getBandwidth();
218 if ( bandwidth > 2 ) // 5Mhz forced to auto
219 bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto;
220 code_rate_HP = descriptor.getCodeRateHpStream();
221 if (code_rate_HP > 4)
222 code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto;
223 code_rate_LP = descriptor.getCodeRateLpStream();
224 if (code_rate_LP > 4)
225 code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto;
226 transmission_mode = descriptor.getTransmissionMode();
227 if (transmission_mode > 1) // TM4k forced to auto
228 transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto;
229 guard_interval = descriptor.getGuardInterval();
230 if (guard_interval > 3)
231 guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto;
232 hierarchy = descriptor.getHierarchyInformation()&3;
233 modulation = descriptor.getConstellation();
235 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
236 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
237 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
238 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
239 guard_interval, hierarchy, modulation);
242 eDVBFrontendParameters::eDVBFrontendParameters()
243 :m_type(-1), m_flags(0)
247 DEFINE_REF(eDVBFrontendParameters);
249 RESULT eDVBFrontendParameters::getSystem(int &t) const
257 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
259 if (m_type != iDVBFrontend::feSatellite)
265 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
267 if (m_type != iDVBFrontend::feCable)
273 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
275 if (m_type != iDVBFrontend::feTerrestrial)
281 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
284 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
285 m_type = iDVBFrontend::feSatellite;
289 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
292 m_type = iDVBFrontend::feCable;
296 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
299 m_type = iDVBFrontend::feTerrestrial;
303 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
308 if (parm->getSystem(type))
312 diff = 1<<30; // big difference
318 case iDVBFrontend::feSatellite:
320 eDVBFrontendParametersSatellite osat;
321 if (parm->getDVBS(osat))
324 if (sat.orbital_position != osat.orbital_position)
326 else if (sat.polarisation != osat.polarisation)
328 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
330 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
334 diff = abs(sat.frequency - osat.frequency);
335 diff += abs(sat.symbol_rate - osat.symbol_rate);
339 case iDVBFrontend::feCable:
340 eDVBFrontendParametersCable ocable;
341 if (parm->getDVBC(ocable))
344 if (exact && cable.modulation != ocable.modulation
345 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
346 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
348 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
352 diff = abs(cable.frequency - ocable.frequency);
353 diff += abs(cable.symbol_rate - ocable.symbol_rate);
356 case iDVBFrontend::feTerrestrial:
357 eDVBFrontendParametersTerrestrial oterrestrial;
358 if (parm->getDVBT(oterrestrial))
361 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
362 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
363 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
365 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
366 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
367 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
369 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
370 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
371 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
373 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
374 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
375 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
377 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
378 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
379 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
381 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
382 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
383 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
385 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
386 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
387 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
390 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
398 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
402 case iDVBFrontend::feSatellite:
404 hash = (sat.orbital_position << 16);
405 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
408 case iDVBFrontend::feCable:
410 hash |= (cable.frequency/1000)&0xFFFF;
412 case iDVBFrontend::feTerrestrial:
414 hash |= (terrestrial.frequency/1000000)&0xFFFF;
421 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
425 case iDVBFrontend::feSatellite:
427 /* high symbol rate transponders tune faster, due to
428 requiring less zigzag and giving more symbols faster.
430 5s are definitely not enough on really low SR when
431 zigzag has to find the exact frequency first.
433 if (sat.symbol_rate > 20000000)
435 else if (sat.symbol_rate > 10000000)
441 case iDVBFrontend::feCable:
444 case iDVBFrontend::feTerrestrial:
452 DEFINE_REF(eDVBFrontend);
454 int eDVBFrontend::PriorityOrder=0;
456 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate)
457 :m_simulate(simulate), m_enabled(false), m_type(-1), m_dvbid(fe), m_slotid(fe)
458 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false)
459 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
460 #if HAVE_DVB_API_VERSION < 3
464 #if HAVE_DVB_API_VERSION < 3
465 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
466 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
468 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
471 m_timeout = eTimer::create(eApp);
472 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
474 m_tuneTimer = eTimer::create(eApp);
475 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
477 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
480 m_idleInputpower[0]=m_idleInputpower[1]=0;
482 ok = !openFrontend();
486 void eDVBFrontend::reopenFrontend()
493 int eDVBFrontend::openFrontend()
495 if (m_state != stateClosed)
496 return -1; // already opened
501 #if HAVE_DVB_API_VERSION < 3
502 FrontendInfo fe_info;
504 dvb_frontend_info fe_info;
506 eDebugNoSimulate("opening frontend %d", m_dvbid);
509 if (!m_simulate || m_type == -1)
511 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
514 eWarning("failed! (%s) %m", m_filename);
520 eWarning("frontend %d already opened", m_dvbid);
523 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
525 eWarning("ioctl FE_GET_INFO failed");
531 switch (fe_info.type)
534 m_type = iDVBFrontend::feSatellite;
537 m_type = iDVBFrontend::feCable;
540 m_type = iDVBFrontend::feTerrestrial;
543 eWarning("unknown frontend type.");
548 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
551 #if HAVE_DVB_API_VERSION < 3
552 if (m_type == iDVBFrontend::feSatellite)
558 m_secfd = ::open(m_sec_filename, O_RDWR);
561 eWarning("failed! (%s) %m", m_sec_filename);
569 eWarning("sec %d already opened", m_dvbid);
573 setTone(iDVBFrontend::toneOff);
574 setVoltage(iDVBFrontend::voltageOff);
578 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
579 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
585 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
587 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
589 long tmp = m_data[LINKED_NEXT_PTR];
592 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
593 if (linked_fe->m_inuse)
595 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
596 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
599 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
605 eDebugNoSimulate("close frontend %d", m_dvbid);
606 if (m_data[SATCR] != -1)
610 m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
611 m_tuneTimer->start(0, true);
612 if(!m_tuneTimer->isActive())
615 eDebug("[turnOffSatCR] no mainloop");
618 timeout = tuneLoopInt();
621 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
625 eDebug("[turnOffSatCR] running mainloop");
629 m_data[ROTOR_CMD] = -1;
632 setTone(iDVBFrontend::toneOff);
633 setVoltage(iDVBFrontend::voltageOff);
636 if (m_sec && !m_simulate)
637 m_sec->setRotorMoving(m_slotid, false);
641 eWarning("couldnt close frontend %d", m_dvbid);
645 setTone(iDVBFrontend::toneOff);
646 setVoltage(iDVBFrontend::voltageOff);
648 #if HAVE_DVB_API_VERSION < 3
651 if (!::close(m_secfd))
654 eWarning("couldnt close sec %d", m_dvbid);
658 m_state = stateClosed;
663 eDVBFrontend::~eDVBFrontend()
665 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
669 void eDVBFrontend::feEvent(int w)
671 eDVBFrontend *sec_fe = this;
672 long tmp = m_data[LINKED_PREV_PTR];
675 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
676 sec_fe = linked_fe->m_frontend;
677 sec_fe->getData(LINKED_NEXT_PTR, tmp);
681 #if HAVE_DVB_API_VERSION < 3
684 dvb_frontend_event event;
688 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
690 if (res && (errno == EAGAIN))
696 #if HAVE_DVB_API_VERSION < 3
697 if (event.type == FE_COMPLETION_EV)
699 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
700 if (event.status & FE_HAS_LOCK)
708 #if HAVE_DVB_API_VERSION >= 3
709 if (event.status & FE_TIMEDOUT) {
710 eDebug("FE_TIMEDOUT! ..abort");
723 eDebug("stateLostLock");
724 state = stateLostLock;
726 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
729 if (m_state != state)
732 m_stateChanged(this);
737 void eDVBFrontend::timeout()
740 if (m_state == stateTuning)
742 m_state = stateFailed;
743 m_stateChanged(this);
747 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
749 /* unsigned 32 bit division */
750 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
752 return (a + b / 2) / b;
755 int eDVBFrontend::readFrontendData(int type)
764 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
765 eDebug("FE_READ_BER failed (%m)");
770 case signalQualitydB: /* this will move into the driver */
772 int sat_max = 1600; // for stv0288 / bsbe2
773 int ret = 0x12345678;
777 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
778 eDebug("FE_READ_SNR failed (%m)");
779 else if (!strcmp(m_description, "BCM4501 (internal)"))
781 float SDS_SNRE = snr << 16;
784 if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
786 static float SNR_COEFF[6] = {
789 197418.0 / 4194304.0,
790 -2602183.0 / 4194304.0,
791 20377212.0 / 4194304.0,
792 -37791203.0 / 4194304.0,
794 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
795 fval2 = pow(10.0, fval1)-1;
796 fval1 = 10.0 * log10(fval2);
800 fval2 = SNR_COEFF[0];
801 for (int i=1; i<6; ++i)
804 fval2 += SNR_COEFF[i];
810 #if HAVE_DVB_API_VERSION >= 3
813 float fval1 = SDS_SNRE / 268435456.0,
816 if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
827 fval4 = -10.0 * log10(fval1);
829 for (int i=0; i < 5; ++i)
830 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
835 ret = (int)(snr_in_db * 100);
837 else if (strstr(m_description, "Alps BSBE1 C01A") ||
838 strstr(m_description, "Alps -S(STV0288)"))
842 else if (snr == 0xFFFF) // i think this should not happen
846 enum { REALVAL, REGVAL };
847 const long CN_lookup[31][2] = {
848 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
849 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
850 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
851 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
852 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
853 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
856 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
857 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
861 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
866 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
871 ret = (((regval - CN_lookup[Imin][REGVAL])
872 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
873 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
874 + CN_lookup[Imin][REALVAL]) * 10;
880 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
881 !strcmp(m_description, "Alps -S") ||
882 !strcmp(m_description, "Philips -S") ||
883 !strcmp(m_description, "LG -S") )
886 ret = (int)((snr-39075)/17.647);
887 } else if (!strcmp(m_description, "Alps BSBE2"))
889 ret = (int)((snr >> 7) * 10);
890 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
892 int mse = (~snr) & 0xFF;
893 switch (parm_u_qam_modulation) {
894 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
895 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
896 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
897 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
898 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
901 } else if (!strcmp(m_description, "Philips TU1216"))
903 snr = 0xFF - (snr & 0xFF);
905 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
907 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
908 ret = (snr * 100) >> 8;
909 else if (!strcmp(m_description, "CXD1981"))
911 int mse = (~snr) & 0xFF;
912 switch (parm_u_qam_modulation) {
915 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
917 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
923 if (type == signalQuality)
925 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
930 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
931 case feCable: // we assume a max of 42db here
932 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
933 case feTerrestrial: // we assume a max of 24db here
934 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
938 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
946 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
947 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
953 #if HAVE_DVB_API_VERSION < 3
954 FrontendStatus status=0;
960 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
961 eDebug("FE_READ_STATUS failed (%m)");
962 return !!(status&FE_HAS_LOCK);
968 #if HAVE_DVB_API_VERSION < 3
969 FrontendStatus status=0;
975 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
976 eDebug("FE_READ_STATUS failed (%m)");
977 return !!(status&FE_HAS_SYNC);
987 void PutToDict(ePyObject &dict, const char*key, long value)
989 ePyObject item = PyInt_FromLong(value);
992 if (PyDict_SetItemString(dict, key, item))
993 eDebug("put %s to dict failed", key);
997 eDebug("could not create PyObject for %s", key);
1000 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1004 if (PyDict_SetItemString(dict, key, item))
1005 eDebug("put %s to dict failed", key);
1009 eDebug("invalid PyObject for %s", key);
1012 void PutToDict(ePyObject &dict, const char*key, const char *value)
1014 ePyObject item = PyString_FromString(value);
1017 if (PyDict_SetItemString(dict, key, item))
1018 eDebug("put %s to dict failed", key);
1022 eDebug("could not create PyObject for %s", key);
1025 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1027 PutToDict(dict, "tuner_type", "DVB-S");
1028 PutToDict(dict, "frequency", feparm.frequency);
1029 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1030 PutToDict(dict, "orbital_position", feparm.orbital_position);
1031 PutToDict(dict, "inversion", feparm.inversion);
1032 PutToDict(dict, "fec_inner", feparm.fec);
1033 PutToDict(dict, "modulation", feparm.modulation);
1034 PutToDict(dict, "polarization", feparm.polarisation);
1035 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1037 PutToDict(dict, "rolloff", feparm.rolloff);
1038 PutToDict(dict, "pilot", feparm.pilot);
1040 PutToDict(dict, "system", feparm.system);
1043 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1045 PutToDict(dict, "tuner_type", "DVB-T");
1046 PutToDict(dict, "frequency", feparm.frequency);
1047 PutToDict(dict, "bandwidth", feparm.bandwidth);
1048 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1049 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1050 PutToDict(dict, "constellation", feparm.modulation);
1051 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1052 PutToDict(dict, "guard_interval", feparm.guard_interval);
1053 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1054 PutToDict(dict, "inversion", feparm.inversion);
1057 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1059 PutToDict(dict, "tuner_type", "DVB-C");
1060 PutToDict(dict, "frequency", feparm.frequency);
1061 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1062 PutToDict(dict, "modulation", feparm.modulation);
1063 PutToDict(dict, "inversion", feparm.inversion);
1064 PutToDict(dict, "fec_inner", feparm.fec_inner);
1067 #if HAVE_DVB_API_VERSION >= 5
1068 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1071 int frequency = parm_frequency + freq_offset;
1072 PutToDict(dict, "frequency", frequency);
1073 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1074 PutToDict(dict, "orbital_position", orb_pos);
1075 PutToDict(dict, "polarization", polarization);
1077 switch(parm_u_qpsk_fec_inner)
1079 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1080 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1081 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1082 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1083 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1084 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1085 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1086 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1087 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1088 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1089 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1090 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1092 PutToDict(dict, "fec_inner", tmp);
1094 switch (p[0].u.data)
1096 default: eDebug("got unsupported system from frontend! report as DVBS!");
1097 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1100 switch (p[2].u.data)
1102 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1103 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1104 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1105 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1107 PutToDict(dict, "rolloff", tmp);
1109 switch (p[3].u.data)
1111 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1112 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1113 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1115 PutToDict(dict, "pilot", tmp);
1117 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1120 PutToDict(dict, "system", tmp);
1122 switch (p[1].u.data)
1124 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1125 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1126 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1128 PutToDict(dict, "modulation", tmp);
1132 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1135 int frequency = parm_frequency + freq_offset;
1136 PutToDict(dict, "frequency", frequency);
1137 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1138 PutToDict(dict, "orbital_position", orb_pos);
1139 PutToDict(dict, "polarization", polarization);
1141 switch((int)parm_u_qpsk_fec_inner)
1143 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1144 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1145 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1146 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1147 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1148 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1150 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1151 #if HAVE_DVB_API_VERSION >=3
1152 case FEC_S2_8PSK_1_2:
1153 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1154 case FEC_S2_8PSK_2_3:
1155 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1156 case FEC_S2_8PSK_3_4:
1157 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1158 case FEC_S2_8PSK_5_6:
1159 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1160 case FEC_S2_8PSK_7_8:
1161 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1162 case FEC_S2_8PSK_8_9:
1163 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1164 case FEC_S2_8PSK_3_5:
1165 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1166 case FEC_S2_8PSK_4_5:
1167 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1168 case FEC_S2_8PSK_9_10:
1169 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1172 PutToDict(dict, "fec_inner", tmp);
1173 #if HAVE_DVB_API_VERSION >=3
1174 PutToDict(dict, "modulation",
1175 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1176 eDVBFrontendParametersSatellite::Modulation_8PSK :
1177 eDVBFrontendParametersSatellite::Modulation_QPSK );
1178 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1180 switch(parm_inversion & 0xc)
1182 default: // unknown rolloff
1183 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1184 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1185 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1187 PutToDict(dict, "rolloff", tmp);
1188 switch(parm_inversion & 0x30)
1190 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1191 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1192 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1194 PutToDict(dict, "pilot", tmp);
1195 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1198 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1200 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1201 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1203 PutToDict(dict, "system", tmp);
1207 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1210 #if HAVE_DVB_API_VERSION < 3
1211 PutToDict(dict, "frequency", parm_frequency);
1213 PutToDict(dict, "frequency", parm_frequency/1000);
1215 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1216 switch(parm_u_qam_fec_inner)
1218 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1219 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1220 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1221 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1222 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1223 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1224 #if HAVE_DVB_API_VERSION >= 3
1225 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1228 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1230 PutToDict(dict, "fec_inner", tmp);
1231 switch(parm_u_qam_modulation)
1233 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1234 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1235 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1236 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1237 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1239 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1241 PutToDict(dict, "modulation", tmp);
1244 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1247 PutToDict(dict, "frequency", parm_frequency);
1248 switch (parm_u_ofdm_bandwidth)
1250 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1251 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1252 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1254 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1256 PutToDict(dict, "bandwidth", tmp);
1257 switch (parm_u_ofdm_code_rate_LP)
1259 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1260 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1261 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1262 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1263 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1265 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1267 PutToDict(dict, "code_rate_lp", tmp);
1268 switch (parm_u_ofdm_code_rate_HP)
1270 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1271 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1272 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1273 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1274 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1276 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1278 PutToDict(dict, "code_rate_hp", tmp);
1279 switch (parm_u_ofdm_constellation)
1281 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1282 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1283 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1285 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1287 PutToDict(dict, "constellation", tmp);
1288 switch (parm_u_ofdm_transmission_mode)
1290 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1291 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1293 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1295 PutToDict(dict, "transmission_mode", tmp);
1296 switch (parm_u_ofdm_guard_interval)
1298 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1299 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1300 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1301 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1303 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1305 PutToDict(dict, "guard_interval", tmp);
1306 switch (parm_u_ofdm_hierarchy_information)
1308 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1309 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1310 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1311 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1313 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1315 PutToDict(dict, "hierarchy_information", tmp);
1318 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1320 if (dest && PyDict_Check(dest))
1322 const char *tmp = "UNKNOWN";
1343 PutToDict(dest, "tuner_state", tmp);
1344 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1345 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1346 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1347 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1348 int sigQualitydB = readFrontendData(signalQualitydB);
1349 if (sigQualitydB == 0x12345678) // not support yet
1351 ePyObject obj=Py_None;
1353 PutToDict(dest, "tuner_signal_quality_db", obj);
1356 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1357 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1361 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1363 if (dest && PyDict_Check(dest))
1365 FRONTENDPARAMETERS front;
1366 #if HAVE_DVB_API_VERSION >= 5
1367 struct dtv_property p[4];
1368 struct dtv_properties cmdseq;
1371 p[0].cmd = DTV_DELIVERY_SYSTEM;
1372 p[1].cmd = DTV_MODULATION;
1373 p[2].cmd = DTV_ROLLOFF;
1374 p[3].cmd = DTV_PILOT;
1376 if (m_simulate || m_fd == -1 || original)
1378 #if HAVE_DVB_API_VERSION >= 5
1379 else if (m_type == feSatellite && // yet just use new api for DVB-S(2) only
1380 ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1382 eDebug("FE_GET_PROPERTY failed (%m)");
1386 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1388 eDebug("FE_GET_FRONTEND failed (%m)");
1396 PutSatelliteDataToDict(dest, oparm.sat);
1399 PutCableDataToDict(dest, oparm.cab);
1402 PutTerrestrialDataToDict(dest, oparm.ter);
1408 FRONTENDPARAMETERS &parm = front;
1409 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1410 switch(parm_inversion & 3)
1413 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1416 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1420 PutToDict(dest, "inversion", tmp);
1424 #if HAVE_DVB_API_VERSION >= 5
1425 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1427 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1431 fillDictWithCableData(dest, parm);
1434 fillDictWithTerrestrialData(dest, parm);
1441 void eDVBFrontend::getFrontendData(ePyObject dest)
1443 if (dest && PyDict_Check(dest))
1446 PutToDict(dest, "tuner_number", m_slotid);
1462 PutToDict(dest, "tuner_type", tmp);
1466 #ifndef FP_IOCTL_GET_ID
1467 #define FP_IOCTL_GET_ID 0
1469 int eDVBFrontend::readInputpower()
1473 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1475 char proc_name2[64];
1476 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1477 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1479 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1481 if (fscanf(f, "%d", &power) != 1)
1482 eDebug("read %s failed!! (%m)", proc_name);
1484 eDebug("%s is %d\n", proc_name, power);
1489 // open front prozessor
1490 int fp=::open("/dev/dbox/fp0", O_RDWR);
1493 eDebug("couldn't open fp");
1496 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1497 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1499 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1508 bool eDVBFrontend::setSecSequencePos(int steps)
1510 eDebugNoSimulate("set sequence pos %d", steps);
1515 if (m_sec_sequence.current() != m_sec_sequence.end())
1516 ++m_sec_sequence.current();
1521 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1522 --m_sec_sequence.current();
1528 void eDVBFrontend::tuneLoop()
1533 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1536 eDVBFrontend *sec_fe = this;
1537 eDVBRegisteredFrontend *regFE = 0;
1538 long tmp = m_data[LINKED_PREV_PTR];
1541 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1542 sec_fe = prev->m_frontend;
1543 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1544 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1545 int state = sec_fe->m_state;
1546 // workaround to put the kernel frontend thread into idle state!
1547 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1549 sec_fe->closeFrontend(true);
1550 state = sec_fe->m_state;
1552 // sec_fe is closed... we must reopen it here..
1553 if (state == stateClosed)
1561 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1563 long *sec_fe_data = sec_fe->m_data;
1564 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1566 switch (m_sec_sequence.current()->cmd)
1568 case eSecCommand::SLEEP:
1569 delay = m_sec_sequence.current()++->msec;
1570 eDebugNoSimulate("[SEC] sleep %dms", delay);
1572 case eSecCommand::GOTO:
1573 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1574 ++m_sec_sequence.current();
1576 case eSecCommand::SET_VOLTAGE:
1578 int voltage = m_sec_sequence.current()++->voltage;
1579 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1580 sec_fe->setVoltage(voltage);
1583 case eSecCommand::IF_VOLTAGE_GOTO:
1585 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1586 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1588 ++m_sec_sequence.current();
1591 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1593 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1594 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1596 ++m_sec_sequence.current();
1599 case eSecCommand::IF_TONE_GOTO:
1601 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1602 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1604 ++m_sec_sequence.current();
1607 case eSecCommand::IF_NOT_TONE_GOTO:
1609 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1610 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1612 ++m_sec_sequence.current();
1615 case eSecCommand::SET_TONE:
1616 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1617 sec_fe->setTone(m_sec_sequence.current()++->tone);
1619 case eSecCommand::SEND_DISEQC:
1620 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1621 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1622 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1623 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1624 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1625 eDebugNoSimulate("(DiSEqC reset)");
1626 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1627 eDebugNoSimulate("(DiSEqC peripherial power on)");
1629 eDebugNoSimulate("");
1630 ++m_sec_sequence.current();
1632 case eSecCommand::SEND_TONEBURST:
1633 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1634 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1636 case eSecCommand::SET_FRONTEND:
1638 int enableEvents = (m_sec_sequence.current()++)->val;
1639 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1640 setFrontend(enableEvents);
1643 case eSecCommand::START_TUNE_TIMEOUT:
1645 int tuneTimeout = m_sec_sequence.current()->timeout;
1646 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1648 m_timeout->start(tuneTimeout, 1);
1649 ++m_sec_sequence.current();
1652 case eSecCommand::SET_TIMEOUT:
1653 m_timeoutCount = m_sec_sequence.current()++->val;
1654 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1656 case eSecCommand::IF_TIMEOUT_GOTO:
1657 if (!m_timeoutCount)
1659 eDebugNoSimulate("[SEC] rotor timout");
1660 setSecSequencePos(m_sec_sequence.current()->steps);
1663 ++m_sec_sequence.current();
1665 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1667 int idx = m_sec_sequence.current()++->val;
1668 if ( idx == 0 || idx == 1 )
1670 m_idleInputpower[idx] = sec_fe->readInputpower();
1671 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1674 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1677 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1679 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1680 int idx = compare.val;
1681 if ( !m_simulate && (idx == 0 || idx == 1) )
1683 int idle = sec_fe->readInputpower();
1684 int diff = abs(idle-m_idleInputpower[idx]);
1687 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1688 setSecSequencePos(compare.steps);
1692 ++m_sec_sequence.current();
1695 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1697 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1700 setSecSequencePos(cmd.steps);
1704 int isLocked = readFrontendData(locked);
1705 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1707 if (!m_timeoutCount && m_retryCount > 0)
1709 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1712 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1715 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1717 cmd.lastSignal = signal;
1720 if (cmd.okcount > 4)
1722 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1723 setSecSequencePos(cmd.steps);
1724 m_state = stateLock;
1725 m_stateChanged(this);
1726 feEvent(-1); // flush events
1734 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1736 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1740 ++m_sec_sequence.current();
1743 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1744 m_runningInputpower = sec_fe->readInputpower();
1745 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
1746 ++m_sec_sequence.current();
1748 case eSecCommand::SET_ROTOR_MOVING:
1750 m_sec->setRotorMoving(m_slotid, true);
1751 ++m_sec_sequence.current();
1753 case eSecCommand::SET_ROTOR_STOPPED:
1755 m_sec->setRotorMoving(m_slotid, false);
1756 ++m_sec_sequence.current();
1758 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1760 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1763 setSecSequencePos(cmd.steps);
1766 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
1767 const char *txt = cmd.direction ? "running" : "stopped";
1769 if (!m_timeoutCount && m_retryCount > 0)
1771 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1773 m_runningInputpower,
1776 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1777 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1780 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1781 if ( cmd.okcount > 6 )
1783 eDebugNoSimulate("[SEC] rotor is %s", txt);
1784 if (setSecSequencePos(cmd.steps))
1790 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1793 ++m_sec_sequence.current();
1796 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1797 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
1798 setSecSequencePos(m_sec_sequence.current()->steps);
1800 ++m_sec_sequence.current();
1802 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
1803 eDebugNoSimulate("[SEC] invalidate current switch params");
1804 sec_fe_data[CSW] = -1;
1805 sec_fe_data[UCSW] = -1;
1806 sec_fe_data[TONEBURST] = -1;
1807 ++m_sec_sequence.current();
1809 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
1810 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
1811 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
1812 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
1813 eDebugNoSimulate("[SEC] update current switch params");
1814 ++m_sec_sequence.current();
1816 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1817 eDebugNoSimulate("[SEC] invalidate current rotorparams");
1818 sec_fe_data[ROTOR_CMD] = -1;
1819 sec_fe_data[ROTOR_POS] = -1;
1820 ++m_sec_sequence.current();
1822 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1823 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
1824 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
1825 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
1826 ++m_sec_sequence.current();
1828 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1829 m_retryCount = m_sec_sequence.current()++->val;
1830 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
1832 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1835 eDebugNoSimulate("[SEC] no more rotor retrys");
1836 setSecSequencePos(m_sec_sequence.current()->steps);
1839 ++m_sec_sequence.current();
1841 case eSecCommand::SET_POWER_LIMITING_MODE:
1846 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
1847 FILE *f=fopen(proc_name, "w");
1848 if (f) // new interface exist?
1850 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1851 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1852 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
1854 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1857 else if (sec_fe->m_need_rotor_workaround)
1860 int slotid = sec_fe->m_slotid;
1861 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1863 sprintf(dev, "/dev/i2c/%d", slotid);
1864 else if (slotid == 2)
1865 sprintf(dev, "/dev/i2c/2"); // first nim socket on DM8000 use /dev/i2c/2
1866 else if (slotid == 3)
1867 sprintf(dev, "/dev/i2c/4"); // second nim socket on DM8000 use /dev/i2c/4
1868 int fd = ::open(dev, O_RDWR);
1870 unsigned char data[2];
1871 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1872 if(::read(fd, data, 1) != 1)
1873 eDebugNoSimulate("[SEC] error read lnbp (%m)");
1874 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
1876 data[0] |= 0x80; // enable static current limiting
1877 eDebugNoSimulate("[SEC] set static current limiting");
1881 data[0] &= ~0x80; // enable dynamic current limiting
1882 eDebugNoSimulate("[SEC] set dynamic current limiting");
1884 if(::write(fd, data, 1) != 1)
1885 eDebugNoSimulate("[SEC] error write lnbp (%m)");
1889 ++m_sec_sequence.current();
1892 case eSecCommand::DELAYED_CLOSE_FRONTEND:
1894 eDebugNoSimulate("[SEC] delayed close frontend");
1895 closeFrontend(false, true);
1896 ++m_sec_sequence.current();
1900 eDebugNoSimulate("[SEC] unhandled sec command %d",
1901 ++m_sec_sequence.current()->cmd);
1902 ++m_sec_sequence.current();
1905 m_tuneTimer->start(delay,true);
1909 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
1914 void eDVBFrontend::setFrontend(bool recvEvents)
1918 eDebug("setting frontend %d", m_dvbid);
1921 feEvent(-1); // flush events
1922 #if HAVE_DVB_API_VERSION >= 5
1923 if (m_type == iDVBFrontend::feSatellite)
1925 fe_rolloff_t rolloff = ROLLOFF_35;
1926 fe_pilot_t pilot = PILOT_OFF;
1927 fe_modulation_t modulation = QPSK;
1928 fe_delivery_system_t system = SYS_DVBS;
1929 switch(oparm.sat.system)
1931 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
1932 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
1934 switch(oparm.sat.modulation)
1936 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
1937 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
1938 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
1940 switch(oparm.sat.pilot)
1942 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
1943 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
1944 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
1946 switch(oparm.sat.rolloff)
1948 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
1949 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
1950 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
1952 struct dtv_property p[10];
1953 struct dtv_properties cmdseq;
1955 p[0].cmd = DTV_CLEAR;
1956 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1957 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
1958 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
1959 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
1960 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
1961 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
1962 if (system == SYS_DVBS2)
1964 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
1965 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
1966 p[9].cmd = DTV_TUNE;
1971 p[7].cmd = DTV_TUNE;
1974 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
1976 perror("FE_SET_PROPERTY failed");
1983 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
1985 perror("FE_SET_FRONTEND failed");
1992 RESULT eDVBFrontend::getFrontendType(int &t)
2000 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2005 eWarning("no SEC module active!");
2008 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2011 #if HAVE_DVB_API_VERSION >= 3
2012 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",
2015 feparm.polarisation,
2019 feparm.orbital_position,
2025 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2028 feparm.polarisation,
2032 feparm.orbital_position);
2034 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2035 switch (feparm.inversion)
2037 case eDVBFrontendParametersSatellite::Inversion_On:
2038 parm_inversion = INVERSION_ON;
2040 case eDVBFrontendParametersSatellite::Inversion_Off:
2041 parm_inversion = INVERSION_OFF;
2044 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2045 parm_inversion = INVERSION_AUTO;
2048 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2052 case eDVBFrontendParametersSatellite::FEC_None:
2053 parm_u_qpsk_fec_inner = FEC_NONE;
2055 case eDVBFrontendParametersSatellite::FEC_1_2:
2056 parm_u_qpsk_fec_inner = FEC_1_2;
2058 case eDVBFrontendParametersSatellite::FEC_2_3:
2059 parm_u_qpsk_fec_inner = FEC_2_3;
2061 case eDVBFrontendParametersSatellite::FEC_3_4:
2062 parm_u_qpsk_fec_inner = FEC_3_4;
2064 case eDVBFrontendParametersSatellite::FEC_5_6:
2065 parm_u_qpsk_fec_inner = FEC_5_6;
2067 case eDVBFrontendParametersSatellite::FEC_7_8:
2068 parm_u_qpsk_fec_inner = FEC_7_8;
2071 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2072 case eDVBFrontendParametersSatellite::FEC_Auto:
2073 parm_u_qpsk_fec_inner = FEC_AUTO;
2077 #if HAVE_DVB_API_VERSION >= 3
2082 case eDVBFrontendParametersSatellite::FEC_1_2:
2083 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2085 case eDVBFrontendParametersSatellite::FEC_2_3:
2086 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2088 case eDVBFrontendParametersSatellite::FEC_3_4:
2089 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2091 case eDVBFrontendParametersSatellite::FEC_3_5:
2092 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2094 case eDVBFrontendParametersSatellite::FEC_4_5:
2095 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2097 case eDVBFrontendParametersSatellite::FEC_5_6:
2098 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2100 case eDVBFrontendParametersSatellite::FEC_7_8:
2101 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2103 case eDVBFrontendParametersSatellite::FEC_8_9:
2104 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2106 case eDVBFrontendParametersSatellite::FEC_9_10:
2107 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2110 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2113 #if HAVE_DVB_API_VERSION < 5
2114 parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff
2115 parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot
2116 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2118 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2119 // 8PSK fec driver values are decimal 9 bigger
2124 // FIXME !!! get frequency range from tuner
2125 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2127 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2130 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2136 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2138 #if HAVE_DVB_API_VERSION < 3
2139 parm_frequency = feparm.frequency;
2141 parm_frequency = feparm.frequency * 1000;
2143 parm_u_qam_symbol_rate = feparm.symbol_rate;
2144 switch (feparm.modulation)
2146 case eDVBFrontendParametersCable::Modulation_QAM16:
2147 parm_u_qam_modulation = QAM_16;
2149 case eDVBFrontendParametersCable::Modulation_QAM32:
2150 parm_u_qam_modulation = QAM_32;
2152 case eDVBFrontendParametersCable::Modulation_QAM64:
2153 parm_u_qam_modulation = QAM_64;
2155 case eDVBFrontendParametersCable::Modulation_QAM128:
2156 parm_u_qam_modulation = QAM_128;
2158 case eDVBFrontendParametersCable::Modulation_QAM256:
2159 parm_u_qam_modulation = QAM_256;
2162 case eDVBFrontendParametersCable::Modulation_Auto:
2163 parm_u_qam_modulation = QAM_AUTO;
2166 switch (feparm.inversion)
2168 case eDVBFrontendParametersCable::Inversion_On:
2169 parm_inversion = INVERSION_ON;
2171 case eDVBFrontendParametersCable::Inversion_Off:
2172 parm_inversion = INVERSION_OFF;
2175 case eDVBFrontendParametersCable::Inversion_Unknown:
2176 parm_inversion = INVERSION_AUTO;
2179 switch (feparm.fec_inner)
2181 case eDVBFrontendParametersCable::FEC_None:
2182 parm_u_qam_fec_inner = FEC_NONE;
2184 case eDVBFrontendParametersCable::FEC_1_2:
2185 parm_u_qam_fec_inner = FEC_1_2;
2187 case eDVBFrontendParametersCable::FEC_2_3:
2188 parm_u_qam_fec_inner = FEC_2_3;
2190 case eDVBFrontendParametersCable::FEC_3_4:
2191 parm_u_qam_fec_inner = FEC_3_4;
2193 case eDVBFrontendParametersCable::FEC_5_6:
2194 parm_u_qam_fec_inner = FEC_5_6;
2196 case eDVBFrontendParametersCable::FEC_7_8:
2197 parm_u_qam_fec_inner = FEC_7_8;
2199 #if HAVE_DVB_API_VERSION >= 3
2200 case eDVBFrontendParametersCable::FEC_8_9:
2201 parm_u_qam_fec_inner = FEC_8_9;
2205 case eDVBFrontendParametersCable::FEC_Auto:
2206 parm_u_qam_fec_inner = FEC_AUTO;
2209 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2210 parm_frequency/1000,
2211 parm_u_qam_symbol_rate,
2212 parm_u_qam_fec_inner,
2213 parm_u_qam_modulation,
2219 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2221 parm_frequency = feparm.frequency;
2223 switch (feparm.bandwidth)
2225 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2226 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2228 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2229 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2231 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2232 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2235 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2236 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2239 switch (feparm.code_rate_LP)
2241 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2242 parm_u_ofdm_code_rate_LP = FEC_1_2;
2244 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2245 parm_u_ofdm_code_rate_LP = FEC_2_3;
2247 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2248 parm_u_ofdm_code_rate_LP = FEC_3_4;
2250 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2251 parm_u_ofdm_code_rate_LP = FEC_5_6;
2253 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2254 parm_u_ofdm_code_rate_LP = FEC_7_8;
2257 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2258 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2261 switch (feparm.code_rate_HP)
2263 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2264 parm_u_ofdm_code_rate_HP = FEC_1_2;
2266 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2267 parm_u_ofdm_code_rate_HP = FEC_2_3;
2269 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2270 parm_u_ofdm_code_rate_HP = FEC_3_4;
2272 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2273 parm_u_ofdm_code_rate_HP = FEC_5_6;
2275 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2276 parm_u_ofdm_code_rate_HP = FEC_7_8;
2279 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2280 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2283 switch (feparm.modulation)
2285 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2286 parm_u_ofdm_constellation = QPSK;
2288 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2289 parm_u_ofdm_constellation = QAM_16;
2291 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2292 parm_u_ofdm_constellation = QAM_64;
2295 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2296 parm_u_ofdm_constellation = QAM_AUTO;
2299 switch (feparm.transmission_mode)
2301 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2302 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2304 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2305 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2308 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2309 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2312 switch (feparm.guard_interval)
2314 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2315 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2317 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2318 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2320 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2321 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2323 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2324 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2327 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2328 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2331 switch (feparm.hierarchy)
2333 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2334 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2336 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2337 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2339 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2340 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2342 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2343 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2346 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2347 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2350 switch (feparm.inversion)
2352 case eDVBFrontendParametersTerrestrial::Inversion_On:
2353 parm_inversion = INVERSION_ON;
2355 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2356 parm_inversion = INVERSION_OFF;
2359 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2360 parm_inversion = INVERSION_AUTO;
2367 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2369 unsigned int timeout = 5000;
2370 eDebugNoSimulate("(%d)tune", m_dvbid);
2376 if (!m_sn && !m_simulate)
2378 eDebug("no frontend device opened... do not try to tune !!!");
2392 m_sec_sequence.clear();
2394 where.calcLockTimeout(timeout);
2400 eDVBFrontendParametersSatellite feparm;
2401 if (where.getDVBS(feparm))
2403 eDebug("no dvbs data!");
2407 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2409 eDVBFrontend *sec_fe = this;
2410 long tmp = m_data[LINKED_PREV_PTR];
2413 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2414 sec_fe = linked_fe->m_frontend;
2415 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2417 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2418 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
2420 m_rotor_mode = feparm.no_rotor_command_on_tune;
2422 m_sec->setRotorMoving(m_slotid, false);
2423 res=prepare_sat(feparm, timeout);
2431 eDVBFrontendParametersCable feparm;
2432 if (where.getDVBC(feparm))
2437 res=prepare_cable(feparm);
2441 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2442 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2447 eDVBFrontendParametersTerrestrial feparm;
2448 if (where.getDVBT(feparm))
2450 eDebug("no -T data");
2454 res=prepare_terrestrial(feparm);
2458 std::string enable_5V;
2459 char configStr[255];
2460 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2461 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2462 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2463 if (enable_5V == "True")
2464 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2466 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2467 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2473 m_sec_sequence.current() = m_sec_sequence.begin();
2477 m_tuneTimer->start(0,true);
2479 if (m_state != stateTuning)
2481 m_state = stateTuning;
2482 m_stateChanged(this);
2491 m_tuneTimer->stop();
2495 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2497 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2501 RESULT eDVBFrontend::setVoltage(int voltage)
2503 if (m_type == feCable)
2505 #if HAVE_DVB_API_VERSION < 3
2508 bool increased=false;
2509 fe_sec_voltage_t vlt;
2511 m_data[CUR_VOLTAGE]=voltage;
2515 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2516 vlt = SEC_VOLTAGE_OFF;
2519 #if HAVE_DVB_API_VERSION < 3
2520 vlt = SEC_VOLTAGE_13_5;
2526 vlt = SEC_VOLTAGE_13;
2529 #if HAVE_DVB_API_VERSION < 3
2530 vlt = SEC_VOLTAGE_18_5;
2536 vlt = SEC_VOLTAGE_18;
2543 #if HAVE_DVB_API_VERSION < 3
2544 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2546 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2547 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2548 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2552 RESULT eDVBFrontend::getState(int &state)
2558 RESULT eDVBFrontend::setTone(int t)
2560 if (m_type != feSatellite)
2562 #if HAVE_DVB_API_VERSION < 3
2565 fe_sec_tone_mode_t tone;
2574 tone = SEC_TONE_OFF;
2581 #if HAVE_DVB_API_VERSION < 3
2582 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2584 return ::ioctl(m_fd, FE_SET_TONE, tone);
2588 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2589 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2592 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2596 #if HAVE_DVB_API_VERSION < 3
2597 struct secCommand cmd;
2598 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
2599 cmd.u.diseqc.cmdtype = diseqc.data[0];
2600 cmd.u.diseqc.addr = diseqc.data[1];
2601 cmd.u.diseqc.cmd = diseqc.data[2];
2602 cmd.u.diseqc.numParams = diseqc.len-3;
2603 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
2604 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
2606 struct dvb_diseqc_master_cmd cmd;
2607 memcpy(cmd.msg, diseqc.data, diseqc.len);
2608 cmd.msg_len = diseqc.len;
2609 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2615 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
2616 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
2618 RESULT eDVBFrontend::sendToneburst(int burst)
2622 #if HAVE_DVB_API_VERSION < 3
2623 secMiniCmd cmd = SEC_MINI_NONE;
2625 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2627 if ( burst == eDVBSatelliteDiseqcParameters::A )
2629 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2631 #if HAVE_DVB_API_VERSION < 3
2632 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
2635 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2641 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2647 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
2649 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
2650 m_sec_sequence.push_back(list);
2652 m_sec_sequence = list;
2656 RESULT eDVBFrontend::getData(int num, long &data)
2658 if ( num < NUM_DATA_ENTRIES )
2666 RESULT eDVBFrontend::setData(int num, long val)
2668 if ( num < NUM_DATA_ENTRIES )
2676 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2679 if (feparm->getSystem(type) || type != m_type || !m_enabled)
2681 if (m_type == eDVBFrontend::feSatellite)
2684 eDVBFrontendParametersSatellite sat_parm;
2685 int ret = feparm->getDVBS(sat_parm);
2687 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
2689 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
2690 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
2694 else if (m_type == eDVBFrontend::feCable)
2695 return 2; // more prio for cable frontends
2696 else if (m_type == eDVBFrontend::feTerrestrial)
2701 bool eDVBFrontend::setSlotInfo(ePyObject obj)
2703 ePyObject Id, Descr, Enabled, IsDVBS2, frontendId;
2704 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5)
2706 Id = PyTuple_GET_ITEM(obj, 0);
2707 Descr = PyTuple_GET_ITEM(obj, 1);
2708 Enabled = PyTuple_GET_ITEM(obj, 2);
2709 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
2710 frontendId = PyTuple_GET_ITEM(obj, 4);
2711 m_slotid = PyInt_AsLong(Id);
2712 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId))
2714 strcpy(m_description, PyString_AS_STRING(Descr));
2715 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
2716 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
2717 // m_slotid, m_description);
2720 m_enabled = Enabled == Py_True;
2721 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
2722 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
2723 !!strstr(m_description, "Alps BSBE2") ||
2724 !!strstr(m_description, "Alps -S") ||
2725 !!strstr(m_description, "BCM4501");
2726 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
2727 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s",
2728 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" );
2731 PyErr_SetString(PyExc_StandardError,
2732 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");