1 #include <lib/dvb/dvb.h>
2 #include <lib/base/eerror.h>
3 #include <lib/base/nconfig.h> // access to python config
9 #ifndef I2C_SLAVE_FORCE
10 #define I2C_SLAVE_FORCE 0x0706
13 #if HAVE_DVB_API_VERSION < 3
14 #include <ost/frontend.h>
16 #define QAM_AUTO (Modulation)6
17 #define TRANSMISSION_MODE_AUTO (TransmitMode)2
18 #define BANDWIDTH_AUTO (BandWidth)3
19 #define GUARD_INTERVAL_AUTO (GuardInterval)4
20 #define HIERARCHY_AUTO (Hierarchy)4
21 #define parm_frequency parm.Frequency
22 #define parm_inversion parm.Inversion
23 #define parm_u_qpsk_symbol_rate parm.u.qpsk.SymbolRate
24 #define parm_u_qpsk_fec_inner parm.u.qpsk.FEC_inner
25 #define parm_u_qam_symbol_rate parm.u.qam.SymbolRate
26 #define parm_u_qam_fec_inner parm.u.qam.FEC_inner
27 #define parm_u_qam_modulation parm.u.qam.QAM
28 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandWidth
29 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.LP_CodeRate
30 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.HP_CodeRate
31 #define parm_u_ofdm_constellation parm.u.ofdm.Constellation
32 #define parm_u_ofdm_transmission_mode parm.u.ofdm.TransmissionMode
33 #define parm_u_ofdm_guard_interval parm.u.ofdm.guardInterval
34 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.HierarchyInformation
36 #include <linux/dvb/frontend.h>
37 #define parm_frequency parm.frequency
38 #define parm_inversion parm.inversion
39 #define parm_u_qpsk_symbol_rate parm.u.qpsk.symbol_rate
40 #define parm_u_qpsk_fec_inner parm.u.qpsk.fec_inner
41 #define parm_u_qam_symbol_rate parm.u.qam.symbol_rate
42 #define parm_u_qam_fec_inner parm.u.qam.fec_inner
43 #define parm_u_qam_modulation parm.u.qam.modulation
44 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandwidth
45 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.code_rate_LP
46 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.code_rate_HP
47 #define parm_u_ofdm_constellation parm.u.ofdm.constellation
48 #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode
49 #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval
50 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information
52 #warning "FEC_9_10 already exist in dvb api ... it seems it is now ready for DVB-S2"
54 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1)
55 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1)
56 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_S2_QPSK_2_3+1)
57 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_S2_QPSK_3_4+1)
58 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_S2_QPSK_5_6+1)
59 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_S2_QPSK_7_8+1)
60 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_S2_QPSK_8_9+1)
61 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_S2_QPSK_3_5+1)
62 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_S2_QPSK_4_5+1)
63 #define FEC_S2_8PSK_1_2 (fe_code_rate_t)(FEC_S2_QPSK_9_10+1)
64 #define FEC_S2_8PSK_2_3 (fe_code_rate_t)(FEC_S2_8PSK_1_2+1)
65 #define FEC_S2_8PSK_3_4 (fe_code_rate_t)(FEC_S2_8PSK_2_3+1)
66 #define FEC_S2_8PSK_5_6 (fe_code_rate_t)(FEC_S2_8PSK_3_4+1)
67 #define FEC_S2_8PSK_7_8 (fe_code_rate_t)(FEC_S2_8PSK_5_6+1)
68 #define FEC_S2_8PSK_8_9 (fe_code_rate_t)(FEC_S2_8PSK_7_8+1)
69 #define FEC_S2_8PSK_3_5 (fe_code_rate_t)(FEC_S2_8PSK_8_9+1)
70 #define FEC_S2_8PSK_4_5 (fe_code_rate_t)(FEC_S2_8PSK_3_5+1)
71 #define FEC_S2_8PSK_9_10 (fe_code_rate_t)(FEC_S2_8PSK_4_5+1)
75 #include <dvbsi++/satellite_delivery_system_descriptor.h>
76 #include <dvbsi++/cable_delivery_system_descriptor.h>
77 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
79 void eDVBDiseqcCommand::setCommandString(const char *str)
84 int slen = strlen(str);
87 eDebug("invalid diseqc command string length (not 2 byte aligned)");
90 if (slen > MAX_DISEQC_LENGTH*2)
92 eDebug("invalid diseqc command string length (string is to long)");
96 for (int i=0; i < slen; ++i)
98 unsigned char c = str[i];
101 case '0' ... '9': c-=48; break;
102 case 'a' ... 'f': c-=87; break;
103 case 'A' ... 'F': c-=55; break;
105 eDebug("invalid character in hex string..ignore complete diseqc command !");
119 void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescriptor &descriptor)
121 frequency = descriptor.getFrequency() * 10;
122 symbol_rate = descriptor.getSymbolRate() * 100;
123 polarisation = descriptor.getPolarization();
124 fec = descriptor.getFecInner();
125 if ( fec != FEC::fNone && fec > FEC::f9_10 )
127 inversion = Inversion::Unknown;
128 pilot = Pilot::Unknown;
129 orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
130 orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
131 orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
132 orbital_position += ((descriptor.getOrbitalPosition()) & 0xF);
133 if (orbital_position && (!descriptor.getWestEastFlag()))
134 orbital_position = 3600 - orbital_position;
135 system = descriptor.getModulationSystem();
136 modulation = descriptor.getModulation();
137 if (system == System::DVB_S && modulation == Modulation::M8PSK)
139 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
142 rolloff = descriptor.getRollOff();
143 if (system == System::DVB_S2)
145 eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
147 polarisation ? "hor" : "vert",
155 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
157 polarisation ? "hor" : "vert",
163 void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descriptor)
165 frequency = descriptor.getFrequency() / 10;
166 symbol_rate = descriptor.getSymbolRate() * 100;
167 fec_inner = descriptor.getFecInner();
168 if ( fec_inner == 0xF )
169 fec_inner = FEC::fNone;
170 modulation = descriptor.getModulation();
171 if ( modulation > 0x5 )
172 modulation = Modulation::Auto;
173 inversion = Inversion::Unknown;
174 eDebug("Cable freq %d, mod %d, sr %d, fec %d",
176 modulation, symbol_rate, fec_inner);
179 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
181 frequency = descriptor.getCentreFrequency() * 10;
182 bandwidth = descriptor.getBandwidth();
183 if ( bandwidth > 2 ) // 5Mhz forced to auto
184 bandwidth = Bandwidth::BwAuto;
185 code_rate_HP = descriptor.getCodeRateHpStream();
186 if (code_rate_HP > 4)
187 code_rate_HP = FEC::fAuto;
188 code_rate_LP = descriptor.getCodeRateLpStream();
189 if (code_rate_LP > 4)
190 code_rate_LP = FEC::fAuto;
191 transmission_mode = descriptor.getTransmissionMode();
192 if (transmission_mode > 1) // TM4k forced to auto
193 transmission_mode = TransmissionMode::TMAuto;
194 guard_interval = descriptor.getGuardInterval();
195 if (guard_interval > 3)
196 guard_interval = GuardInterval::GI_Auto;
197 hierarchy = descriptor.getHierarchyInformation()&3;
198 modulation = descriptor.getConstellation();
200 modulation = Modulation::Auto;
201 inversion = Inversion::Unknown;
202 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
203 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
204 guard_interval, hierarchy, modulation);
207 eDVBFrontendParameters::eDVBFrontendParameters(): m_type(-1)
211 DEFINE_REF(eDVBFrontendParameters);
213 RESULT eDVBFrontendParameters::getSystem(int &t) const
221 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
223 if (m_type != iDVBFrontend::feSatellite)
229 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
231 if (m_type != iDVBFrontend::feCable)
237 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
239 if (m_type != iDVBFrontend::feTerrestrial)
245 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
248 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
249 m_type = iDVBFrontend::feSatellite;
253 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
256 m_type = iDVBFrontend::feCable;
260 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
263 m_type = iDVBFrontend::feTerrestrial;
267 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
272 if (parm->getSystem(type))
276 diff = 1<<30; // big difference
282 case iDVBFrontend::feSatellite:
284 eDVBFrontendParametersSatellite osat;
285 if (parm->getDVBS(osat))
288 if (sat.orbital_position != osat.orbital_position)
290 else if (sat.polarisation != osat.polarisation)
292 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC::fAuto && osat.fec != eDVBFrontendParametersSatellite::FEC::fAuto)
294 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation::Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation::Auto)
298 diff = abs(sat.frequency - osat.frequency);
299 diff += abs(sat.symbol_rate - osat.symbol_rate);
303 case iDVBFrontend::feCable:
304 eDVBFrontendParametersCable ocable;
305 if (parm->getDVBC(ocable))
308 if (exact && cable.modulation != ocable.modulation
309 && cable.modulation != eDVBFrontendParametersCable::Modulation::Auto
310 && ocable.modulation != eDVBFrontendParametersCable::Modulation::Auto)
312 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC::fAuto && ocable.fec_inner != eDVBFrontendParametersCable::FEC::fAuto)
316 diff = abs(cable.frequency - ocable.frequency);
317 diff += abs(cable.symbol_rate - ocable.symbol_rate);
320 case iDVBFrontend::feTerrestrial:
321 eDVBFrontendParametersTerrestrial oterrestrial;
322 if (parm->getDVBT(oterrestrial))
326 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
327 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto &&
328 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto)
330 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
331 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation::Auto &&
332 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation::Auto)
334 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
335 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto &&
336 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto)
338 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
339 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto &&
340 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto)
342 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
343 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy::HAuto &&
344 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy::HAuto)
346 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
347 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC::fAuto &&
348 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC::fAuto)
350 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
351 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC::fAuto &&
352 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC::fAuto)
355 diff = abs(terrestrial.frequency - oterrestrial.frequency);
363 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
367 case iDVBFrontend::feSatellite:
369 hash = (sat.orbital_position << 16);
370 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
373 case iDVBFrontend::feCable:
375 hash |= (cable.frequency/1000)&0xFFFF;
377 case iDVBFrontend::feTerrestrial:
379 hash |= (terrestrial.frequency/1000)&0xFFFF;
386 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
390 case iDVBFrontend::feSatellite:
392 /* high symbol rate transponders tune faster, due to
393 requiring less zigzag and giving more symbols faster.
395 5s are definitely not enough on really low SR when
396 zigzag has to find the exact frequency first.
398 if (sat.symbol_rate > 20000000)
400 else if (sat.symbol_rate > 10000000)
406 case iDVBFrontend::feCable:
409 case iDVBFrontend::feTerrestrial:
417 DEFINE_REF(eDVBFrontend);
419 int eDVBFrontend::PriorityOrder=0;
421 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok)
422 :m_enabled(false), m_type(-1), m_dvbid(fe), m_slotid(fe)
423 ,m_fd(-1), m_need_rotor_workaround(false), m_can_handle_dvbs2(false)
424 ,m_sn(0), m_timeout(0), m_tuneTimer(0)
425 #if HAVE_DVB_API_VERSION < 3
429 #if HAVE_DVB_API_VERSION < 3
430 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
431 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
433 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
435 m_timeout = new eTimer(eApp);
436 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
438 m_tuneTimer = new eTimer(eApp);
439 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
441 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
444 m_idleInputpower[0]=m_idleInputpower[1]=0;
446 ok = !openFrontend();
450 int eDVBFrontend::openFrontend()
453 return -1; // already opened
458 #if HAVE_DVB_API_VERSION < 3
459 FrontendInfo fe_info;
461 dvb_frontend_info fe_info;
463 eDebug("opening frontend %d", m_dvbid);
466 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
469 eWarning("failed! (%s) %m", m_filename);
474 eWarning("frontend %d already opened", m_dvbid);
477 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
479 eWarning("ioctl FE_GET_INFO failed");
485 switch (fe_info.type)
488 m_type = iDVBFrontend::feSatellite;
491 m_type = iDVBFrontend::feCable;
494 m_type = iDVBFrontend::feTerrestrial;
497 eWarning("unknown frontend type.");
502 eDebug("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
505 #if HAVE_DVB_API_VERSION < 3
506 if (m_type == iDVBFrontend::feSatellite)
510 m_secfd = ::open(m_sec_filename, O_RDWR);
513 eWarning("failed! (%s) %m", m_sec_filename);
520 eWarning("sec %d already opened", m_dvbid);
524 setTone(iDVBFrontend::toneOff);
525 setVoltage(iDVBFrontend::voltageOff);
527 m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Read);
528 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
533 int eDVBFrontend::closeFrontend()
535 long tmp = m_data[LINKED_NEXT_PTR];
538 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
539 if (linked_fe->m_inuse)
541 eDebug("dont close frontend %d until the linked frontend %d in slot %d is still in use",
542 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
545 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
549 eDebug("close frontend %d", m_dvbid);
551 setTone(iDVBFrontend::toneOff);
552 setVoltage(iDVBFrontend::voltageOff);
554 m_sec->setRotorMoving(false);
558 eWarning("couldnt close frontend %d", m_dvbid);
559 m_data[CSW] = m_data[UCSW] = m_data[TONEBURST] = -1;
561 #if HAVE_DVB_API_VERSION < 3
564 if (!::close(m_secfd))
567 eWarning("couldnt close sec %d", m_dvbid);
576 eDVBFrontend::~eDVBFrontend()
578 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
584 void eDVBFrontend::feEvent(int w)
588 #if HAVE_DVB_API_VERSION < 3
591 dvb_frontend_event event;
595 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
597 if (res && (errno == EAGAIN))
602 eWarning("FE_GET_EVENT failed! %m");
609 #if HAVE_DVB_API_VERSION < 3
610 if (event.type == FE_COMPLETION_EV)
612 eDebug("(%d)fe event: status %x, inversion %s", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off");
613 if (event.status & FE_HAS_LOCK)
623 eDebug("stateLostLock");
624 state = stateLostLock;
625 m_data[CSW] = m_data[UCSW] = m_data[TONEBURST] = -1; // reset diseqc
628 if (m_state != state)
631 m_stateChanged(this);
636 void eDVBFrontend::timeout()
639 if (m_state == stateTuning)
641 m_state = stateFailed;
642 m_stateChanged(this);
646 int eDVBFrontend::readFrontendData(int type)
653 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
654 eDebug("FE_READ_BER failed (%m)");
660 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
661 eDebug("FE_READ_SNR failed (%m)");
664 case signalQualitydB: /* this will move into the driver */
667 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
668 eDebug("FE_READ_SNR failed (%m)");
669 if (!strcmp(m_description, "BCM4501 (internal)"))
671 unsigned int SDS_SNRE = snr << 16;
673 static float SNR_COEFF[6] = {
676 197418.0 / 4194304.0,
677 -2602183.0 / 4194304.0,
678 20377212.0 / 4194304.0,
679 -37791203.0 / 4194304.0,
682 float fval1, fval2, snr_in_db;
684 fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0));
685 fval2 = pow(10.0, fval1)-1;
686 fval1 = 10.0 * log10(fval2);
690 fval2 = SNR_COEFF[0];
694 fval2 += SNR_COEFF[i];
700 return (int)(snr_in_db * 100.0);
702 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
703 !strcmp(m_description, "Alps -S") ||
704 !strcmp(m_description, "Philips -S") ||
705 !strcmp(m_description, "LG -S") )
707 float snr_in_db=(snr-39075)/1764.7;
708 return (int)(snr_in_db * 100.0);
709 } else if (!strcmp(m_description, "Alps BSBE2"))
711 return (int)((snr >> 7) * 10.0);
713 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
719 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
720 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
725 #if HAVE_DVB_API_VERSION < 3
726 FrontendStatus status=0;
730 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
731 eDebug("FE_READ_STATUS failed (%m)");
732 return !!(status&FE_HAS_LOCK);
736 #if HAVE_DVB_API_VERSION < 3
737 FrontendStatus status=0;
741 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
742 eDebug("FE_READ_STATUS failed (%m)");
743 return !!(status&FE_HAS_SYNC);
751 void PutToDict(ePyObject &dict, const char*key, long value)
753 ePyObject item = PyInt_FromLong(value);
756 if (PyDict_SetItemString(dict, key, item))
757 eDebug("put %s to dict failed", key);
761 eDebug("could not create PyObject for %s", key);
764 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
768 if (PyDict_SetItemString(dict, key, item))
769 eDebug("put %s to dict failed", key);
773 eDebug("invalid PyObject for %s", key);
776 void PutToDict(ePyObject &dict, const char*key, const char *value)
778 ePyObject item = PyString_FromString(value);
781 if (PyDict_SetItemString(dict, key, item))
782 eDebug("put %s to dict failed", key);
786 eDebug("could not create PyObject for %s", key);
789 void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, eDVBFrontend *fe)
794 fe->getData(eDVBFrontend::CSW, csw);
795 fe->getData(eDVBFrontend::FREQ_OFFSET, freq_offset);
796 int frequency = parm_frequency + freq_offset;
797 PutToDict(dict, "frequency", frequency);
798 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
799 switch(parm_u_qpsk_fec_inner)
822 #if HAVE_DVB_API_VERSION >=3
823 case FEC_S2_8PSK_1_2:
824 case FEC_S2_QPSK_1_2:
827 case FEC_S2_8PSK_2_3:
828 case FEC_S2_QPSK_2_3:
831 case FEC_S2_8PSK_3_4:
832 case FEC_S2_QPSK_3_4:
835 case FEC_S2_8PSK_5_6:
836 case FEC_S2_QPSK_5_6:
839 case FEC_S2_8PSK_7_8:
840 case FEC_S2_QPSK_7_8:
843 case FEC_S2_8PSK_8_9:
844 case FEC_S2_QPSK_8_9:
847 case FEC_S2_8PSK_3_5:
848 case FEC_S2_QPSK_3_5:
851 case FEC_S2_8PSK_4_5:
852 case FEC_S2_QPSK_4_5:
855 case FEC_S2_8PSK_9_10:
856 case FEC_S2_QPSK_9_10:
861 PutToDict(dict, "fec_inner", tmp);
862 #if HAVE_DVB_API_VERSION >=3
863 PutToDict(dict, "modulation",
864 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ? "8PSK": "QPSK" );
865 if (parm_u_qpsk_fec_inner > FEC_AUTO)
867 switch(parm_inversion & 0xc)
869 default: // unknown rolloff
871 tmp = "ROLLOFF_0_35";
874 tmp = "ROLLOFF_0_25";
877 tmp = "ROLLOFF_0_20";
880 PutToDict(dict, "rolloff", tmp);
881 if (parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10)
883 switch(parm_inversion & 0x30)
888 case 0x10: // pilot on
891 case 0x20: // pilot auto
895 PutToDict(dict, "pilot", tmp);
902 PutToDict(dict, "modulation", "QPSK" );
905 PutToDict(dict, "system", tmp);
908 void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
911 #if HAVE_DVB_API_VERSION < 3
912 PutToDict(dict, "frequency", parm_frequency);
914 PutToDict(dict, "frequency", parm_frequency/1000);
916 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
917 switch(parm_u_qam_fec_inner)
937 #if HAVE_DVB_API_VERSION >= 3
947 PutToDict(dict, "fec_inner", tmp);
948 switch(parm_u_qam_modulation)
970 PutToDict(dict, "modulation", tmp);
973 void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
976 PutToDict(dict, "frequency", parm_frequency);
977 switch (parm_u_ofdm_bandwidth)
979 case BANDWIDTH_8_MHZ:
980 tmp = "BANDWIDTH_8_MHZ";
982 case BANDWIDTH_7_MHZ:
983 tmp = "BANDWIDTH_7_MHZ";
985 case BANDWIDTH_6_MHZ:
986 tmp = "BANDWIDTH_6_MHZ";
990 tmp = "BANDWIDTH_AUTO";
993 PutToDict(dict, "bandwidth", tmp);
994 switch (parm_u_ofdm_code_rate_LP)
1016 PutToDict(dict, "code_rate_lp", tmp);
1017 switch (parm_u_ofdm_code_rate_HP)
1039 PutToDict(dict, "code_rate_hp", tmp);
1040 switch (parm_u_ofdm_constellation)
1056 PutToDict(dict, "constellation", tmp);
1057 switch (parm_u_ofdm_transmission_mode)
1059 case TRANSMISSION_MODE_2K:
1060 tmp = "TRANSMISSION_MODE_2K";
1062 case TRANSMISSION_MODE_8K:
1063 tmp = "TRANSMISSION_MODE_8K";
1066 case TRANSMISSION_MODE_AUTO:
1067 tmp = "TRANSMISSION_MODE_AUTO";
1070 PutToDict(dict, "transmission_mode", tmp);
1071 switch (parm_u_ofdm_guard_interval)
1073 case GUARD_INTERVAL_1_32:
1074 tmp = "GUARD_INTERVAL_1_32";
1076 case GUARD_INTERVAL_1_16:
1077 tmp = "GUARD_INTERVAL_1_16";
1079 case GUARD_INTERVAL_1_8:
1080 tmp = "GUARD_INTERVAL_1_8";
1082 case GUARD_INTERVAL_1_4:
1083 tmp = "GUARD_INTERVAL_1_4";
1086 case GUARD_INTERVAL_AUTO:
1087 tmp = "GUARD_INTERVAL_AUTO";
1090 PutToDict(dict, "guard_interval", tmp);
1091 switch (parm_u_ofdm_hierarchy_information)
1093 case HIERARCHY_NONE:
1094 tmp = "HIERARCHY_NONE";
1097 tmp = "HIERARCHY_1";
1100 tmp = "HIERARCHY_2";
1103 tmp = "HIERARCHY_4";
1106 case HIERARCHY_AUTO:
1107 tmp = "HIERARCHY_AUTO";
1110 PutToDict(dict, "hierarchy_information", tmp);
1113 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1115 if (dest && PyDict_Check(dest))
1117 const char *tmp = "UNKNOWN";
1138 PutToDict(dest, "tuner_state", tmp);
1139 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1140 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1141 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1142 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1143 int sigQualitydB = readFrontendData(signalQualitydB);
1144 if (sigQualitydB == 0x12345678) // not support yet
1146 ePyObject obj=Py_None;
1148 PutToDict(dest, "tuner_signal_quality_db", obj);
1151 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1152 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1156 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1158 if (m_fd != -1 && dest && PyDict_Check(dest))
1166 FRONTENDPARAMETERS front;
1167 if (!original && ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1168 eDebug("FE_GET_FRONTEND (%m)");
1171 const FRONTENDPARAMETERS &parm = original ? this->parm : front;
1172 const char *tmp = "INVERSION_AUTO";
1173 switch(parm_inversion)
1176 tmp = "INVERSION_ON";
1179 tmp = "INVERSION_OFF";
1185 PutToDict(dest, "inversion", tmp);
1190 fillDictWithSatelliteData(dest, original?parm:front, this);
1193 fillDictWithCableData(dest, original?parm:front);
1196 fillDictWithTerrestrialData(dest, original?parm:front);
1207 void eDVBFrontend::getFrontendData(ePyObject dest)
1209 if (dest && PyDict_Check(dest))
1212 PutToDict(dest, "tuner_number", m_dvbid);
1228 PutToDict(dest, "tuner_type", tmp);
1232 #ifndef FP_IOCTL_GET_ID
1233 #define FP_IOCTL_GET_ID 0
1235 int eDVBFrontend::readInputpower()
1237 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1239 sprintf(proc_name, "/proc/stb/fp/lnb_sense%d", m_slotid);
1240 FILE *f=fopen(proc_name, "r");
1243 if (fscanf(f, "%08x", &power) != 1)
1244 eDebug("read %s failed!! (%m)", proc_name);
1246 eDebug("%s is %d\n", proc_name, power);
1251 // open front prozessor
1252 int fp=::open("/dev/dbox/fp0", O_RDWR);
1255 eDebug("couldn't open fp");
1258 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1259 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1261 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1270 bool eDVBFrontend::setSecSequencePos(int steps)
1272 eDebug("set sequence pos %d", steps);
1277 if (m_sec_sequence.current() != m_sec_sequence.end())
1278 ++m_sec_sequence.current();
1283 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1284 --m_sec_sequence.current();
1290 void eDVBFrontend::setRotorData(int pos, int cmd)
1292 m_data[ROTOR_CMD] = cmd;
1293 m_data[ROTOR_POS] = pos;
1294 if ( m_data[SATPOS_DEPENDS_PTR] != -1 )
1296 eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend*) m_data[SATPOS_DEPENDS_PTR];
1297 satpos_depends_to_fe->m_frontend->m_data[ROTOR_CMD] = cmd;
1298 satpos_depends_to_fe->m_frontend->m_data[ROTOR_POS] = pos;
1302 eDVBRegisteredFrontend *next = (eDVBRegisteredFrontend *)m_data[LINKED_NEXT_PTR];
1303 while ( (long)next != -1 )
1305 next->m_frontend->m_data[ROTOR_CMD] = cmd;
1306 next->m_frontend->m_data[ROTOR_POS] = pos;
1307 next = (eDVBRegisteredFrontend *)next->m_frontend->m_data[LINKED_NEXT_PTR];
1309 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)m_data[LINKED_PREV_PTR];
1310 while ( (long)prev != -1 )
1312 prev->m_frontend->m_data[ROTOR_CMD] = cmd;
1313 prev->m_frontend->m_data[ROTOR_POS] = pos;
1314 prev = (eDVBRegisteredFrontend *)prev->m_frontend->m_data[LINKED_PREV_PTR];
1319 void eDVBFrontend::tuneLoop() // called by m_tuneTimer
1322 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1324 // eDebug("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1325 switch (m_sec_sequence.current()->cmd)
1327 case eSecCommand::SLEEP:
1328 delay = m_sec_sequence.current()++->msec;
1329 eDebug("[SEC] sleep %dms", delay);
1331 case eSecCommand::GOTO:
1332 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1333 ++m_sec_sequence.current();
1335 case eSecCommand::SET_VOLTAGE:
1337 int voltage = m_sec_sequence.current()++->voltage;
1338 eDebug("[SEC] setVoltage %d", voltage);
1339 setVoltage(voltage);
1342 case eSecCommand::IF_VOLTAGE_GOTO:
1344 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1345 if ( compare.voltage == m_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1347 ++m_sec_sequence.current();
1350 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1352 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1353 if ( compare.voltage != m_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1355 ++m_sec_sequence.current();
1358 case eSecCommand::IF_TONE_GOTO:
1360 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1361 if ( compare.tone == m_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1363 ++m_sec_sequence.current();
1366 case eSecCommand::IF_NOT_TONE_GOTO:
1368 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1369 if ( compare.tone != m_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1371 ++m_sec_sequence.current();
1374 case eSecCommand::SET_TONE:
1375 eDebug("[SEC] setTone %d", m_sec_sequence.current()->tone);
1376 setTone(m_sec_sequence.current()++->tone);
1378 case eSecCommand::SEND_DISEQC:
1379 sendDiseqc(m_sec_sequence.current()->diseqc);
1380 eDebugNoNewLine("[SEC] sendDiseqc: ");
1381 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1382 eDebugNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1384 ++m_sec_sequence.current();
1386 case eSecCommand::SEND_TONEBURST:
1387 eDebug("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1388 sendToneburst(m_sec_sequence.current()++->toneburst);
1390 case eSecCommand::SET_FRONTEND:
1391 eDebug("[SEC] setFrontend");
1393 ++m_sec_sequence.current();
1395 case eSecCommand::START_TUNE_TIMEOUT:
1397 m_timeout->start(m_sec_sequence.current()->timeout, 1);
1398 ++m_sec_sequence.current();
1401 case eSecCommand::SET_TIMEOUT:
1402 m_timeoutCount = m_sec_sequence.current()++->val;
1403 eDebug("[SEC] set timeout %d", m_timeoutCount);
1405 case eSecCommand::IF_TIMEOUT_GOTO:
1406 if (!m_timeoutCount)
1408 eDebug("[SEC] rotor timout");
1409 m_sec->setRotorMoving(false);
1410 setSecSequencePos(m_sec_sequence.current()->steps);
1413 ++m_sec_sequence.current();
1415 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1417 int idx = m_sec_sequence.current()++->val;
1418 if ( idx == 0 || idx == 1 )
1420 m_idleInputpower[idx] = readInputpower();
1421 eDebug("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1424 eDebug("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1427 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1429 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1430 int idx = compare.val;
1431 if ( idx == 0 || idx == 1 )
1433 int idle = readInputpower();
1434 int diff = abs(idle-m_idleInputpower[idx]);
1437 eDebug("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1438 setSecSequencePos(compare.steps);
1442 ++m_sec_sequence.current();
1445 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1447 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1448 if (readFrontendData(locked))
1450 eDebug("[SEC] locked step %d ok", cmd.okcount);
1452 if (cmd.okcount > 12)
1454 eDebug("ok > 12 .. goto %d\n",m_sec_sequence.current()->steps);
1455 setSecSequencePos(cmd.steps);
1461 eDebug("[SEC] rotor locked step %d failed", cmd.okcount);
1463 if (!m_timeoutCount && m_retryCount > 0)
1467 ++m_sec_sequence.current();
1470 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1471 m_runningInputpower = readInputpower();
1472 eDebug("[SEC] runningInputpower is %d", m_runningInputpower);
1473 ++m_sec_sequence.current();
1475 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1477 int idleInputpower = m_idleInputpower[ (m_data[CUR_VOLTAGE]&1) ? 0 : 1];
1478 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1479 const char *txt = cmd.direction ? "running" : "stopped";
1480 eDebug("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1482 m_runningInputpower,
1485 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1486 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1489 eDebug("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1490 if ( cmd.okcount > 6 )
1492 m_sec->setRotorMoving(cmd.direction);
1493 eDebug("[SEC] rotor is %s", txt);
1494 if (setSecSequencePos(cmd.steps))
1500 eDebug("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1502 if (!m_timeoutCount && m_retryCount > 0)
1506 ++m_sec_sequence.current();
1509 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1510 if (m_data[ROTOR_CMD] != -1 && m_data[ROTOR_POS] != -1)
1511 setSecSequencePos(m_sec_sequence.current()->steps);
1513 ++m_sec_sequence.current();
1515 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1516 eDebug("[SEC] invalidate current rotorparams");
1517 setRotorData(-1,-1);
1518 ++m_sec_sequence.current();
1520 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1521 setRotorData(m_data[NEW_ROTOR_POS], m_data[NEW_ROTOR_CMD]);
1522 eDebug("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, m_data[ROTOR_CMD], m_data[ROTOR_POS]);
1523 ++m_sec_sequence.current();
1525 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1526 m_retryCount = m_sec_sequence.current()++->val;
1527 eDebug("[SEC] set rotor retries %d", m_retryCount);
1529 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1532 eDebug("[SEC] no more rotor retrys");
1533 setSecSequencePos(m_sec_sequence.current()->steps);
1536 ++m_sec_sequence.current();
1538 case eSecCommand::SET_POWER_LIMITING_MODE:
1541 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", m_dvbid);
1542 FILE *f=fopen(proc_name, "w");
1543 if (f) // new interface exist?
1545 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1546 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1547 eDebug("write %s failed!! (%m)", proc_name);
1549 eDebug("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1552 else if (m_need_rotor_workaround)
1556 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1558 sprintf(dev, "/dev/i2c/%d", m_slotid);
1559 else if (m_slotid == 2)
1560 sprintf(dev, "/dev/i2c/2"); // first nim socket on DM8000 use /dev/i2c/2
1561 else if (m_slotid == 3)
1562 sprintf(dev, "/dev/i2c/4"); // second nim socket on DM8000 use /dev/i2c/4
1563 int fd = ::open(dev, O_RDWR);
1565 unsigned char data[2];
1566 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1567 if(::read(fd, data, 1) != 1)
1568 eDebug("[SEC] error read lnbp (%m)");
1569 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
1571 data[0] |= 0x80; // enable static current limiting
1572 eDebug("[SEC] set static current limiting");
1576 data[0] &= ~0x80; // enable dynamic current limiting
1577 eDebug("[SEC] set dynamic current limiting");
1579 if(::write(fd, data, 1) != 1)
1580 eDebug("[SEC] error write lnbp (%m)");
1583 ++m_sec_sequence.current();
1587 eDebug("[SEC] unhandled sec command %d",
1588 ++m_sec_sequence.current()->cmd);
1589 ++m_sec_sequence.current();
1591 m_tuneTimer->start(delay,true);
1595 void eDVBFrontend::setFrontend()
1597 eDebug("setting frontend %d", m_dvbid);
1600 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
1602 perror("FE_SET_FRONTEND failed");
1607 RESULT eDVBFrontend::getFrontendType(int &t)
1615 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
1620 eWarning("no SEC module active!");
1623 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
1626 eDebug("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
1629 feparm.polarisation,
1633 feparm.orbital_position);
1634 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
1635 switch (feparm.inversion)
1637 case eDVBFrontendParametersSatellite::Inversion::On:
1638 parm_inversion = INVERSION_ON;
1640 case eDVBFrontendParametersSatellite::Inversion::Off:
1641 parm_inversion = INVERSION_OFF;
1644 case eDVBFrontendParametersSatellite::Inversion::Unknown:
1645 parm_inversion = INVERSION_AUTO;
1648 if (feparm.system == eDVBFrontendParametersSatellite::System::DVB_S)
1651 case eDVBFrontendParametersSatellite::FEC::fNone:
1652 parm_u_qpsk_fec_inner = FEC_NONE;
1654 case eDVBFrontendParametersSatellite::FEC::f1_2:
1655 parm_u_qpsk_fec_inner = FEC_1_2;
1657 case eDVBFrontendParametersSatellite::FEC::f2_3:
1658 parm_u_qpsk_fec_inner = FEC_2_3;
1660 case eDVBFrontendParametersSatellite::FEC::f3_4:
1661 parm_u_qpsk_fec_inner = FEC_3_4;
1663 case eDVBFrontendParametersSatellite::FEC::f5_6:
1664 parm_u_qpsk_fec_inner = FEC_5_6;
1666 case eDVBFrontendParametersSatellite::FEC::f7_8:
1667 parm_u_qpsk_fec_inner = FEC_7_8;
1670 eDebug("no valid fec for DVB-S set.. assume auto");
1671 case eDVBFrontendParametersSatellite::FEC::fAuto:
1672 parm_u_qpsk_fec_inner = FEC_AUTO;
1675 #if HAVE_DVB_API_VERSION >= 3
1680 case eDVBFrontendParametersSatellite::FEC::f1_2:
1681 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
1683 case eDVBFrontendParametersSatellite::FEC::f2_3:
1684 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
1686 case eDVBFrontendParametersSatellite::FEC::f3_4:
1687 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
1689 case eDVBFrontendParametersSatellite::FEC::f3_5:
1690 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
1692 case eDVBFrontendParametersSatellite::FEC::f4_5:
1693 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
1695 case eDVBFrontendParametersSatellite::FEC::f5_6:
1696 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
1698 case eDVBFrontendParametersSatellite::FEC::f7_8:
1699 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
1701 case eDVBFrontendParametersSatellite::FEC::f8_9:
1702 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
1704 case eDVBFrontendParametersSatellite::FEC::f9_10:
1705 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
1708 eDebug("no valid fec for DVB-S2 set.. abort !!");
1711 parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff
1712 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation::M8PSK) {
1713 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
1714 // 8PSK fec driver values are decimal 9 bigger
1715 parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot
1719 // FIXME !!! get frequency range from tuner
1720 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
1722 eDebug("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
1725 eDebug("tuning to %d mhz", parm_frequency/1000);
1730 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
1732 #if HAVE_DVB_API_VERSION < 3
1733 parm_frequency = feparm.frequency;
1735 parm_frequency = feparm.frequency * 1000;
1737 parm_u_qam_symbol_rate = feparm.symbol_rate;
1738 switch (feparm.modulation)
1740 case eDVBFrontendParametersCable::Modulation::QAM16:
1741 parm_u_qam_modulation = QAM_16;
1743 case eDVBFrontendParametersCable::Modulation::QAM32:
1744 parm_u_qam_modulation = QAM_32;
1746 case eDVBFrontendParametersCable::Modulation::QAM64:
1747 parm_u_qam_modulation = QAM_64;
1749 case eDVBFrontendParametersCable::Modulation::QAM128:
1750 parm_u_qam_modulation = QAM_128;
1752 case eDVBFrontendParametersCable::Modulation::QAM256:
1753 parm_u_qam_modulation = QAM_256;
1756 case eDVBFrontendParametersCable::Modulation::Auto:
1757 parm_u_qam_modulation = QAM_AUTO;
1760 switch (feparm.inversion)
1762 case eDVBFrontendParametersCable::Inversion::On:
1763 parm_inversion = INVERSION_ON;
1765 case eDVBFrontendParametersCable::Inversion::Off:
1766 parm_inversion = INVERSION_OFF;
1769 case eDVBFrontendParametersCable::Inversion::Unknown:
1770 parm_inversion = INVERSION_AUTO;
1773 switch (feparm.fec_inner)
1775 case eDVBFrontendParametersCable::FEC::fNone:
1776 parm_u_qam_fec_inner = FEC_NONE;
1778 case eDVBFrontendParametersCable::FEC::f1_2:
1779 parm_u_qam_fec_inner = FEC_1_2;
1781 case eDVBFrontendParametersCable::FEC::f2_3:
1782 parm_u_qam_fec_inner = FEC_2_3;
1784 case eDVBFrontendParametersCable::FEC::f3_4:
1785 parm_u_qam_fec_inner = FEC_3_4;
1787 case eDVBFrontendParametersCable::FEC::f5_6:
1788 parm_u_qam_fec_inner = FEC_5_6;
1790 case eDVBFrontendParametersCable::FEC::f7_8:
1791 parm_u_qam_fec_inner = FEC_7_8;
1793 #if HAVE_DVB_API_VERSION >= 3
1794 case eDVBFrontendParametersCable::FEC::f8_9:
1795 parm_u_qam_fec_inner = FEC_8_9;
1799 case eDVBFrontendParametersCable::FEC::fAuto:
1800 parm_u_qam_fec_inner = FEC_AUTO;
1803 eDebug("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
1804 parm_frequency/1000,
1805 parm_u_qam_symbol_rate,
1806 parm_u_qam_fec_inner,
1807 parm_u_qam_modulation,
1812 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
1814 parm_frequency = feparm.frequency;
1816 switch (feparm.bandwidth)
1818 case eDVBFrontendParametersTerrestrial::Bandwidth::Bw8MHz:
1819 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
1821 case eDVBFrontendParametersTerrestrial::Bandwidth::Bw7MHz:
1822 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
1824 case eDVBFrontendParametersTerrestrial::Bandwidth::Bw6MHz:
1825 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
1828 case eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto:
1829 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
1832 switch (feparm.code_rate_LP)
1834 case eDVBFrontendParametersTerrestrial::FEC::f1_2:
1835 parm_u_ofdm_code_rate_LP = FEC_1_2;
1837 case eDVBFrontendParametersTerrestrial::FEC::f2_3:
1838 parm_u_ofdm_code_rate_LP = FEC_2_3;
1840 case eDVBFrontendParametersTerrestrial::FEC::f3_4:
1841 parm_u_ofdm_code_rate_LP = FEC_3_4;
1843 case eDVBFrontendParametersTerrestrial::FEC::f5_6:
1844 parm_u_ofdm_code_rate_LP = FEC_5_6;
1846 case eDVBFrontendParametersTerrestrial::FEC::f7_8:
1847 parm_u_ofdm_code_rate_LP = FEC_7_8;
1850 case eDVBFrontendParametersTerrestrial::FEC::fAuto:
1851 parm_u_ofdm_code_rate_LP = FEC_AUTO;
1854 switch (feparm.code_rate_HP)
1856 case eDVBFrontendParametersTerrestrial::FEC::f1_2:
1857 parm_u_ofdm_code_rate_HP = FEC_1_2;
1859 case eDVBFrontendParametersTerrestrial::FEC::f2_3:
1860 parm_u_ofdm_code_rate_HP = FEC_2_3;
1862 case eDVBFrontendParametersTerrestrial::FEC::f3_4:
1863 parm_u_ofdm_code_rate_HP = FEC_3_4;
1865 case eDVBFrontendParametersTerrestrial::FEC::f5_6:
1866 parm_u_ofdm_code_rate_HP = FEC_5_6;
1868 case eDVBFrontendParametersTerrestrial::FEC::f7_8:
1869 parm_u_ofdm_code_rate_HP = FEC_7_8;
1872 case eDVBFrontendParametersTerrestrial::FEC::fAuto:
1873 parm_u_ofdm_code_rate_HP = FEC_AUTO;
1876 switch (feparm.modulation)
1878 case eDVBFrontendParametersTerrestrial::Modulation::QPSK:
1879 parm_u_ofdm_constellation = QPSK;
1881 case eDVBFrontendParametersTerrestrial::Modulation::QAM16:
1882 parm_u_ofdm_constellation = QAM_16;
1884 case eDVBFrontendParametersTerrestrial::Modulation::QAM64:
1885 parm_u_ofdm_constellation = QAM_64;
1888 case eDVBFrontendParametersTerrestrial::Modulation::Auto:
1889 parm_u_ofdm_constellation = QAM_AUTO;
1892 switch (feparm.transmission_mode)
1894 case eDVBFrontendParametersTerrestrial::TransmissionMode::TM2k:
1895 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
1897 case eDVBFrontendParametersTerrestrial::TransmissionMode::TM8k:
1898 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
1901 case eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto:
1902 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
1905 switch (feparm.guard_interval)
1907 case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_32:
1908 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
1910 case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_16:
1911 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
1913 case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_8:
1914 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
1916 case eDVBFrontendParametersTerrestrial::GuardInterval::GI_1_4:
1917 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
1920 case eDVBFrontendParametersTerrestrial::GuardInterval::GI_Auto:
1921 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
1924 switch (feparm.hierarchy)
1926 case eDVBFrontendParametersTerrestrial::Hierarchy::HNone:
1927 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
1929 case eDVBFrontendParametersTerrestrial::Hierarchy::H1:
1930 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
1932 case eDVBFrontendParametersTerrestrial::Hierarchy::H2:
1933 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
1935 case eDVBFrontendParametersTerrestrial::Hierarchy::H4:
1936 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
1939 case eDVBFrontendParametersTerrestrial::Hierarchy::HAuto:
1940 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
1943 switch (feparm.inversion)
1945 case eDVBFrontendParametersTerrestrial::Inversion::On:
1946 parm_inversion = INVERSION_ON;
1948 case eDVBFrontendParametersTerrestrial::Inversion::Off:
1949 parm_inversion = INVERSION_OFF;
1952 case eDVBFrontendParametersTerrestrial::Inversion::Unknown:
1953 parm_inversion = INVERSION_AUTO;
1959 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
1961 unsigned int timeout = 5000;
1962 eDebug("(%d)tune", m_dvbid);
1970 eDebug("no frontend device opened... do not try to tune !!!");
1982 m_sec_sequence.clear();
1984 where.calcLockTimeout(timeout);
1990 eDVBFrontendParametersSatellite feparm;
1991 if (where.getDVBS(feparm))
1993 eDebug("no dvbs data!");
1997 m_sec->setRotorMoving(false);
1998 res=prepare_sat(feparm, timeout);
2006 eDVBFrontendParametersCable feparm;
2007 if (where.getDVBC(feparm))
2012 res=prepare_cable(feparm);
2016 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2017 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
2022 eDVBFrontendParametersTerrestrial feparm;
2023 if (where.getDVBT(feparm))
2025 eDebug("no -T data");
2029 res=prepare_terrestrial(feparm);
2033 std::string enable_5V;
2034 char configStr[255];
2035 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2036 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2037 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2038 if (enable_5V == "True")
2039 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2041 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2042 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND) );
2048 m_tuneTimer->start(0,true);
2049 m_sec_sequence.current() = m_sec_sequence.begin();
2051 if (m_state != stateTuning)
2054 m_state = stateTuning;
2055 m_stateChanged(this);
2061 m_tuneTimer->stop();
2065 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2067 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2071 RESULT eDVBFrontend::setVoltage(int voltage)
2073 if (m_type == feCable)
2075 #if HAVE_DVB_API_VERSION < 3
2078 bool increased=false;
2079 fe_sec_voltage_t vlt;
2081 m_data[CUR_VOLTAGE]=voltage;
2085 for (int i=0; i < 3; ++i) // reset diseqc
2087 vlt = SEC_VOLTAGE_OFF;
2090 #if HAVE_DVB_API_VERSION < 3
2091 vlt = SEC_VOLTAGE_13_5;
2097 vlt = SEC_VOLTAGE_13;
2100 #if HAVE_DVB_API_VERSION < 3
2101 vlt = SEC_VOLTAGE_18_5;
2107 vlt = SEC_VOLTAGE_18;
2112 #if HAVE_DVB_API_VERSION < 3
2113 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2115 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2116 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2117 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2121 RESULT eDVBFrontend::getState(int &state)
2127 RESULT eDVBFrontend::setTone(int t)
2129 if (m_type != feSatellite)
2131 #if HAVE_DVB_API_VERSION < 3
2134 fe_sec_tone_mode_t tone;
2143 tone = SEC_TONE_OFF;
2148 #if HAVE_DVB_API_VERSION < 3
2149 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2151 return ::ioctl(m_fd, FE_SET_TONE, tone);
2155 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2156 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2159 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2161 #if HAVE_DVB_API_VERSION < 3
2162 struct secCommand cmd;
2163 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
2164 cmd.u.diseqc.cmdtype = diseqc.data[0];
2165 cmd.u.diseqc.addr = diseqc.data[1];
2166 cmd.u.diseqc.cmd = diseqc.data[2];
2167 cmd.u.diseqc.numParams = diseqc.len-3;
2168 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
2169 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
2171 struct dvb_diseqc_master_cmd cmd;
2172 memcpy(cmd.msg, diseqc.data, diseqc.len);
2173 cmd.msg_len = diseqc.len;
2174 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2180 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
2181 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
2183 RESULT eDVBFrontend::sendToneburst(int burst)
2185 #if HAVE_DVB_API_VERSION < 3
2186 secMiniCmd cmd = SEC_MINI_NONE;
2188 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2190 if ( burst == eDVBSatelliteDiseqcParameters::A )
2192 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2194 #if HAVE_DVB_API_VERSION < 3
2195 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
2198 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2204 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2210 RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list)
2212 m_sec_sequence = list;
2216 RESULT eDVBFrontend::getData(int num, long &data)
2218 if ( num < NUM_DATA_ENTRIES )
2226 RESULT eDVBFrontend::setData(int num, long val)
2228 if ( num < NUM_DATA_ENTRIES )
2236 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2239 if (feparm->getSystem(type) || type != m_type || !m_enabled)
2241 if (m_type == eDVBFrontend::feSatellite)
2244 eDVBFrontendParametersSatellite sat_parm;
2245 int ret = feparm->getDVBS(sat_parm);
2247 if (sat_parm.system == eDVBFrontendParametersSatellite::System::DVB_S2 && !m_can_handle_dvbs2)
2249 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
2250 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System::DVB_S && m_can_handle_dvbs2)
2254 else if (m_type == eDVBFrontend::feCable)
2255 return 2; // more prio for cable frontends
2256 else if (m_type == eDVBFrontend::feTerrestrial)
2261 bool eDVBFrontend::setSlotInfo(ePyObject obj)
2263 ePyObject Id, Descr, Enabled;
2264 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 3)
2266 Id = PyTuple_GET_ITEM(obj, 0);
2267 Descr = PyTuple_GET_ITEM(obj, 1);
2268 Enabled = PyTuple_GET_ITEM(obj, 2);
2269 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled))
2271 strcpy(m_description, PyString_AS_STRING(Descr));
2272 m_slotid = PyInt_AsLong(Id);
2273 m_enabled = Enabled == Py_True;
2274 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
2275 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
2276 !!strstr(m_description, "Alps BSBE2") ||
2277 !!strstr(m_description, "Alps -S") ||
2278 !!strstr(m_description, "BCM4501");
2279 m_can_handle_dvbs2 = !!strstr(m_description, "Alps BSBE2") || !!strstr(m_description, "BCM4501");
2280 eDebug("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s",
2281 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" );
2284 PyErr_SetString(PyExc_StandardError,
2285 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");