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 #ifdef BUILD_VUPLUS /* ikseong */
498 int eDVBFrontend::openFrontend()
500 if (m_state != stateClosed)
501 return -1; // already opened
506 #if HAVE_DVB_API_VERSION < 3
507 FrontendInfo fe_info;
509 dvb_frontend_info fe_info;
511 eDebugNoSimulate("opening frontend %d", m_dvbid);
514 if (!m_simulate || m_type == -1)
516 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
519 eWarning("failed! (%s) %m", m_filename);
522 #ifdef BUILD_VUPLUS /* ikseong */
534 eWarning("frontend %d already opened", m_dvbid);
537 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
539 eWarning("ioctl FE_GET_INFO failed");
545 switch (fe_info.type)
548 m_type = iDVBFrontend::feSatellite;
551 m_type = iDVBFrontend::feCable;
554 m_type = iDVBFrontend::feTerrestrial;
557 eWarning("unknown frontend type.");
562 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
565 #if HAVE_DVB_API_VERSION < 3
566 if (m_type == iDVBFrontend::feSatellite)
572 m_secfd = ::open(m_sec_filename, O_RDWR);
575 eWarning("failed! (%s) %m", m_sec_filename);
583 eWarning("sec %d already opened", m_dvbid);
587 setTone(iDVBFrontend::toneOff);
588 setVoltage(iDVBFrontend::voltageOff);
592 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
593 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
599 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
601 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
603 long tmp = m_data[LINKED_NEXT_PTR];
606 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
607 if (linked_fe->m_inuse)
609 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
610 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
613 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
619 eDebugNoSimulate("close frontend %d", m_dvbid);
620 if (m_data[SATCR] != -1)
624 m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
625 m_tuneTimer->start(0, true);
626 if(!m_tuneTimer->isActive())
629 eDebug("[turnOffSatCR] no mainloop");
632 timeout = tuneLoopInt();
635 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
639 eDebug("[turnOffSatCR] running mainloop");
643 m_data[ROTOR_CMD] = -1;
646 setTone(iDVBFrontend::toneOff);
647 setVoltage(iDVBFrontend::voltageOff);
650 if (m_sec && !m_simulate)
651 m_sec->setRotorMoving(m_slotid, false);
655 eWarning("couldnt close frontend %d", m_dvbid);
659 setTone(iDVBFrontend::toneOff);
660 setVoltage(iDVBFrontend::voltageOff);
662 #if HAVE_DVB_API_VERSION < 3
665 if (!::close(m_secfd))
668 eWarning("couldnt close sec %d", m_dvbid);
672 m_state = stateClosed;
677 eDVBFrontend::~eDVBFrontend()
679 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
683 void eDVBFrontend::feEvent(int w)
685 eDVBFrontend *sec_fe = this;
686 long tmp = m_data[LINKED_PREV_PTR];
689 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
690 sec_fe = linked_fe->m_frontend;
691 sec_fe->getData(LINKED_NEXT_PTR, tmp);
695 #if HAVE_DVB_API_VERSION < 3
698 dvb_frontend_event event;
702 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
704 if (res && (errno == EAGAIN))
710 #if HAVE_DVB_API_VERSION < 3
711 if (event.type == FE_COMPLETION_EV)
713 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
714 if (event.status & FE_HAS_LOCK)
722 #if HAVE_DVB_API_VERSION >= 3
723 if (event.status & FE_TIMEDOUT) {
724 eDebug("FE_TIMEDOUT! ..abort");
737 eDebug("stateLostLock");
738 state = stateLostLock;
740 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
743 if (m_state != state)
746 m_stateChanged(this);
751 void eDVBFrontend::timeout()
754 if (m_state == stateTuning)
756 #ifdef BUILD_VUPLUS /* ikseong */
757 eDVBFrontend *sec_fe = this;
758 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
760 m_state = stateFailed;
761 m_stateChanged(this);
765 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
767 /* unsigned 32 bit division */
768 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
770 return (a + b / 2) / b;
773 int eDVBFrontend::readFrontendData(int type)
782 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
783 eDebug("FE_READ_BER failed (%m)");
788 case signalQualitydB: /* this will move into the driver */
790 int sat_max = 1600; // for stv0288 / bsbe2
791 int ret = 0x12345678;
795 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
796 eDebug("FE_READ_SNR failed (%m)");
797 else if (!strcmp(m_description, "BCM4501 (internal)"))
799 float SDS_SNRE = snr << 16;
802 if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
804 static float SNR_COEFF[6] = {
807 197418.0 / 4194304.0,
808 -2602183.0 / 4194304.0,
809 20377212.0 / 4194304.0,
810 -37791203.0 / 4194304.0,
812 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
813 fval2 = pow(10.0, fval1)-1;
814 fval1 = 10.0 * log10(fval2);
818 fval2 = SNR_COEFF[0];
819 for (int i=1; i<6; ++i)
822 fval2 += SNR_COEFF[i];
828 #if HAVE_DVB_API_VERSION >= 3
831 float fval1 = SDS_SNRE / 268435456.0,
834 if (parm_u_qpsk_fec_inner <= FEC_S2_QPSK_9_10) // DVB-S2 QPSK
845 fval4 = -10.0 * log10(fval1);
847 for (int i=0; i < 5; ++i)
848 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
853 ret = (int)(snr_in_db * 100);
855 else if (strstr(m_description, "Alps BSBE1 C01A") ||
856 strstr(m_description, "Alps -S(STV0288)"))
860 else if (snr == 0xFFFF) // i think this should not happen
864 enum { REALVAL, REGVAL };
865 const long CN_lookup[31][2] = {
866 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
867 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
868 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
869 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
870 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
871 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
874 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
875 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
879 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
884 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
889 ret = (((regval - CN_lookup[Imin][REGVAL])
890 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
891 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
892 + CN_lookup[Imin][REALVAL]) * 10;
898 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
899 !strcmp(m_description, "Alps -S") ||
900 !strcmp(m_description, "Philips -S") ||
901 !strcmp(m_description, "LG -S") )
904 ret = (int)((snr-39075)/17.647);
905 } else if (!strcmp(m_description, "Alps BSBE2"))
907 ret = (int)((snr >> 7) * 10);
908 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
910 int mse = (~snr) & 0xFF;
911 switch (parm_u_qam_modulation) {
912 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
913 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
914 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
915 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
916 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
919 } else if (!strcmp(m_description, "Philips TU1216"))
921 snr = 0xFF - (snr & 0xFF);
923 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
925 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
926 ret = (snr * 100) >> 8;
928 if (type == signalQuality)
930 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
935 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
936 case feCable: // we assume a max of 42db here
937 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
938 case feTerrestrial: // we assume a max of 24db here
939 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
943 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
951 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
952 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
958 #if HAVE_DVB_API_VERSION < 3
959 FrontendStatus status=0;
965 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
966 eDebug("FE_READ_STATUS failed (%m)");
967 return !!(status&FE_HAS_LOCK);
973 #if HAVE_DVB_API_VERSION < 3
974 FrontendStatus status=0;
980 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
981 eDebug("FE_READ_STATUS failed (%m)");
982 return !!(status&FE_HAS_SYNC);
992 void PutToDict(ePyObject &dict, const char*key, long value)
994 ePyObject item = PyInt_FromLong(value);
997 if (PyDict_SetItemString(dict, key, item))
998 eDebug("put %s to dict failed", key);
1002 eDebug("could not create PyObject for %s", key);
1005 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1009 if (PyDict_SetItemString(dict, key, item))
1010 eDebug("put %s to dict failed", key);
1014 eDebug("invalid PyObject for %s", key);
1017 void PutToDict(ePyObject &dict, const char*key, const char *value)
1019 ePyObject item = PyString_FromString(value);
1022 if (PyDict_SetItemString(dict, key, item))
1023 eDebug("put %s to dict failed", key);
1027 eDebug("could not create PyObject for %s", key);
1030 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1032 PutToDict(dict, "tuner_type", "DVB-S");
1033 PutToDict(dict, "frequency", feparm.frequency);
1034 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1035 PutToDict(dict, "orbital_position", feparm.orbital_position);
1036 PutToDict(dict, "inversion", feparm.inversion);
1037 PutToDict(dict, "fec_inner", feparm.fec);
1038 PutToDict(dict, "modulation", feparm.modulation);
1039 PutToDict(dict, "polarization", feparm.polarisation);
1040 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1042 PutToDict(dict, "rolloff", feparm.rolloff);
1043 PutToDict(dict, "pilot", feparm.pilot);
1045 PutToDict(dict, "system", feparm.system);
1048 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1050 PutToDict(dict, "tuner_type", "DVB-T");
1051 PutToDict(dict, "frequency", feparm.frequency);
1052 PutToDict(dict, "bandwidth", feparm.bandwidth);
1053 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1054 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1055 PutToDict(dict, "constellation", feparm.modulation);
1056 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1057 PutToDict(dict, "guard_interval", feparm.guard_interval);
1058 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1059 PutToDict(dict, "inversion", feparm.inversion);
1062 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1064 PutToDict(dict, "tuner_type", "DVB-C");
1065 PutToDict(dict, "frequency", feparm.frequency);
1066 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1067 PutToDict(dict, "modulation", feparm.modulation);
1068 PutToDict(dict, "inversion", feparm.inversion);
1069 PutToDict(dict, "fec_inner", feparm.fec_inner);
1072 #if HAVE_DVB_API_VERSION >= 5
1073 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1076 int frequency = parm_frequency + freq_offset;
1077 PutToDict(dict, "frequency", frequency);
1078 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1079 PutToDict(dict, "orbital_position", orb_pos);
1080 PutToDict(dict, "polarization", polarization);
1082 switch(parm_u_qpsk_fec_inner)
1084 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1085 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1086 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1087 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1088 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1089 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1090 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1091 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1092 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1093 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1094 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1095 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1098 switch (p[0].u.data)
1100 default: eDebug("got unsupported system from frontend! report as DVBS!");
1101 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1104 switch (p[2].u.data)
1106 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1107 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1108 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1109 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1111 PutToDict(dict, "rolloff", tmp);
1113 switch (p[3].u.data)
1115 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1116 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1117 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1119 PutToDict(dict, "pilot", tmp);
1121 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1124 PutToDict(dict, "system", tmp);
1126 switch (p[1].u.data)
1128 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1129 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1130 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1132 PutToDict(dict, "modulation", tmp);
1136 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1139 int frequency = parm_frequency + freq_offset;
1140 PutToDict(dict, "frequency", frequency);
1141 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1142 PutToDict(dict, "orbital_position", orb_pos);
1143 PutToDict(dict, "polarization", polarization);
1145 switch((int)parm_u_qpsk_fec_inner)
1147 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1148 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1149 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1150 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1151 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1152 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1154 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1155 #if HAVE_DVB_API_VERSION >=3
1156 case FEC_S2_8PSK_1_2:
1157 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1158 case FEC_S2_8PSK_2_3:
1159 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1160 case FEC_S2_8PSK_3_4:
1161 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1162 case FEC_S2_8PSK_5_6:
1163 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1164 case FEC_S2_8PSK_7_8:
1165 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1166 case FEC_S2_8PSK_8_9:
1167 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1168 case FEC_S2_8PSK_3_5:
1169 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1170 case FEC_S2_8PSK_4_5:
1171 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1172 case FEC_S2_8PSK_9_10:
1173 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1176 PutToDict(dict, "fec_inner", tmp);
1177 #if HAVE_DVB_API_VERSION >=3
1178 PutToDict(dict, "modulation",
1179 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1180 eDVBFrontendParametersSatellite::Modulation_8PSK :
1181 eDVBFrontendParametersSatellite::Modulation_QPSK );
1182 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1184 switch(parm_inversion & 0xc)
1186 default: // unknown rolloff
1187 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1188 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1189 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1191 PutToDict(dict, "rolloff", tmp);
1192 switch(parm_inversion & 0x30)
1194 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1195 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1196 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1198 PutToDict(dict, "pilot", tmp);
1199 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1202 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1204 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1205 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1207 PutToDict(dict, "system", tmp);
1211 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1214 #if HAVE_DVB_API_VERSION < 3
1215 PutToDict(dict, "frequency", parm_frequency);
1217 PutToDict(dict, "frequency", parm_frequency/1000);
1219 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1220 switch(parm_u_qam_fec_inner)
1222 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1223 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1224 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1225 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1226 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1227 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1228 #if HAVE_DVB_API_VERSION >= 3
1229 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1232 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1234 PutToDict(dict, "fec_inner", tmp);
1235 switch(parm_u_qam_modulation)
1237 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1238 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1239 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1240 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1241 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1243 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1245 PutToDict(dict, "modulation", tmp);
1248 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1251 PutToDict(dict, "frequency", parm_frequency);
1252 switch (parm_u_ofdm_bandwidth)
1254 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1255 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1256 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1258 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1260 PutToDict(dict, "bandwidth", tmp);
1261 switch (parm_u_ofdm_code_rate_LP)
1263 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1264 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1265 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1266 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1267 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1269 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1271 PutToDict(dict, "code_rate_lp", tmp);
1272 switch (parm_u_ofdm_code_rate_HP)
1274 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1275 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1276 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1277 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1278 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1280 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1282 PutToDict(dict, "code_rate_hp", tmp);
1283 switch (parm_u_ofdm_constellation)
1285 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1286 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1287 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1289 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1291 PutToDict(dict, "constellation", tmp);
1292 switch (parm_u_ofdm_transmission_mode)
1294 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1295 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1297 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1299 PutToDict(dict, "transmission_mode", tmp);
1300 switch (parm_u_ofdm_guard_interval)
1302 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1303 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1304 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1305 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1307 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1309 PutToDict(dict, "guard_interval", tmp);
1310 switch (parm_u_ofdm_hierarchy_information)
1312 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1313 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1314 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1315 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1317 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1319 PutToDict(dict, "hierarchy_information", tmp);
1322 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1324 if (dest && PyDict_Check(dest))
1326 const char *tmp = "UNKNOWN";
1347 PutToDict(dest, "tuner_state", tmp);
1348 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1349 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1350 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1351 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1352 int sigQualitydB = readFrontendData(signalQualitydB);
1353 if (sigQualitydB == 0x12345678) // not support yet
1355 ePyObject obj=Py_None;
1357 PutToDict(dest, "tuner_signal_quality_db", obj);
1360 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1361 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1365 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1367 if (dest && PyDict_Check(dest))
1369 FRONTENDPARAMETERS front;
1370 #if HAVE_DVB_API_VERSION >= 5
1371 struct dtv_property p[4];
1372 struct dtv_properties cmdseq;
1375 p[0].cmd = DTV_DELIVERY_SYSTEM;
1376 p[1].cmd = DTV_MODULATION;
1377 p[2].cmd = DTV_ROLLOFF;
1378 p[3].cmd = DTV_PILOT;
1380 if (m_simulate || m_fd == -1 || original)
1382 #if HAVE_DVB_API_VERSION >= 5
1383 else if (m_type == feSatellite && // yet just use new api for DVB-S(2) only
1384 ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1386 eDebug("FE_GET_PROPERTY failed (%m)");
1390 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1392 eDebug("FE_GET_FRONTEND failed (%m)");
1400 PutSatelliteDataToDict(dest, oparm.sat);
1403 PutCableDataToDict(dest, oparm.cab);
1406 PutTerrestrialDataToDict(dest, oparm.ter);
1412 FRONTENDPARAMETERS &parm = front;
1413 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1414 switch(parm_inversion & 3)
1417 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1420 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1424 PutToDict(dest, "inversion", tmp);
1428 #if HAVE_DVB_API_VERSION >= 5
1429 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1431 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1435 fillDictWithCableData(dest, parm);
1438 fillDictWithTerrestrialData(dest, parm);
1445 void eDVBFrontend::getFrontendData(ePyObject dest)
1447 if (dest && PyDict_Check(dest))
1450 PutToDict(dest, "tuner_number", m_slotid);
1466 PutToDict(dest, "tuner_type", tmp);
1470 #ifndef FP_IOCTL_GET_ID
1471 #define FP_IOCTL_GET_ID 0
1473 int eDVBFrontend::readInputpower()
1477 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1479 char proc_name2[64];
1480 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1481 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1483 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1485 if (fscanf(f, "%d", &power) != 1)
1486 eDebug("read %s failed!! (%m)", proc_name);
1488 eDebug("%s is %d\n", proc_name, power);
1493 // open front prozessor
1494 int fp=::open("/dev/dbox/fp0", O_RDWR);
1497 eDebug("couldn't open fp");
1500 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1501 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1503 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1512 bool eDVBFrontend::setSecSequencePos(int steps)
1514 eDebugNoSimulate("set sequence pos %d", steps);
1519 if (m_sec_sequence.current() != m_sec_sequence.end())
1520 ++m_sec_sequence.current();
1525 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1526 --m_sec_sequence.current();
1532 void eDVBFrontend::tuneLoop()
1537 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1540 eDVBFrontend *sec_fe = this;
1541 eDVBRegisteredFrontend *regFE = 0;
1542 long tmp = m_data[LINKED_PREV_PTR];
1545 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1546 sec_fe = prev->m_frontend;
1547 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1548 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1549 int state = sec_fe->m_state;
1550 // workaround to put the kernel frontend thread into idle state!
1551 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1553 sec_fe->closeFrontend(true);
1554 state = sec_fe->m_state;
1556 // sec_fe is closed... we must reopen it here..
1557 if (state == stateClosed)
1565 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1567 long *sec_fe_data = sec_fe->m_data;
1568 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1570 switch (m_sec_sequence.current()->cmd)
1572 case eSecCommand::SLEEP:
1573 delay = m_sec_sequence.current()++->msec;
1574 eDebugNoSimulate("[SEC] sleep %dms", delay);
1576 case eSecCommand::GOTO:
1577 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1578 ++m_sec_sequence.current();
1580 case eSecCommand::SET_VOLTAGE:
1582 int voltage = m_sec_sequence.current()++->voltage;
1583 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1584 sec_fe->setVoltage(voltage);
1587 case eSecCommand::IF_VOLTAGE_GOTO:
1589 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1590 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1592 ++m_sec_sequence.current();
1595 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1597 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1598 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1600 ++m_sec_sequence.current();
1603 case eSecCommand::IF_TONE_GOTO:
1605 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1606 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1608 ++m_sec_sequence.current();
1611 case eSecCommand::IF_NOT_TONE_GOTO:
1613 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1614 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1616 ++m_sec_sequence.current();
1619 case eSecCommand::SET_TONE:
1620 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1621 sec_fe->setTone(m_sec_sequence.current()++->tone);
1623 case eSecCommand::SEND_DISEQC:
1624 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1625 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1626 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1627 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1628 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1629 eDebugNoSimulate("(DiSEqC reset)");
1630 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1631 eDebugNoSimulate("(DiSEqC peripherial power on)");
1633 eDebugNoSimulate("");
1634 ++m_sec_sequence.current();
1636 case eSecCommand::SEND_TONEBURST:
1637 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1638 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1640 case eSecCommand::SET_FRONTEND:
1642 int enableEvents = (m_sec_sequence.current()++)->val;
1643 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1644 setFrontend(enableEvents);
1647 case eSecCommand::START_TUNE_TIMEOUT:
1649 int tuneTimeout = m_sec_sequence.current()->timeout;
1650 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1652 m_timeout->start(tuneTimeout, 1);
1653 ++m_sec_sequence.current();
1656 case eSecCommand::SET_TIMEOUT:
1657 m_timeoutCount = m_sec_sequence.current()++->val;
1658 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1660 case eSecCommand::IF_TIMEOUT_GOTO:
1661 if (!m_timeoutCount)
1663 eDebugNoSimulate("[SEC] rotor timout");
1664 setSecSequencePos(m_sec_sequence.current()->steps);
1667 ++m_sec_sequence.current();
1669 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1671 int idx = m_sec_sequence.current()++->val;
1672 if ( idx == 0 || idx == 1 )
1674 m_idleInputpower[idx] = sec_fe->readInputpower();
1675 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1678 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1681 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1683 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1684 int idx = compare.val;
1685 if ( !m_simulate && (idx == 0 || idx == 1) )
1687 int idle = sec_fe->readInputpower();
1688 int diff = abs(idle-m_idleInputpower[idx]);
1691 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1692 setSecSequencePos(compare.steps);
1696 ++m_sec_sequence.current();
1699 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1701 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1704 setSecSequencePos(cmd.steps);
1708 int isLocked = readFrontendData(locked);
1709 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1711 if (!m_timeoutCount && m_retryCount > 0)
1713 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1716 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1719 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1721 cmd.lastSignal = signal;
1724 if (cmd.okcount > 4)
1726 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1727 setSecSequencePos(cmd.steps);
1728 m_state = stateLock;
1729 m_stateChanged(this);
1730 feEvent(-1); // flush events
1738 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1740 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1744 ++m_sec_sequence.current();
1747 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1748 m_runningInputpower = sec_fe->readInputpower();
1749 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
1750 ++m_sec_sequence.current();
1752 case eSecCommand::SET_ROTOR_MOVING:
1754 m_sec->setRotorMoving(m_slotid, true);
1755 ++m_sec_sequence.current();
1757 case eSecCommand::SET_ROTOR_STOPPED:
1759 m_sec->setRotorMoving(m_slotid, false);
1760 ++m_sec_sequence.current();
1762 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1764 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1767 setSecSequencePos(cmd.steps);
1770 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
1771 const char *txt = cmd.direction ? "running" : "stopped";
1773 if (!m_timeoutCount && m_retryCount > 0)
1775 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1777 m_runningInputpower,
1780 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1781 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1784 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1785 if ( cmd.okcount > 6 )
1787 eDebugNoSimulate("[SEC] rotor is %s", txt);
1788 if (setSecSequencePos(cmd.steps))
1794 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1797 ++m_sec_sequence.current();
1800 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1801 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
1802 setSecSequencePos(m_sec_sequence.current()->steps);
1804 ++m_sec_sequence.current();
1806 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
1807 eDebugNoSimulate("[SEC] invalidate current switch params");
1808 sec_fe_data[CSW] = -1;
1809 sec_fe_data[UCSW] = -1;
1810 sec_fe_data[TONEBURST] = -1;
1811 ++m_sec_sequence.current();
1813 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
1814 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
1815 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
1816 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
1817 eDebugNoSimulate("[SEC] update current switch params");
1818 ++m_sec_sequence.current();
1820 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1821 eDebugNoSimulate("[SEC] invalidate current rotorparams");
1822 sec_fe_data[ROTOR_CMD] = -1;
1823 sec_fe_data[ROTOR_POS] = -1;
1824 ++m_sec_sequence.current();
1826 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1827 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
1828 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
1829 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
1830 ++m_sec_sequence.current();
1832 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1833 m_retryCount = m_sec_sequence.current()++->val;
1834 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
1836 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1839 eDebugNoSimulate("[SEC] no more rotor retrys");
1840 setSecSequencePos(m_sec_sequence.current()->steps);
1843 ++m_sec_sequence.current();
1845 case eSecCommand::SET_POWER_LIMITING_MODE:
1850 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
1851 FILE *f=fopen(proc_name, "w");
1852 if (f) // new interface exist?
1854 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1855 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1856 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
1858 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1861 else if (sec_fe->m_need_rotor_workaround)
1864 int slotid = sec_fe->m_slotid;
1865 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1867 sprintf(dev, "/dev/i2c/%d", slotid);
1868 else if (slotid == 2)
1869 sprintf(dev, "/dev/i2c/2"); // first nim socket on DM8000 use /dev/i2c/2
1870 else if (slotid == 3)
1871 sprintf(dev, "/dev/i2c/4"); // second nim socket on DM8000 use /dev/i2c/4
1872 int fd = ::open(dev, O_RDWR);
1874 unsigned char data[2];
1875 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1876 if(::read(fd, data, 1) != 1)
1877 eDebugNoSimulate("[SEC] error read lnbp (%m)");
1878 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
1880 data[0] |= 0x80; // enable static current limiting
1881 eDebugNoSimulate("[SEC] set static current limiting");
1885 data[0] &= ~0x80; // enable dynamic current limiting
1886 eDebugNoSimulate("[SEC] set dynamic current limiting");
1888 if(::write(fd, data, 1) != 1)
1889 eDebugNoSimulate("[SEC] error write lnbp (%m)");
1893 ++m_sec_sequence.current();
1896 case eSecCommand::DELAYED_CLOSE_FRONTEND:
1898 eDebugNoSimulate("[SEC] delayed close frontend");
1899 closeFrontend(false, true);
1900 ++m_sec_sequence.current();
1904 eDebugNoSimulate("[SEC] unhandled sec command %d",
1905 ++m_sec_sequence.current()->cmd);
1906 ++m_sec_sequence.current();
1909 m_tuneTimer->start(delay,true);
1913 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
1918 void eDVBFrontend::setFrontend(bool recvEvents)
1922 eDebug("setting frontend %d", m_dvbid);
1925 feEvent(-1); // flush events
1926 #if HAVE_DVB_API_VERSION >= 5
1927 if (m_type == iDVBFrontend::feSatellite)
1929 fe_rolloff_t rolloff = ROLLOFF_35;
1930 fe_pilot_t pilot = PILOT_OFF;
1931 fe_modulation_t modulation = QPSK;
1932 fe_delivery_system_t system = SYS_DVBS;
1933 switch(oparm.sat.system)
1935 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
1936 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
1938 switch(oparm.sat.modulation)
1940 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
1941 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
1942 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
1944 switch(oparm.sat.pilot)
1946 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
1947 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
1948 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
1950 switch(oparm.sat.rolloff)
1952 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
1953 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
1954 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
1956 struct dtv_property p[10];
1957 struct dtv_properties cmdseq;
1959 p[0].cmd = DTV_CLEAR;
1960 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1961 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
1962 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
1963 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
1964 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
1965 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
1966 if (system == SYS_DVBS2)
1968 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
1969 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
1970 p[9].cmd = DTV_TUNE;
1975 p[7].cmd = DTV_TUNE;
1978 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
1980 perror("FE_SET_PROPERTY failed");
1987 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
1989 perror("FE_SET_FRONTEND failed");
1996 RESULT eDVBFrontend::getFrontendType(int &t)
2004 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2009 eWarning("no SEC module active!");
2012 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2015 #if HAVE_DVB_API_VERSION >= 3
2016 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",
2019 feparm.polarisation,
2023 feparm.orbital_position,
2029 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2032 feparm.polarisation,
2036 feparm.orbital_position);
2038 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2039 switch (feparm.inversion)
2041 case eDVBFrontendParametersSatellite::Inversion_On:
2042 parm_inversion = INVERSION_ON;
2044 case eDVBFrontendParametersSatellite::Inversion_Off:
2045 parm_inversion = INVERSION_OFF;
2048 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2049 parm_inversion = INVERSION_AUTO;
2052 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2056 case eDVBFrontendParametersSatellite::FEC_None:
2057 parm_u_qpsk_fec_inner = FEC_NONE;
2059 case eDVBFrontendParametersSatellite::FEC_1_2:
2060 parm_u_qpsk_fec_inner = FEC_1_2;
2062 case eDVBFrontendParametersSatellite::FEC_2_3:
2063 parm_u_qpsk_fec_inner = FEC_2_3;
2065 case eDVBFrontendParametersSatellite::FEC_3_4:
2066 parm_u_qpsk_fec_inner = FEC_3_4;
2068 case eDVBFrontendParametersSatellite::FEC_5_6:
2069 parm_u_qpsk_fec_inner = FEC_5_6;
2071 case eDVBFrontendParametersSatellite::FEC_7_8:
2072 parm_u_qpsk_fec_inner = FEC_7_8;
2075 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2076 case eDVBFrontendParametersSatellite::FEC_Auto:
2077 parm_u_qpsk_fec_inner = FEC_AUTO;
2081 #if HAVE_DVB_API_VERSION >= 3
2086 case eDVBFrontendParametersSatellite::FEC_1_2:
2087 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2089 case eDVBFrontendParametersSatellite::FEC_2_3:
2090 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2092 case eDVBFrontendParametersSatellite::FEC_3_4:
2093 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2095 case eDVBFrontendParametersSatellite::FEC_3_5:
2096 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2098 case eDVBFrontendParametersSatellite::FEC_4_5:
2099 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2101 case eDVBFrontendParametersSatellite::FEC_5_6:
2102 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2104 case eDVBFrontendParametersSatellite::FEC_7_8:
2105 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2107 case eDVBFrontendParametersSatellite::FEC_8_9:
2108 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2110 case eDVBFrontendParametersSatellite::FEC_9_10:
2111 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2114 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2117 #if HAVE_DVB_API_VERSION < 5
2118 parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff
2119 parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot
2120 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2122 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2123 // 8PSK fec driver values are decimal 9 bigger
2128 // FIXME !!! get frequency range from tuner
2129 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2131 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2134 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2140 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2142 #if HAVE_DVB_API_VERSION < 3
2143 parm_frequency = feparm.frequency;
2145 parm_frequency = feparm.frequency * 1000;
2147 parm_u_qam_symbol_rate = feparm.symbol_rate;
2148 switch (feparm.modulation)
2150 case eDVBFrontendParametersCable::Modulation_QAM16:
2151 parm_u_qam_modulation = QAM_16;
2153 case eDVBFrontendParametersCable::Modulation_QAM32:
2154 parm_u_qam_modulation = QAM_32;
2156 case eDVBFrontendParametersCable::Modulation_QAM64:
2157 parm_u_qam_modulation = QAM_64;
2159 case eDVBFrontendParametersCable::Modulation_QAM128:
2160 parm_u_qam_modulation = QAM_128;
2162 case eDVBFrontendParametersCable::Modulation_QAM256:
2163 parm_u_qam_modulation = QAM_256;
2166 case eDVBFrontendParametersCable::Modulation_Auto:
2167 parm_u_qam_modulation = QAM_AUTO;
2170 switch (feparm.inversion)
2172 case eDVBFrontendParametersCable::Inversion_On:
2173 parm_inversion = INVERSION_ON;
2175 case eDVBFrontendParametersCable::Inversion_Off:
2176 parm_inversion = INVERSION_OFF;
2179 case eDVBFrontendParametersCable::Inversion_Unknown:
2180 parm_inversion = INVERSION_AUTO;
2183 switch (feparm.fec_inner)
2185 case eDVBFrontendParametersCable::FEC_None:
2186 parm_u_qam_fec_inner = FEC_NONE;
2188 case eDVBFrontendParametersCable::FEC_1_2:
2189 parm_u_qam_fec_inner = FEC_1_2;
2191 case eDVBFrontendParametersCable::FEC_2_3:
2192 parm_u_qam_fec_inner = FEC_2_3;
2194 case eDVBFrontendParametersCable::FEC_3_4:
2195 parm_u_qam_fec_inner = FEC_3_4;
2197 case eDVBFrontendParametersCable::FEC_5_6:
2198 parm_u_qam_fec_inner = FEC_5_6;
2200 case eDVBFrontendParametersCable::FEC_7_8:
2201 parm_u_qam_fec_inner = FEC_7_8;
2203 #if HAVE_DVB_API_VERSION >= 3
2204 case eDVBFrontendParametersCable::FEC_8_9:
2205 parm_u_qam_fec_inner = FEC_8_9;
2209 case eDVBFrontendParametersCable::FEC_Auto:
2210 parm_u_qam_fec_inner = FEC_AUTO;
2213 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2214 parm_frequency/1000,
2215 parm_u_qam_symbol_rate,
2216 parm_u_qam_fec_inner,
2217 parm_u_qam_modulation,
2223 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2225 parm_frequency = feparm.frequency;
2227 switch (feparm.bandwidth)
2229 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2230 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2232 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2233 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2235 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2236 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2239 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2240 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2243 switch (feparm.code_rate_LP)
2245 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2246 parm_u_ofdm_code_rate_LP = FEC_1_2;
2248 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2249 parm_u_ofdm_code_rate_LP = FEC_2_3;
2251 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2252 parm_u_ofdm_code_rate_LP = FEC_3_4;
2254 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2255 parm_u_ofdm_code_rate_LP = FEC_5_6;
2257 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2258 parm_u_ofdm_code_rate_LP = FEC_7_8;
2261 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2262 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2265 switch (feparm.code_rate_HP)
2267 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2268 parm_u_ofdm_code_rate_HP = FEC_1_2;
2270 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2271 parm_u_ofdm_code_rate_HP = FEC_2_3;
2273 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2274 parm_u_ofdm_code_rate_HP = FEC_3_4;
2276 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2277 parm_u_ofdm_code_rate_HP = FEC_5_6;
2279 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2280 parm_u_ofdm_code_rate_HP = FEC_7_8;
2283 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2284 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2287 switch (feparm.modulation)
2289 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2290 parm_u_ofdm_constellation = QPSK;
2292 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2293 parm_u_ofdm_constellation = QAM_16;
2295 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2296 parm_u_ofdm_constellation = QAM_64;
2299 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2300 parm_u_ofdm_constellation = QAM_AUTO;
2303 switch (feparm.transmission_mode)
2305 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2306 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2308 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2309 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2312 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2313 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2316 switch (feparm.guard_interval)
2318 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2319 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2321 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2322 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2324 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2325 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2327 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2328 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2331 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2332 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2335 switch (feparm.hierarchy)
2337 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2338 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2340 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2341 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2343 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2344 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2346 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2347 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2350 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2351 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2354 switch (feparm.inversion)
2356 case eDVBFrontendParametersTerrestrial::Inversion_On:
2357 parm_inversion = INVERSION_ON;
2359 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2360 parm_inversion = INVERSION_OFF;
2363 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2364 parm_inversion = INVERSION_AUTO;
2371 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2373 unsigned int timeout = 5000;
2374 eDebugNoSimulate("(%d)tune", m_dvbid);
2380 if (!m_sn && !m_simulate)
2382 eDebug("no frontend device opened... do not try to tune !!!");
2396 m_sec_sequence.clear();
2398 where.calcLockTimeout(timeout);
2404 eDVBFrontendParametersSatellite feparm;
2405 if (where.getDVBS(feparm))
2407 eDebug("no dvbs data!");
2411 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2413 eDVBFrontend *sec_fe = this;
2414 long tmp = m_data[LINKED_PREV_PTR];
2417 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2418 sec_fe = linked_fe->m_frontend;
2419 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2421 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2422 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
2424 m_rotor_mode = feparm.no_rotor_command_on_tune;
2426 m_sec->setRotorMoving(m_slotid, false);
2427 res=prepare_sat(feparm, timeout);
2435 eDVBFrontendParametersCable feparm;
2436 if (where.getDVBC(feparm))
2441 res=prepare_cable(feparm);
2445 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2446 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2451 eDVBFrontendParametersTerrestrial feparm;
2452 if (where.getDVBT(feparm))
2454 eDebug("no -T data");
2458 res=prepare_terrestrial(feparm);
2462 std::string enable_5V;
2463 char configStr[255];
2464 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2465 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2466 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2467 if (enable_5V == "True")
2468 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2470 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2471 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2477 m_sec_sequence.current() = m_sec_sequence.begin();
2481 m_tuneTimer->start(0,true);
2483 if (m_state != stateTuning)
2485 m_state = stateTuning;
2486 m_stateChanged(this);
2495 m_tuneTimer->stop();
2499 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2501 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2505 RESULT eDVBFrontend::setVoltage(int voltage)
2507 if (m_type == feCable)
2509 #if HAVE_DVB_API_VERSION < 3
2512 bool increased=false;
2513 fe_sec_voltage_t vlt;
2515 m_data[CUR_VOLTAGE]=voltage;
2519 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2520 vlt = SEC_VOLTAGE_OFF;
2523 #if HAVE_DVB_API_VERSION < 3
2524 vlt = SEC_VOLTAGE_13_5;
2530 vlt = SEC_VOLTAGE_13;
2533 #if HAVE_DVB_API_VERSION < 3
2534 vlt = SEC_VOLTAGE_18_5;
2540 vlt = SEC_VOLTAGE_18;
2547 #if HAVE_DVB_API_VERSION < 3
2548 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2550 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2551 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2552 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2556 RESULT eDVBFrontend::getState(int &state)
2562 RESULT eDVBFrontend::setTone(int t)
2564 if (m_type != feSatellite)
2566 #if HAVE_DVB_API_VERSION < 3
2569 fe_sec_tone_mode_t tone;
2578 tone = SEC_TONE_OFF;
2585 #if HAVE_DVB_API_VERSION < 3
2586 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2588 return ::ioctl(m_fd, FE_SET_TONE, tone);
2592 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2593 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2596 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2600 #if HAVE_DVB_API_VERSION < 3
2601 struct secCommand cmd;
2602 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
2603 cmd.u.diseqc.cmdtype = diseqc.data[0];
2604 cmd.u.diseqc.addr = diseqc.data[1];
2605 cmd.u.diseqc.cmd = diseqc.data[2];
2606 cmd.u.diseqc.numParams = diseqc.len-3;
2607 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
2608 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
2610 struct dvb_diseqc_master_cmd cmd;
2611 memcpy(cmd.msg, diseqc.data, diseqc.len);
2612 cmd.msg_len = diseqc.len;
2613 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2619 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
2620 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
2622 RESULT eDVBFrontend::sendToneburst(int burst)
2626 #if HAVE_DVB_API_VERSION < 3
2627 secMiniCmd cmd = SEC_MINI_NONE;
2629 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2631 if ( burst == eDVBSatelliteDiseqcParameters::A )
2633 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2635 #if HAVE_DVB_API_VERSION < 3
2636 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
2639 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2645 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2651 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
2653 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
2654 m_sec_sequence.push_back(list);
2656 m_sec_sequence = list;
2660 RESULT eDVBFrontend::getData(int num, long &data)
2662 if ( num < NUM_DATA_ENTRIES )
2670 RESULT eDVBFrontend::setData(int num, long val)
2672 if ( num < NUM_DATA_ENTRIES )
2680 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2683 if (feparm->getSystem(type) || type != m_type || !m_enabled)
2685 if (m_type == eDVBFrontend::feSatellite)
2688 eDVBFrontendParametersSatellite sat_parm;
2689 int ret = feparm->getDVBS(sat_parm);
2691 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
2693 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
2694 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
2698 else if (m_type == eDVBFrontend::feCable)
2699 return 2; // more prio for cable frontends
2700 else if (m_type == eDVBFrontend::feTerrestrial)
2705 bool eDVBFrontend::setSlotInfo(ePyObject obj)
2707 ePyObject Id, Descr, Enabled, IsDVBS2;
2708 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 4)
2710 Id = PyTuple_GET_ITEM(obj, 0);
2711 Descr = PyTuple_GET_ITEM(obj, 1);
2712 Enabled = PyTuple_GET_ITEM(obj, 2);
2713 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
2714 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2))
2716 strcpy(m_description, PyString_AS_STRING(Descr));
2717 m_slotid = PyInt_AsLong(Id);
2718 m_enabled = Enabled == Py_True;
2719 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
2720 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
2721 !!strstr(m_description, "Alps BSBE2") ||
2722 !!strstr(m_description, "Alps -S") ||
2723 !!strstr(m_description, "BCM4501");
2724 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
2725 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s",
2726 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" );
2729 PyErr_SetString(PyExc_StandardError,
2730 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");