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");
1097 PutToDict(dict, "fec_inner", tmp);
1099 switch (p[0].u.data)
1101 default: eDebug("got unsupported system from frontend! report as DVBS!");
1102 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1105 switch (p[2].u.data)
1107 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1108 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1109 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1110 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1112 PutToDict(dict, "rolloff", tmp);
1114 switch (p[3].u.data)
1116 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1117 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1118 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1120 PutToDict(dict, "pilot", tmp);
1122 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1125 PutToDict(dict, "system", tmp);
1127 switch (p[1].u.data)
1129 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1130 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1131 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1133 PutToDict(dict, "modulation", tmp);
1137 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1140 int frequency = parm_frequency + freq_offset;
1141 PutToDict(dict, "frequency", frequency);
1142 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1143 PutToDict(dict, "orbital_position", orb_pos);
1144 PutToDict(dict, "polarization", polarization);
1146 switch((int)parm_u_qpsk_fec_inner)
1148 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1149 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1150 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1151 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1152 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1153 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1155 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1156 #if HAVE_DVB_API_VERSION >=3
1157 case FEC_S2_8PSK_1_2:
1158 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1159 case FEC_S2_8PSK_2_3:
1160 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1161 case FEC_S2_8PSK_3_4:
1162 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1163 case FEC_S2_8PSK_5_6:
1164 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1165 case FEC_S2_8PSK_7_8:
1166 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1167 case FEC_S2_8PSK_8_9:
1168 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1169 case FEC_S2_8PSK_3_5:
1170 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1171 case FEC_S2_8PSK_4_5:
1172 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1173 case FEC_S2_8PSK_9_10:
1174 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1177 PutToDict(dict, "fec_inner", tmp);
1178 #if HAVE_DVB_API_VERSION >=3
1179 PutToDict(dict, "modulation",
1180 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1181 eDVBFrontendParametersSatellite::Modulation_8PSK :
1182 eDVBFrontendParametersSatellite::Modulation_QPSK );
1183 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1185 switch(parm_inversion & 0xc)
1187 default: // unknown rolloff
1188 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1189 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1190 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1192 PutToDict(dict, "rolloff", tmp);
1193 switch(parm_inversion & 0x30)
1195 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1196 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1197 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1199 PutToDict(dict, "pilot", tmp);
1200 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1203 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1205 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1206 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1208 PutToDict(dict, "system", tmp);
1212 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1215 #if HAVE_DVB_API_VERSION < 3
1216 PutToDict(dict, "frequency", parm_frequency);
1218 PutToDict(dict, "frequency", parm_frequency/1000);
1220 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1221 switch(parm_u_qam_fec_inner)
1223 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1224 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1225 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1226 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1227 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1228 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1229 #if HAVE_DVB_API_VERSION >= 3
1230 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1233 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1235 PutToDict(dict, "fec_inner", tmp);
1236 switch(parm_u_qam_modulation)
1238 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1239 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1240 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1241 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1242 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1244 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1246 PutToDict(dict, "modulation", tmp);
1249 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1252 PutToDict(dict, "frequency", parm_frequency);
1253 switch (parm_u_ofdm_bandwidth)
1255 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1256 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1257 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1259 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1261 PutToDict(dict, "bandwidth", tmp);
1262 switch (parm_u_ofdm_code_rate_LP)
1264 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1265 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1266 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1267 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1268 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1270 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1272 PutToDict(dict, "code_rate_lp", tmp);
1273 switch (parm_u_ofdm_code_rate_HP)
1275 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1276 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1277 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1278 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1279 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1281 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1283 PutToDict(dict, "code_rate_hp", tmp);
1284 switch (parm_u_ofdm_constellation)
1286 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1287 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1288 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1290 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1292 PutToDict(dict, "constellation", tmp);
1293 switch (parm_u_ofdm_transmission_mode)
1295 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1296 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1298 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1300 PutToDict(dict, "transmission_mode", tmp);
1301 switch (parm_u_ofdm_guard_interval)
1303 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1304 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1305 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1306 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1308 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1310 PutToDict(dict, "guard_interval", tmp);
1311 switch (parm_u_ofdm_hierarchy_information)
1313 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1314 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1315 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1316 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1318 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1320 PutToDict(dict, "hierarchy_information", tmp);
1323 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1325 if (dest && PyDict_Check(dest))
1327 const char *tmp = "UNKNOWN";
1348 PutToDict(dest, "tuner_state", tmp);
1349 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1350 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1351 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1352 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1353 int sigQualitydB = readFrontendData(signalQualitydB);
1354 if (sigQualitydB == 0x12345678) // not support yet
1356 ePyObject obj=Py_None;
1358 PutToDict(dest, "tuner_signal_quality_db", obj);
1361 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1362 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1366 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1368 if (dest && PyDict_Check(dest))
1370 FRONTENDPARAMETERS front;
1371 #if HAVE_DVB_API_VERSION >= 5
1372 struct dtv_property p[4];
1373 struct dtv_properties cmdseq;
1376 p[0].cmd = DTV_DELIVERY_SYSTEM;
1377 p[1].cmd = DTV_MODULATION;
1378 p[2].cmd = DTV_ROLLOFF;
1379 p[3].cmd = DTV_PILOT;
1381 if (m_simulate || m_fd == -1 || original)
1383 #if HAVE_DVB_API_VERSION >= 5
1384 else if (m_type == feSatellite && // yet just use new api for DVB-S(2) only
1385 ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1387 eDebug("FE_GET_PROPERTY failed (%m)");
1391 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1393 eDebug("FE_GET_FRONTEND failed (%m)");
1401 PutSatelliteDataToDict(dest, oparm.sat);
1404 PutCableDataToDict(dest, oparm.cab);
1407 PutTerrestrialDataToDict(dest, oparm.ter);
1413 FRONTENDPARAMETERS &parm = front;
1414 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1415 switch(parm_inversion & 3)
1418 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1421 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1425 PutToDict(dest, "inversion", tmp);
1429 #if HAVE_DVB_API_VERSION >= 5
1430 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1432 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1436 fillDictWithCableData(dest, parm);
1439 fillDictWithTerrestrialData(dest, parm);
1446 void eDVBFrontend::getFrontendData(ePyObject dest)
1448 if (dest && PyDict_Check(dest))
1451 PutToDict(dest, "tuner_number", m_slotid);
1467 PutToDict(dest, "tuner_type", tmp);
1471 #ifndef FP_IOCTL_GET_ID
1472 #define FP_IOCTL_GET_ID 0
1474 int eDVBFrontend::readInputpower()
1478 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1480 char proc_name2[64];
1481 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1482 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1484 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1486 if (fscanf(f, "%d", &power) != 1)
1487 eDebug("read %s failed!! (%m)", proc_name);
1489 eDebug("%s is %d\n", proc_name, power);
1494 // open front prozessor
1495 int fp=::open("/dev/dbox/fp0", O_RDWR);
1498 eDebug("couldn't open fp");
1501 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1502 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1504 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1513 bool eDVBFrontend::setSecSequencePos(int steps)
1515 eDebugNoSimulate("set sequence pos %d", steps);
1520 if (m_sec_sequence.current() != m_sec_sequence.end())
1521 ++m_sec_sequence.current();
1526 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1527 --m_sec_sequence.current();
1533 void eDVBFrontend::tuneLoop()
1538 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1541 eDVBFrontend *sec_fe = this;
1542 eDVBRegisteredFrontend *regFE = 0;
1543 long tmp = m_data[LINKED_PREV_PTR];
1546 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1547 sec_fe = prev->m_frontend;
1548 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1549 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1550 int state = sec_fe->m_state;
1551 // workaround to put the kernel frontend thread into idle state!
1552 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1554 sec_fe->closeFrontend(true);
1555 state = sec_fe->m_state;
1557 // sec_fe is closed... we must reopen it here..
1558 if (state == stateClosed)
1566 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1568 long *sec_fe_data = sec_fe->m_data;
1569 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1571 switch (m_sec_sequence.current()->cmd)
1573 case eSecCommand::SLEEP:
1574 delay = m_sec_sequence.current()++->msec;
1575 eDebugNoSimulate("[SEC] sleep %dms", delay);
1577 case eSecCommand::GOTO:
1578 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1579 ++m_sec_sequence.current();
1581 case eSecCommand::SET_VOLTAGE:
1583 int voltage = m_sec_sequence.current()++->voltage;
1584 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1585 sec_fe->setVoltage(voltage);
1588 case eSecCommand::IF_VOLTAGE_GOTO:
1590 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1591 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1593 ++m_sec_sequence.current();
1596 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1598 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1599 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1601 ++m_sec_sequence.current();
1604 case eSecCommand::IF_TONE_GOTO:
1606 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1607 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1609 ++m_sec_sequence.current();
1612 case eSecCommand::IF_NOT_TONE_GOTO:
1614 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1615 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1617 ++m_sec_sequence.current();
1620 case eSecCommand::SET_TONE:
1621 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1622 sec_fe->setTone(m_sec_sequence.current()++->tone);
1624 case eSecCommand::SEND_DISEQC:
1625 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1626 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1627 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1628 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1629 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1630 eDebugNoSimulate("(DiSEqC reset)");
1631 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1632 eDebugNoSimulate("(DiSEqC peripherial power on)");
1634 eDebugNoSimulate("");
1635 ++m_sec_sequence.current();
1637 case eSecCommand::SEND_TONEBURST:
1638 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1639 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1641 case eSecCommand::SET_FRONTEND:
1643 int enableEvents = (m_sec_sequence.current()++)->val;
1644 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1645 setFrontend(enableEvents);
1648 case eSecCommand::START_TUNE_TIMEOUT:
1650 int tuneTimeout = m_sec_sequence.current()->timeout;
1651 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1653 m_timeout->start(tuneTimeout, 1);
1654 ++m_sec_sequence.current();
1657 case eSecCommand::SET_TIMEOUT:
1658 m_timeoutCount = m_sec_sequence.current()++->val;
1659 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1661 case eSecCommand::IF_TIMEOUT_GOTO:
1662 if (!m_timeoutCount)
1664 eDebugNoSimulate("[SEC] rotor timout");
1665 setSecSequencePos(m_sec_sequence.current()->steps);
1668 ++m_sec_sequence.current();
1670 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1672 int idx = m_sec_sequence.current()++->val;
1673 if ( idx == 0 || idx == 1 )
1675 m_idleInputpower[idx] = sec_fe->readInputpower();
1676 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1679 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1682 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1684 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1685 int idx = compare.val;
1686 if ( !m_simulate && (idx == 0 || idx == 1) )
1688 int idle = sec_fe->readInputpower();
1689 int diff = abs(idle-m_idleInputpower[idx]);
1692 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1693 setSecSequencePos(compare.steps);
1697 ++m_sec_sequence.current();
1700 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1702 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1705 setSecSequencePos(cmd.steps);
1709 int isLocked = readFrontendData(locked);
1710 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1712 if (!m_timeoutCount && m_retryCount > 0)
1714 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1717 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1720 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1722 cmd.lastSignal = signal;
1725 if (cmd.okcount > 4)
1727 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1728 setSecSequencePos(cmd.steps);
1729 m_state = stateLock;
1730 m_stateChanged(this);
1731 feEvent(-1); // flush events
1739 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1741 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1745 ++m_sec_sequence.current();
1748 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1749 m_runningInputpower = sec_fe->readInputpower();
1750 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
1751 ++m_sec_sequence.current();
1753 case eSecCommand::SET_ROTOR_MOVING:
1755 m_sec->setRotorMoving(m_slotid, true);
1756 ++m_sec_sequence.current();
1758 case eSecCommand::SET_ROTOR_STOPPED:
1760 m_sec->setRotorMoving(m_slotid, false);
1761 ++m_sec_sequence.current();
1763 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1765 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1768 setSecSequencePos(cmd.steps);
1771 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
1772 const char *txt = cmd.direction ? "running" : "stopped";
1774 if (!m_timeoutCount && m_retryCount > 0)
1776 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1778 m_runningInputpower,
1781 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1782 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1785 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1786 if ( cmd.okcount > 6 )
1788 eDebugNoSimulate("[SEC] rotor is %s", txt);
1789 if (setSecSequencePos(cmd.steps))
1795 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1798 ++m_sec_sequence.current();
1801 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1802 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
1803 setSecSequencePos(m_sec_sequence.current()->steps);
1805 ++m_sec_sequence.current();
1807 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
1808 eDebugNoSimulate("[SEC] invalidate current switch params");
1809 sec_fe_data[CSW] = -1;
1810 sec_fe_data[UCSW] = -1;
1811 sec_fe_data[TONEBURST] = -1;
1812 ++m_sec_sequence.current();
1814 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
1815 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
1816 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
1817 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
1818 eDebugNoSimulate("[SEC] update current switch params");
1819 ++m_sec_sequence.current();
1821 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1822 eDebugNoSimulate("[SEC] invalidate current rotorparams");
1823 sec_fe_data[ROTOR_CMD] = -1;
1824 sec_fe_data[ROTOR_POS] = -1;
1825 ++m_sec_sequence.current();
1827 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1828 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
1829 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
1830 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
1831 ++m_sec_sequence.current();
1833 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1834 m_retryCount = m_sec_sequence.current()++->val;
1835 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
1837 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1840 eDebugNoSimulate("[SEC] no more rotor retrys");
1841 setSecSequencePos(m_sec_sequence.current()->steps);
1844 ++m_sec_sequence.current();
1846 case eSecCommand::SET_POWER_LIMITING_MODE:
1851 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
1852 FILE *f=fopen(proc_name, "w");
1853 if (f) // new interface exist?
1855 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1856 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1857 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
1859 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1862 else if (sec_fe->m_need_rotor_workaround)
1865 int slotid = sec_fe->m_slotid;
1866 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1868 sprintf(dev, "/dev/i2c/%d", slotid);
1869 else if (slotid == 2)
1870 sprintf(dev, "/dev/i2c/2"); // first nim socket on DM8000 use /dev/i2c/2
1871 else if (slotid == 3)
1872 sprintf(dev, "/dev/i2c/4"); // second nim socket on DM8000 use /dev/i2c/4
1873 int fd = ::open(dev, O_RDWR);
1875 unsigned char data[2];
1876 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1877 if(::read(fd, data, 1) != 1)
1878 eDebugNoSimulate("[SEC] error read lnbp (%m)");
1879 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
1881 data[0] |= 0x80; // enable static current limiting
1882 eDebugNoSimulate("[SEC] set static current limiting");
1886 data[0] &= ~0x80; // enable dynamic current limiting
1887 eDebugNoSimulate("[SEC] set dynamic current limiting");
1889 if(::write(fd, data, 1) != 1)
1890 eDebugNoSimulate("[SEC] error write lnbp (%m)");
1894 ++m_sec_sequence.current();
1897 case eSecCommand::DELAYED_CLOSE_FRONTEND:
1899 eDebugNoSimulate("[SEC] delayed close frontend");
1900 closeFrontend(false, true);
1901 ++m_sec_sequence.current();
1905 eDebugNoSimulate("[SEC] unhandled sec command %d",
1906 ++m_sec_sequence.current()->cmd);
1907 ++m_sec_sequence.current();
1910 m_tuneTimer->start(delay,true);
1914 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
1919 void eDVBFrontend::setFrontend(bool recvEvents)
1923 eDebug("setting frontend %d", m_dvbid);
1926 feEvent(-1); // flush events
1927 #if HAVE_DVB_API_VERSION >= 5
1928 if (m_type == iDVBFrontend::feSatellite)
1930 fe_rolloff_t rolloff = ROLLOFF_35;
1931 fe_pilot_t pilot = PILOT_OFF;
1932 fe_modulation_t modulation = QPSK;
1933 fe_delivery_system_t system = SYS_DVBS;
1934 switch(oparm.sat.system)
1936 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
1937 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
1939 switch(oparm.sat.modulation)
1941 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
1942 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
1943 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
1945 switch(oparm.sat.pilot)
1947 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
1948 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
1949 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
1951 switch(oparm.sat.rolloff)
1953 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
1954 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
1955 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
1957 struct dtv_property p[10];
1958 struct dtv_properties cmdseq;
1960 p[0].cmd = DTV_CLEAR;
1961 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1962 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
1963 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
1964 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
1965 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
1966 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
1967 if (system == SYS_DVBS2)
1969 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
1970 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
1971 p[9].cmd = DTV_TUNE;
1976 p[7].cmd = DTV_TUNE;
1979 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
1981 perror("FE_SET_PROPERTY failed");
1988 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
1990 perror("FE_SET_FRONTEND failed");
1997 RESULT eDVBFrontend::getFrontendType(int &t)
2005 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2010 eWarning("no SEC module active!");
2013 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2016 #if HAVE_DVB_API_VERSION >= 3
2017 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",
2020 feparm.polarisation,
2024 feparm.orbital_position,
2030 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2033 feparm.polarisation,
2037 feparm.orbital_position);
2039 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2040 switch (feparm.inversion)
2042 case eDVBFrontendParametersSatellite::Inversion_On:
2043 parm_inversion = INVERSION_ON;
2045 case eDVBFrontendParametersSatellite::Inversion_Off:
2046 parm_inversion = INVERSION_OFF;
2049 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2050 parm_inversion = INVERSION_AUTO;
2053 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2057 case eDVBFrontendParametersSatellite::FEC_None:
2058 parm_u_qpsk_fec_inner = FEC_NONE;
2060 case eDVBFrontendParametersSatellite::FEC_1_2:
2061 parm_u_qpsk_fec_inner = FEC_1_2;
2063 case eDVBFrontendParametersSatellite::FEC_2_3:
2064 parm_u_qpsk_fec_inner = FEC_2_3;
2066 case eDVBFrontendParametersSatellite::FEC_3_4:
2067 parm_u_qpsk_fec_inner = FEC_3_4;
2069 case eDVBFrontendParametersSatellite::FEC_5_6:
2070 parm_u_qpsk_fec_inner = FEC_5_6;
2072 case eDVBFrontendParametersSatellite::FEC_7_8:
2073 parm_u_qpsk_fec_inner = FEC_7_8;
2076 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2077 case eDVBFrontendParametersSatellite::FEC_Auto:
2078 parm_u_qpsk_fec_inner = FEC_AUTO;
2082 #if HAVE_DVB_API_VERSION >= 3
2087 case eDVBFrontendParametersSatellite::FEC_1_2:
2088 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2090 case eDVBFrontendParametersSatellite::FEC_2_3:
2091 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2093 case eDVBFrontendParametersSatellite::FEC_3_4:
2094 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2096 case eDVBFrontendParametersSatellite::FEC_3_5:
2097 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2099 case eDVBFrontendParametersSatellite::FEC_4_5:
2100 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2102 case eDVBFrontendParametersSatellite::FEC_5_6:
2103 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2105 case eDVBFrontendParametersSatellite::FEC_7_8:
2106 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2108 case eDVBFrontendParametersSatellite::FEC_8_9:
2109 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2111 case eDVBFrontendParametersSatellite::FEC_9_10:
2112 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2115 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2118 #if HAVE_DVB_API_VERSION < 5
2119 parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff
2120 parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot
2121 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2123 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2124 // 8PSK fec driver values are decimal 9 bigger
2129 // FIXME !!! get frequency range from tuner
2130 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2132 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2135 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2141 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2143 #if HAVE_DVB_API_VERSION < 3
2144 parm_frequency = feparm.frequency;
2146 parm_frequency = feparm.frequency * 1000;
2148 parm_u_qam_symbol_rate = feparm.symbol_rate;
2149 switch (feparm.modulation)
2151 case eDVBFrontendParametersCable::Modulation_QAM16:
2152 parm_u_qam_modulation = QAM_16;
2154 case eDVBFrontendParametersCable::Modulation_QAM32:
2155 parm_u_qam_modulation = QAM_32;
2157 case eDVBFrontendParametersCable::Modulation_QAM64:
2158 parm_u_qam_modulation = QAM_64;
2160 case eDVBFrontendParametersCable::Modulation_QAM128:
2161 parm_u_qam_modulation = QAM_128;
2163 case eDVBFrontendParametersCable::Modulation_QAM256:
2164 parm_u_qam_modulation = QAM_256;
2167 case eDVBFrontendParametersCable::Modulation_Auto:
2168 parm_u_qam_modulation = QAM_AUTO;
2171 switch (feparm.inversion)
2173 case eDVBFrontendParametersCable::Inversion_On:
2174 parm_inversion = INVERSION_ON;
2176 case eDVBFrontendParametersCable::Inversion_Off:
2177 parm_inversion = INVERSION_OFF;
2180 case eDVBFrontendParametersCable::Inversion_Unknown:
2181 parm_inversion = INVERSION_AUTO;
2184 switch (feparm.fec_inner)
2186 case eDVBFrontendParametersCable::FEC_None:
2187 parm_u_qam_fec_inner = FEC_NONE;
2189 case eDVBFrontendParametersCable::FEC_1_2:
2190 parm_u_qam_fec_inner = FEC_1_2;
2192 case eDVBFrontendParametersCable::FEC_2_3:
2193 parm_u_qam_fec_inner = FEC_2_3;
2195 case eDVBFrontendParametersCable::FEC_3_4:
2196 parm_u_qam_fec_inner = FEC_3_4;
2198 case eDVBFrontendParametersCable::FEC_5_6:
2199 parm_u_qam_fec_inner = FEC_5_6;
2201 case eDVBFrontendParametersCable::FEC_7_8:
2202 parm_u_qam_fec_inner = FEC_7_8;
2204 #if HAVE_DVB_API_VERSION >= 3
2205 case eDVBFrontendParametersCable::FEC_8_9:
2206 parm_u_qam_fec_inner = FEC_8_9;
2210 case eDVBFrontendParametersCable::FEC_Auto:
2211 parm_u_qam_fec_inner = FEC_AUTO;
2214 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2215 parm_frequency/1000,
2216 parm_u_qam_symbol_rate,
2217 parm_u_qam_fec_inner,
2218 parm_u_qam_modulation,
2224 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2226 parm_frequency = feparm.frequency;
2228 switch (feparm.bandwidth)
2230 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2231 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2233 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2234 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2236 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2237 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2240 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2241 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2244 switch (feparm.code_rate_LP)
2246 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2247 parm_u_ofdm_code_rate_LP = FEC_1_2;
2249 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2250 parm_u_ofdm_code_rate_LP = FEC_2_3;
2252 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2253 parm_u_ofdm_code_rate_LP = FEC_3_4;
2255 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2256 parm_u_ofdm_code_rate_LP = FEC_5_6;
2258 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2259 parm_u_ofdm_code_rate_LP = FEC_7_8;
2262 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2263 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2266 switch (feparm.code_rate_HP)
2268 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2269 parm_u_ofdm_code_rate_HP = FEC_1_2;
2271 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2272 parm_u_ofdm_code_rate_HP = FEC_2_3;
2274 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2275 parm_u_ofdm_code_rate_HP = FEC_3_4;
2277 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2278 parm_u_ofdm_code_rate_HP = FEC_5_6;
2280 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2281 parm_u_ofdm_code_rate_HP = FEC_7_8;
2284 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2285 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2288 switch (feparm.modulation)
2290 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2291 parm_u_ofdm_constellation = QPSK;
2293 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2294 parm_u_ofdm_constellation = QAM_16;
2296 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2297 parm_u_ofdm_constellation = QAM_64;
2300 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2301 parm_u_ofdm_constellation = QAM_AUTO;
2304 switch (feparm.transmission_mode)
2306 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2307 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2309 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2310 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2313 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2314 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2317 switch (feparm.guard_interval)
2319 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2320 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2322 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2323 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2325 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2326 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2328 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2329 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2332 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2333 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2336 switch (feparm.hierarchy)
2338 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2339 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2341 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2342 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2344 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2345 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2347 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2348 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2351 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2352 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2355 switch (feparm.inversion)
2357 case eDVBFrontendParametersTerrestrial::Inversion_On:
2358 parm_inversion = INVERSION_ON;
2360 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2361 parm_inversion = INVERSION_OFF;
2364 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2365 parm_inversion = INVERSION_AUTO;
2372 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2374 unsigned int timeout = 5000;
2375 eDebugNoSimulate("(%d)tune", m_dvbid);
2381 if (!m_sn && !m_simulate)
2383 eDebug("no frontend device opened... do not try to tune !!!");
2397 m_sec_sequence.clear();
2399 where.calcLockTimeout(timeout);
2405 eDVBFrontendParametersSatellite feparm;
2406 if (where.getDVBS(feparm))
2408 eDebug("no dvbs data!");
2412 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2414 eDVBFrontend *sec_fe = this;
2415 long tmp = m_data[LINKED_PREV_PTR];
2418 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2419 sec_fe = linked_fe->m_frontend;
2420 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2422 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2423 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
2425 m_rotor_mode = feparm.no_rotor_command_on_tune;
2427 m_sec->setRotorMoving(m_slotid, false);
2428 res=prepare_sat(feparm, timeout);
2436 eDVBFrontendParametersCable feparm;
2437 if (where.getDVBC(feparm))
2442 res=prepare_cable(feparm);
2446 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2447 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2452 eDVBFrontendParametersTerrestrial feparm;
2453 if (where.getDVBT(feparm))
2455 eDebug("no -T data");
2459 res=prepare_terrestrial(feparm);
2463 std::string enable_5V;
2464 char configStr[255];
2465 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2466 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2467 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2468 if (enable_5V == "True")
2469 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2471 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2472 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2478 m_sec_sequence.current() = m_sec_sequence.begin();
2482 m_tuneTimer->start(0,true);
2484 if (m_state != stateTuning)
2486 m_state = stateTuning;
2487 m_stateChanged(this);
2496 m_tuneTimer->stop();
2500 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2502 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2506 RESULT eDVBFrontend::setVoltage(int voltage)
2508 if (m_type == feCable)
2510 #if HAVE_DVB_API_VERSION < 3
2513 bool increased=false;
2514 fe_sec_voltage_t vlt;
2516 m_data[CUR_VOLTAGE]=voltage;
2520 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2521 vlt = SEC_VOLTAGE_OFF;
2524 #if HAVE_DVB_API_VERSION < 3
2525 vlt = SEC_VOLTAGE_13_5;
2531 vlt = SEC_VOLTAGE_13;
2534 #if HAVE_DVB_API_VERSION < 3
2535 vlt = SEC_VOLTAGE_18_5;
2541 vlt = SEC_VOLTAGE_18;
2548 #if HAVE_DVB_API_VERSION < 3
2549 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2551 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2552 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2553 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2557 RESULT eDVBFrontend::getState(int &state)
2563 RESULT eDVBFrontend::setTone(int t)
2565 if (m_type != feSatellite)
2567 #if HAVE_DVB_API_VERSION < 3
2570 fe_sec_tone_mode_t tone;
2579 tone = SEC_TONE_OFF;
2586 #if HAVE_DVB_API_VERSION < 3
2587 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2589 return ::ioctl(m_fd, FE_SET_TONE, tone);
2593 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2594 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2597 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2601 #if HAVE_DVB_API_VERSION < 3
2602 struct secCommand cmd;
2603 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
2604 cmd.u.diseqc.cmdtype = diseqc.data[0];
2605 cmd.u.diseqc.addr = diseqc.data[1];
2606 cmd.u.diseqc.cmd = diseqc.data[2];
2607 cmd.u.diseqc.numParams = diseqc.len-3;
2608 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
2609 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
2611 struct dvb_diseqc_master_cmd cmd;
2612 memcpy(cmd.msg, diseqc.data, diseqc.len);
2613 cmd.msg_len = diseqc.len;
2614 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2620 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
2621 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
2623 RESULT eDVBFrontend::sendToneburst(int burst)
2627 #if HAVE_DVB_API_VERSION < 3
2628 secMiniCmd cmd = SEC_MINI_NONE;
2630 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2632 if ( burst == eDVBSatelliteDiseqcParameters::A )
2634 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2636 #if HAVE_DVB_API_VERSION < 3
2637 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
2640 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2646 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2652 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
2654 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
2655 m_sec_sequence.push_back(list);
2657 m_sec_sequence = list;
2661 RESULT eDVBFrontend::getData(int num, long &data)
2663 if ( num < NUM_DATA_ENTRIES )
2671 RESULT eDVBFrontend::setData(int num, long val)
2673 if ( num < NUM_DATA_ENTRIES )
2681 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2684 if (feparm->getSystem(type) || type != m_type || !m_enabled)
2686 if (m_type == eDVBFrontend::feSatellite)
2689 eDVBFrontendParametersSatellite sat_parm;
2690 int ret = feparm->getDVBS(sat_parm);
2692 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
2694 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
2695 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
2699 else if (m_type == eDVBFrontend::feCable)
2700 return 2; // more prio for cable frontends
2701 else if (m_type == eDVBFrontend::feTerrestrial)
2706 bool eDVBFrontend::setSlotInfo(ePyObject obj)
2708 ePyObject Id, Descr, Enabled, IsDVBS2;
2709 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 4)
2711 Id = PyTuple_GET_ITEM(obj, 0);
2712 Descr = PyTuple_GET_ITEM(obj, 1);
2713 Enabled = PyTuple_GET_ITEM(obj, 2);
2714 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
2715 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2))
2717 strcpy(m_description, PyString_AS_STRING(Descr));
2718 m_slotid = PyInt_AsLong(Id);
2719 m_enabled = Enabled == Py_True;
2720 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
2721 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
2722 !!strstr(m_description, "Alps BSBE2") ||
2723 !!strstr(m_description, "Alps -S") ||
2724 !!strstr(m_description, "BCM4501");
2725 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
2726 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s",
2727 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" );
2730 PyErr_SetString(PyExc_StandardError,
2731 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");