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_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 int eDVBFrontend::openFrontend()
488 if (m_state != stateClosed)
489 return -1; // already opened
494 #if HAVE_DVB_API_VERSION < 3
495 FrontendInfo fe_info;
497 dvb_frontend_info fe_info;
499 eDebugNoSimulate("opening frontend %d", m_dvbid);
502 if (!m_simulate || m_type == -1)
504 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
507 eWarning("failed! (%s) %m", m_filename);
513 eWarning("frontend %d already opened", m_dvbid);
516 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
518 eWarning("ioctl FE_GET_INFO failed");
524 switch (fe_info.type)
527 m_type = iDVBFrontend::feSatellite;
530 m_type = iDVBFrontend::feCable;
533 m_type = iDVBFrontend::feTerrestrial;
536 eWarning("unknown frontend type.");
541 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
544 #if HAVE_DVB_API_VERSION < 3
545 if (m_type == iDVBFrontend::feSatellite)
551 m_secfd = ::open(m_sec_filename, O_RDWR);
554 eWarning("failed! (%s) %m", m_sec_filename);
562 eWarning("sec %d already opened", m_dvbid);
566 setTone(iDVBFrontend::toneOff);
567 setVoltage(iDVBFrontend::voltageOff);
571 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
572 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
578 int eDVBFrontend::closeFrontend(bool force)
580 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
582 long tmp = m_data[LINKED_NEXT_PTR];
585 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
586 if (linked_fe->m_inuse)
588 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
589 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
592 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
598 eDebugNoSimulate("close frontend %d", m_dvbid);
599 if (m_data[SATCR] != -1)
601 turnOffSatCR(m_data[SATCR]);
603 setTone(iDVBFrontend::toneOff);
604 setVoltage(iDVBFrontend::voltageOff);
606 if (m_sec && !m_simulate)
607 m_sec->setRotorMoving(false);
611 eWarning("couldnt close frontend %d", m_dvbid);
615 setTone(iDVBFrontend::toneOff);
616 setVoltage(iDVBFrontend::voltageOff);
618 #if HAVE_DVB_API_VERSION < 3
621 if (!::close(m_secfd))
624 eWarning("couldnt close sec %d", m_dvbid);
628 m_state = stateClosed;
633 eDVBFrontend::~eDVBFrontend()
635 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
639 void eDVBFrontend::feEvent(int w)
641 eDVBFrontend *sec_fe = this;
642 long tmp = m_data[LINKED_PREV_PTR];
645 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
646 sec_fe = linked_fe->m_frontend;
647 sec_fe->getData(LINKED_NEXT_PTR, tmp);
651 #if HAVE_DVB_API_VERSION < 3
654 dvb_frontend_event event;
658 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
660 if (res && (errno == EAGAIN))
666 #if HAVE_DVB_API_VERSION < 3
667 if (event.type == FE_COMPLETION_EV)
669 eDebug("(%d)fe event: status %x, inversion %s", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off");
670 if (event.status & FE_HAS_LOCK)
680 eDebug("stateLostLock");
681 state = stateLostLock;
682 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
685 if (m_state != state)
688 m_stateChanged(this);
693 void eDVBFrontend::timeout()
696 if (m_state == stateTuning)
698 m_state = stateFailed;
699 m_stateChanged(this);
703 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
705 /* unsigned 32 bit division */
706 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
708 return (a + b / 2) / b;
711 int eDVBFrontend::readFrontendData(int type)
720 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
721 eDebug("FE_READ_BER failed (%m)");
726 case signalQualitydB: /* this will move into the driver */
728 int sat_max = 1600; // for stv0288 / bsbe2
729 int ret = 0x12345678;
733 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
734 eDebug("FE_READ_SNR failed (%m)");
735 else if (!strcmp(m_description, "BCM4501 (internal)"))
737 float SDS_SNRE = snr << 16;
740 if (parm_u_qpsk_fec_inner <= FEC_AUTO) // DVB-S1 / QPSK
742 static float SNR_COEFF[6] = {
745 197418.0 / 4194304.0,
746 -2602183.0 / 4194304.0,
747 20377212.0 / 4194304.0,
748 -37791203.0 / 4194304.0,
750 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
751 fval2 = pow(10.0, fval1)-1;
752 fval1 = 10.0 * log10(fval2);
756 fval2 = SNR_COEFF[0];
757 for (int i=1; i<6; ++i)
760 fval2 += SNR_COEFF[i];
766 #if HAVE_DVB_API_VERSION >= 3
769 float fval1 = SDS_SNRE / 268435456.0,
772 if (parm_u_qpsk_fec_inner <= FEC_S2_QPSK_9_10) // DVB-S2 QPSK
783 fval4 = -10.0 * log10(fval1);
785 for (int i=0; i < 5; ++i)
786 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
791 ret = (int)(snr_in_db * 100);
793 else if (strstr(m_description, "Alps BSBE1 C01A") ||
794 !strcmp(m_description, "Alps -S(STV0288)"))
798 else if (snr == 0xFFFF) // i think this should not happen
802 enum { REALVAL, REGVAL };
803 const long CN_lookup[31][2] = {
804 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
805 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
806 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
807 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
808 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
809 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
812 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
813 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
817 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
822 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
827 ret = (((regval - CN_lookup[Imin][REGVAL])
828 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
829 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
830 + CN_lookup[Imin][REALVAL]) * 10;
836 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
837 !strcmp(m_description, "Alps -S") ||
838 !strcmp(m_description, "Philips -S") ||
839 !strcmp(m_description, "LG -S") )
842 ret = (int)((snr-39075)/17.647);
843 } else if (!strcmp(m_description, "Alps BSBE2"))
845 ret = (int)((snr >> 7) * 10);
846 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
848 int mse = (~snr) & 0xFF;
849 switch (parm_u_qam_modulation) {
850 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
851 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
852 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
853 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
854 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
857 } else if (!strcmp(m_description, "Philips TU1216"))
859 snr = 0xFF - (snr & 0xFF);
861 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
863 else if (!strcmp(m_description, "BCM4506"))
864 ret = (snr * 100) >> 8;
866 if (type == signalQuality)
868 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
873 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
874 case feCable: // we assume a max of 42db here
875 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
876 case feTerrestrial: // we assume a max of 24db here
877 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
881 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
889 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
890 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
896 #if HAVE_DVB_API_VERSION < 3
897 FrontendStatus status=0;
903 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
904 eDebug("FE_READ_STATUS failed (%m)");
905 return !!(status&FE_HAS_LOCK);
911 #if HAVE_DVB_API_VERSION < 3
912 FrontendStatus status=0;
918 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
919 eDebug("FE_READ_STATUS failed (%m)");
920 return !!(status&FE_HAS_SYNC);
930 void PutToDict(ePyObject &dict, const char*key, long value)
932 ePyObject item = PyInt_FromLong(value);
935 if (PyDict_SetItemString(dict, key, item))
936 eDebug("put %s to dict failed", key);
940 eDebug("could not create PyObject for %s", key);
943 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
947 if (PyDict_SetItemString(dict, key, item))
948 eDebug("put %s to dict failed", key);
952 eDebug("invalid PyObject for %s", key);
955 void PutToDict(ePyObject &dict, const char*key, const char *value)
957 ePyObject item = PyString_FromString(value);
960 if (PyDict_SetItemString(dict, key, item))
961 eDebug("put %s to dict failed", key);
965 eDebug("could not create PyObject for %s", key);
968 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
970 PutToDict(dict, "tuner_type", "DVB-S");
971 PutToDict(dict, "frequency", feparm.frequency);
972 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
973 PutToDict(dict, "orbital_position", feparm.orbital_position);
974 PutToDict(dict, "inversion", feparm.inversion);
975 PutToDict(dict, "fec_inner", feparm.fec);
976 PutToDict(dict, "modulation", feparm.modulation);
977 PutToDict(dict, "polarization", feparm.polarisation);
978 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
980 PutToDict(dict, "rolloff", feparm.rolloff);
981 PutToDict(dict, "pilot", feparm.pilot);
983 PutToDict(dict, "system", feparm.system);
986 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
988 PutToDict(dict, "tuner_type", "DVB-T");
989 PutToDict(dict, "frequency", feparm.frequency);
990 PutToDict(dict, "bandwidth", feparm.bandwidth);
991 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
992 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
993 PutToDict(dict, "constellation", feparm.modulation);
994 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
995 PutToDict(dict, "guard_interval", feparm.guard_interval);
996 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
997 PutToDict(dict, "inversion", feparm.inversion);
1000 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1002 PutToDict(dict, "tuner_type", "DVB-C");
1003 PutToDict(dict, "frequency", feparm.frequency);
1004 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1005 PutToDict(dict, "modulation", feparm.modulation);
1006 PutToDict(dict, "inversion", feparm.inversion);
1007 PutToDict(dict, "fec_inner", feparm.fec_inner);
1010 #if HAVE_DVB_API_VERSION >= 5
1011 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1014 int frequency = parm_frequency + freq_offset;
1015 PutToDict(dict, "frequency", frequency);
1016 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1017 PutToDict(dict, "orbital_position", orb_pos);
1018 PutToDict(dict, "polarization", polarization);
1020 switch(parm_u_qpsk_fec_inner)
1022 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1023 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1024 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1025 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1026 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1027 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1028 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1029 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1030 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1031 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1032 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1033 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1036 switch (p[0].u.data)
1038 default: eDebug("got unsupported system from frontend! report as DVBS!");
1039 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1042 switch (p[2].u.data)
1044 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1045 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1046 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1047 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1049 PutToDict(dict, "rolloff", tmp);
1051 switch (p[3].u.data)
1053 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1054 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1055 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1057 PutToDict(dict, "pilot", tmp);
1059 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1062 PutToDict(dict, "system", tmp);
1064 switch (p[1].u.data)
1066 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1067 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1068 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1070 PutToDict(dict, "modulation", tmp);
1074 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1077 int frequency = parm_frequency + freq_offset;
1078 PutToDict(dict, "frequency", frequency);
1079 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1080 PutToDict(dict, "orbital_position", orb_pos);
1081 PutToDict(dict, "polarization", polarization);
1083 switch(parm_u_qpsk_fec_inner)
1085 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1086 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1087 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1088 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1089 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1090 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1092 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1093 #if HAVE_DVB_API_VERSION >=3
1094 case FEC_S2_8PSK_1_2:
1095 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1096 case FEC_S2_8PSK_2_3:
1097 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1098 case FEC_S2_8PSK_3_4:
1099 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1100 case FEC_S2_8PSK_5_6:
1101 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1102 case FEC_S2_8PSK_7_8:
1103 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1104 case FEC_S2_8PSK_8_9:
1105 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1106 case FEC_S2_8PSK_3_5:
1107 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1108 case FEC_S2_8PSK_4_5:
1109 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1110 case FEC_S2_8PSK_9_10:
1111 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1114 PutToDict(dict, "fec_inner", tmp);
1115 #if HAVE_DVB_API_VERSION >=3
1116 PutToDict(dict, "modulation",
1117 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1118 eDVBFrontendParametersSatellite::Modulation_8PSK :
1119 eDVBFrontendParametersSatellite::Modulation_QPSK );
1120 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1122 switch(parm_inversion & 0xc)
1124 default: // unknown rolloff
1125 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1126 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1127 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1129 PutToDict(dict, "rolloff", tmp);
1130 switch(parm_inversion & 0x30)
1132 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1133 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1134 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1136 PutToDict(dict, "pilot", tmp);
1137 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1140 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1142 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1143 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1145 PutToDict(dict, "system", tmp);
1149 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1152 #if HAVE_DVB_API_VERSION < 3
1153 PutToDict(dict, "frequency", parm_frequency);
1155 PutToDict(dict, "frequency", parm_frequency/1000);
1157 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1158 switch(parm_u_qam_fec_inner)
1160 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1161 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1162 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1163 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1164 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1165 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1166 #if HAVE_DVB_API_VERSION >= 3
1167 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1170 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1172 PutToDict(dict, "fec_inner", tmp);
1173 switch(parm_u_qam_modulation)
1175 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1176 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1177 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1178 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1179 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1181 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1183 PutToDict(dict, "modulation", tmp);
1186 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1189 PutToDict(dict, "frequency", parm_frequency);
1190 switch (parm_u_ofdm_bandwidth)
1192 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1193 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1194 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1196 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1198 PutToDict(dict, "bandwidth", tmp);
1199 switch (parm_u_ofdm_code_rate_LP)
1201 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1202 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1203 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1204 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1205 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1207 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1209 PutToDict(dict, "code_rate_lp", tmp);
1210 switch (parm_u_ofdm_code_rate_HP)
1212 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1213 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1214 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1215 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1216 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1218 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1220 PutToDict(dict, "code_rate_hp", tmp);
1221 switch (parm_u_ofdm_constellation)
1223 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1224 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1225 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1227 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1229 PutToDict(dict, "constellation", tmp);
1230 switch (parm_u_ofdm_transmission_mode)
1232 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1233 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1235 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1237 PutToDict(dict, "transmission_mode", tmp);
1238 switch (parm_u_ofdm_guard_interval)
1240 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1241 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1242 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1243 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1245 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1247 PutToDict(dict, "guard_interval", tmp);
1248 switch (parm_u_ofdm_hierarchy_information)
1250 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1251 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1252 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1253 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1255 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1257 PutToDict(dict, "hierarchy_information", tmp);
1260 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1262 if (dest && PyDict_Check(dest))
1264 const char *tmp = "UNKNOWN";
1285 PutToDict(dest, "tuner_state", tmp);
1286 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1287 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1288 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1289 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1290 int sigQualitydB = readFrontendData(signalQualitydB);
1291 if (sigQualitydB == 0x12345678) // not support yet
1293 ePyObject obj=Py_None;
1295 PutToDict(dest, "tuner_signal_quality_db", obj);
1298 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1299 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1303 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1305 if (dest && PyDict_Check(dest))
1307 FRONTENDPARAMETERS front;
1308 #if HAVE_DVB_API_VERSION >= 5
1309 struct dtv_property p[4];
1310 struct dtv_properties cmdseq;
1313 p[0].cmd = DTV_DELIVERY_SYSTEM;
1314 p[1].cmd = DTV_MODULATION;
1315 p[2].cmd = DTV_ROLLOFF;
1316 p[3].cmd = DTV_PILOT;
1318 if (m_simulate || m_fd == -1 || original)
1320 #if HAVE_DVB_API_VERSION >= 5
1321 else if (m_type == feSatellite && // yet just use new api for DVB-S(2) only
1322 ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1324 eDebug("FE_GET_PROPERTY failed (%m)");
1328 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1330 eDebug("FE_GET_FRONTEND failed (%m)");
1338 PutSatelliteDataToDict(dest, oparm.sat);
1341 PutCableDataToDict(dest, oparm.cab);
1344 PutTerrestrialDataToDict(dest, oparm.ter);
1350 FRONTENDPARAMETERS &parm = front;
1351 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1352 switch(parm_inversion & 3)
1355 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1358 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1362 PutToDict(dest, "inversion", tmp);
1366 #if HAVE_DVB_API_VERSION >= 5
1367 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1369 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1373 fillDictWithCableData(dest, parm);
1376 fillDictWithTerrestrialData(dest, parm);
1383 void eDVBFrontend::getFrontendData(ePyObject dest)
1385 if (dest && PyDict_Check(dest))
1388 PutToDict(dest, "tuner_number", m_slotid);
1404 PutToDict(dest, "tuner_type", tmp);
1408 #ifndef FP_IOCTL_GET_ID
1409 #define FP_IOCTL_GET_ID 0
1411 int eDVBFrontend::readInputpower()
1415 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1417 sprintf(proc_name, "/proc/stb/fp/lnb_sense%d", m_slotid);
1418 FILE *f=fopen(proc_name, "r");
1421 if (fscanf(f, "%d", &power) != 1)
1422 eDebug("read %s failed!! (%m)", proc_name);
1424 eDebug("%s is %d\n", proc_name, power);
1429 // open front prozessor
1430 int fp=::open("/dev/dbox/fp0", O_RDWR);
1433 eDebug("couldn't open fp");
1436 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1437 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1439 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1448 bool eDVBFrontend::setSecSequencePos(int steps)
1450 eDebugNoSimulate("set sequence pos %d", steps);
1455 if (m_sec_sequence.current() != m_sec_sequence.end())
1456 ++m_sec_sequence.current();
1461 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1462 --m_sec_sequence.current();
1468 void eDVBFrontend::tuneLoop() // called by m_tuneTimer
1471 eDVBFrontend *sec_fe = this;
1472 eDVBRegisteredFrontend *regFE = 0;
1473 long tmp = m_data[LINKED_PREV_PTR];
1476 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1477 sec_fe = prev->m_frontend;
1478 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1479 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1480 int state = sec_fe->m_state;
1481 // workaround to put the kernel frontend thread into idle state!
1482 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1484 sec_fe->closeFrontend(true);
1485 state = sec_fe->m_state;
1487 // sec_fe is closed... we must reopen it here..
1488 if (state == stateClosed)
1496 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1498 long *sec_fe_data = sec_fe->m_data;
1499 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1500 switch (m_sec_sequence.current()->cmd)
1502 case eSecCommand::SLEEP:
1503 delay = m_sec_sequence.current()++->msec;
1504 eDebugNoSimulate("[SEC] sleep %dms", delay);
1506 case eSecCommand::GOTO:
1507 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1508 ++m_sec_sequence.current();
1510 case eSecCommand::SET_VOLTAGE:
1512 int voltage = m_sec_sequence.current()++->voltage;
1513 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1514 sec_fe->setVoltage(voltage);
1517 case eSecCommand::IF_VOLTAGE_GOTO:
1519 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1520 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1522 ++m_sec_sequence.current();
1525 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1527 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1528 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1530 ++m_sec_sequence.current();
1533 case eSecCommand::IF_TONE_GOTO:
1535 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1536 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1538 ++m_sec_sequence.current();
1541 case eSecCommand::IF_NOT_TONE_GOTO:
1543 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1544 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1546 ++m_sec_sequence.current();
1549 case eSecCommand::SET_TONE:
1550 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1551 sec_fe->setTone(m_sec_sequence.current()++->tone);
1553 case eSecCommand::SEND_DISEQC:
1554 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1555 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1556 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1557 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1558 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1559 eDebugNoSimulate("(DiSEqC reset)");
1560 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1561 eDebugNoSimulate("(DiSEqC peripherial power on)");
1563 eDebugNoSimulate("");
1564 ++m_sec_sequence.current();
1566 case eSecCommand::SEND_TONEBURST:
1567 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1568 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1570 case eSecCommand::SET_FRONTEND:
1572 int enableEvents = (m_sec_sequence.current()++)->val;
1573 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1574 setFrontend(enableEvents);
1577 case eSecCommand::START_TUNE_TIMEOUT:
1579 int tuneTimeout = m_sec_sequence.current()->timeout;
1580 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1582 m_timeout->start(tuneTimeout, 1);
1583 ++m_sec_sequence.current();
1586 case eSecCommand::SET_TIMEOUT:
1587 m_timeoutCount = m_sec_sequence.current()++->val;
1588 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1590 case eSecCommand::IF_TIMEOUT_GOTO:
1591 if (!m_timeoutCount)
1593 eDebugNoSimulate("[SEC] rotor timout");
1594 setSecSequencePos(m_sec_sequence.current()->steps);
1597 ++m_sec_sequence.current();
1599 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1601 int idx = m_sec_sequence.current()++->val;
1602 if ( idx == 0 || idx == 1 )
1604 m_idleInputpower[idx] = sec_fe->readInputpower();
1605 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1608 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1611 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1613 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1614 int idx = compare.val;
1615 if ( !m_simulate && (idx == 0 || idx == 1) )
1617 int idle = sec_fe->readInputpower();
1618 int diff = abs(idle-m_idleInputpower[idx]);
1621 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1622 setSecSequencePos(compare.steps);
1626 ++m_sec_sequence.current();
1629 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1631 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1634 setSecSequencePos(cmd.steps);
1638 int isLocked = readFrontendData(locked);
1639 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1641 if (!m_timeoutCount && m_retryCount > 0)
1643 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1646 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1649 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1651 cmd.lastSignal = signal;
1654 if (cmd.okcount > 4)
1656 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1657 setSecSequencePos(cmd.steps);
1658 m_state = stateLock;
1659 m_stateChanged(this);
1660 feEvent(-1); // flush events
1668 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1670 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1674 ++m_sec_sequence.current();
1677 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1678 m_runningInputpower = sec_fe->readInputpower();
1679 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
1680 ++m_sec_sequence.current();
1682 case eSecCommand::SET_ROTOR_MOVING:
1684 m_sec->setRotorMoving(true);
1685 ++m_sec_sequence.current();
1687 case eSecCommand::SET_ROTOR_STOPPED:
1689 m_sec->setRotorMoving(false);
1690 ++m_sec_sequence.current();
1692 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1694 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1697 setSecSequencePos(cmd.steps);
1700 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
1701 const char *txt = cmd.direction ? "running" : "stopped";
1703 if (!m_timeoutCount && m_retryCount > 0)
1705 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1707 m_runningInputpower,
1710 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1711 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1714 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1715 if ( cmd.okcount > 6 )
1717 eDebugNoSimulate("[SEC] rotor is %s", txt);
1718 if (setSecSequencePos(cmd.steps))
1724 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1727 ++m_sec_sequence.current();
1730 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1731 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
1732 setSecSequencePos(m_sec_sequence.current()->steps);
1734 ++m_sec_sequence.current();
1736 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
1737 eDebugNoSimulate("[SEC] invalidate current switch params");
1738 sec_fe_data[CSW] = -1;
1739 sec_fe_data[UCSW] = -1;
1740 sec_fe_data[TONEBURST] = -1;
1741 ++m_sec_sequence.current();
1743 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
1744 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
1745 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
1746 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
1747 eDebugNoSimulate("[SEC] update current switch params");
1748 ++m_sec_sequence.current();
1750 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1751 eDebugNoSimulate("[SEC] invalidate current rotorparams");
1752 sec_fe_data[ROTOR_CMD] = -1;
1753 sec_fe_data[ROTOR_POS] = -1;
1754 ++m_sec_sequence.current();
1756 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1757 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
1758 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
1759 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
1760 ++m_sec_sequence.current();
1762 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1763 m_retryCount = m_sec_sequence.current()++->val;
1764 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
1766 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1769 eDebugNoSimulate("[SEC] no more rotor retrys");
1770 setSecSequencePos(m_sec_sequence.current()->steps);
1773 ++m_sec_sequence.current();
1775 case eSecCommand::SET_POWER_LIMITING_MODE:
1780 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
1781 FILE *f=fopen(proc_name, "w");
1782 if (f) // new interface exist?
1784 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1785 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1786 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
1788 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1791 else if (sec_fe->m_need_rotor_workaround)
1794 int slotid = sec_fe->m_slotid;
1795 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1797 sprintf(dev, "/dev/i2c/%d", slotid);
1798 else if (slotid == 2)
1799 sprintf(dev, "/dev/i2c/2"); // first nim socket on DM8000 use /dev/i2c/2
1800 else if (slotid == 3)
1801 sprintf(dev, "/dev/i2c/4"); // second nim socket on DM8000 use /dev/i2c/4
1802 int fd = ::open(dev, O_RDWR);
1804 unsigned char data[2];
1805 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1806 if(::read(fd, data, 1) != 1)
1807 eDebugNoSimulate("[SEC] error read lnbp (%m)");
1808 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
1810 data[0] |= 0x80; // enable static current limiting
1811 eDebugNoSimulate("[SEC] set static current limiting");
1815 data[0] &= ~0x80; // enable dynamic current limiting
1816 eDebugNoSimulate("[SEC] set dynamic current limiting");
1818 if(::write(fd, data, 1) != 1)
1819 eDebugNoSimulate("[SEC] error write lnbp (%m)");
1823 ++m_sec_sequence.current();
1827 eDebugNoSimulate("[SEC] unhandled sec command %d",
1828 ++m_sec_sequence.current()->cmd);
1829 ++m_sec_sequence.current();
1832 m_tuneTimer->start(delay,true);
1836 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
1840 void eDVBFrontend::setFrontend(bool recvEvents)
1844 eDebug("setting frontend %d", m_dvbid);
1847 feEvent(-1); // flush events
1848 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
1849 #if HAVE_DVB_API_VERSION >= 5
1850 if (m_type == iDVBFrontend::feSatellite)
1852 fe_rolloff_t rolloff = ROLLOFF_35;
1853 fe_pilot_t pilot = PILOT_OFF;
1854 fe_modulation_t modulation = QPSK;
1855 fe_delivery_system_t system = SYS_DVBS;
1856 switch(oparm.sat.system)
1858 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
1859 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
1861 switch(oparm.sat.modulation)
1863 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
1864 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
1865 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
1867 switch(oparm.sat.pilot)
1869 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
1870 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
1871 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
1873 switch(oparm.sat.rolloff)
1875 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
1876 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
1877 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
1879 struct dtv_property p[10];
1880 struct dtv_properties cmdseq;
1882 p[0].cmd = DTV_CLEAR;
1883 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1884 p[2].cmd = DTV_FREQUENCY, p[1].u.data = parm_frequency;
1885 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
1886 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
1887 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
1888 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
1889 if (system = SYS_DVBS2)
1891 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
1892 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
1893 p[9].cmd = DTV_TUNE;
1898 p[7].cmd = DTV_TUNE;
1901 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
1903 perror("FE_SET_PROPERTY failed");
1910 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
1912 perror("FE_SET_FRONTEND failed");
1919 RESULT eDVBFrontend::getFrontendType(int &t)
1927 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
1932 eWarning("no SEC module active!");
1935 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
1938 #if HAVE_DVB_API_VERSION >= 3
1939 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",
1942 feparm.polarisation,
1946 feparm.orbital_position,
1952 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
1955 feparm.polarisation,
1959 feparm.orbital_position);
1961 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
1962 switch (feparm.inversion)
1964 case eDVBFrontendParametersSatellite::Inversion_On:
1965 parm_inversion = INVERSION_ON;
1967 case eDVBFrontendParametersSatellite::Inversion_Off:
1968 parm_inversion = INVERSION_OFF;
1971 case eDVBFrontendParametersSatellite::Inversion_Unknown:
1972 parm_inversion = INVERSION_AUTO;
1975 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
1979 case eDVBFrontendParametersSatellite::FEC_None:
1980 parm_u_qpsk_fec_inner = FEC_NONE;
1982 case eDVBFrontendParametersSatellite::FEC_1_2:
1983 parm_u_qpsk_fec_inner = FEC_1_2;
1985 case eDVBFrontendParametersSatellite::FEC_2_3:
1986 parm_u_qpsk_fec_inner = FEC_2_3;
1988 case eDVBFrontendParametersSatellite::FEC_3_4:
1989 parm_u_qpsk_fec_inner = FEC_3_4;
1991 case eDVBFrontendParametersSatellite::FEC_5_6:
1992 parm_u_qpsk_fec_inner = FEC_5_6;
1994 case eDVBFrontendParametersSatellite::FEC_7_8:
1995 parm_u_qpsk_fec_inner = FEC_7_8;
1998 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
1999 case eDVBFrontendParametersSatellite::FEC_Auto:
2000 parm_u_qpsk_fec_inner = FEC_AUTO;
2004 #if HAVE_DVB_API_VERSION >= 3
2009 case eDVBFrontendParametersSatellite::FEC_1_2:
2010 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2012 case eDVBFrontendParametersSatellite::FEC_2_3:
2013 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2015 case eDVBFrontendParametersSatellite::FEC_3_4:
2016 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2018 case eDVBFrontendParametersSatellite::FEC_3_5:
2019 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2021 case eDVBFrontendParametersSatellite::FEC_4_5:
2022 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2024 case eDVBFrontendParametersSatellite::FEC_5_6:
2025 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2027 case eDVBFrontendParametersSatellite::FEC_7_8:
2028 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2030 case eDVBFrontendParametersSatellite::FEC_8_9:
2031 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2033 case eDVBFrontendParametersSatellite::FEC_9_10:
2034 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2037 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2040 #if HAVE_DVB_API_VERSION < 5
2041 parm_inversion |= (feparm.rolloff << 2); // Hack.. we use bit 2..3 of inversion param for rolloff
2042 parm_inversion |= (feparm.pilot << 4); // Hack.. we use bit 4..5 of inversion param for pilot
2043 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2045 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2046 // 8PSK fec driver values are decimal 9 bigger
2051 // FIXME !!! get frequency range from tuner
2052 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2054 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2057 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2063 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2065 #if HAVE_DVB_API_VERSION < 3
2066 parm_frequency = feparm.frequency;
2068 parm_frequency = feparm.frequency * 1000;
2070 parm_u_qam_symbol_rate = feparm.symbol_rate;
2071 switch (feparm.modulation)
2073 case eDVBFrontendParametersCable::Modulation_QAM16:
2074 parm_u_qam_modulation = QAM_16;
2076 case eDVBFrontendParametersCable::Modulation_QAM32:
2077 parm_u_qam_modulation = QAM_32;
2079 case eDVBFrontendParametersCable::Modulation_QAM64:
2080 parm_u_qam_modulation = QAM_64;
2082 case eDVBFrontendParametersCable::Modulation_QAM128:
2083 parm_u_qam_modulation = QAM_128;
2085 case eDVBFrontendParametersCable::Modulation_QAM256:
2086 parm_u_qam_modulation = QAM_256;
2089 case eDVBFrontendParametersCable::Modulation_Auto:
2090 parm_u_qam_modulation = QAM_AUTO;
2093 switch (feparm.inversion)
2095 case eDVBFrontendParametersCable::Inversion_On:
2096 parm_inversion = INVERSION_ON;
2098 case eDVBFrontendParametersCable::Inversion_Off:
2099 parm_inversion = INVERSION_OFF;
2102 case eDVBFrontendParametersCable::Inversion_Unknown:
2103 parm_inversion = INVERSION_AUTO;
2106 switch (feparm.fec_inner)
2108 case eDVBFrontendParametersCable::FEC_None:
2109 parm_u_qam_fec_inner = FEC_NONE;
2111 case eDVBFrontendParametersCable::FEC_1_2:
2112 parm_u_qam_fec_inner = FEC_1_2;
2114 case eDVBFrontendParametersCable::FEC_2_3:
2115 parm_u_qam_fec_inner = FEC_2_3;
2117 case eDVBFrontendParametersCable::FEC_3_4:
2118 parm_u_qam_fec_inner = FEC_3_4;
2120 case eDVBFrontendParametersCable::FEC_5_6:
2121 parm_u_qam_fec_inner = FEC_5_6;
2123 case eDVBFrontendParametersCable::FEC_7_8:
2124 parm_u_qam_fec_inner = FEC_7_8;
2126 #if HAVE_DVB_API_VERSION >= 3
2127 case eDVBFrontendParametersCable::FEC_8_9:
2128 parm_u_qam_fec_inner = FEC_8_9;
2132 case eDVBFrontendParametersCable::FEC_Auto:
2133 parm_u_qam_fec_inner = FEC_AUTO;
2136 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2137 parm_frequency/1000,
2138 parm_u_qam_symbol_rate,
2139 parm_u_qam_fec_inner,
2140 parm_u_qam_modulation,
2146 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2148 parm_frequency = feparm.frequency;
2150 switch (feparm.bandwidth)
2152 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2153 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2155 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2156 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2158 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2159 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2162 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2163 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2166 switch (feparm.code_rate_LP)
2168 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2169 parm_u_ofdm_code_rate_LP = FEC_1_2;
2171 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2172 parm_u_ofdm_code_rate_LP = FEC_2_3;
2174 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2175 parm_u_ofdm_code_rate_LP = FEC_3_4;
2177 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2178 parm_u_ofdm_code_rate_LP = FEC_5_6;
2180 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2181 parm_u_ofdm_code_rate_LP = FEC_7_8;
2184 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2185 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2188 switch (feparm.code_rate_HP)
2190 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2191 parm_u_ofdm_code_rate_HP = FEC_1_2;
2193 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2194 parm_u_ofdm_code_rate_HP = FEC_2_3;
2196 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2197 parm_u_ofdm_code_rate_HP = FEC_3_4;
2199 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2200 parm_u_ofdm_code_rate_HP = FEC_5_6;
2202 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2203 parm_u_ofdm_code_rate_HP = FEC_7_8;
2206 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2207 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2210 switch (feparm.modulation)
2212 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2213 parm_u_ofdm_constellation = QPSK;
2215 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2216 parm_u_ofdm_constellation = QAM_16;
2218 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2219 parm_u_ofdm_constellation = QAM_64;
2222 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2223 parm_u_ofdm_constellation = QAM_AUTO;
2226 switch (feparm.transmission_mode)
2228 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2229 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2231 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2232 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2235 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2236 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2239 switch (feparm.guard_interval)
2241 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2242 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2244 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2245 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2247 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2248 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2250 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2251 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2254 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2255 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2258 switch (feparm.hierarchy)
2260 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2261 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2263 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2264 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2266 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2267 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2269 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2270 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2273 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2274 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2277 switch (feparm.inversion)
2279 case eDVBFrontendParametersTerrestrial::Inversion_On:
2280 parm_inversion = INVERSION_ON;
2282 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2283 parm_inversion = INVERSION_OFF;
2286 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2287 parm_inversion = INVERSION_AUTO;
2294 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2296 unsigned int timeout = 5000;
2297 eDebugNoSimulate("(%d)tune", m_dvbid);
2303 if (!m_sn && !m_simulate)
2305 eDebug("no frontend device opened... do not try to tune !!!");
2319 m_sec_sequence.clear();
2321 where.calcLockTimeout(timeout);
2327 eDVBFrontendParametersSatellite feparm;
2328 if (where.getDVBS(feparm))
2330 eDebug("no dvbs data!");
2335 m_sec->setRotorMoving(false);
2336 res=prepare_sat(feparm, timeout);
2344 eDVBFrontendParametersCable feparm;
2345 if (where.getDVBC(feparm))
2350 res=prepare_cable(feparm);
2354 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2355 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2360 eDVBFrontendParametersTerrestrial feparm;
2361 if (where.getDVBT(feparm))
2363 eDebug("no -T data");
2367 res=prepare_terrestrial(feparm);
2371 std::string enable_5V;
2372 char configStr[255];
2373 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2374 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2375 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2376 if (enable_5V == "True")
2377 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2379 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2380 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2386 m_sec_sequence.current() = m_sec_sequence.begin();
2390 m_tuneTimer->start(0,true);
2391 if (m_state != stateTuning)
2394 m_state = stateTuning;
2395 m_stateChanged(this);
2404 m_tuneTimer->stop();
2408 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2410 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2414 RESULT eDVBFrontend::setVoltage(int voltage)
2416 if (m_type == feCable)
2418 #if HAVE_DVB_API_VERSION < 3
2421 bool increased=false;
2422 fe_sec_voltage_t vlt;
2424 m_data[CUR_VOLTAGE]=voltage;
2428 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2429 vlt = SEC_VOLTAGE_OFF;
2432 #if HAVE_DVB_API_VERSION < 3
2433 vlt = SEC_VOLTAGE_13_5;
2439 vlt = SEC_VOLTAGE_13;
2442 #if HAVE_DVB_API_VERSION < 3
2443 vlt = SEC_VOLTAGE_18_5;
2449 vlt = SEC_VOLTAGE_18;
2456 #if HAVE_DVB_API_VERSION < 3
2457 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2459 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2460 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2461 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2465 RESULT eDVBFrontend::getState(int &state)
2471 RESULT eDVBFrontend::setTone(int t)
2473 if (m_type != feSatellite)
2475 #if HAVE_DVB_API_VERSION < 3
2478 fe_sec_tone_mode_t tone;
2487 tone = SEC_TONE_OFF;
2494 #if HAVE_DVB_API_VERSION < 3
2495 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2497 return ::ioctl(m_fd, FE_SET_TONE, tone);
2501 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2502 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2505 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2509 #if HAVE_DVB_API_VERSION < 3
2510 struct secCommand cmd;
2511 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
2512 cmd.u.diseqc.cmdtype = diseqc.data[0];
2513 cmd.u.diseqc.addr = diseqc.data[1];
2514 cmd.u.diseqc.cmd = diseqc.data[2];
2515 cmd.u.diseqc.numParams = diseqc.len-3;
2516 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
2517 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
2519 struct dvb_diseqc_master_cmd cmd;
2520 memcpy(cmd.msg, diseqc.data, diseqc.len);
2521 cmd.msg_len = diseqc.len;
2522 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2528 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
2529 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
2531 RESULT eDVBFrontend::sendToneburst(int burst)
2535 #if HAVE_DVB_API_VERSION < 3
2536 secMiniCmd cmd = SEC_MINI_NONE;
2538 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2540 if ( burst == eDVBSatelliteDiseqcParameters::A )
2542 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2544 #if HAVE_DVB_API_VERSION < 3
2545 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
2548 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2554 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2560 RESULT eDVBFrontend::setSecSequence(const eSecCommandList &list)
2562 m_sec_sequence = list;
2566 RESULT eDVBFrontend::getData(int num, long &data)
2568 if ( num < NUM_DATA_ENTRIES )
2576 RESULT eDVBFrontend::setData(int num, long val)
2578 if ( num < NUM_DATA_ENTRIES )
2586 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2589 if (feparm->getSystem(type) || type != m_type || !m_enabled)
2591 if (m_type == eDVBFrontend::feSatellite)
2594 eDVBFrontendParametersSatellite sat_parm;
2595 int ret = feparm->getDVBS(sat_parm);
2597 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
2599 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
2600 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
2604 else if (m_type == eDVBFrontend::feCable)
2605 return 2; // more prio for cable frontends
2606 else if (m_type == eDVBFrontend::feTerrestrial)
2611 bool eDVBFrontend::setSlotInfo(ePyObject obj)
2613 ePyObject Id, Descr, Enabled, IsDVBS2;
2614 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 4)
2616 Id = PyTuple_GET_ITEM(obj, 0);
2617 Descr = PyTuple_GET_ITEM(obj, 1);
2618 Enabled = PyTuple_GET_ITEM(obj, 2);
2619 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
2620 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2))
2622 strcpy(m_description, PyString_AS_STRING(Descr));
2623 m_slotid = PyInt_AsLong(Id);
2624 m_enabled = Enabled == Py_True;
2625 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
2626 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
2627 !!strstr(m_description, "Alps BSBE2") ||
2628 !!strstr(m_description, "Alps -S") ||
2629 !!strstr(m_description, "BCM4501");
2630 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
2631 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s",
2632 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" );
2635 PyErr_SetString(PyExc_StandardError,
2636 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");
2640 RESULT eDVBFrontend::turnOffSatCR(int satcr)
2642 eSecCommandList sec_sequence;
2643 // check if voltage is disabled
2644 eSecCommand::pair compare;
2645 compare.steps = +9; //nothing to do
2646 compare.voltage = iDVBFrontend::voltageOff;
2647 sec_sequence.push_back( eSecCommand(eSecCommand::IF_NOT_VOLTAGE_GOTO, compare) );
2648 sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2649 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50 ) );
2651 sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18_5) );
2652 sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
2653 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 250) );
2655 eDVBDiseqcCommand diseqc;
2656 memset(diseqc.data, 0, MAX_DISEQC_LENGTH);
2658 diseqc.data[0] = 0xE0;
2659 diseqc.data[1] = 0x10;
2660 diseqc.data[2] = 0x5A;
2661 diseqc.data[3] = satcr << 5;
2662 diseqc.data[4] = 0x00;
2664 sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
2665 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50+20+14*diseqc.len) );
2666 sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2667 setSecSequence(sec_sequence);
2671 RESULT eDVBFrontend::ScanSatCR()
2675 setTone(iDVBFrontend::toneOff);