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;
500 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
501 :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
502 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false), m_can_handle_dvbt2(false)
503 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
504 #if HAVE_DVB_API_VERSION < 3
508 #if HAVE_DVB_API_VERSION < 3
509 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
510 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
512 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
515 m_timeout = eTimer::create(eApp);
516 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
518 m_tuneTimer = eTimer::create(eApp);
519 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
521 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
524 m_idleInputpower[0]=m_idleInputpower[1]=0;
526 ok = !openFrontend();
530 void eDVBFrontend::reopenFrontend()
537 int eDVBFrontend::openFrontend()
539 if (m_state != stateClosed)
540 return -1; // already opened
545 #if HAVE_DVB_API_VERSION < 3
546 FrontendInfo fe_info;
548 dvb_frontend_info fe_info;
552 eDebug("opening frontend %d", m_dvbid);
555 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
558 eWarning("failed! (%s) %m", m_filename);
563 eWarning("frontend %d already opened", m_dvbid);
566 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
568 eWarning("ioctl FE_GET_INFO failed");
574 switch (fe_info.type)
577 m_type = iDVBFrontend::feSatellite;
580 m_type = iDVBFrontend::feCable;
583 m_type = iDVBFrontend::feTerrestrial;
586 eWarning("unknown frontend type.");
592 m_simulate_fe->m_type = m_type;
593 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
596 #if HAVE_DVB_API_VERSION < 3
597 if (m_type == iDVBFrontend::feSatellite)
603 m_secfd = ::open(m_sec_filename, O_RDWR);
606 eWarning("failed! (%s) %m", m_sec_filename);
614 eWarning("sec %d already opened", m_dvbid);
618 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
619 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
622 setTone(iDVBFrontend::toneOff);
623 setVoltage(iDVBFrontend::voltageOff);
628 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
630 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
632 long tmp = m_data[LINKED_NEXT_PTR];
635 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
636 if (linked_fe->m_inuse)
638 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
639 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
642 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
648 eDebugNoSimulate("close frontend %d", m_dvbid);
649 if (m_data[SATCR] != -1)
653 m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
654 m_tuneTimer->start(0, true);
655 if(!m_tuneTimer->isActive())
658 eDebug("[turnOffSatCR] no mainloop");
661 timeout = tuneLoopInt();
664 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
668 eDebug("[turnOffSatCR] running mainloop");
672 m_data[ROTOR_CMD] = -1;
675 setTone(iDVBFrontend::toneOff);
676 setVoltage(iDVBFrontend::voltageOff);
679 if (m_sec && !m_simulate)
680 m_sec->setRotorMoving(m_slotid, false);
684 eWarning("couldnt close frontend %d", m_dvbid);
688 setTone(iDVBFrontend::toneOff);
689 setVoltage(iDVBFrontend::voltageOff);
691 #if HAVE_DVB_API_VERSION < 3
694 if (!::close(m_secfd))
697 eWarning("couldnt close sec %d", m_dvbid);
701 m_state = stateClosed;
706 eDVBFrontend::~eDVBFrontend()
708 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
712 void eDVBFrontend::feEvent(int w)
714 eDVBFrontend *sec_fe = this;
715 long tmp = m_data[LINKED_PREV_PTR];
718 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
719 sec_fe = linked_fe->m_frontend;
720 sec_fe->getData(LINKED_NEXT_PTR, tmp);
724 #if HAVE_DVB_API_VERSION < 3
727 dvb_frontend_event event;
731 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
733 if (res && (errno == EAGAIN))
739 #if HAVE_DVB_API_VERSION < 3
740 if (event.type == FE_COMPLETION_EV)
742 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
743 if (event.status & FE_HAS_LOCK)
751 #if HAVE_DVB_API_VERSION >= 3
752 if (event.status & FE_TIMEDOUT) {
753 eDebug("FE_TIMEDOUT! ..abort");
766 eDebug("stateLostLock");
767 state = stateLostLock;
769 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
772 if (m_state != state)
775 m_stateChanged(this);
780 void eDVBFrontend::timeout()
783 if (m_state == stateTuning)
785 #ifdef BUILD_VUPLUS /* ikseong */
786 eDVBFrontend *sec_fe = this;
787 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
789 m_state = stateFailed;
790 m_stateChanged(this);
794 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
796 /* unsigned 32 bit division */
797 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
799 return (a + b / 2) / b;
802 int eDVBFrontend::readFrontendData(int type)
811 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
812 eDebug("FE_READ_BER failed (%m)");
817 case signalQualitydB: /* this will move into the driver */
819 int sat_max = 1600; // for stv0288 / bsbe2
820 int ret = 0x12345678;
824 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
825 eDebug("FE_READ_SNR failed (%m)");
826 else if (!strcmp(m_description, "BCM4501 (internal)"))
828 float SDS_SNRE = snr << 16;
831 if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
833 static float SNR_COEFF[6] = {
836 197418.0 / 4194304.0,
837 -2602183.0 / 4194304.0,
838 20377212.0 / 4194304.0,
839 -37791203.0 / 4194304.0,
841 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
842 fval2 = pow(10.0, fval1)-1;
843 fval1 = 10.0 * log10(fval2);
847 fval2 = SNR_COEFF[0];
848 for (int i=1; i<6; ++i)
851 fval2 += SNR_COEFF[i];
857 #if HAVE_DVB_API_VERSION >= 3
860 float fval1 = SDS_SNRE / 268435456.0,
863 if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
874 fval4 = -10.0 * log10(fval1);
876 for (int i=0; i < 5; ++i)
877 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
882 ret = (int)(snr_in_db * 100);
884 else if (strstr(m_description, "Alps BSBE1 C01A") ||
885 strstr(m_description, "Alps -S(STV0288)"))
889 else if (snr == 0xFFFF) // i think this should not happen
893 enum { REALVAL, REGVAL };
894 const long CN_lookup[31][2] = {
895 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
896 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
897 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
898 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
899 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
900 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
903 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
904 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
908 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
913 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
918 ret = (((regval - CN_lookup[Imin][REGVAL])
919 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
920 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
921 + CN_lookup[Imin][REALVAL]) * 10;
927 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
928 !strcmp(m_description, "Alps -S") ||
929 !strcmp(m_description, "Philips -S") ||
930 !strcmp(m_description, "LG -S") )
933 ret = (int)((snr-39075)/17.647);
934 } else if (!strcmp(m_description, "Alps BSBE2"))
936 ret = (int)((snr >> 7) * 10);
937 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
939 int mse = (~snr) & 0xFF;
940 switch (parm_u_qam_modulation) {
941 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
942 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
943 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
944 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
945 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
948 } else if (!strcmp(m_description, "Philips TU1216"))
950 snr = 0xFF - (snr & 0xFF);
952 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
954 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
955 ret = (snr * 100) >> 8;
956 else if (!strcmp(m_description, "CXD1981"))
958 int mse = (~snr) & 0xFF;
959 switch (parm_u_qam_modulation) {
962 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
964 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
970 if (type == signalQuality)
972 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
977 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
978 case feCable: // we assume a max of 42db here
979 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
980 case feTerrestrial: // we assume a max of 24db here
981 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
985 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
993 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
994 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1000 #if HAVE_DVB_API_VERSION < 3
1001 FrontendStatus status=0;
1007 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1008 eDebug("FE_READ_STATUS failed (%m)");
1009 return !!(status&FE_HAS_LOCK);
1015 #if HAVE_DVB_API_VERSION < 3
1016 FrontendStatus status=0;
1022 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1023 eDebug("FE_READ_STATUS failed (%m)");
1024 return !!(status&FE_HAS_SYNC);
1028 case frontendNumber:
1034 void PutToDict(ePyObject &dict, const char*key, long value)
1036 ePyObject item = PyInt_FromLong(value);
1039 if (PyDict_SetItemString(dict, key, item))
1040 eDebug("put %s to dict failed", key);
1044 eDebug("could not create PyObject for %s", key);
1047 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1051 if (PyDict_SetItemString(dict, key, item))
1052 eDebug("put %s to dict failed", key);
1056 eDebug("invalid PyObject for %s", key);
1059 void PutToDict(ePyObject &dict, const char*key, const char *value)
1061 ePyObject item = PyString_FromString(value);
1064 if (PyDict_SetItemString(dict, key, item))
1065 eDebug("put %s to dict failed", key);
1069 eDebug("could not create PyObject for %s", key);
1072 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1074 PutToDict(dict, "tuner_type", "DVB-S");
1075 PutToDict(dict, "frequency", feparm.frequency);
1076 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1077 PutToDict(dict, "orbital_position", feparm.orbital_position);
1078 PutToDict(dict, "inversion", feparm.inversion);
1079 PutToDict(dict, "fec_inner", feparm.fec);
1080 PutToDict(dict, "modulation", feparm.modulation);
1081 PutToDict(dict, "polarization", feparm.polarisation);
1082 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1084 PutToDict(dict, "rolloff", feparm.rolloff);
1085 PutToDict(dict, "pilot", feparm.pilot);
1087 PutToDict(dict, "system", feparm.system);
1090 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1092 PutToDict(dict, "tuner_type", "DVB-T");
1093 PutToDict(dict, "frequency", feparm.frequency);
1094 PutToDict(dict, "bandwidth", feparm.bandwidth);
1095 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1096 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1097 PutToDict(dict, "constellation", feparm.modulation);
1098 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1099 PutToDict(dict, "guard_interval", feparm.guard_interval);
1100 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1101 PutToDict(dict, "inversion", feparm.inversion);
1102 PutToDict(dict, "system", feparm.system);
1103 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1105 PutToDict(dict, "plp_id", feparm.plpid);
1109 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1111 PutToDict(dict, "tuner_type", "DVB-C");
1112 PutToDict(dict, "frequency", feparm.frequency);
1113 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1114 PutToDict(dict, "modulation", feparm.modulation);
1115 PutToDict(dict, "inversion", feparm.inversion);
1116 PutToDict(dict, "fec_inner", feparm.fec_inner);
1119 #if HAVE_DVB_API_VERSION >= 5
1120 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1123 int frequency = parm_frequency + freq_offset;
1124 PutToDict(dict, "frequency", frequency);
1125 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1126 PutToDict(dict, "orbital_position", orb_pos);
1127 PutToDict(dict, "polarization", polarization);
1129 switch(parm_u_qpsk_fec_inner)
1131 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1132 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1133 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1134 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1135 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1136 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1137 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1138 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1139 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1140 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1141 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1142 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1144 PutToDict(dict, "fec_inner", tmp);
1146 switch (p[0].u.data)
1148 default: eDebug("got unsupported system from frontend! report as DVBS!");
1149 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1152 switch (p[2].u.data)
1154 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1155 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1156 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1157 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1159 PutToDict(dict, "rolloff", tmp);
1161 switch (p[3].u.data)
1163 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1164 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1165 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1167 PutToDict(dict, "pilot", tmp);
1169 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1172 PutToDict(dict, "system", tmp);
1174 switch (p[1].u.data)
1176 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1177 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1178 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1180 PutToDict(dict, "modulation", tmp);
1182 switch(parm_inversion & 3)
1184 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1185 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1186 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1188 PutToDict(dict, "inversion", tmp);
1191 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1195 tmp = p[1].u.data/1000;
1196 PutToDict(dict, "frequency", tmp);
1198 PutToDict(dict, "symbol_rate", p[2].u.data);
1200 switch (p[3].u.data)
1202 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1203 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1204 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1205 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1206 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1207 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1208 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1210 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1212 PutToDict(dict, "fec_inner", tmp);
1214 switch (p[4].u.data)
1216 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1217 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1218 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1219 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1220 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1222 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1224 PutToDict(dict, "modulation", tmp);
1226 switch (p[5].u.data)
1228 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1229 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1231 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1233 PutToDict(dict, "inversion", tmp);
1236 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1240 switch (p[0].u.data)
1242 default: eDebug("got unsupported system from frontend! report as DVBT!");
1243 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1246 #ifdef DTV_DVBT2_PLP_ID
1248 PutToDict(dict, "plp_id", tmp);
1250 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1253 PutToDict(dict, "system", tmp);
1256 PutToDict(dict, "frequency", tmp);
1258 switch (p[2].u.data)
1260 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1261 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1262 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1263 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1264 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1265 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1267 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1269 PutToDict(dict, "bandwidth", tmp);
1271 switch (p[3].u.data)
1273 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1274 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1275 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1276 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1277 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1278 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1279 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1280 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1282 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1284 PutToDict(dict, "code_rate_lp", tmp);
1286 switch (p[4].u.data)
1288 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1289 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1290 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1291 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1292 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1293 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1294 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1295 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1297 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1299 PutToDict(dict, "code_rate_hp", tmp);
1301 switch (p[5].u.data)
1303 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1304 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1305 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1306 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1308 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1310 PutToDict(dict, "constellation", tmp);
1313 switch (p[6].u.data)
1315 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1316 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1317 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1318 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1319 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1320 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1322 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1324 PutToDict(dict, "transmission_mode", tmp);
1326 switch (p[7].u.data)
1328 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1329 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1330 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1331 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1332 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1333 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1334 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1336 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1338 PutToDict(dict, "guard_interval", tmp);
1340 switch (p[8].u.data)
1342 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1343 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1344 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1345 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1347 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1349 PutToDict(dict, "hierarchy_information", tmp);
1351 switch (p[9].u.data)
1353 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1354 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1356 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1358 PutToDict(dict, "inversion", tmp);
1361 #else // #if HAVE_DVB_API_VERSION >= 5
1362 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1365 int frequency = parm_frequency + freq_offset;
1366 PutToDict(dict, "frequency", frequency);
1367 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1368 PutToDict(dict, "orbital_position", orb_pos);
1369 PutToDict(dict, "polarization", polarization);
1371 switch((int)parm_u_qpsk_fec_inner)
1373 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1374 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1375 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1376 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1377 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1378 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1380 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1381 #if HAVE_DVB_API_VERSION >=3
1382 case FEC_S2_8PSK_1_2:
1383 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1384 case FEC_S2_8PSK_2_3:
1385 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1386 case FEC_S2_8PSK_3_4:
1387 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1388 case FEC_S2_8PSK_5_6:
1389 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1390 case FEC_S2_8PSK_7_8:
1391 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1392 case FEC_S2_8PSK_8_9:
1393 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1394 case FEC_S2_8PSK_3_5:
1395 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1396 case FEC_S2_8PSK_4_5:
1397 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1398 case FEC_S2_8PSK_9_10:
1399 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1402 PutToDict(dict, "fec_inner", tmp);
1403 #if HAVE_DVB_API_VERSION >=3
1404 PutToDict(dict, "modulation",
1405 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1406 eDVBFrontendParametersSatellite::Modulation_8PSK :
1407 eDVBFrontendParametersSatellite::Modulation_QPSK );
1408 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1410 switch(parm_inversion & 0xc)
1412 default: // unknown rolloff
1413 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1414 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1415 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1417 PutToDict(dict, "rolloff", tmp);
1418 switch(parm_inversion & 0x30)
1420 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1421 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1422 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1424 PutToDict(dict, "pilot", tmp);
1425 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1428 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1430 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1431 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1433 PutToDict(dict, "system", tmp);
1436 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1439 #if HAVE_DVB_API_VERSION < 3
1440 PutToDict(dict, "frequency", parm_frequency);
1442 PutToDict(dict, "frequency", parm_frequency/1000);
1444 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1445 switch(parm_u_qam_fec_inner)
1447 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1448 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1449 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1450 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1451 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1452 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1453 #if HAVE_DVB_API_VERSION >= 3
1454 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1457 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1459 PutToDict(dict, "fec_inner", tmp);
1460 switch(parm_u_qam_modulation)
1462 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1463 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1464 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1465 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1466 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1468 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1470 PutToDict(dict, "modulation", tmp);
1473 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1476 PutToDict(dict, "frequency", parm_frequency);
1477 switch (parm_u_ofdm_bandwidth)
1479 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1480 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1481 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1483 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1485 PutToDict(dict, "bandwidth", tmp);
1486 switch (parm_u_ofdm_code_rate_LP)
1488 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1489 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1490 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1491 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1492 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1494 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1496 PutToDict(dict, "code_rate_lp", tmp);
1497 switch (parm_u_ofdm_code_rate_HP)
1499 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1500 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1501 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1502 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1503 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1505 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1507 PutToDict(dict, "code_rate_hp", tmp);
1508 switch (parm_u_ofdm_constellation)
1510 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1511 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1512 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1514 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1516 PutToDict(dict, "constellation", tmp);
1517 switch (parm_u_ofdm_transmission_mode)
1519 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1520 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1522 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1524 PutToDict(dict, "transmission_mode", tmp);
1525 switch (parm_u_ofdm_guard_interval)
1527 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1528 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1529 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1530 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1532 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1534 PutToDict(dict, "guard_interval", tmp);
1535 switch (parm_u_ofdm_hierarchy_information)
1537 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1538 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1539 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1540 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1542 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1544 PutToDict(dict, "hierarchy_information", tmp);
1547 #endif // #if HAVE_DVB_API_VERSION >= 5
1549 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1551 if (dest && PyDict_Check(dest))
1553 const char *tmp = "UNKNOWN";
1574 PutToDict(dest, "tuner_state", tmp);
1575 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1576 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1577 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1578 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1579 int sigQualitydB = readFrontendData(signalQualitydB);
1580 if (sigQualitydB == 0x12345678) // not support yet
1582 ePyObject obj=Py_None;
1584 PutToDict(dest, "tuner_signal_quality_db", obj);
1587 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1588 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1592 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1594 if (dest && PyDict_Check(dest))
1596 FRONTENDPARAMETERS front;
1597 #if HAVE_DVB_API_VERSION >= 5
1598 struct dtv_property p[16];
1599 struct dtv_properties cmdseq;
1605 p[0].cmd = DTV_DELIVERY_SYSTEM;
1606 p[1].cmd = DTV_MODULATION;
1607 p[2].cmd = DTV_ROLLOFF;
1608 p[3].cmd = DTV_PILOT;
1612 p[0].cmd = DTV_DELIVERY_SYSTEM;
1613 p[1].cmd = DTV_FREQUENCY;
1614 p[2].cmd = DTV_SYMBOL_RATE;
1615 p[3].cmd = DTV_INNER_FEC;
1616 p[4].cmd = DTV_MODULATION;
1617 p[5].cmd = DTV_INVERSION;
1621 p[0].cmd = DTV_DELIVERY_SYSTEM;
1622 p[1].cmd = DTV_FREQUENCY;
1623 p[2].cmd = DTV_BANDWIDTH_HZ;
1624 p[3].cmd = DTV_CODE_RATE_LP;
1625 p[4].cmd = DTV_CODE_RATE_HP;
1626 p[5].cmd = DTV_MODULATION;
1627 p[6].cmd = DTV_TRANSMISSION_MODE;
1628 p[7].cmd = DTV_GUARD_INTERVAL;
1629 p[8].cmd = DTV_HIERARCHY;
1630 p[9].cmd = DTV_INVERSION;
1631 #ifdef DTV_DVBT2_PLP_ID
1632 p[10].cmd = DTV_DVBT2_PLP_ID;
1640 if (m_simulate || m_fd == -1 || original)
1644 #if HAVE_DVB_API_VERSION >= 5
1645 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1647 eDebug("FE_GET_PROPERTY failed (%m)");
1650 else if (m_type == feSatellite && // use for DVB-S(2) only
1651 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1653 eDebug("FE_GET_FRONTEND failed (%m)");
1657 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1659 eDebug("FE_GET_FRONTEND failed (%m)");
1668 PutSatelliteDataToDict(dest, oparm.sat);
1671 PutCableDataToDict(dest, oparm.cab);
1674 PutTerrestrialDataToDict(dest, oparm.ter);
1680 FRONTENDPARAMETERS &parm = front;
1681 #if HAVE_DVB_API_VERSION >= 5
1685 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1688 fillDictWithCableData(dest, p);
1691 fillDictWithTerrestrialData(dest, p);
1695 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1696 switch(parm_inversion & 3)
1699 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1702 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1706 PutToDict(dest, "inversion", tmp);
1710 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1713 fillDictWithCableData(dest, parm);
1716 fillDictWithTerrestrialData(dest, parm);
1724 void eDVBFrontend::getFrontendData(ePyObject dest)
1726 if (dest && PyDict_Check(dest))
1729 PutToDict(dest, "tuner_number", m_slotid);
1745 PutToDict(dest, "tuner_type", tmp);
1749 #ifndef FP_IOCTL_GET_ID
1750 #define FP_IOCTL_GET_ID 0
1752 int eDVBFrontend::readInputpower()
1756 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1758 char proc_name2[64];
1759 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1760 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1762 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1764 if (fscanf(f, "%d", &power) != 1)
1765 eDebug("read %s failed!! (%m)", proc_name);
1767 eDebug("%s is %d\n", proc_name, power);
1772 // open front prozessor
1773 int fp=::open("/dev/dbox/fp0", O_RDWR);
1776 eDebug("couldn't open fp");
1779 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1780 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1782 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1791 bool eDVBFrontend::setSecSequencePos(int steps)
1793 eDebugNoSimulate("set sequence pos %d", steps);
1798 if (m_sec_sequence.current() != m_sec_sequence.end())
1799 ++m_sec_sequence.current();
1804 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1805 --m_sec_sequence.current();
1811 void eDVBFrontend::tuneLoop()
1816 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1819 eDVBFrontend *sec_fe = this;
1820 eDVBRegisteredFrontend *regFE = 0;
1821 long tmp = m_data[LINKED_PREV_PTR];
1824 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1825 sec_fe = prev->m_frontend;
1826 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1827 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1828 int state = sec_fe->m_state;
1829 // workaround to put the kernel frontend thread into idle state!
1830 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1832 sec_fe->closeFrontend(true);
1833 state = sec_fe->m_state;
1835 // sec_fe is closed... we must reopen it here..
1836 if (state == stateClosed)
1844 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1846 long *sec_fe_data = sec_fe->m_data;
1847 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1849 switch (m_sec_sequence.current()->cmd)
1851 case eSecCommand::SLEEP:
1852 delay = m_sec_sequence.current()++->msec;
1853 eDebugNoSimulate("[SEC] sleep %dms", delay);
1855 case eSecCommand::GOTO:
1856 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1857 ++m_sec_sequence.current();
1859 case eSecCommand::SET_VOLTAGE:
1861 int voltage = m_sec_sequence.current()++->voltage;
1862 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1863 sec_fe->setVoltage(voltage);
1866 case eSecCommand::IF_VOLTAGE_GOTO:
1868 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1869 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1871 ++m_sec_sequence.current();
1874 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1876 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1877 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1879 ++m_sec_sequence.current();
1882 case eSecCommand::IF_TONE_GOTO:
1884 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1885 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1887 ++m_sec_sequence.current();
1890 case eSecCommand::IF_NOT_TONE_GOTO:
1892 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1893 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1895 ++m_sec_sequence.current();
1898 case eSecCommand::SET_TONE:
1899 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1900 sec_fe->setTone(m_sec_sequence.current()++->tone);
1902 case eSecCommand::SEND_DISEQC:
1903 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1904 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1905 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1906 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1907 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1908 eDebugNoSimulate("(DiSEqC reset)");
1909 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1910 eDebugNoSimulate("(DiSEqC peripherial power on)");
1912 eDebugNoSimulate("");
1913 ++m_sec_sequence.current();
1915 case eSecCommand::SEND_TONEBURST:
1916 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1917 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1919 case eSecCommand::SET_FRONTEND:
1921 int enableEvents = (m_sec_sequence.current()++)->val;
1922 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1923 setFrontend(enableEvents);
1926 case eSecCommand::START_TUNE_TIMEOUT:
1928 int tuneTimeout = m_sec_sequence.current()->timeout;
1929 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1931 m_timeout->start(tuneTimeout, 1);
1932 ++m_sec_sequence.current();
1935 case eSecCommand::SET_TIMEOUT:
1936 m_timeoutCount = m_sec_sequence.current()++->val;
1937 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1939 case eSecCommand::IF_TIMEOUT_GOTO:
1940 if (!m_timeoutCount)
1942 eDebugNoSimulate("[SEC] rotor timout");
1943 setSecSequencePos(m_sec_sequence.current()->steps);
1946 ++m_sec_sequence.current();
1948 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1950 int idx = m_sec_sequence.current()++->val;
1951 if ( idx == 0 || idx == 1 )
1953 m_idleInputpower[idx] = sec_fe->readInputpower();
1954 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1957 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1960 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1962 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1963 int idx = compare.val;
1964 if ( !m_simulate && (idx == 0 || idx == 1) )
1966 int idle = sec_fe->readInputpower();
1967 int diff = abs(idle-m_idleInputpower[idx]);
1970 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1971 setSecSequencePos(compare.steps);
1975 ++m_sec_sequence.current();
1978 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1980 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1983 setSecSequencePos(cmd.steps);
1987 int isLocked = readFrontendData(locked);
1988 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1990 if (!m_timeoutCount && m_retryCount > 0)
1992 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1995 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1998 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
2000 cmd.lastSignal = signal;
2003 if (cmd.okcount > 4)
2005 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2006 setSecSequencePos(cmd.steps);
2007 m_state = stateLock;
2008 m_stateChanged(this);
2009 feEvent(-1); // flush events
2017 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2019 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2023 ++m_sec_sequence.current();
2026 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2027 m_runningInputpower = sec_fe->readInputpower();
2028 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2029 ++m_sec_sequence.current();
2031 case eSecCommand::SET_ROTOR_MOVING:
2033 m_sec->setRotorMoving(m_slotid, true);
2034 ++m_sec_sequence.current();
2036 case eSecCommand::SET_ROTOR_STOPPED:
2038 m_sec->setRotorMoving(m_slotid, false);
2039 ++m_sec_sequence.current();
2041 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2043 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2046 setSecSequencePos(cmd.steps);
2049 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2050 const char *txt = cmd.direction ? "running" : "stopped";
2052 if (!m_timeoutCount && m_retryCount > 0)
2054 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2056 m_runningInputpower,
2059 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2060 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2063 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2064 if ( cmd.okcount > 6 )
2066 eDebugNoSimulate("[SEC] rotor is %s", txt);
2067 if (setSecSequencePos(cmd.steps))
2073 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2076 ++m_sec_sequence.current();
2079 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2080 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2081 setSecSequencePos(m_sec_sequence.current()->steps);
2083 ++m_sec_sequence.current();
2085 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2086 eDebugNoSimulate("[SEC] invalidate current switch params");
2087 sec_fe_data[CSW] = -1;
2088 sec_fe_data[UCSW] = -1;
2089 sec_fe_data[TONEBURST] = -1;
2090 ++m_sec_sequence.current();
2092 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2093 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2094 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2095 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2096 eDebugNoSimulate("[SEC] update current switch params");
2097 ++m_sec_sequence.current();
2099 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2100 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2101 sec_fe_data[ROTOR_CMD] = -1;
2102 sec_fe_data[ROTOR_POS] = -1;
2103 ++m_sec_sequence.current();
2105 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2106 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2107 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2108 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2109 ++m_sec_sequence.current();
2111 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2112 m_retryCount = m_sec_sequence.current()++->val;
2113 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2115 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2118 eDebugNoSimulate("[SEC] no more rotor retrys");
2119 setSecSequencePos(m_sec_sequence.current()->steps);
2122 ++m_sec_sequence.current();
2124 case eSecCommand::SET_POWER_LIMITING_MODE:
2129 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2130 FILE *f=fopen(proc_name, "w");
2131 if (f) // new interface exist?
2133 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2134 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2135 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2137 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2140 else if (sec_fe->m_need_rotor_workaround)
2143 int slotid = sec_fe->m_slotid;
2144 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2146 sprintf(dev, "/dev/i2c-%d", slotid);
2147 else if (slotid == 2)
2148 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2149 else if (slotid == 3)
2150 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2151 int fd = ::open(dev, O_RDWR);
2153 unsigned char data[2];
2154 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2155 if(::read(fd, data, 1) != 1)
2156 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2157 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2159 data[0] |= 0x80; // enable static current limiting
2160 eDebugNoSimulate("[SEC] set static current limiting");
2164 data[0] &= ~0x80; // enable dynamic current limiting
2165 eDebugNoSimulate("[SEC] set dynamic current limiting");
2167 if(::write(fd, data, 1) != 1)
2168 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2172 ++m_sec_sequence.current();
2175 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2177 eDebugNoSimulate("[SEC] delayed close frontend");
2178 closeFrontend(false, true);
2179 ++m_sec_sequence.current();
2183 eDebugNoSimulate("[SEC] unhandled sec command %d",
2184 ++m_sec_sequence.current()->cmd);
2185 ++m_sec_sequence.current();
2188 m_tuneTimer->start(delay,true);
2192 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2197 void eDVBFrontend::setFrontend(bool recvEvents)
2201 eDebug("setting frontend %d", m_dvbid);
2204 feEvent(-1); // flush events
2205 #if HAVE_DVB_API_VERSION >= 5
2206 if (m_type == iDVBFrontend::feSatellite)
2208 fe_rolloff_t rolloff = ROLLOFF_35;
2209 fe_pilot_t pilot = PILOT_OFF;
2210 fe_modulation_t modulation = QPSK;
2211 fe_delivery_system_t system = SYS_DVBS;
2212 switch(oparm.sat.system)
2214 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2215 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2217 switch(oparm.sat.modulation)
2219 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2220 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2221 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2223 switch(oparm.sat.pilot)
2225 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2226 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2227 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2229 switch(oparm.sat.rolloff)
2231 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2232 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2233 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2235 struct dtv_property p[10];
2236 struct dtv_properties cmdseq;
2238 p[0].cmd = DTV_CLEAR;
2239 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2240 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2241 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2242 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2243 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2244 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2245 if (system == SYS_DVBS2)
2247 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2248 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2249 p[9].cmd = DTV_TUNE;
2254 p[7].cmd = DTV_TUNE;
2257 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2259 perror("FE_SET_PROPERTY failed");
2263 else if (m_type == iDVBFrontend::feCable)
2265 struct dtv_property p[8];
2266 struct dtv_properties cmdseq;
2268 p[0].cmd = DTV_CLEAR;
2269 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2270 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2272 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2274 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2275 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2276 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2277 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2278 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2279 p[7].cmd = DTV_TUNE;
2281 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2283 perror("FE_SET_PROPERTY failed");
2287 else if (m_type == iDVBFrontend::feTerrestrial)
2289 fe_delivery_system_t system = SYS_DVBT;
2290 switch (oparm.ter.system)
2293 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2294 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2297 switch (oparm.ter.bandwidth)
2299 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2300 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2301 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2303 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2304 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2305 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2306 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2308 struct dtv_property p[13];
2309 struct dtv_properties cmdseq;
2312 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2313 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2314 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2315 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2316 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2317 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2318 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2319 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2320 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2321 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2322 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2323 #ifdef DTV_DVBT2_PLP_ID
2324 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
2326 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2327 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2329 perror("FE_SET_PROPERTY failed");
2336 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2338 perror("FE_SET_FRONTEND failed");
2345 RESULT eDVBFrontend::getFrontendType(int &t)
2353 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2358 eWarning("no SEC module active!");
2361 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2364 #if HAVE_DVB_API_VERSION >= 3
2365 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",
2368 feparm.polarisation,
2372 feparm.orbital_position,
2378 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2381 feparm.polarisation,
2385 feparm.orbital_position);
2387 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2388 switch (feparm.inversion)
2390 case eDVBFrontendParametersSatellite::Inversion_On:
2391 parm_inversion = INVERSION_ON;
2393 case eDVBFrontendParametersSatellite::Inversion_Off:
2394 parm_inversion = INVERSION_OFF;
2397 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2398 parm_inversion = INVERSION_AUTO;
2401 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2405 case eDVBFrontendParametersSatellite::FEC_None:
2406 parm_u_qpsk_fec_inner = FEC_NONE;
2408 case eDVBFrontendParametersSatellite::FEC_1_2:
2409 parm_u_qpsk_fec_inner = FEC_1_2;
2411 case eDVBFrontendParametersSatellite::FEC_2_3:
2412 parm_u_qpsk_fec_inner = FEC_2_3;
2414 case eDVBFrontendParametersSatellite::FEC_3_4:
2415 parm_u_qpsk_fec_inner = FEC_3_4;
2417 case eDVBFrontendParametersSatellite::FEC_5_6:
2418 parm_u_qpsk_fec_inner = FEC_5_6;
2420 case eDVBFrontendParametersSatellite::FEC_7_8:
2421 parm_u_qpsk_fec_inner = FEC_7_8;
2424 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2425 case eDVBFrontendParametersSatellite::FEC_Auto:
2426 parm_u_qpsk_fec_inner = FEC_AUTO;
2430 #if HAVE_DVB_API_VERSION >= 3
2435 case eDVBFrontendParametersSatellite::FEC_1_2:
2436 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2438 case eDVBFrontendParametersSatellite::FEC_2_3:
2439 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2441 case eDVBFrontendParametersSatellite::FEC_3_4:
2442 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2444 case eDVBFrontendParametersSatellite::FEC_3_5:
2445 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2447 case eDVBFrontendParametersSatellite::FEC_4_5:
2448 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2450 case eDVBFrontendParametersSatellite::FEC_5_6:
2451 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2453 case eDVBFrontendParametersSatellite::FEC_7_8:
2454 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2456 case eDVBFrontendParametersSatellite::FEC_8_9:
2457 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2459 case eDVBFrontendParametersSatellite::FEC_9_10:
2460 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2463 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2466 #if HAVE_DVB_API_VERSION < 5
2467 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2468 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2469 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2471 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2472 // 8PSK fec driver values are decimal 9 bigger
2477 // FIXME !!! get frequency range from tuner
2478 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2480 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2483 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2489 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2491 #if HAVE_DVB_API_VERSION < 3
2492 parm_frequency = feparm.frequency;
2494 parm_frequency = feparm.frequency * 1000;
2496 parm_u_qam_symbol_rate = feparm.symbol_rate;
2497 switch (feparm.modulation)
2499 case eDVBFrontendParametersCable::Modulation_QAM16:
2500 parm_u_qam_modulation = QAM_16;
2502 case eDVBFrontendParametersCable::Modulation_QAM32:
2503 parm_u_qam_modulation = QAM_32;
2505 case eDVBFrontendParametersCable::Modulation_QAM64:
2506 parm_u_qam_modulation = QAM_64;
2508 case eDVBFrontendParametersCable::Modulation_QAM128:
2509 parm_u_qam_modulation = QAM_128;
2511 case eDVBFrontendParametersCable::Modulation_QAM256:
2512 parm_u_qam_modulation = QAM_256;
2515 case eDVBFrontendParametersCable::Modulation_Auto:
2516 parm_u_qam_modulation = QAM_AUTO;
2519 switch (feparm.inversion)
2521 case eDVBFrontendParametersCable::Inversion_On:
2522 parm_inversion = INVERSION_ON;
2524 case eDVBFrontendParametersCable::Inversion_Off:
2525 parm_inversion = INVERSION_OFF;
2528 case eDVBFrontendParametersCable::Inversion_Unknown:
2529 parm_inversion = INVERSION_AUTO;
2532 switch (feparm.fec_inner)
2534 case eDVBFrontendParametersCable::FEC_None:
2535 parm_u_qam_fec_inner = FEC_NONE;
2537 case eDVBFrontendParametersCable::FEC_1_2:
2538 parm_u_qam_fec_inner = FEC_1_2;
2540 case eDVBFrontendParametersCable::FEC_2_3:
2541 parm_u_qam_fec_inner = FEC_2_3;
2543 case eDVBFrontendParametersCable::FEC_3_4:
2544 parm_u_qam_fec_inner = FEC_3_4;
2546 case eDVBFrontendParametersCable::FEC_5_6:
2547 parm_u_qam_fec_inner = FEC_5_6;
2549 case eDVBFrontendParametersCable::FEC_7_8:
2550 parm_u_qam_fec_inner = FEC_7_8;
2552 #if HAVE_DVB_API_VERSION >= 3
2553 case eDVBFrontendParametersCable::FEC_8_9:
2554 parm_u_qam_fec_inner = FEC_8_9;
2558 case eDVBFrontendParametersCable::FEC_Auto:
2559 parm_u_qam_fec_inner = FEC_AUTO;
2562 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2563 parm_frequency/1000,
2564 parm_u_qam_symbol_rate,
2565 parm_u_qam_fec_inner,
2566 parm_u_qam_modulation,
2572 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2574 parm_frequency = feparm.frequency;
2576 switch (feparm.bandwidth)
2578 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2579 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2581 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2582 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2584 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2585 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2587 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2588 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2590 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2591 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2593 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2594 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2597 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2598 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2601 switch (feparm.code_rate_LP)
2603 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2604 parm_u_ofdm_code_rate_LP = FEC_1_2;
2606 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2607 parm_u_ofdm_code_rate_LP = FEC_2_3;
2609 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2610 parm_u_ofdm_code_rate_LP = FEC_3_4;
2612 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2613 parm_u_ofdm_code_rate_LP = FEC_5_6;
2615 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2616 parm_u_ofdm_code_rate_LP = FEC_7_8;
2618 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2619 parm_u_ofdm_code_rate_LP = FEC_6_7;
2621 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2622 parm_u_ofdm_code_rate_LP = FEC_8_9;
2625 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2626 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2629 switch (feparm.code_rate_HP)
2631 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2632 parm_u_ofdm_code_rate_HP = FEC_1_2;
2634 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2635 parm_u_ofdm_code_rate_HP = FEC_2_3;
2637 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2638 parm_u_ofdm_code_rate_HP = FEC_3_4;
2640 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2641 parm_u_ofdm_code_rate_HP = FEC_5_6;
2643 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2644 parm_u_ofdm_code_rate_HP = FEC_7_8;
2646 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2647 parm_u_ofdm_code_rate_HP = FEC_6_7;
2649 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2650 parm_u_ofdm_code_rate_HP = FEC_8_9;
2653 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2654 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2657 switch (feparm.modulation)
2659 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2660 parm_u_ofdm_constellation = QPSK;
2662 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2663 parm_u_ofdm_constellation = QAM_16;
2665 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2666 parm_u_ofdm_constellation = QAM_64;
2668 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2669 parm_u_ofdm_constellation = QAM_256;
2672 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2673 parm_u_ofdm_constellation = QAM_AUTO;
2676 switch (feparm.transmission_mode)
2678 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2679 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2681 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2682 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2684 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2685 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2687 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2688 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2690 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2691 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2693 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2694 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2697 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2698 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2701 switch (feparm.guard_interval)
2703 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2704 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2706 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2707 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2709 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2710 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2712 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2713 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2715 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2716 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2718 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2719 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2721 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2722 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2725 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2726 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2729 switch (feparm.hierarchy)
2731 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2732 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2734 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2735 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2737 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2738 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2740 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2741 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2744 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2745 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2748 switch (feparm.inversion)
2750 case eDVBFrontendParametersTerrestrial::Inversion_On:
2751 parm_inversion = INVERSION_ON;
2753 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2754 parm_inversion = INVERSION_OFF;
2757 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2758 parm_inversion = INVERSION_AUTO;
2761 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",
2762 parm_frequency/1000,
2763 parm_u_ofdm_bandwidth,
2764 parm_u_ofdm_code_rate_LP,
2765 parm_u_ofdm_code_rate_HP,
2766 parm_u_ofdm_constellation,
2767 parm_u_ofdm_transmission_mode,
2768 parm_u_ofdm_guard_interval,
2769 parm_u_ofdm_hierarchy_information,
2777 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2779 unsigned int timeout = 5000;
2780 eDebugNoSimulate("(%d)tune", m_dvbid);
2786 if (!m_sn && !m_simulate)
2788 eDebug("no frontend device opened... do not try to tune !!!");
2802 m_sec_sequence.clear();
2804 where.calcLockTimeout(timeout);
2810 eDVBFrontendParametersSatellite feparm;
2811 if (where.getDVBS(feparm))
2813 eDebug("no dvbs data!");
2817 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2819 eDVBFrontend *sec_fe = this;
2820 long tmp = m_data[LINKED_PREV_PTR];
2823 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2824 sec_fe = linked_fe->m_frontend;
2825 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2827 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2828 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
2830 m_rotor_mode = feparm.no_rotor_command_on_tune;
2832 m_sec->setRotorMoving(m_slotid, false);
2833 res=prepare_sat(feparm, timeout);
2841 eDVBFrontendParametersCable feparm;
2842 if (where.getDVBC(feparm))
2847 res=prepare_cable(feparm);
2851 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2852 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2857 eDVBFrontendParametersTerrestrial feparm;
2858 if (where.getDVBT(feparm))
2860 eDebug("no -T data");
2864 res=prepare_terrestrial(feparm);
2868 std::string enable_5V;
2869 char configStr[255];
2870 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2871 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2872 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2873 if (enable_5V == "True")
2874 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2876 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2877 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2883 m_sec_sequence.current() = m_sec_sequence.begin();
2887 m_tuneTimer->start(0,true);
2889 if (m_state != stateTuning)
2891 m_state = stateTuning;
2892 m_stateChanged(this);
2901 m_tuneTimer->stop();
2905 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2907 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2911 RESULT eDVBFrontend::setVoltage(int voltage)
2913 if (m_type == feCable)
2915 #if HAVE_DVB_API_VERSION < 3
2918 bool increased=false;
2919 fe_sec_voltage_t vlt;
2921 m_data[CUR_VOLTAGE]=voltage;
2925 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2926 vlt = SEC_VOLTAGE_OFF;
2929 #if HAVE_DVB_API_VERSION < 3
2930 vlt = SEC_VOLTAGE_13_5;
2936 vlt = SEC_VOLTAGE_13;
2939 #if HAVE_DVB_API_VERSION < 3
2940 vlt = SEC_VOLTAGE_18_5;
2946 vlt = SEC_VOLTAGE_18;
2953 #if HAVE_DVB_API_VERSION < 3
2954 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2956 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2957 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2958 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2962 RESULT eDVBFrontend::getState(int &state)
2968 RESULT eDVBFrontend::setTone(int t)
2970 if (m_type != feSatellite)
2972 #if HAVE_DVB_API_VERSION < 3
2975 fe_sec_tone_mode_t tone;
2984 tone = SEC_TONE_OFF;
2991 #if HAVE_DVB_API_VERSION < 3
2992 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2994 return ::ioctl(m_fd, FE_SET_TONE, tone);
2998 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2999 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
3002 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3006 #if HAVE_DVB_API_VERSION < 3
3007 struct secCommand cmd;
3008 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3009 cmd.u.diseqc.cmdtype = diseqc.data[0];
3010 cmd.u.diseqc.addr = diseqc.data[1];
3011 cmd.u.diseqc.cmd = diseqc.data[2];
3012 cmd.u.diseqc.numParams = diseqc.len-3;
3013 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3014 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3016 struct dvb_diseqc_master_cmd cmd;
3017 memcpy(cmd.msg, diseqc.data, diseqc.len);
3018 cmd.msg_len = diseqc.len;
3019 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3025 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3026 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3028 RESULT eDVBFrontend::sendToneburst(int burst)
3032 #if HAVE_DVB_API_VERSION < 3
3033 secMiniCmd cmd = SEC_MINI_NONE;
3035 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3037 if ( burst == eDVBSatelliteDiseqcParameters::A )
3039 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3041 #if HAVE_DVB_API_VERSION < 3
3042 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3045 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3051 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3057 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3059 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3060 m_sec_sequence.push_back(list);
3062 m_sec_sequence = list;
3066 RESULT eDVBFrontend::getData(int num, long &data)
3068 if ( num < NUM_DATA_ENTRIES )
3076 RESULT eDVBFrontend::setData(int num, long val)
3078 if ( num < NUM_DATA_ENTRIES )
3086 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3089 if (feparm->getSystem(type) || type != m_type || !m_enabled)
3091 if (m_type == eDVBFrontend::feSatellite)
3094 eDVBFrontendParametersSatellite sat_parm;
3095 int ret = feparm->getDVBS(sat_parm);
3097 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
3099 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
3100 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
3104 else if (m_type == eDVBFrontend::feCable)
3105 return 2; // more prio for cable frontends
3106 else if (m_type == eDVBFrontend::feTerrestrial)
3108 eDVBFrontendParametersTerrestrial ter_parm;
3109 if ( feparm->getDVBT(ter_parm) )
3113 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
3115 return m_can_handle_dvbt2 ? 1 : 0;
3119 return m_can_handle_dvbt2 ? 1 : 2;
3125 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3127 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3128 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3130 Id = PyTuple_GET_ITEM(obj, 0);
3131 Descr = PyTuple_GET_ITEM(obj, 1);
3132 Enabled = PyTuple_GET_ITEM(obj, 2);
3133 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3134 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3135 frontendId = PyTuple_GET_ITEM(obj, 5);
3136 m_slotid = PyInt_AsLong(Id);
3137 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3139 strcpy(m_description, PyString_AS_STRING(Descr));
3140 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3141 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3142 // m_slotid, m_description);
3145 m_enabled = Enabled == Py_True;
3146 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3147 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3148 !!strstr(m_description, "Alps BSBE2") ||
3149 !!strstr(m_description, "Alps -S") ||
3150 !!strstr(m_description, "BCM4501");
3151 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
3152 m_can_handle_dvbt2 = IsDVBT2 == Py_True;
3153 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3154 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" );
3157 PyErr_SetString(PyExc_StandardError,
3158 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");