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 /* EN 300 468 V1.11.1 DVB-SI SPEC */
217 frequency = descriptor.getCentreFrequency() * 10;
218 switch (descriptor.getBandwidth())
220 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
221 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
222 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
223 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
224 case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
225 case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
226 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
228 switch (descriptor.getCodeRateHpStream())
230 case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
231 case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
232 case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
233 case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
234 case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
235 default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
237 switch (descriptor.getCodeRateLpStream())
239 case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
240 case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
241 case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
242 case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
243 case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
244 default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
246 switch (descriptor.getTransmissionMode())
248 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
249 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
250 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
251 case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
252 case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
253 case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
254 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
256 switch (descriptor.getGuardInterval())
258 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
259 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
260 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
261 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
262 case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
263 case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
264 case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
265 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
267 // hierarchy = descriptor.getHierarchyInformation();
268 hierarchy = descriptor.getHierarchyInformation()&3;
269 if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
270 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
271 modulation = descriptor.getConstellation();
272 if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
273 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
274 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
275 system = eDVBFrontendParametersTerrestrial::System_DVB_T;
277 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
278 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
279 guard_interval, hierarchy, modulation);
282 eDVBFrontendParameters::eDVBFrontendParameters()
283 :m_type(-1), m_flags(0)
287 DEFINE_REF(eDVBFrontendParameters);
289 RESULT eDVBFrontendParameters::getSystem(int &t) const
297 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
299 if (m_type != iDVBFrontend::feSatellite)
305 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
307 if (m_type != iDVBFrontend::feCable)
313 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
315 if (m_type != iDVBFrontend::feTerrestrial)
321 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
324 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
325 m_type = iDVBFrontend::feSatellite;
329 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
332 m_type = iDVBFrontend::feCable;
336 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
339 m_type = iDVBFrontend::feTerrestrial;
343 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
348 if (parm->getSystem(type))
352 diff = 1<<30; // big difference
358 case iDVBFrontend::feSatellite:
360 eDVBFrontendParametersSatellite osat;
361 if (parm->getDVBS(osat))
364 if (sat.orbital_position != osat.orbital_position)
366 else if (sat.polarisation != osat.polarisation)
368 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
370 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
374 diff = abs(sat.frequency - osat.frequency);
375 diff += abs(sat.symbol_rate - osat.symbol_rate);
379 case iDVBFrontend::feCable:
380 eDVBFrontendParametersCable ocable;
381 if (parm->getDVBC(ocable))
384 if (exact && cable.modulation != ocable.modulation
385 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
386 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
388 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
392 diff = abs(cable.frequency - ocable.frequency);
393 diff += abs(cable.symbol_rate - ocable.symbol_rate);
396 case iDVBFrontend::feTerrestrial:
397 eDVBFrontendParametersTerrestrial oterrestrial;
398 if (parm->getDVBT(oterrestrial))
401 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
402 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
403 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
405 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
406 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
407 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
409 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
410 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
411 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
413 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
414 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
415 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
417 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
418 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
419 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
421 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
422 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
423 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
425 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
426 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
427 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
430 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
438 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
442 case iDVBFrontend::feSatellite:
444 hash = (sat.orbital_position << 16);
445 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
448 case iDVBFrontend::feCable:
450 hash |= (cable.frequency/1000)&0xFFFF;
452 case iDVBFrontend::feTerrestrial:
454 hash |= (terrestrial.frequency/1000000)&0xFFFF;
461 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
465 case iDVBFrontend::feSatellite:
467 /* high symbol rate transponders tune faster, due to
468 requiring less zigzag and giving more symbols faster.
470 5s are definitely not enough on really low SR when
471 zigzag has to find the exact frequency first.
473 if (sat.symbol_rate > 20000000)
475 else if (sat.symbol_rate > 10000000)
481 case iDVBFrontend::feCable:
484 case iDVBFrontend::feTerrestrial:
492 DEFINE_REF(eDVBFrontend);
494 int eDVBFrontend::PriorityOrder=0;
496 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
497 :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
498 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false), m_can_handle_dvbt2(false)
499 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
500 #if HAVE_DVB_API_VERSION < 3
504 #if HAVE_DVB_API_VERSION < 3
505 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
506 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
508 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
511 m_timeout = eTimer::create(eApp);
512 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
514 m_tuneTimer = eTimer::create(eApp);
515 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
517 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
520 m_idleInputpower[0]=m_idleInputpower[1]=0;
522 ok = !openFrontend();
526 void eDVBFrontend::reopenFrontend()
533 int eDVBFrontend::openFrontend()
535 if (m_state != stateClosed)
536 return -1; // already opened
541 #if HAVE_DVB_API_VERSION < 3
542 FrontendInfo fe_info;
544 dvb_frontend_info fe_info;
548 eDebug("opening frontend %d", m_dvbid);
551 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
554 eWarning("failed! (%s) %m", m_filename);
559 eWarning("frontend %d already opened", m_dvbid);
562 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
564 eWarning("ioctl FE_GET_INFO failed");
570 switch (fe_info.type)
573 m_type = iDVBFrontend::feSatellite;
576 m_type = iDVBFrontend::feCable;
579 m_type = iDVBFrontend::feTerrestrial;
582 eWarning("unknown frontend type.");
588 m_simulate_fe->m_type = m_type;
589 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
592 #if HAVE_DVB_API_VERSION < 3
593 if (m_type == iDVBFrontend::feSatellite)
599 m_secfd = ::open(m_sec_filename, O_RDWR);
602 eWarning("failed! (%s) %m", m_sec_filename);
610 eWarning("sec %d already opened", m_dvbid);
614 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
615 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
618 setTone(iDVBFrontend::toneOff);
619 setVoltage(iDVBFrontend::voltageOff);
624 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
626 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
628 long tmp = m_data[LINKED_NEXT_PTR];
631 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
632 if (linked_fe->m_inuse)
634 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
635 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
638 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
644 eDebugNoSimulate("close frontend %d", m_dvbid);
645 if (m_data[SATCR] != -1)
649 m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
650 m_tuneTimer->start(0, true);
651 if(!m_tuneTimer->isActive())
654 eDebug("[turnOffSatCR] no mainloop");
657 timeout = tuneLoopInt();
660 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
664 eDebug("[turnOffSatCR] running mainloop");
668 m_data[ROTOR_CMD] = -1;
671 setTone(iDVBFrontend::toneOff);
672 setVoltage(iDVBFrontend::voltageOff);
675 if (m_sec && !m_simulate)
676 m_sec->setRotorMoving(m_slotid, false);
680 eWarning("couldnt close frontend %d", m_dvbid);
684 setTone(iDVBFrontend::toneOff);
685 setVoltage(iDVBFrontend::voltageOff);
687 #if HAVE_DVB_API_VERSION < 3
690 if (!::close(m_secfd))
693 eWarning("couldnt close sec %d", m_dvbid);
697 m_state = stateClosed;
702 eDVBFrontend::~eDVBFrontend()
704 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
708 void eDVBFrontend::feEvent(int w)
710 eDVBFrontend *sec_fe = this;
711 long tmp = m_data[LINKED_PREV_PTR];
714 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
715 sec_fe = linked_fe->m_frontend;
716 sec_fe->getData(LINKED_NEXT_PTR, tmp);
720 #if HAVE_DVB_API_VERSION < 3
723 dvb_frontend_event event;
727 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
729 if (res && (errno == EAGAIN))
735 #if HAVE_DVB_API_VERSION < 3
736 if (event.type == FE_COMPLETION_EV)
738 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
739 if (event.status & FE_HAS_LOCK)
747 #if HAVE_DVB_API_VERSION >= 3
748 if (event.status & FE_TIMEDOUT) {
749 eDebug("FE_TIMEDOUT! ..abort");
762 eDebug("stateLostLock");
763 state = stateLostLock;
765 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
768 if (m_state != state)
771 m_stateChanged(this);
776 void eDVBFrontend::timeout()
779 if (m_state == stateTuning)
781 #ifdef BUILD_VUPLUS /* ikseong */
782 eDVBFrontend *sec_fe = this;
783 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
785 m_state = stateFailed;
786 m_stateChanged(this);
790 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
792 /* unsigned 32 bit division */
793 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
795 return (a + b / 2) / b;
798 int eDVBFrontend::readFrontendData(int type)
807 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
808 eDebug("FE_READ_BER failed (%m)");
813 case signalQualitydB: /* this will move into the driver */
815 int sat_max = 1600; // for stv0288 / bsbe2
816 int ret = 0x12345678;
820 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
821 eDebug("FE_READ_SNR failed (%m)");
822 else if (!strcmp(m_description, "BCM4501 (internal)"))
824 float SDS_SNRE = snr << 16;
827 if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
829 static float SNR_COEFF[6] = {
832 197418.0 / 4194304.0,
833 -2602183.0 / 4194304.0,
834 20377212.0 / 4194304.0,
835 -37791203.0 / 4194304.0,
837 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
838 fval2 = pow(10.0, fval1)-1;
839 fval1 = 10.0 * log10(fval2);
843 fval2 = SNR_COEFF[0];
844 for (int i=1; i<6; ++i)
847 fval2 += SNR_COEFF[i];
853 #if HAVE_DVB_API_VERSION >= 3
856 float fval1 = SDS_SNRE / 268435456.0,
859 if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
870 fval4 = -10.0 * log10(fval1);
872 for (int i=0; i < 5; ++i)
873 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
878 ret = (int)(snr_in_db * 100);
880 else if (strstr(m_description, "Alps BSBE1 C01A") ||
881 strstr(m_description, "Alps -S(STV0288)"))
885 else if (snr == 0xFFFF) // i think this should not happen
889 enum { REALVAL, REGVAL };
890 const long CN_lookup[31][2] = {
891 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
892 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
893 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
894 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
895 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
896 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
899 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
900 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
904 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
909 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
914 ret = (((regval - CN_lookup[Imin][REGVAL])
915 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
916 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
917 + CN_lookup[Imin][REALVAL]) * 10;
923 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
924 !strcmp(m_description, "Alps -S") ||
925 !strcmp(m_description, "Philips -S") ||
926 !strcmp(m_description, "LG -S") )
929 ret = (int)((snr-39075)/17.647);
930 } else if (!strcmp(m_description, "Alps BSBE2"))
932 ret = (int)((snr >> 7) * 10);
933 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
935 int mse = (~snr) & 0xFF;
936 switch (parm_u_qam_modulation) {
937 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
938 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
939 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
940 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
941 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
944 } else if (!strcmp(m_description, "Philips TU1216"))
946 snr = 0xFF - (snr & 0xFF);
948 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
950 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
951 ret = (snr * 100) >> 8;
952 else if (!strcmp(m_description, "CXD1981"))
954 int mse = (~snr) & 0xFF;
955 switch (parm_u_qam_modulation) {
958 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
960 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
966 if (type == signalQuality)
968 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
973 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
974 case feCable: // we assume a max of 42db here
975 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
976 case feTerrestrial: // we assume a max of 24db here
977 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
981 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
989 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
990 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
996 #if HAVE_DVB_API_VERSION < 3
997 FrontendStatus status=0;
1003 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1004 eDebug("FE_READ_STATUS failed (%m)");
1005 return !!(status&FE_HAS_LOCK);
1011 #if HAVE_DVB_API_VERSION < 3
1012 FrontendStatus status=0;
1018 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1019 eDebug("FE_READ_STATUS failed (%m)");
1020 return !!(status&FE_HAS_SYNC);
1024 case frontendNumber:
1030 void PutToDict(ePyObject &dict, const char*key, long value)
1032 ePyObject item = PyInt_FromLong(value);
1035 if (PyDict_SetItemString(dict, key, item))
1036 eDebug("put %s to dict failed", key);
1040 eDebug("could not create PyObject for %s", key);
1043 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1047 if (PyDict_SetItemString(dict, key, item))
1048 eDebug("put %s to dict failed", key);
1052 eDebug("invalid PyObject for %s", key);
1055 void PutToDict(ePyObject &dict, const char*key, const char *value)
1057 ePyObject item = PyString_FromString(value);
1060 if (PyDict_SetItemString(dict, key, item))
1061 eDebug("put %s to dict failed", key);
1065 eDebug("could not create PyObject for %s", key);
1068 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1070 PutToDict(dict, "tuner_type", "DVB-S");
1071 PutToDict(dict, "frequency", feparm.frequency);
1072 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1073 PutToDict(dict, "orbital_position", feparm.orbital_position);
1074 PutToDict(dict, "inversion", feparm.inversion);
1075 PutToDict(dict, "fec_inner", feparm.fec);
1076 PutToDict(dict, "modulation", feparm.modulation);
1077 PutToDict(dict, "polarization", feparm.polarisation);
1078 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1080 PutToDict(dict, "rolloff", feparm.rolloff);
1081 PutToDict(dict, "pilot", feparm.pilot);
1083 PutToDict(dict, "system", feparm.system);
1086 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1088 PutToDict(dict, "tuner_type", "DVB-T");
1089 PutToDict(dict, "frequency", feparm.frequency);
1090 PutToDict(dict, "bandwidth", feparm.bandwidth);
1091 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1092 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1093 PutToDict(dict, "constellation", feparm.modulation);
1094 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1095 PutToDict(dict, "guard_interval", feparm.guard_interval);
1096 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1097 PutToDict(dict, "inversion", feparm.inversion);
1098 PutToDict(dict, "system", feparm.system);
1099 PutToDict(dict, "plp_id", feparm.plpid);
1102 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1104 PutToDict(dict, "tuner_type", "DVB-C");
1105 PutToDict(dict, "frequency", feparm.frequency);
1106 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1107 PutToDict(dict, "modulation", feparm.modulation);
1108 PutToDict(dict, "inversion", feparm.inversion);
1109 PutToDict(dict, "fec_inner", feparm.fec_inner);
1112 #if HAVE_DVB_API_VERSION >= 5
1113 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1116 int frequency = parm_frequency + freq_offset;
1117 PutToDict(dict, "frequency", frequency);
1118 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1119 PutToDict(dict, "orbital_position", orb_pos);
1120 PutToDict(dict, "polarization", polarization);
1122 switch(parm_u_qpsk_fec_inner)
1124 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1125 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1126 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1127 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1128 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1129 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1130 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1131 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1132 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1133 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1134 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1135 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1137 PutToDict(dict, "fec_inner", tmp);
1139 switch (p[0].u.data)
1141 default: eDebug("got unsupported system from frontend! report as DVBS!");
1142 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1145 switch (p[2].u.data)
1147 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1148 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1149 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1150 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1152 PutToDict(dict, "rolloff", tmp);
1154 switch (p[3].u.data)
1156 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1157 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1158 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1160 PutToDict(dict, "pilot", tmp);
1162 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1165 PutToDict(dict, "system", tmp);
1167 switch (p[1].u.data)
1169 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1170 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1171 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1173 PutToDict(dict, "modulation", tmp);
1176 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1180 tmp = p[1].u.data/1000;
1181 PutToDict(dict, "frequency", tmp);
1183 PutToDict(dict, "symbol_rate", p[2].u.data);
1185 switch (p[3].u.data)
1187 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None;
1188 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2;
1189 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3;
1190 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4;
1191 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6;
1192 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8;
1193 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9;
1195 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto;
1197 PutToDict(dict, "fec_inner", tmp);
1199 switch (p[4].u.data)
1201 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16;
1202 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32;
1203 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64;
1204 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128;
1205 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256;
1207 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto;
1209 PutToDict(dict, "modulation", tmp);
1211 switch (p[5].u.data)
1213 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off;
1214 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On;
1216 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
1218 PutToDict(dict, "inversion", tmp);
1221 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1225 switch (p[0].u.data)
1228 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T;
1229 case SYS_DVBT2: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2;
1231 PutToDict(dict, "system", tmp);
1233 tmp = p[1].u.data/1000;
1234 PutToDict(dict, "frequency", tmp);
1236 switch (p[2].u.data)
1238 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1239 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1240 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1241 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1242 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1243 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1245 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1247 PutToDict(dict, "bandwidth", tmp);
1249 switch (p[3].u.data)
1251 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1252 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1253 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1254 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1255 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1256 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1257 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1258 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1260 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1262 PutToDict(dict, "code_rate_lp", tmp);
1264 switch (p[4].u.data)
1266 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1267 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1268 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1269 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1270 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1271 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1272 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1273 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1275 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1277 PutToDict(dict, "code_rate_hp", tmp);
1279 switch (p[5].u.data)
1281 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1282 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1283 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1284 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1286 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1288 PutToDict(dict, "constellation", tmp);
1291 switch (p[6].u.data)
1293 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1294 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1295 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1296 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1297 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1298 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1300 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1302 PutToDict(dict, "transmission_mode", tmp);
1304 switch (p[7].u.data)
1306 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1307 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1308 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1309 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1310 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1311 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1312 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1314 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1316 PutToDict(dict, "guard_interval", tmp);
1318 switch (p[8].u.data)
1320 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1321 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1322 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1323 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1325 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1327 PutToDict(dict, "hierarchy_information", tmp);
1329 switch (p[9].u.data)
1331 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off;
1332 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On;
1334 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
1336 PutToDict(dict, "inversion", tmp);
1337 #ifdef DTV_DVBT2_PLP_ID
1339 PutToDict(dict, "plp_id", tmp);
1343 #else // #if HAVE_DVB_API_VERSION >= 5
1344 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1347 int frequency = parm_frequency + freq_offset;
1348 PutToDict(dict, "frequency", frequency);
1349 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1350 PutToDict(dict, "orbital_position", orb_pos);
1351 PutToDict(dict, "polarization", polarization);
1353 switch((int)parm_u_qpsk_fec_inner)
1355 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1356 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1357 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1358 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1359 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1360 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1362 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1363 #if HAVE_DVB_API_VERSION >=3
1364 case FEC_S2_8PSK_1_2:
1365 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1366 case FEC_S2_8PSK_2_3:
1367 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1368 case FEC_S2_8PSK_3_4:
1369 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1370 case FEC_S2_8PSK_5_6:
1371 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1372 case FEC_S2_8PSK_7_8:
1373 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1374 case FEC_S2_8PSK_8_9:
1375 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1376 case FEC_S2_8PSK_3_5:
1377 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1378 case FEC_S2_8PSK_4_5:
1379 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1380 case FEC_S2_8PSK_9_10:
1381 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1384 PutToDict(dict, "fec_inner", tmp);
1385 #if HAVE_DVB_API_VERSION >=3
1386 PutToDict(dict, "modulation",
1387 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1388 eDVBFrontendParametersSatellite::Modulation_8PSK :
1389 eDVBFrontendParametersSatellite::Modulation_QPSK );
1390 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1392 switch(parm_inversion & 0xc)
1394 default: // unknown rolloff
1395 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1396 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1397 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1399 PutToDict(dict, "rolloff", tmp);
1400 switch(parm_inversion & 0x30)
1402 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1403 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1404 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1406 PutToDict(dict, "pilot", tmp);
1407 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1410 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1412 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1413 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1415 PutToDict(dict, "system", tmp);
1418 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1421 #if HAVE_DVB_API_VERSION < 3
1422 PutToDict(dict, "frequency", parm_frequency);
1424 PutToDict(dict, "frequency", parm_frequency/1000);
1426 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1427 switch(parm_u_qam_fec_inner)
1429 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1430 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1431 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1432 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1433 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1434 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1435 #if HAVE_DVB_API_VERSION >= 3
1436 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1439 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1441 PutToDict(dict, "fec_inner", tmp);
1442 switch(parm_u_qam_modulation)
1444 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1445 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1446 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1447 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1448 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1450 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1452 PutToDict(dict, "modulation", tmp);
1455 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1458 PutToDict(dict, "frequency", parm_frequency);
1459 switch (parm_u_ofdm_bandwidth)
1461 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1462 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1463 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1465 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1467 PutToDict(dict, "bandwidth", tmp);
1468 switch (parm_u_ofdm_code_rate_LP)
1470 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1471 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1472 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1473 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1474 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1476 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1478 PutToDict(dict, "code_rate_lp", tmp);
1479 switch (parm_u_ofdm_code_rate_HP)
1481 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1482 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1483 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1484 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1485 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1487 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1489 PutToDict(dict, "code_rate_hp", tmp);
1490 switch (parm_u_ofdm_constellation)
1492 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1493 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1494 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1496 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1498 PutToDict(dict, "constellation", tmp);
1499 switch (parm_u_ofdm_transmission_mode)
1501 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1502 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1504 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1506 PutToDict(dict, "transmission_mode", tmp);
1507 switch (parm_u_ofdm_guard_interval)
1509 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1510 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1511 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1512 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1514 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1516 PutToDict(dict, "guard_interval", tmp);
1517 switch (parm_u_ofdm_hierarchy_information)
1519 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1520 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1521 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1522 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1524 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1526 PutToDict(dict, "hierarchy_information", tmp);
1529 #endif // #if HAVE_DVB_API_VERSION >= 5
1531 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1533 if (dest && PyDict_Check(dest))
1535 const char *tmp = "UNKNOWN";
1556 PutToDict(dest, "tuner_state", tmp);
1557 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1558 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1559 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1560 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1561 int sigQualitydB = readFrontendData(signalQualitydB);
1562 if (sigQualitydB == 0x12345678) // not support yet
1564 ePyObject obj=Py_None;
1566 PutToDict(dest, "tuner_signal_quality_db", obj);
1569 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1570 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1574 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1576 if (dest && PyDict_Check(dest))
1578 struct dtv_property p[16];
1579 struct dtv_properties cmdseq;
1582 FRONTENDPARAMETERS front;
1583 if (m_simulate || m_fd == -1 || original)
1585 #if HAVE_DVB_API_VERSION >= 5
1591 p[0].cmd = DTV_DELIVERY_SYSTEM;
1592 p[1].cmd = DTV_MODULATION;
1593 p[2].cmd = DTV_ROLLOFF;
1594 p[3].cmd = DTV_PILOT;
1598 p[0].cmd = DTV_DELIVERY_SYSTEM;
1599 p[1].cmd = DTV_FREQUENCY;
1600 p[2].cmd = DTV_SYMBOL_RATE;
1601 p[3].cmd = DTV_INNER_FEC;
1602 p[4].cmd = DTV_MODULATION;
1603 p[5].cmd = DTV_INVERSION;
1607 p[0].cmd = DTV_DELIVERY_SYSTEM;
1608 p[1].cmd = DTV_FREQUENCY;
1609 p[2].cmd = DTV_BANDWIDTH_HZ;
1610 p[3].cmd = DTV_CODE_RATE_LP;
1611 p[4].cmd = DTV_CODE_RATE_HP;
1612 p[5].cmd = DTV_MODULATION;
1613 p[6].cmd = DTV_TRANSMISSION_MODE;
1614 p[7].cmd = DTV_GUARD_INTERVAL;
1615 p[8].cmd = DTV_HIERARCHY;
1616 p[9].cmd = DTV_INVERSION;
1617 #ifdef DTV_DVBT2_PLP_ID
1618 p[10].cmd = DTV_DVBT2_PLP_ID;
1625 if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1627 eDebug("FE_GET_PROPERTY failed (%m)");
1632 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1634 eDebug("FE_GET_FRONTEND failed (%m)");
1643 PutSatelliteDataToDict(dest, oparm.sat);
1646 PutCableDataToDict(dest, oparm.cab);
1649 PutTerrestrialDataToDict(dest, oparm.ter);
1655 FRONTENDPARAMETERS &parm = front;
1656 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1657 switch(parm_inversion & 3)
1660 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1663 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1667 PutToDict(dest, "inversion", tmp);
1670 #if HAVE_DVB_API_VERSION >= 5
1672 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1674 fillDictWithCableData(dest, p);
1677 fillDictWithTerrestrialData(dest, p);
1681 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1684 fillDictWithCableData(dest, parm);
1687 fillDictWithTerrestrialData(dest, parm);
1695 void eDVBFrontend::getFrontendData(ePyObject dest)
1697 if (dest && PyDict_Check(dest))
1700 PutToDict(dest, "tuner_number", m_slotid);
1716 PutToDict(dest, "tuner_type", tmp);
1720 #ifndef FP_IOCTL_GET_ID
1721 #define FP_IOCTL_GET_ID 0
1723 int eDVBFrontend::readInputpower()
1727 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1729 char proc_name2[64];
1730 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1731 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1733 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1735 if (fscanf(f, "%d", &power) != 1)
1736 eDebug("read %s failed!! (%m)", proc_name);
1738 eDebug("%s is %d\n", proc_name, power);
1743 // open front prozessor
1744 int fp=::open("/dev/dbox/fp0", O_RDWR);
1747 eDebug("couldn't open fp");
1750 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1751 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1753 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1762 bool eDVBFrontend::setSecSequencePos(int steps)
1764 eDebugNoSimulate("set sequence pos %d", steps);
1769 if (m_sec_sequence.current() != m_sec_sequence.end())
1770 ++m_sec_sequence.current();
1775 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1776 --m_sec_sequence.current();
1782 void eDVBFrontend::tuneLoop()
1787 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1790 eDVBFrontend *sec_fe = this;
1791 eDVBRegisteredFrontend *regFE = 0;
1792 long tmp = m_data[LINKED_PREV_PTR];
1795 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1796 sec_fe = prev->m_frontend;
1797 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1798 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1799 int state = sec_fe->m_state;
1800 // workaround to put the kernel frontend thread into idle state!
1801 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1803 sec_fe->closeFrontend(true);
1804 state = sec_fe->m_state;
1806 // sec_fe is closed... we must reopen it here..
1807 if (state == stateClosed)
1815 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1817 long *sec_fe_data = sec_fe->m_data;
1818 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1820 switch (m_sec_sequence.current()->cmd)
1822 case eSecCommand::SLEEP:
1823 delay = m_sec_sequence.current()++->msec;
1824 eDebugNoSimulate("[SEC] sleep %dms", delay);
1826 case eSecCommand::GOTO:
1827 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1828 ++m_sec_sequence.current();
1830 case eSecCommand::SET_VOLTAGE:
1832 int voltage = m_sec_sequence.current()++->voltage;
1833 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1834 sec_fe->setVoltage(voltage);
1837 case eSecCommand::IF_VOLTAGE_GOTO:
1839 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1840 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1842 ++m_sec_sequence.current();
1845 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1847 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1848 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1850 ++m_sec_sequence.current();
1853 case eSecCommand::IF_TONE_GOTO:
1855 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1856 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1858 ++m_sec_sequence.current();
1861 case eSecCommand::IF_NOT_TONE_GOTO:
1863 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1864 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1866 ++m_sec_sequence.current();
1869 case eSecCommand::SET_TONE:
1870 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1871 sec_fe->setTone(m_sec_sequence.current()++->tone);
1873 case eSecCommand::SEND_DISEQC:
1874 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1875 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1876 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1877 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1878 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1879 eDebugNoSimulate("(DiSEqC reset)");
1880 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1881 eDebugNoSimulate("(DiSEqC peripherial power on)");
1883 eDebugNoSimulate("");
1884 ++m_sec_sequence.current();
1886 case eSecCommand::SEND_TONEBURST:
1887 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1888 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1890 case eSecCommand::SET_FRONTEND:
1892 int enableEvents = (m_sec_sequence.current()++)->val;
1893 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1894 setFrontend(enableEvents);
1897 case eSecCommand::START_TUNE_TIMEOUT:
1899 int tuneTimeout = m_sec_sequence.current()->timeout;
1900 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1902 m_timeout->start(tuneTimeout, 1);
1903 ++m_sec_sequence.current();
1906 case eSecCommand::SET_TIMEOUT:
1907 m_timeoutCount = m_sec_sequence.current()++->val;
1908 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1910 case eSecCommand::IF_TIMEOUT_GOTO:
1911 if (!m_timeoutCount)
1913 eDebugNoSimulate("[SEC] rotor timout");
1914 setSecSequencePos(m_sec_sequence.current()->steps);
1917 ++m_sec_sequence.current();
1919 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1921 int idx = m_sec_sequence.current()++->val;
1922 if ( idx == 0 || idx == 1 )
1924 m_idleInputpower[idx] = sec_fe->readInputpower();
1925 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1928 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1931 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1933 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1934 int idx = compare.val;
1935 if ( !m_simulate && (idx == 0 || idx == 1) )
1937 int idle = sec_fe->readInputpower();
1938 int diff = abs(idle-m_idleInputpower[idx]);
1941 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1942 setSecSequencePos(compare.steps);
1946 ++m_sec_sequence.current();
1949 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1951 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1954 setSecSequencePos(cmd.steps);
1958 int isLocked = readFrontendData(locked);
1959 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1961 if (!m_timeoutCount && m_retryCount > 0)
1963 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1966 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1969 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1971 cmd.lastSignal = signal;
1974 if (cmd.okcount > 4)
1976 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1977 setSecSequencePos(cmd.steps);
1978 m_state = stateLock;
1979 m_stateChanged(this);
1980 feEvent(-1); // flush events
1988 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1990 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1994 ++m_sec_sequence.current();
1997 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1998 m_runningInputpower = sec_fe->readInputpower();
1999 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2000 ++m_sec_sequence.current();
2002 case eSecCommand::SET_ROTOR_MOVING:
2004 m_sec->setRotorMoving(m_slotid, true);
2005 ++m_sec_sequence.current();
2007 case eSecCommand::SET_ROTOR_STOPPED:
2009 m_sec->setRotorMoving(m_slotid, false);
2010 ++m_sec_sequence.current();
2012 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2014 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2017 setSecSequencePos(cmd.steps);
2020 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2021 const char *txt = cmd.direction ? "running" : "stopped";
2023 if (!m_timeoutCount && m_retryCount > 0)
2025 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2027 m_runningInputpower,
2030 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2031 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2034 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2035 if ( cmd.okcount > 6 )
2037 eDebugNoSimulate("[SEC] rotor is %s", txt);
2038 if (setSecSequencePos(cmd.steps))
2044 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2047 ++m_sec_sequence.current();
2050 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2051 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2052 setSecSequencePos(m_sec_sequence.current()->steps);
2054 ++m_sec_sequence.current();
2056 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2057 eDebugNoSimulate("[SEC] invalidate current switch params");
2058 sec_fe_data[CSW] = -1;
2059 sec_fe_data[UCSW] = -1;
2060 sec_fe_data[TONEBURST] = -1;
2061 ++m_sec_sequence.current();
2063 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2064 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2065 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2066 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2067 eDebugNoSimulate("[SEC] update current switch params");
2068 ++m_sec_sequence.current();
2070 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2071 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2072 sec_fe_data[ROTOR_CMD] = -1;
2073 sec_fe_data[ROTOR_POS] = -1;
2074 ++m_sec_sequence.current();
2076 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2077 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2078 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2079 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2080 ++m_sec_sequence.current();
2082 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2083 m_retryCount = m_sec_sequence.current()++->val;
2084 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2086 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2089 eDebugNoSimulate("[SEC] no more rotor retrys");
2090 setSecSequencePos(m_sec_sequence.current()->steps);
2093 ++m_sec_sequence.current();
2095 case eSecCommand::SET_POWER_LIMITING_MODE:
2100 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2101 FILE *f=fopen(proc_name, "w");
2102 if (f) // new interface exist?
2104 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2105 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2106 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2108 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2111 else if (sec_fe->m_need_rotor_workaround)
2114 int slotid = sec_fe->m_slotid;
2115 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2117 sprintf(dev, "/dev/i2c-%d", slotid);
2118 else if (slotid == 2)
2119 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2120 else if (slotid == 3)
2121 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2122 int fd = ::open(dev, O_RDWR);
2124 unsigned char data[2];
2125 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2126 if(::read(fd, data, 1) != 1)
2127 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2128 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2130 data[0] |= 0x80; // enable static current limiting
2131 eDebugNoSimulate("[SEC] set static current limiting");
2135 data[0] &= ~0x80; // enable dynamic current limiting
2136 eDebugNoSimulate("[SEC] set dynamic current limiting");
2138 if(::write(fd, data, 1) != 1)
2139 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2143 ++m_sec_sequence.current();
2146 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2148 eDebugNoSimulate("[SEC] delayed close frontend");
2149 closeFrontend(false, true);
2150 ++m_sec_sequence.current();
2154 eDebugNoSimulate("[SEC] unhandled sec command %d",
2155 ++m_sec_sequence.current()->cmd);
2156 ++m_sec_sequence.current();
2159 m_tuneTimer->start(delay,true);
2163 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2168 void eDVBFrontend::setFrontend(bool recvEvents)
2172 eDebug("setting frontend %d", m_dvbid);
2175 feEvent(-1); // flush events
2176 #if HAVE_DVB_API_VERSION >= 5
2177 if (m_type == iDVBFrontend::feSatellite)
2179 fe_rolloff_t rolloff = ROLLOFF_35;
2180 fe_pilot_t pilot = PILOT_OFF;
2181 fe_modulation_t modulation = QPSK;
2182 fe_delivery_system_t system = SYS_DVBS;
2183 switch(oparm.sat.system)
2185 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2186 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2188 switch(oparm.sat.modulation)
2190 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2191 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2192 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2194 switch(oparm.sat.pilot)
2196 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2197 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2198 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2200 switch(oparm.sat.rolloff)
2202 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2203 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2204 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2206 struct dtv_property p[10];
2207 struct dtv_properties cmdseq;
2209 p[0].cmd = DTV_CLEAR;
2210 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2211 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2212 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2213 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2214 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2215 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2216 if (system == SYS_DVBS2)
2218 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2219 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2220 p[9].cmd = DTV_TUNE;
2225 p[7].cmd = DTV_TUNE;
2228 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2230 perror("FE_SET_PROPERTY failed");
2234 else if (m_type == iDVBFrontend::feCable)
2236 struct dtv_property p[7];
2237 struct dtv_properties cmdseq;
2239 p[0].cmd = DTV_CLEAR;
2240 p[1].cmd = DTV_FREQUENCY, p[1].u.data = parm_frequency;
2241 p[2].cmd = DTV_MODULATION, p[2].u.data = parm_u_qam_modulation;
2242 p[3].cmd = DTV_SYMBOL_RATE, p[3].u.data = parm_u_qam_symbol_rate;
2243 p[4].cmd = DTV_INNER_FEC, p[4].u.data = parm_u_qam_fec_inner;
2244 p[5].cmd = DTV_INVERSION, p[5].u.data = parm_inversion;
2245 p[6].cmd = DTV_TUNE;
2247 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2249 perror("FE_SET_PROPERTY failed");
2253 else if (m_type == iDVBFrontend::feTerrestrial)
2255 fe_delivery_system_t system = SYS_DVBT;
2256 switch (oparm.ter.system)
2259 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2260 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2263 switch (oparm.ter.bandwidth)
2265 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2266 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2267 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2269 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2270 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2271 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2272 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2274 struct dtv_property p[13];
2275 struct dtv_properties cmdseq;
2278 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2279 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2280 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2281 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2282 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2283 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2284 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2285 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2286 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2287 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2288 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2289 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2290 #ifdef DTV_DVBT2_PLP_ID
2291 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
2293 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2295 perror("FE_SET_PROPERTY failed");
2302 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2304 perror("FE_SET_FRONTEND failed");
2311 RESULT eDVBFrontend::getFrontendType(int &t)
2319 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2324 eWarning("no SEC module active!");
2327 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2330 #if HAVE_DVB_API_VERSION >= 3
2331 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",
2334 feparm.polarisation,
2338 feparm.orbital_position,
2344 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2347 feparm.polarisation,
2351 feparm.orbital_position);
2353 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2354 switch (feparm.inversion)
2356 case eDVBFrontendParametersSatellite::Inversion_On:
2357 parm_inversion = INVERSION_ON;
2359 case eDVBFrontendParametersSatellite::Inversion_Off:
2360 parm_inversion = INVERSION_OFF;
2363 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2364 parm_inversion = INVERSION_AUTO;
2367 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2371 case eDVBFrontendParametersSatellite::FEC_None:
2372 parm_u_qpsk_fec_inner = FEC_NONE;
2374 case eDVBFrontendParametersSatellite::FEC_1_2:
2375 parm_u_qpsk_fec_inner = FEC_1_2;
2377 case eDVBFrontendParametersSatellite::FEC_2_3:
2378 parm_u_qpsk_fec_inner = FEC_2_3;
2380 case eDVBFrontendParametersSatellite::FEC_3_4:
2381 parm_u_qpsk_fec_inner = FEC_3_4;
2383 case eDVBFrontendParametersSatellite::FEC_5_6:
2384 parm_u_qpsk_fec_inner = FEC_5_6;
2386 case eDVBFrontendParametersSatellite::FEC_7_8:
2387 parm_u_qpsk_fec_inner = FEC_7_8;
2390 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2391 case eDVBFrontendParametersSatellite::FEC_Auto:
2392 parm_u_qpsk_fec_inner = FEC_AUTO;
2396 #if HAVE_DVB_API_VERSION >= 3
2401 case eDVBFrontendParametersSatellite::FEC_1_2:
2402 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2404 case eDVBFrontendParametersSatellite::FEC_2_3:
2405 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2407 case eDVBFrontendParametersSatellite::FEC_3_4:
2408 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2410 case eDVBFrontendParametersSatellite::FEC_3_5:
2411 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2413 case eDVBFrontendParametersSatellite::FEC_4_5:
2414 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2416 case eDVBFrontendParametersSatellite::FEC_5_6:
2417 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2419 case eDVBFrontendParametersSatellite::FEC_7_8:
2420 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2422 case eDVBFrontendParametersSatellite::FEC_8_9:
2423 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2425 case eDVBFrontendParametersSatellite::FEC_9_10:
2426 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2429 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2432 #if HAVE_DVB_API_VERSION < 5
2433 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2434 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2435 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2437 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2438 // 8PSK fec driver values are decimal 9 bigger
2443 // FIXME !!! get frequency range from tuner
2444 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2446 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2449 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2455 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2457 #if HAVE_DVB_API_VERSION < 3
2458 parm_frequency = feparm.frequency;
2460 parm_frequency = feparm.frequency * 1000;
2462 parm_u_qam_symbol_rate = feparm.symbol_rate;
2463 switch (feparm.modulation)
2465 case eDVBFrontendParametersCable::Modulation_QAM16:
2466 parm_u_qam_modulation = QAM_16;
2468 case eDVBFrontendParametersCable::Modulation_QAM32:
2469 parm_u_qam_modulation = QAM_32;
2471 case eDVBFrontendParametersCable::Modulation_QAM64:
2472 parm_u_qam_modulation = QAM_64;
2474 case eDVBFrontendParametersCable::Modulation_QAM128:
2475 parm_u_qam_modulation = QAM_128;
2477 case eDVBFrontendParametersCable::Modulation_QAM256:
2478 parm_u_qam_modulation = QAM_256;
2481 case eDVBFrontendParametersCable::Modulation_Auto:
2482 parm_u_qam_modulation = QAM_AUTO;
2485 switch (feparm.inversion)
2487 case eDVBFrontendParametersCable::Inversion_On:
2488 parm_inversion = INVERSION_ON;
2490 case eDVBFrontendParametersCable::Inversion_Off:
2491 parm_inversion = INVERSION_OFF;
2494 case eDVBFrontendParametersCable::Inversion_Unknown:
2495 parm_inversion = INVERSION_AUTO;
2498 switch (feparm.fec_inner)
2500 case eDVBFrontendParametersCable::FEC_None:
2501 parm_u_qam_fec_inner = FEC_NONE;
2503 case eDVBFrontendParametersCable::FEC_1_2:
2504 parm_u_qam_fec_inner = FEC_1_2;
2506 case eDVBFrontendParametersCable::FEC_2_3:
2507 parm_u_qam_fec_inner = FEC_2_3;
2509 case eDVBFrontendParametersCable::FEC_3_4:
2510 parm_u_qam_fec_inner = FEC_3_4;
2512 case eDVBFrontendParametersCable::FEC_5_6:
2513 parm_u_qam_fec_inner = FEC_5_6;
2515 case eDVBFrontendParametersCable::FEC_7_8:
2516 parm_u_qam_fec_inner = FEC_7_8;
2518 #if HAVE_DVB_API_VERSION >= 3
2519 case eDVBFrontendParametersCable::FEC_8_9:
2520 parm_u_qam_fec_inner = FEC_8_9;
2524 case eDVBFrontendParametersCable::FEC_Auto:
2525 parm_u_qam_fec_inner = FEC_AUTO;
2528 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2529 parm_frequency/1000,
2530 parm_u_qam_symbol_rate,
2531 parm_u_qam_fec_inner,
2532 parm_u_qam_modulation,
2538 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2540 parm_frequency = feparm.frequency;
2542 switch (feparm.bandwidth)
2544 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2545 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2547 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2548 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2550 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2551 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2553 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2554 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2556 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2557 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2559 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2560 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2563 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2564 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2567 switch (feparm.code_rate_LP)
2569 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2570 parm_u_ofdm_code_rate_LP = FEC_1_2;
2572 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2573 parm_u_ofdm_code_rate_LP = FEC_2_3;
2575 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2576 parm_u_ofdm_code_rate_LP = FEC_3_4;
2578 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2579 parm_u_ofdm_code_rate_LP = FEC_5_6;
2581 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2582 parm_u_ofdm_code_rate_LP = FEC_7_8;
2584 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2585 parm_u_ofdm_code_rate_LP = FEC_6_7;
2587 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2588 parm_u_ofdm_code_rate_LP = FEC_8_9;
2591 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2592 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2595 switch (feparm.code_rate_HP)
2597 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2598 parm_u_ofdm_code_rate_HP = FEC_1_2;
2600 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2601 parm_u_ofdm_code_rate_HP = FEC_2_3;
2603 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2604 parm_u_ofdm_code_rate_HP = FEC_3_4;
2606 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2607 parm_u_ofdm_code_rate_HP = FEC_5_6;
2609 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2610 parm_u_ofdm_code_rate_HP = FEC_7_8;
2612 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2613 parm_u_ofdm_code_rate_HP = FEC_6_7;
2615 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2616 parm_u_ofdm_code_rate_HP = FEC_8_9;
2619 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2620 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2623 switch (feparm.modulation)
2625 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2626 parm_u_ofdm_constellation = QPSK;
2628 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2629 parm_u_ofdm_constellation = QAM_16;
2631 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2632 parm_u_ofdm_constellation = QAM_64;
2634 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2635 parm_u_ofdm_constellation = QAM_256;
2638 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2639 parm_u_ofdm_constellation = QAM_AUTO;
2642 switch (feparm.transmission_mode)
2644 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2645 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2647 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2648 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2650 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2651 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2653 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2654 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2656 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2657 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2659 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2660 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2663 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2664 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2667 switch (feparm.guard_interval)
2669 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2670 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2672 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2673 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2675 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2676 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2678 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2679 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2681 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2682 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2684 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2685 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2687 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2688 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2691 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2692 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2695 switch (feparm.hierarchy)
2697 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2698 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2700 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2701 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2703 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2704 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2706 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2707 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2710 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2711 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2714 switch (feparm.inversion)
2716 case eDVBFrontendParametersTerrestrial::Inversion_On:
2717 parm_inversion = INVERSION_ON;
2719 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2720 parm_inversion = INVERSION_OFF;
2723 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2724 parm_inversion = INVERSION_AUTO;
2727 eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d",
2728 parm_frequency/1000,
2729 parm_u_ofdm_bandwidth,
2730 parm_u_ofdm_code_rate_LP,
2731 parm_u_ofdm_code_rate_HP,
2732 parm_u_ofdm_constellation,
2733 parm_u_ofdm_transmission_mode,
2734 parm_u_ofdm_guard_interval,
2735 parm_u_ofdm_hierarchy_information,
2741 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2743 unsigned int timeout = 5000;
2744 eDebugNoSimulate("(%d)tune", m_dvbid);
2750 if (!m_sn && !m_simulate)
2752 eDebug("no frontend device opened... do not try to tune !!!");
2766 m_sec_sequence.clear();
2768 where.calcLockTimeout(timeout);
2774 eDVBFrontendParametersSatellite feparm;
2775 if (where.getDVBS(feparm))
2777 eDebug("no dvbs data!");
2781 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2783 eDVBFrontend *sec_fe = this;
2784 long tmp = m_data[LINKED_PREV_PTR];
2787 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2788 sec_fe = linked_fe->m_frontend;
2789 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2791 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2792 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
2794 m_rotor_mode = feparm.no_rotor_command_on_tune;
2796 m_sec->setRotorMoving(m_slotid, false);
2797 res=prepare_sat(feparm, timeout);
2805 eDVBFrontendParametersCable feparm;
2806 if (where.getDVBC(feparm))
2811 res=prepare_cable(feparm);
2815 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2816 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2821 eDVBFrontendParametersTerrestrial feparm;
2822 if (where.getDVBT(feparm))
2824 eDebug("no -T data");
2828 res=prepare_terrestrial(feparm);
2832 std::string enable_5V;
2833 char configStr[255];
2834 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2835 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2836 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2837 if (enable_5V == "True")
2838 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2840 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2841 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2847 m_sec_sequence.current() = m_sec_sequence.begin();
2851 m_tuneTimer->start(0,true);
2853 if (m_state != stateTuning)
2855 m_state = stateTuning;
2856 m_stateChanged(this);
2865 m_tuneTimer->stop();
2869 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2871 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2875 RESULT eDVBFrontend::setVoltage(int voltage)
2877 if (m_type == feCable)
2879 #if HAVE_DVB_API_VERSION < 3
2882 bool increased=false;
2883 fe_sec_voltage_t vlt;
2885 m_data[CUR_VOLTAGE]=voltage;
2889 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2890 vlt = SEC_VOLTAGE_OFF;
2893 #if HAVE_DVB_API_VERSION < 3
2894 vlt = SEC_VOLTAGE_13_5;
2900 vlt = SEC_VOLTAGE_13;
2903 #if HAVE_DVB_API_VERSION < 3
2904 vlt = SEC_VOLTAGE_18_5;
2910 vlt = SEC_VOLTAGE_18;
2917 #if HAVE_DVB_API_VERSION < 3
2918 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2920 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2921 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2922 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2926 RESULT eDVBFrontend::getState(int &state)
2932 RESULT eDVBFrontend::setTone(int t)
2934 if (m_type != feSatellite)
2936 #if HAVE_DVB_API_VERSION < 3
2939 fe_sec_tone_mode_t tone;
2948 tone = SEC_TONE_OFF;
2955 #if HAVE_DVB_API_VERSION < 3
2956 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2958 return ::ioctl(m_fd, FE_SET_TONE, tone);
2962 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2963 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2966 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2970 #if HAVE_DVB_API_VERSION < 3
2971 struct secCommand cmd;
2972 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
2973 cmd.u.diseqc.cmdtype = diseqc.data[0];
2974 cmd.u.diseqc.addr = diseqc.data[1];
2975 cmd.u.diseqc.cmd = diseqc.data[2];
2976 cmd.u.diseqc.numParams = diseqc.len-3;
2977 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
2978 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
2980 struct dvb_diseqc_master_cmd cmd;
2981 memcpy(cmd.msg, diseqc.data, diseqc.len);
2982 cmd.msg_len = diseqc.len;
2983 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2989 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
2990 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
2992 RESULT eDVBFrontend::sendToneburst(int burst)
2996 #if HAVE_DVB_API_VERSION < 3
2997 secMiniCmd cmd = SEC_MINI_NONE;
2999 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3001 if ( burst == eDVBSatelliteDiseqcParameters::A )
3003 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3005 #if HAVE_DVB_API_VERSION < 3
3006 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3009 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3015 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3021 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3023 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3024 m_sec_sequence.push_back(list);
3026 m_sec_sequence = list;
3030 RESULT eDVBFrontend::getData(int num, long &data)
3032 if ( num < NUM_DATA_ENTRIES )
3040 RESULT eDVBFrontend::setData(int num, long val)
3042 if ( num < NUM_DATA_ENTRIES )
3050 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3053 if (feparm->getSystem(type) || type != m_type || !m_enabled)
3055 if (m_type == eDVBFrontend::feSatellite)
3058 eDVBFrontendParametersSatellite sat_parm;
3059 int ret = feparm->getDVBS(sat_parm);
3061 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
3063 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
3064 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
3068 else if (m_type == eDVBFrontend::feCable)
3069 return 2; // more prio for cable frontends
3070 else if (m_type == eDVBFrontend::feTerrestrial)
3072 eDVBFrontendParametersTerrestrial ter_parm;
3073 if ( feparm->getDVBT(ter_parm) )
3077 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
3079 return m_can_handle_dvbt2 ? 1 : 0;
3083 return m_can_handle_dvbt2 ? 1 : 2;
3089 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3091 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3092 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3094 Id = PyTuple_GET_ITEM(obj, 0);
3095 Descr = PyTuple_GET_ITEM(obj, 1);
3096 Enabled = PyTuple_GET_ITEM(obj, 2);
3097 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3098 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3099 frontendId = PyTuple_GET_ITEM(obj, 5);
3100 m_slotid = PyInt_AsLong(Id);
3101 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3103 strcpy(m_description, PyString_AS_STRING(Descr));
3104 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3105 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3106 // m_slotid, m_description);
3109 m_enabled = Enabled == Py_True;
3110 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3111 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3112 !!strstr(m_description, "Alps BSBE2") ||
3113 !!strstr(m_description, "Alps -S") ||
3114 !!strstr(m_description, "BCM4501");
3115 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
3116 m_can_handle_dvbt2 = IsDVBT2 == Py_True;
3117 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3118 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No", m_can_handle_dvbt2 ? "Yes" : "No" );
3121 PyErr_SetString(PyExc_StandardError,
3122 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");