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))
400 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
401 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
402 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
404 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
405 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
406 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
408 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
409 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
410 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
412 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
413 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
414 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
416 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
417 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
418 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
420 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
421 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
422 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
424 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
425 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
426 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
428 else if (oterrestrial.system != terrestrial.system)
430 else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
431 oterrestrial.plpid != terrestrial.plpid)
434 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
442 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
446 case iDVBFrontend::feSatellite:
448 hash = (sat.orbital_position << 16);
449 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
452 case iDVBFrontend::feCable:
454 hash |= (cable.frequency/1000)&0xFFFF;
456 case iDVBFrontend::feTerrestrial:
458 hash |= (terrestrial.frequency/1000000)&0xFFFF;
465 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
469 case iDVBFrontend::feSatellite:
471 /* high symbol rate transponders tune faster, due to
472 requiring less zigzag and giving more symbols faster.
474 5s are definitely not enough on really low SR when
475 zigzag has to find the exact frequency first.
477 if (sat.symbol_rate > 20000000)
479 else if (sat.symbol_rate > 10000000)
485 case iDVBFrontend::feCable:
488 case iDVBFrontend::feTerrestrial:
496 DEFINE_REF(eDVBFrontend);
498 int eDVBFrontend::PriorityOrder=0;
499 int eDVBFrontend::PreferredFrontendIndex=-1;
502 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
503 :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
504 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false), m_can_handle_dvbt2(false)
505 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
506 #if HAVE_DVB_API_VERSION < 3
510 #if HAVE_DVB_API_VERSION < 3
511 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
512 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
514 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
517 m_timeout = eTimer::create(eApp);
518 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
520 m_tuneTimer = eTimer::create(eApp);
521 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
523 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
526 m_idleInputpower[0]=m_idleInputpower[1]=0;
528 ok = !openFrontend();
532 void eDVBFrontend::reopenFrontend()
539 int eDVBFrontend::openFrontend()
541 if (m_state != stateClosed)
542 return -1; // already opened
547 #if HAVE_DVB_API_VERSION < 3
548 FrontendInfo fe_info;
550 dvb_frontend_info fe_info;
554 eDebug("opening frontend %d", m_dvbid);
557 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
560 eWarning("failed! (%s) %m", m_filename);
565 eWarning("frontend %d already opened", m_dvbid);
568 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
570 eWarning("ioctl FE_GET_INFO failed");
576 switch (fe_info.type)
579 m_type = iDVBFrontend::feSatellite;
582 m_type = iDVBFrontend::feCable;
585 m_type = iDVBFrontend::feTerrestrial;
588 eWarning("unknown frontend type.");
594 m_simulate_fe->m_type = m_type;
595 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
598 #if HAVE_DVB_API_VERSION < 3
599 if (m_type == iDVBFrontend::feSatellite)
605 m_secfd = ::open(m_sec_filename, O_RDWR);
608 eWarning("failed! (%s) %m", m_sec_filename);
616 eWarning("sec %d already opened", m_dvbid);
620 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
621 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
624 setTone(iDVBFrontend::toneOff);
625 setVoltage(iDVBFrontend::voltageOff);
630 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
632 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
634 long tmp = m_data[LINKED_NEXT_PTR];
637 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
638 if (linked_fe->m_inuse)
640 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
641 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
644 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
650 eDebugNoSimulate("close frontend %d", m_dvbid);
651 if (m_data[SATCR] != -1)
655 m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
656 m_tuneTimer->start(0, true);
657 if(!m_tuneTimer->isActive())
660 eDebug("[turnOffSatCR] no mainloop");
663 timeout = tuneLoopInt();
666 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
670 eDebug("[turnOffSatCR] running mainloop");
674 m_data[ROTOR_CMD] = -1;
677 setTone(iDVBFrontend::toneOff);
678 setVoltage(iDVBFrontend::voltageOff);
681 if (m_sec && !m_simulate)
682 m_sec->setRotorMoving(m_slotid, false);
686 eWarning("couldnt close frontend %d", m_dvbid);
690 setTone(iDVBFrontend::toneOff);
691 setVoltage(iDVBFrontend::voltageOff);
693 #if HAVE_DVB_API_VERSION < 3
696 if (!::close(m_secfd))
699 eWarning("couldnt close sec %d", m_dvbid);
703 m_state = stateClosed;
708 eDVBFrontend::~eDVBFrontend()
710 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
714 void eDVBFrontend::feEvent(int w)
716 eDVBFrontend *sec_fe = this;
717 long tmp = m_data[LINKED_PREV_PTR];
720 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
721 sec_fe = linked_fe->m_frontend;
722 sec_fe->getData(LINKED_NEXT_PTR, tmp);
726 #if HAVE_DVB_API_VERSION < 3
729 dvb_frontend_event event;
733 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
735 if (res && (errno == EAGAIN))
741 #if HAVE_DVB_API_VERSION < 3
742 if (event.type == FE_COMPLETION_EV)
744 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
745 if (event.status & FE_HAS_LOCK)
753 #if HAVE_DVB_API_VERSION >= 3
754 if (event.status & FE_TIMEDOUT) {
755 eDebug("FE_TIMEDOUT! ..abort");
768 eDebug("stateLostLock");
769 state = stateLostLock;
771 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
774 if (m_state != state)
777 m_stateChanged(this);
782 void eDVBFrontend::timeout()
785 if (m_state == stateTuning)
787 #ifdef BUILD_VUPLUS /* ikseong */
788 eDVBFrontend *sec_fe = this;
789 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
791 m_state = stateFailed;
792 m_stateChanged(this);
796 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
798 /* unsigned 32 bit division */
799 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
801 return (a + b / 2) / b;
804 int eDVBFrontend::readFrontendData(int type)
813 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
814 eDebug("FE_READ_BER failed (%m)");
819 case signalQualitydB: /* this will move into the driver */
821 int sat_max = 1600; // for stv0288 / bsbe2
822 int ret = 0x12345678;
826 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
827 eDebug("FE_READ_SNR failed (%m)");
828 else if (!strcmp(m_description, "BCM4501 (internal)"))
830 float SDS_SNRE = snr << 16;
833 if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
835 static float SNR_COEFF[6] = {
838 197418.0 / 4194304.0,
839 -2602183.0 / 4194304.0,
840 20377212.0 / 4194304.0,
841 -37791203.0 / 4194304.0,
843 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
844 fval2 = pow(10.0, fval1)-1;
845 fval1 = 10.0 * log10(fval2);
849 fval2 = SNR_COEFF[0];
850 for (int i=1; i<6; ++i)
853 fval2 += SNR_COEFF[i];
859 #if HAVE_DVB_API_VERSION >= 3
862 float fval1 = SDS_SNRE / 268435456.0,
865 if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
876 fval4 = -10.0 * log10(fval1);
878 for (int i=0; i < 5; ++i)
879 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
884 ret = (int)(snr_in_db * 100);
886 else if (strstr(m_description, "Alps BSBE1 C01A") ||
887 strstr(m_description, "Alps -S(STV0288)"))
891 else if (snr == 0xFFFF) // i think this should not happen
895 enum { REALVAL, REGVAL };
896 const long CN_lookup[31][2] = {
897 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
898 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
899 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
900 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
901 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
902 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
905 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
906 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
910 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
915 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
920 ret = (((regval - CN_lookup[Imin][REGVAL])
921 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
922 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
923 + CN_lookup[Imin][REALVAL]) * 10;
929 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
930 !strcmp(m_description, "Alps -S") ||
931 !strcmp(m_description, "Philips -S") ||
932 !strcmp(m_description, "LG -S") )
935 ret = (int)((snr-39075)/17.647);
936 } else if (!strcmp(m_description, "Alps BSBE2"))
938 ret = (int)((snr >> 7) * 10);
939 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
941 int mse = (~snr) & 0xFF;
942 switch (parm_u_qam_modulation) {
943 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
944 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
945 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
946 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
947 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
950 } else if (!strcmp(m_description, "Philips TU1216"))
952 snr = 0xFF - (snr & 0xFF);
954 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
956 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
957 ret = (snr * 100) >> 8;
958 else if (!strcmp(m_description, "CXD1981"))
960 int mse = (~snr) & 0xFF;
961 switch (parm_u_qam_modulation) {
964 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
966 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
972 if (type == signalQuality)
974 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
979 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
980 case feCable: // we assume a max of 42db here
981 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
982 case feTerrestrial: // we assume a max of 24db here
983 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
987 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
995 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
996 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1002 #if HAVE_DVB_API_VERSION < 3
1003 FrontendStatus status=0;
1009 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1010 eDebug("FE_READ_STATUS failed (%m)");
1011 return !!(status&FE_HAS_LOCK);
1017 #if HAVE_DVB_API_VERSION < 3
1018 FrontendStatus status=0;
1024 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1025 eDebug("FE_READ_STATUS failed (%m)");
1026 return !!(status&FE_HAS_SYNC);
1030 case frontendNumber:
1036 void PutToDict(ePyObject &dict, const char*key, long value)
1038 ePyObject item = PyInt_FromLong(value);
1041 if (PyDict_SetItemString(dict, key, item))
1042 eDebug("put %s to dict failed", key);
1046 eDebug("could not create PyObject for %s", key);
1049 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1053 if (PyDict_SetItemString(dict, key, item))
1054 eDebug("put %s to dict failed", key);
1058 eDebug("invalid PyObject for %s", key);
1061 void PutToDict(ePyObject &dict, const char*key, const char *value)
1063 ePyObject item = PyString_FromString(value);
1066 if (PyDict_SetItemString(dict, key, item))
1067 eDebug("put %s to dict failed", key);
1071 eDebug("could not create PyObject for %s", key);
1074 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1076 PutToDict(dict, "tuner_type", "DVB-S");
1077 PutToDict(dict, "frequency", feparm.frequency);
1078 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1079 PutToDict(dict, "orbital_position", feparm.orbital_position);
1080 PutToDict(dict, "inversion", feparm.inversion);
1081 PutToDict(dict, "fec_inner", feparm.fec);
1082 PutToDict(dict, "modulation", feparm.modulation);
1083 PutToDict(dict, "polarization", feparm.polarisation);
1084 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1086 PutToDict(dict, "rolloff", feparm.rolloff);
1087 PutToDict(dict, "pilot", feparm.pilot);
1089 PutToDict(dict, "system", feparm.system);
1092 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1094 PutToDict(dict, "tuner_type", "DVB-T");
1095 PutToDict(dict, "frequency", feparm.frequency);
1096 PutToDict(dict, "bandwidth", feparm.bandwidth);
1097 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1098 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1099 PutToDict(dict, "constellation", feparm.modulation);
1100 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1101 PutToDict(dict, "guard_interval", feparm.guard_interval);
1102 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1103 PutToDict(dict, "inversion", feparm.inversion);
1104 PutToDict(dict, "system", feparm.system);
1105 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1107 PutToDict(dict, "plp_id", feparm.plpid);
1111 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1113 PutToDict(dict, "tuner_type", "DVB-C");
1114 PutToDict(dict, "frequency", feparm.frequency);
1115 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1116 PutToDict(dict, "modulation", feparm.modulation);
1117 PutToDict(dict, "inversion", feparm.inversion);
1118 PutToDict(dict, "fec_inner", feparm.fec_inner);
1121 #if HAVE_DVB_API_VERSION >= 5
1122 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1125 int frequency = parm_frequency + freq_offset;
1126 PutToDict(dict, "frequency", frequency);
1127 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1128 PutToDict(dict, "orbital_position", orb_pos);
1129 PutToDict(dict, "polarization", polarization);
1131 switch(parm_u_qpsk_fec_inner)
1133 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1134 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1135 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1136 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1137 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1138 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1139 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1140 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1141 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1142 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1143 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1144 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1146 PutToDict(dict, "fec_inner", tmp);
1148 switch (p[0].u.data)
1150 default: eDebug("got unsupported system from frontend! report as DVBS!");
1151 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1154 switch (p[2].u.data)
1156 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1157 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1158 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1159 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1161 PutToDict(dict, "rolloff", tmp);
1163 switch (p[3].u.data)
1165 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1166 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1167 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1169 PutToDict(dict, "pilot", tmp);
1171 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1174 PutToDict(dict, "system", tmp);
1176 switch (p[1].u.data)
1178 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1179 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1180 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1182 PutToDict(dict, "modulation", tmp);
1184 switch(parm_inversion & 3)
1186 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1187 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1188 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1190 PutToDict(dict, "inversion", tmp);
1193 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1197 tmp = p[1].u.data/1000;
1198 PutToDict(dict, "frequency", tmp);
1200 PutToDict(dict, "symbol_rate", p[2].u.data);
1202 switch (p[3].u.data)
1204 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1205 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1206 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1207 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1208 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1209 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1210 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1212 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1214 PutToDict(dict, "fec_inner", tmp);
1216 switch (p[4].u.data)
1218 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1219 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1220 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1221 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1222 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1224 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1226 PutToDict(dict, "modulation", tmp);
1228 switch (p[5].u.data)
1230 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1231 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1233 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1235 PutToDict(dict, "inversion", tmp);
1238 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1242 switch (p[0].u.data)
1244 default: eDebug("got unsupported system from frontend! report as DVBT!");
1245 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1248 #ifdef DTV_DVBT2_PLP_ID
1250 PutToDict(dict, "plp_id", tmp);
1252 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1255 PutToDict(dict, "system", tmp);
1258 PutToDict(dict, "frequency", tmp);
1260 switch (p[2].u.data)
1262 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1263 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1264 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1265 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1266 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1267 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1269 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1271 PutToDict(dict, "bandwidth", tmp);
1273 switch (p[3].u.data)
1275 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1276 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1277 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1278 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1279 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1280 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1281 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1282 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1284 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1286 PutToDict(dict, "code_rate_lp", tmp);
1288 switch (p[4].u.data)
1290 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1291 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1292 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1293 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1294 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1295 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1296 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1297 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1299 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1301 PutToDict(dict, "code_rate_hp", tmp);
1303 switch (p[5].u.data)
1305 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1306 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1307 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1308 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1310 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1312 PutToDict(dict, "constellation", tmp);
1315 switch (p[6].u.data)
1317 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1318 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1319 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1320 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1321 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1322 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1324 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1326 PutToDict(dict, "transmission_mode", tmp);
1328 switch (p[7].u.data)
1330 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1331 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1332 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1333 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1334 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1335 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1336 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1338 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1340 PutToDict(dict, "guard_interval", tmp);
1342 switch (p[8].u.data)
1344 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1345 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1346 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1347 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1349 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1351 PutToDict(dict, "hierarchy_information", tmp);
1353 switch (p[9].u.data)
1355 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1356 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1358 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1360 PutToDict(dict, "inversion", tmp);
1363 #else // #if HAVE_DVB_API_VERSION >= 5
1364 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1367 int frequency = parm_frequency + freq_offset;
1368 PutToDict(dict, "frequency", frequency);
1369 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1370 PutToDict(dict, "orbital_position", orb_pos);
1371 PutToDict(dict, "polarization", polarization);
1373 switch((int)parm_u_qpsk_fec_inner)
1375 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1376 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1377 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1378 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1379 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1380 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1382 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1383 #if HAVE_DVB_API_VERSION >=3
1384 case FEC_S2_8PSK_1_2:
1385 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1386 case FEC_S2_8PSK_2_3:
1387 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1388 case FEC_S2_8PSK_3_4:
1389 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1390 case FEC_S2_8PSK_5_6:
1391 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1392 case FEC_S2_8PSK_7_8:
1393 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1394 case FEC_S2_8PSK_8_9:
1395 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1396 case FEC_S2_8PSK_3_5:
1397 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1398 case FEC_S2_8PSK_4_5:
1399 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1400 case FEC_S2_8PSK_9_10:
1401 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1404 PutToDict(dict, "fec_inner", tmp);
1405 #if HAVE_DVB_API_VERSION >=3
1406 PutToDict(dict, "modulation",
1407 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1408 eDVBFrontendParametersSatellite::Modulation_8PSK :
1409 eDVBFrontendParametersSatellite::Modulation_QPSK );
1410 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1412 switch(parm_inversion & 0xc)
1414 default: // unknown rolloff
1415 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1416 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1417 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1419 PutToDict(dict, "rolloff", tmp);
1420 switch(parm_inversion & 0x30)
1422 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1423 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1424 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1426 PutToDict(dict, "pilot", tmp);
1427 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1430 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1432 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1433 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1435 PutToDict(dict, "system", tmp);
1438 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1441 #if HAVE_DVB_API_VERSION < 3
1442 PutToDict(dict, "frequency", parm_frequency);
1444 PutToDict(dict, "frequency", parm_frequency/1000);
1446 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1447 switch(parm_u_qam_fec_inner)
1449 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1450 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1451 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1452 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1453 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1454 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1455 #if HAVE_DVB_API_VERSION >= 3
1456 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1459 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1461 PutToDict(dict, "fec_inner", tmp);
1462 switch(parm_u_qam_modulation)
1464 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1465 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1466 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1467 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1468 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1470 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1472 PutToDict(dict, "modulation", tmp);
1475 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1478 PutToDict(dict, "frequency", parm_frequency);
1479 switch (parm_u_ofdm_bandwidth)
1481 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1482 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1483 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1485 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1487 PutToDict(dict, "bandwidth", tmp);
1488 switch (parm_u_ofdm_code_rate_LP)
1490 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1491 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1492 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1493 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1494 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1496 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1498 PutToDict(dict, "code_rate_lp", tmp);
1499 switch (parm_u_ofdm_code_rate_HP)
1501 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1502 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1503 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1504 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1505 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1507 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1509 PutToDict(dict, "code_rate_hp", tmp);
1510 switch (parm_u_ofdm_constellation)
1512 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1513 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1514 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1516 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1518 PutToDict(dict, "constellation", tmp);
1519 switch (parm_u_ofdm_transmission_mode)
1521 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1522 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1524 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1526 PutToDict(dict, "transmission_mode", tmp);
1527 switch (parm_u_ofdm_guard_interval)
1529 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1530 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1531 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1532 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1534 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1536 PutToDict(dict, "guard_interval", tmp);
1537 switch (parm_u_ofdm_hierarchy_information)
1539 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1540 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1541 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1542 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1544 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1546 PutToDict(dict, "hierarchy_information", tmp);
1549 #endif // #if HAVE_DVB_API_VERSION >= 5
1551 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1553 if (dest && PyDict_Check(dest))
1555 const char *tmp = "UNKNOWN";
1576 PutToDict(dest, "tuner_state", tmp);
1577 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1578 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1579 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1580 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1581 int sigQualitydB = readFrontendData(signalQualitydB);
1582 if (sigQualitydB == 0x12345678) // not support yet
1584 ePyObject obj=Py_None;
1586 PutToDict(dest, "tuner_signal_quality_db", obj);
1589 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1590 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1594 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1596 if (dest && PyDict_Check(dest))
1598 FRONTENDPARAMETERS front;
1599 #if HAVE_DVB_API_VERSION >= 5
1600 struct dtv_property p[16];
1601 struct dtv_properties cmdseq;
1607 p[0].cmd = DTV_DELIVERY_SYSTEM;
1608 p[1].cmd = DTV_MODULATION;
1609 p[2].cmd = DTV_ROLLOFF;
1610 p[3].cmd = DTV_PILOT;
1614 p[0].cmd = DTV_DELIVERY_SYSTEM;
1615 p[1].cmd = DTV_FREQUENCY;
1616 p[2].cmd = DTV_SYMBOL_RATE;
1617 p[3].cmd = DTV_INNER_FEC;
1618 p[4].cmd = DTV_MODULATION;
1619 p[5].cmd = DTV_INVERSION;
1623 p[0].cmd = DTV_DELIVERY_SYSTEM;
1624 p[1].cmd = DTV_FREQUENCY;
1625 p[2].cmd = DTV_BANDWIDTH_HZ;
1626 p[3].cmd = DTV_CODE_RATE_LP;
1627 p[4].cmd = DTV_CODE_RATE_HP;
1628 p[5].cmd = DTV_MODULATION;
1629 p[6].cmd = DTV_TRANSMISSION_MODE;
1630 p[7].cmd = DTV_GUARD_INTERVAL;
1631 p[8].cmd = DTV_HIERARCHY;
1632 p[9].cmd = DTV_INVERSION;
1633 #ifdef DTV_DVBT2_PLP_ID
1634 p[10].cmd = DTV_DVBT2_PLP_ID;
1642 if (m_simulate || m_fd == -1 || original)
1646 #if HAVE_DVB_API_VERSION >= 5
1647 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1649 eDebug("FE_GET_PROPERTY failed (%m)");
1652 else if (m_type == feSatellite && // use for DVB-S(2) only
1653 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1655 eDebug("FE_GET_FRONTEND failed (%m)");
1659 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1661 eDebug("FE_GET_FRONTEND failed (%m)");
1670 PutSatelliteDataToDict(dest, oparm.sat);
1673 PutCableDataToDict(dest, oparm.cab);
1676 PutTerrestrialDataToDict(dest, oparm.ter);
1682 FRONTENDPARAMETERS &parm = front;
1683 #if HAVE_DVB_API_VERSION >= 5
1687 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1690 fillDictWithCableData(dest, p);
1693 fillDictWithTerrestrialData(dest, p);
1697 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1698 switch(parm_inversion & 3)
1701 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1704 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1708 PutToDict(dest, "inversion", tmp);
1712 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1715 fillDictWithCableData(dest, parm);
1718 fillDictWithTerrestrialData(dest, parm);
1726 void eDVBFrontend::getFrontendData(ePyObject dest)
1728 if (dest && PyDict_Check(dest))
1731 PutToDict(dest, "tuner_number", m_slotid);
1747 PutToDict(dest, "tuner_type", tmp);
1751 #ifndef FP_IOCTL_GET_ID
1752 #define FP_IOCTL_GET_ID 0
1754 int eDVBFrontend::readInputpower()
1758 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1760 char proc_name2[64];
1761 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1762 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1764 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1766 if (fscanf(f, "%d", &power) != 1)
1767 eDebug("read %s failed!! (%m)", proc_name);
1769 eDebug("%s is %d\n", proc_name, power);
1774 // open front prozessor
1775 int fp=::open("/dev/dbox/fp0", O_RDWR);
1778 eDebug("couldn't open fp");
1781 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1782 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1784 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1793 bool eDVBFrontend::setSecSequencePos(int steps)
1795 eDebugNoSimulate("set sequence pos %d", steps);
1800 if (m_sec_sequence.current() != m_sec_sequence.end())
1801 ++m_sec_sequence.current();
1806 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1807 --m_sec_sequence.current();
1813 void eDVBFrontend::tuneLoop()
1818 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1821 eDVBFrontend *sec_fe = this;
1822 eDVBRegisteredFrontend *regFE = 0;
1823 long tmp = m_data[LINKED_PREV_PTR];
1826 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1827 sec_fe = prev->m_frontend;
1828 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1829 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1830 int state = sec_fe->m_state;
1831 // workaround to put the kernel frontend thread into idle state!
1832 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1834 sec_fe->closeFrontend(true);
1835 state = sec_fe->m_state;
1837 // sec_fe is closed... we must reopen it here..
1838 if (state == stateClosed)
1846 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1848 long *sec_fe_data = sec_fe->m_data;
1849 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1851 switch (m_sec_sequence.current()->cmd)
1853 case eSecCommand::SLEEP:
1854 delay = m_sec_sequence.current()++->msec;
1855 eDebugNoSimulate("[SEC] sleep %dms", delay);
1857 case eSecCommand::GOTO:
1858 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1859 ++m_sec_sequence.current();
1861 case eSecCommand::SET_VOLTAGE:
1863 int voltage = m_sec_sequence.current()++->voltage;
1864 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1865 sec_fe->setVoltage(voltage);
1868 case eSecCommand::IF_VOLTAGE_GOTO:
1870 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1871 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1873 ++m_sec_sequence.current();
1876 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1878 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1879 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1881 ++m_sec_sequence.current();
1884 case eSecCommand::IF_TONE_GOTO:
1886 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1887 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1889 ++m_sec_sequence.current();
1892 case eSecCommand::IF_NOT_TONE_GOTO:
1894 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1895 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1897 ++m_sec_sequence.current();
1900 case eSecCommand::SET_TONE:
1901 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1902 sec_fe->setTone(m_sec_sequence.current()++->tone);
1904 case eSecCommand::SEND_DISEQC:
1905 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1906 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1907 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1908 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1909 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1910 eDebugNoSimulate("(DiSEqC reset)");
1911 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1912 eDebugNoSimulate("(DiSEqC peripherial power on)");
1914 eDebugNoSimulate("");
1915 ++m_sec_sequence.current();
1917 case eSecCommand::SEND_TONEBURST:
1918 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1919 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1921 case eSecCommand::SET_FRONTEND:
1923 int enableEvents = (m_sec_sequence.current()++)->val;
1924 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1925 setFrontend(enableEvents);
1928 case eSecCommand::START_TUNE_TIMEOUT:
1930 int tuneTimeout = m_sec_sequence.current()->timeout;
1931 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1933 m_timeout->start(tuneTimeout, 1);
1934 ++m_sec_sequence.current();
1937 case eSecCommand::SET_TIMEOUT:
1938 m_timeoutCount = m_sec_sequence.current()++->val;
1939 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1941 case eSecCommand::IF_TIMEOUT_GOTO:
1942 if (!m_timeoutCount)
1944 eDebugNoSimulate("[SEC] rotor timout");
1945 setSecSequencePos(m_sec_sequence.current()->steps);
1948 ++m_sec_sequence.current();
1950 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1952 int idx = m_sec_sequence.current()++->val;
1953 if ( idx == 0 || idx == 1 )
1955 m_idleInputpower[idx] = sec_fe->readInputpower();
1956 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1959 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1962 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1964 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1965 int idx = compare.val;
1966 if ( !m_simulate && (idx == 0 || idx == 1) )
1968 int idle = sec_fe->readInputpower();
1969 int diff = abs(idle-m_idleInputpower[idx]);
1972 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1973 setSecSequencePos(compare.steps);
1977 ++m_sec_sequence.current();
1980 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1982 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1985 setSecSequencePos(cmd.steps);
1989 int isLocked = readFrontendData(locked);
1990 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1992 if (!m_timeoutCount && m_retryCount > 0)
1994 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1997 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
2000 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2002 cmd.lastSignal = signal;
2005 if (cmd.okcount > 4)
2007 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2008 setSecSequencePos(cmd.steps);
2009 m_state = stateLock;
2010 m_stateChanged(this);
2011 feEvent(-1); // flush events
2019 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2021 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2025 ++m_sec_sequence.current();
2028 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2029 m_runningInputpower = sec_fe->readInputpower();
2030 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2031 ++m_sec_sequence.current();
2033 case eSecCommand::SET_ROTOR_MOVING:
2035 m_sec->setRotorMoving(m_slotid, true);
2036 ++m_sec_sequence.current();
2038 case eSecCommand::SET_ROTOR_STOPPED:
2040 m_sec->setRotorMoving(m_slotid, false);
2041 ++m_sec_sequence.current();
2043 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2045 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2048 setSecSequencePos(cmd.steps);
2051 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2052 const char *txt = cmd.direction ? "running" : "stopped";
2054 if (!m_timeoutCount && m_retryCount > 0)
2056 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2058 m_runningInputpower,
2061 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2062 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2065 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2066 if ( cmd.okcount > 6 )
2068 eDebugNoSimulate("[SEC] rotor is %s", txt);
2069 if (setSecSequencePos(cmd.steps))
2075 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2078 ++m_sec_sequence.current();
2081 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2082 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2083 setSecSequencePos(m_sec_sequence.current()->steps);
2085 ++m_sec_sequence.current();
2087 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2088 eDebugNoSimulate("[SEC] invalidate current switch params");
2089 sec_fe_data[CSW] = -1;
2090 sec_fe_data[UCSW] = -1;
2091 sec_fe_data[TONEBURST] = -1;
2092 ++m_sec_sequence.current();
2094 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2095 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2096 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2097 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2098 eDebugNoSimulate("[SEC] update current switch params");
2099 ++m_sec_sequence.current();
2101 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2102 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2103 sec_fe_data[ROTOR_CMD] = -1;
2104 sec_fe_data[ROTOR_POS] = -1;
2105 ++m_sec_sequence.current();
2107 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2108 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2109 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2110 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2111 ++m_sec_sequence.current();
2113 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2114 m_retryCount = m_sec_sequence.current()++->val;
2115 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2117 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2120 eDebugNoSimulate("[SEC] no more rotor retrys");
2121 setSecSequencePos(m_sec_sequence.current()->steps);
2124 ++m_sec_sequence.current();
2126 case eSecCommand::SET_POWER_LIMITING_MODE:
2131 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2132 FILE *f=fopen(proc_name, "w");
2133 if (f) // new interface exist?
2135 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2136 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2137 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2139 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2142 else if (sec_fe->m_need_rotor_workaround)
2145 int slotid = sec_fe->m_slotid;
2146 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2148 sprintf(dev, "/dev/i2c-%d", slotid);
2149 else if (slotid == 2)
2150 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2151 else if (slotid == 3)
2152 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2153 int fd = ::open(dev, O_RDWR);
2155 unsigned char data[2];
2156 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2157 if(::read(fd, data, 1) != 1)
2158 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2159 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2161 data[0] |= 0x80; // enable static current limiting
2162 eDebugNoSimulate("[SEC] set static current limiting");
2166 data[0] &= ~0x80; // enable dynamic current limiting
2167 eDebugNoSimulate("[SEC] set dynamic current limiting");
2169 if(::write(fd, data, 1) != 1)
2170 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2174 ++m_sec_sequence.current();
2177 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2179 eDebugNoSimulate("[SEC] delayed close frontend");
2180 closeFrontend(false, true);
2181 ++m_sec_sequence.current();
2185 eDebugNoSimulate("[SEC] unhandled sec command %d",
2186 ++m_sec_sequence.current()->cmd);
2187 ++m_sec_sequence.current();
2190 m_tuneTimer->start(delay,true);
2194 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2199 void eDVBFrontend::setFrontend(bool recvEvents)
2203 eDebug("setting frontend %d", m_dvbid);
2206 feEvent(-1); // flush events
2207 #if HAVE_DVB_API_VERSION >= 5
2208 if (m_type == iDVBFrontend::feSatellite)
2210 fe_rolloff_t rolloff = ROLLOFF_35;
2211 fe_pilot_t pilot = PILOT_OFF;
2212 fe_modulation_t modulation = QPSK;
2213 fe_delivery_system_t system = SYS_DVBS;
2214 switch(oparm.sat.system)
2216 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2217 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2219 switch(oparm.sat.modulation)
2221 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2222 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2223 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2225 switch(oparm.sat.pilot)
2227 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2228 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2229 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2231 switch(oparm.sat.rolloff)
2233 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2234 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2235 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2237 struct dtv_property p[10];
2238 struct dtv_properties cmdseq;
2240 p[0].cmd = DTV_CLEAR;
2241 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2242 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2243 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2244 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2245 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2246 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2247 if (system == SYS_DVBS2)
2249 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2250 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2251 p[9].cmd = DTV_TUNE;
2256 p[7].cmd = DTV_TUNE;
2259 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2261 perror("FE_SET_PROPERTY failed");
2265 else if (m_type == iDVBFrontend::feCable)
2267 struct dtv_property p[8];
2268 struct dtv_properties cmdseq;
2270 p[0].cmd = DTV_CLEAR;
2271 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2272 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2274 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2276 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2277 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2278 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2279 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2280 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2281 p[7].cmd = DTV_TUNE;
2283 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2285 perror("FE_SET_PROPERTY failed");
2289 else if (m_type == iDVBFrontend::feTerrestrial)
2291 fe_delivery_system_t system = SYS_DVBT;
2292 switch (oparm.ter.system)
2295 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2296 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2299 switch (oparm.ter.bandwidth)
2301 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2302 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2303 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2305 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2306 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2307 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2308 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2310 struct dtv_property p[13];
2311 struct dtv_properties cmdseq;
2314 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2315 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2316 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2317 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2318 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2319 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2320 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2321 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2322 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2323 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2324 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2325 #ifdef DTV_DVBT2_PLP_ID
2326 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
2328 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2329 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2331 perror("FE_SET_PROPERTY failed");
2338 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2340 perror("FE_SET_FRONTEND failed");
2347 RESULT eDVBFrontend::getFrontendType(int &t)
2355 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2360 eWarning("no SEC module active!");
2363 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2366 #if HAVE_DVB_API_VERSION >= 3
2367 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",
2370 feparm.polarisation,
2374 feparm.orbital_position,
2380 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2383 feparm.polarisation,
2387 feparm.orbital_position);
2389 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2390 switch (feparm.inversion)
2392 case eDVBFrontendParametersSatellite::Inversion_On:
2393 parm_inversion = INVERSION_ON;
2395 case eDVBFrontendParametersSatellite::Inversion_Off:
2396 parm_inversion = INVERSION_OFF;
2399 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2400 parm_inversion = INVERSION_AUTO;
2403 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2407 case eDVBFrontendParametersSatellite::FEC_None:
2408 parm_u_qpsk_fec_inner = FEC_NONE;
2410 case eDVBFrontendParametersSatellite::FEC_1_2:
2411 parm_u_qpsk_fec_inner = FEC_1_2;
2413 case eDVBFrontendParametersSatellite::FEC_2_3:
2414 parm_u_qpsk_fec_inner = FEC_2_3;
2416 case eDVBFrontendParametersSatellite::FEC_3_4:
2417 parm_u_qpsk_fec_inner = FEC_3_4;
2419 case eDVBFrontendParametersSatellite::FEC_5_6:
2420 parm_u_qpsk_fec_inner = FEC_5_6;
2422 case eDVBFrontendParametersSatellite::FEC_7_8:
2423 parm_u_qpsk_fec_inner = FEC_7_8;
2426 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2427 case eDVBFrontendParametersSatellite::FEC_Auto:
2428 parm_u_qpsk_fec_inner = FEC_AUTO;
2432 #if HAVE_DVB_API_VERSION >= 3
2437 case eDVBFrontendParametersSatellite::FEC_1_2:
2438 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2440 case eDVBFrontendParametersSatellite::FEC_2_3:
2441 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2443 case eDVBFrontendParametersSatellite::FEC_3_4:
2444 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2446 case eDVBFrontendParametersSatellite::FEC_3_5:
2447 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2449 case eDVBFrontendParametersSatellite::FEC_4_5:
2450 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2452 case eDVBFrontendParametersSatellite::FEC_5_6:
2453 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2455 case eDVBFrontendParametersSatellite::FEC_7_8:
2456 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2458 case eDVBFrontendParametersSatellite::FEC_8_9:
2459 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2461 case eDVBFrontendParametersSatellite::FEC_9_10:
2462 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2465 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2468 #if HAVE_DVB_API_VERSION < 5
2469 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2470 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2471 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2473 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2474 // 8PSK fec driver values are decimal 9 bigger
2479 // FIXME !!! get frequency range from tuner
2480 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2482 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2485 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2491 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2493 #if HAVE_DVB_API_VERSION < 3
2494 parm_frequency = feparm.frequency;
2496 parm_frequency = feparm.frequency * 1000;
2498 parm_u_qam_symbol_rate = feparm.symbol_rate;
2499 switch (feparm.modulation)
2501 case eDVBFrontendParametersCable::Modulation_QAM16:
2502 parm_u_qam_modulation = QAM_16;
2504 case eDVBFrontendParametersCable::Modulation_QAM32:
2505 parm_u_qam_modulation = QAM_32;
2507 case eDVBFrontendParametersCable::Modulation_QAM64:
2508 parm_u_qam_modulation = QAM_64;
2510 case eDVBFrontendParametersCable::Modulation_QAM128:
2511 parm_u_qam_modulation = QAM_128;
2513 case eDVBFrontendParametersCable::Modulation_QAM256:
2514 parm_u_qam_modulation = QAM_256;
2517 case eDVBFrontendParametersCable::Modulation_Auto:
2518 parm_u_qam_modulation = QAM_AUTO;
2521 switch (feparm.inversion)
2523 case eDVBFrontendParametersCable::Inversion_On:
2524 parm_inversion = INVERSION_ON;
2526 case eDVBFrontendParametersCable::Inversion_Off:
2527 parm_inversion = INVERSION_OFF;
2530 case eDVBFrontendParametersCable::Inversion_Unknown:
2531 parm_inversion = INVERSION_AUTO;
2534 switch (feparm.fec_inner)
2536 case eDVBFrontendParametersCable::FEC_None:
2537 parm_u_qam_fec_inner = FEC_NONE;
2539 case eDVBFrontendParametersCable::FEC_1_2:
2540 parm_u_qam_fec_inner = FEC_1_2;
2542 case eDVBFrontendParametersCable::FEC_2_3:
2543 parm_u_qam_fec_inner = FEC_2_3;
2545 case eDVBFrontendParametersCable::FEC_3_4:
2546 parm_u_qam_fec_inner = FEC_3_4;
2548 case eDVBFrontendParametersCable::FEC_5_6:
2549 parm_u_qam_fec_inner = FEC_5_6;
2551 case eDVBFrontendParametersCable::FEC_7_8:
2552 parm_u_qam_fec_inner = FEC_7_8;
2554 #if HAVE_DVB_API_VERSION >= 3
2555 case eDVBFrontendParametersCable::FEC_8_9:
2556 parm_u_qam_fec_inner = FEC_8_9;
2560 case eDVBFrontendParametersCable::FEC_Auto:
2561 parm_u_qam_fec_inner = FEC_AUTO;
2564 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2565 parm_frequency/1000,
2566 parm_u_qam_symbol_rate,
2567 parm_u_qam_fec_inner,
2568 parm_u_qam_modulation,
2574 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2576 parm_frequency = feparm.frequency;
2578 switch (feparm.bandwidth)
2580 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2581 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2583 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2584 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2586 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2587 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2589 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2590 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2592 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2593 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2595 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2596 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2599 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2600 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2603 switch (feparm.code_rate_LP)
2605 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2606 parm_u_ofdm_code_rate_LP = FEC_1_2;
2608 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2609 parm_u_ofdm_code_rate_LP = FEC_2_3;
2611 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2612 parm_u_ofdm_code_rate_LP = FEC_3_4;
2614 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2615 parm_u_ofdm_code_rate_LP = FEC_5_6;
2617 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2618 parm_u_ofdm_code_rate_LP = FEC_7_8;
2620 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2621 parm_u_ofdm_code_rate_LP = FEC_6_7;
2623 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2624 parm_u_ofdm_code_rate_LP = FEC_8_9;
2627 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2628 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2631 switch (feparm.code_rate_HP)
2633 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2634 parm_u_ofdm_code_rate_HP = FEC_1_2;
2636 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2637 parm_u_ofdm_code_rate_HP = FEC_2_3;
2639 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2640 parm_u_ofdm_code_rate_HP = FEC_3_4;
2642 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2643 parm_u_ofdm_code_rate_HP = FEC_5_6;
2645 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2646 parm_u_ofdm_code_rate_HP = FEC_7_8;
2648 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2649 parm_u_ofdm_code_rate_HP = FEC_6_7;
2651 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2652 parm_u_ofdm_code_rate_HP = FEC_8_9;
2655 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2656 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2659 switch (feparm.modulation)
2661 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2662 parm_u_ofdm_constellation = QPSK;
2664 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2665 parm_u_ofdm_constellation = QAM_16;
2667 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2668 parm_u_ofdm_constellation = QAM_64;
2670 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2671 parm_u_ofdm_constellation = QAM_256;
2674 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2675 parm_u_ofdm_constellation = QAM_AUTO;
2678 switch (feparm.transmission_mode)
2680 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2681 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2683 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2684 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2686 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2687 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2689 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2690 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2692 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2693 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2695 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2696 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2699 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2700 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2703 switch (feparm.guard_interval)
2705 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2706 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2708 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2709 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2711 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2712 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2714 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2715 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2717 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2718 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2720 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2721 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2723 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2724 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2727 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2728 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2731 switch (feparm.hierarchy)
2733 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2734 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2736 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2737 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2739 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2740 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2742 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2743 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2746 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2747 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2750 switch (feparm.inversion)
2752 case eDVBFrontendParametersTerrestrial::Inversion_On:
2753 parm_inversion = INVERSION_ON;
2755 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2756 parm_inversion = INVERSION_OFF;
2759 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2760 parm_inversion = INVERSION_AUTO;
2763 eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d, system %d, plpid %d",
2764 parm_frequency/1000,
2765 parm_u_ofdm_bandwidth,
2766 parm_u_ofdm_code_rate_LP,
2767 parm_u_ofdm_code_rate_HP,
2768 parm_u_ofdm_constellation,
2769 parm_u_ofdm_transmission_mode,
2770 parm_u_ofdm_guard_interval,
2771 parm_u_ofdm_hierarchy_information,
2779 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2781 unsigned int timeout = 5000;
2782 eDebugNoSimulate("(%d)tune", m_dvbid);
2788 if (!m_sn && !m_simulate)
2790 eDebug("no frontend device opened... do not try to tune !!!");
2804 m_sec_sequence.clear();
2806 where.calcLockTimeout(timeout);
2812 eDVBFrontendParametersSatellite feparm;
2813 if (where.getDVBS(feparm))
2815 eDebug("no dvbs data!");
2819 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2821 eDVBFrontend *sec_fe = this;
2822 long tmp = m_data[LINKED_PREV_PTR];
2825 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2826 sec_fe = linked_fe->m_frontend;
2827 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2829 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2830 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
2832 m_rotor_mode = feparm.no_rotor_command_on_tune;
2834 m_sec->setRotorMoving(m_slotid, false);
2835 res=prepare_sat(feparm, timeout);
2843 eDVBFrontendParametersCable feparm;
2844 if (where.getDVBC(feparm))
2849 res=prepare_cable(feparm);
2853 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2854 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2859 eDVBFrontendParametersTerrestrial feparm;
2860 if (where.getDVBT(feparm))
2862 eDebug("no -T data");
2866 res=prepare_terrestrial(feparm);
2870 std::string enable_5V;
2871 char configStr[255];
2872 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2873 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2874 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2875 if (enable_5V == "True")
2876 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2878 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2879 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2885 m_sec_sequence.current() = m_sec_sequence.begin();
2889 m_tuneTimer->start(0,true);
2891 if (m_state != stateTuning)
2893 m_state = stateTuning;
2894 m_stateChanged(this);
2903 m_tuneTimer->stop();
2907 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2909 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2913 RESULT eDVBFrontend::setVoltage(int voltage)
2915 if (m_type == feCable)
2917 #if HAVE_DVB_API_VERSION < 3
2920 bool increased=false;
2921 fe_sec_voltage_t vlt;
2923 m_data[CUR_VOLTAGE]=voltage;
2927 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2928 vlt = SEC_VOLTAGE_OFF;
2931 #if HAVE_DVB_API_VERSION < 3
2932 vlt = SEC_VOLTAGE_13_5;
2938 vlt = SEC_VOLTAGE_13;
2941 #if HAVE_DVB_API_VERSION < 3
2942 vlt = SEC_VOLTAGE_18_5;
2948 vlt = SEC_VOLTAGE_18;
2955 #if HAVE_DVB_API_VERSION < 3
2956 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2958 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2959 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2960 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2964 RESULT eDVBFrontend::getState(int &state)
2970 RESULT eDVBFrontend::setTone(int t)
2972 if (m_type != feSatellite)
2974 #if HAVE_DVB_API_VERSION < 3
2977 fe_sec_tone_mode_t tone;
2986 tone = SEC_TONE_OFF;
2993 #if HAVE_DVB_API_VERSION < 3
2994 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2996 return ::ioctl(m_fd, FE_SET_TONE, tone);
3000 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
3001 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3004 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3008 #if HAVE_DVB_API_VERSION < 3
3009 struct secCommand cmd;
3010 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3011 cmd.u.diseqc.cmdtype = diseqc.data[0];
3012 cmd.u.diseqc.addr = diseqc.data[1];
3013 cmd.u.diseqc.cmd = diseqc.data[2];
3014 cmd.u.diseqc.numParams = diseqc.len-3;
3015 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3016 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3018 struct dvb_diseqc_master_cmd cmd;
3019 memcpy(cmd.msg, diseqc.data, diseqc.len);
3020 cmd.msg_len = diseqc.len;
3021 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3027 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3028 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3030 RESULT eDVBFrontend::sendToneburst(int burst)
3034 #if HAVE_DVB_API_VERSION < 3
3035 secMiniCmd cmd = SEC_MINI_NONE;
3037 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3039 if ( burst == eDVBSatelliteDiseqcParameters::A )
3041 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3043 #if HAVE_DVB_API_VERSION < 3
3044 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3047 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3053 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3059 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3061 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3062 m_sec_sequence.push_back(list);
3064 m_sec_sequence = list;
3068 RESULT eDVBFrontend::getData(int num, long &data)
3070 if ( num < NUM_DATA_ENTRIES )
3078 RESULT eDVBFrontend::setData(int num, long val)
3080 if ( num < NUM_DATA_ENTRIES )
3088 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3092 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
3094 if (feparm->getSystem(type) || type != m_type || !m_enabled)
3097 if (m_type == eDVBFrontend::feSatellite)
3099 eDVBFrontendParametersSatellite sat_parm;
3100 if (feparm->getDVBS(sat_parm) < 0)
3104 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
3108 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
3109 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
3111 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
3116 else if (m_type == eDVBFrontend::feCable)
3118 eDVBFrontendParametersCable cab_parm;
3119 if (feparm->getDVBC(cab_parm) < 0)
3126 else if (m_type == eDVBFrontend::feTerrestrial)
3128 eDVBFrontendParametersTerrestrial ter_parm;
3129 if (feparm->getDVBT(ter_parm) < 0)
3133 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !m_can_handle_dvbt2)
3138 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && m_can_handle_dvbt2)
3140 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3145 if (score && preferred)
3147 /* make 'sure' we always prefer this frontend */
3154 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3156 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3157 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3159 Id = PyTuple_GET_ITEM(obj, 0);
3160 Descr = PyTuple_GET_ITEM(obj, 1);
3161 Enabled = PyTuple_GET_ITEM(obj, 2);
3162 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3163 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3164 frontendId = PyTuple_GET_ITEM(obj, 5);
3165 m_slotid = PyInt_AsLong(Id);
3166 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3168 strcpy(m_description, PyString_AS_STRING(Descr));
3169 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3170 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3171 // m_slotid, m_description);
3174 m_enabled = Enabled == Py_True;
3175 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3176 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3177 !!strstr(m_description, "Alps BSBE2") ||
3178 !!strstr(m_description, "Alps -S") ||
3179 !!strstr(m_description, "BCM4501");
3180 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
3181 m_can_handle_dvbt2 = IsDVBT2 == Py_True;
3182 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3183 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" );
3186 PyErr_SetString(PyExc_StandardError,
3187 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");