1 #include <lib/dvb/dvb.h>
2 #include <lib/dvb/frontendparms.h>
3 #include <lib/base/eerror.h>
4 #include <lib/base/nconfig.h> // access to python config
10 #ifndef I2C_SLAVE_FORCE
11 #define I2C_SLAVE_FORCE 0x0706
14 #if HAVE_DVB_API_VERSION < 3
15 #include <ost/frontend.h>
17 #define QAM_AUTO (Modulation)6
18 #define TRANSMISSION_MODE_AUTO (TransmitMode)2
19 #define BANDWIDTH_AUTO (BandWidth)3
20 #define GUARD_INTERVAL_AUTO (GuardInterval)4
21 #define HIERARCHY_AUTO (Hierarchy)4
22 #define parm_frequency parm.Frequency
23 #define parm_inversion parm.Inversion
24 #define parm_u_qpsk_symbol_rate parm.u.qpsk.SymbolRate
25 #define parm_u_qpsk_fec_inner parm.u.qpsk.FEC_inner
26 #define parm_u_qam_symbol_rate parm.u.qam.SymbolRate
27 #define parm_u_qam_fec_inner parm.u.qam.FEC_inner
28 #define parm_u_qam_modulation parm.u.qam.QAM
29 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandWidth
30 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.LP_CodeRate
31 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.HP_CodeRate
32 #define parm_u_ofdm_constellation parm.u.ofdm.Constellation
33 #define parm_u_ofdm_transmission_mode parm.u.ofdm.TransmissionMode
34 #define parm_u_ofdm_guard_interval parm.u.ofdm.guardInterval
35 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.HierarchyInformation
37 #include <linux/dvb/frontend.h>
38 #define parm_frequency parm.frequency
39 #define parm_inversion parm.inversion
40 #define parm_u_qpsk_symbol_rate parm.u.qpsk.symbol_rate
41 #define parm_u_qpsk_fec_inner parm.u.qpsk.fec_inner
42 #define parm_u_qam_symbol_rate parm.u.qam.symbol_rate
43 #define parm_u_qam_fec_inner parm.u.qam.fec_inner
44 #define parm_u_qam_modulation parm.u.qam.modulation
45 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandwidth
46 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.code_rate_LP
47 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.code_rate_HP
48 #define parm_u_ofdm_constellation parm.u.ofdm.constellation
49 #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode
50 #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval
51 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information
52 #if HAVE_DVB_API_VERSION < 5
53 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1)
54 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1)
55 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_S2_QPSK_2_3+1)
56 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_S2_QPSK_3_4+1)
57 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_S2_QPSK_5_6+1)
58 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_S2_QPSK_7_8+1)
59 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_S2_QPSK_8_9+1)
60 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_S2_QPSK_3_5+1)
61 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_S2_QPSK_4_5+1)
62 #define FEC_S2_8PSK_1_2 (fe_code_rate_t)(FEC_S2_QPSK_9_10+1)
63 #define FEC_S2_8PSK_2_3 (fe_code_rate_t)(FEC_S2_8PSK_1_2+1)
64 #define FEC_S2_8PSK_3_4 (fe_code_rate_t)(FEC_S2_8PSK_2_3+1)
65 #define FEC_S2_8PSK_5_6 (fe_code_rate_t)(FEC_S2_8PSK_3_4+1)
66 #define FEC_S2_8PSK_7_8 (fe_code_rate_t)(FEC_S2_8PSK_5_6+1)
67 #define FEC_S2_8PSK_8_9 (fe_code_rate_t)(FEC_S2_8PSK_7_8+1)
68 #define FEC_S2_8PSK_3_5 (fe_code_rate_t)(FEC_S2_8PSK_8_9+1)
69 #define FEC_S2_8PSK_4_5 (fe_code_rate_t)(FEC_S2_8PSK_3_5+1)
70 #define FEC_S2_8PSK_9_10 (fe_code_rate_t)(FEC_S2_8PSK_4_5+1)
72 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2)
73 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3)
74 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4)
75 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6)
76 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8)
77 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9)
78 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5)
79 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5)
80 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10)
84 #include <dvbsi++/satellite_delivery_system_descriptor.h>
85 #include <dvbsi++/cable_delivery_system_descriptor.h>
86 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
88 #define eDebugNoSimulate(x...) \
96 eDebugNoNewLine("SIMULATE:"); \
101 #define eDebugNoSimulateNoNewLine(x...) \
104 eDebugNoNewLine(x); \
109 eDebugNoNewLine("SIMULATE:"); \
110 eDebugNoNewLine(x); \
114 void eDVBDiseqcCommand::setCommandString(const char *str)
119 int slen = strlen(str);
122 eDebug("invalid diseqc command string length (not 2 byte aligned)");
125 if (slen > MAX_DISEQC_LENGTH*2)
127 eDebug("invalid diseqc command string length (string is to long)");
131 for (int i=0; i < slen; ++i)
133 unsigned char c = str[i];
136 case '0' ... '9': c-=48; break;
137 case 'a' ... 'f': c-=87; break;
138 case 'A' ... 'F': c-=55; break;
140 eDebug("invalid character in hex string..ignore complete diseqc command !");
154 void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescriptor &descriptor)
156 frequency = descriptor.getFrequency() * 10;
157 symbol_rate = descriptor.getSymbolRate() * 100;
158 polarisation = descriptor.getPolarization();
159 fec = descriptor.getFecInner();
160 if ( fec != eDVBFrontendParametersSatellite::FEC_None && fec > eDVBFrontendParametersSatellite::FEC_9_10 )
161 fec = eDVBFrontendParametersSatellite::FEC_Auto;
162 inversion = eDVBFrontendParametersSatellite::Inversion_Unknown;
163 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
164 orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
165 orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
166 orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
167 orbital_position += ((descriptor.getOrbitalPosition()) & 0xF);
168 if (orbital_position && (!descriptor.getWestEastFlag()))
169 orbital_position = 3600 - orbital_position;
170 system = descriptor.getModulationSystem();
171 modulation = descriptor.getModulation();
172 if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
174 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
175 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
177 rolloff = descriptor.getRollOff();
178 if (system == eDVBFrontendParametersSatellite::System_DVB_S2)
180 eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
182 polarisation ? "hor" : "vert",
190 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
192 polarisation ? "hor" : "vert",
198 void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descriptor)
200 frequency = descriptor.getFrequency() / 10;
201 symbol_rate = descriptor.getSymbolRate() * 100;
202 fec_inner = descriptor.getFecInner();
203 if ( fec_inner != eDVBFrontendParametersCable::FEC_None && fec_inner > eDVBFrontendParametersCable::FEC_8_9 )
204 fec_inner = eDVBFrontendParametersCable::FEC_Auto;
205 modulation = descriptor.getModulation();
206 if ( modulation > 0x5 )
207 modulation = eDVBFrontendParametersCable::Modulation_Auto;
208 inversion = eDVBFrontendParametersCable::Inversion_Unknown;
209 eDebug("Cable freq %d, mod %d, sr %d, fec %d",
211 modulation, symbol_rate, fec_inner);
214 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
216 /* EN 300 468 V1.11.1 DVB-SI SPEC */
217 frequency = descriptor.getCentreFrequency() * 10;
218 switch (descriptor.getBandwidth())
220 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
221 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
222 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
223 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
224 case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
225 case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
226 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
228 switch (descriptor.getCodeRateHpStream())
230 case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
231 case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
232 case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
233 case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
234 case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
235 default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
237 switch (descriptor.getCodeRateLpStream())
239 case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
240 case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
241 case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
242 case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
243 case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
244 default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
246 switch (descriptor.getTransmissionMode())
248 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
249 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
250 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
251 case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
252 case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
253 case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
254 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
256 switch (descriptor.getGuardInterval())
258 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
259 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
260 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
261 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
262 case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
263 case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
264 case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
265 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
267 // hierarchy = descriptor.getHierarchyInformation();
268 hierarchy = descriptor.getHierarchyInformation()&3;
269 if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
270 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
271 modulation = descriptor.getConstellation();
272 if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
273 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
274 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
275 system = eDVBFrontendParametersTerrestrial::System_DVB_T;
277 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
278 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
279 guard_interval, hierarchy, modulation);
282 eDVBFrontendParameters::eDVBFrontendParameters()
283 :m_type(-1), m_flags(0)
287 DEFINE_REF(eDVBFrontendParameters);
289 RESULT eDVBFrontendParameters::getSystem(int &t) const
297 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
299 if (m_type != iDVBFrontend::feSatellite)
305 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
307 if (m_type != iDVBFrontend::feCable)
313 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
315 if (m_type != iDVBFrontend::feTerrestrial)
321 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
324 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
325 m_type = iDVBFrontend::feSatellite;
329 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
332 m_type = iDVBFrontend::feCable;
336 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
339 m_type = iDVBFrontend::feTerrestrial;
343 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
348 if (parm->getSystem(type))
352 diff = 1<<30; // big difference
358 case iDVBFrontend::feSatellite:
360 eDVBFrontendParametersSatellite osat;
361 if (parm->getDVBS(osat))
364 if (sat.orbital_position != osat.orbital_position)
366 else if (sat.polarisation != osat.polarisation)
368 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
370 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
374 diff = abs(sat.frequency - osat.frequency);
375 diff += abs(sat.symbol_rate - osat.symbol_rate);
379 case iDVBFrontend::feCable:
380 eDVBFrontendParametersCable ocable;
381 if (parm->getDVBC(ocable))
384 if (exact && cable.modulation != ocable.modulation
385 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
386 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
388 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
392 diff = abs(cable.frequency - ocable.frequency);
393 diff += abs(cable.symbol_rate - ocable.symbol_rate);
396 case iDVBFrontend::feTerrestrial:
397 eDVBFrontendParametersTerrestrial oterrestrial;
398 if (parm->getDVBT(oterrestrial))
401 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
402 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
403 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
405 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
406 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
407 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
409 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
410 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
411 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
413 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
414 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
415 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
417 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
418 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
419 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
421 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
422 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
423 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
425 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
426 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
427 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
430 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
438 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
442 case iDVBFrontend::feSatellite:
444 hash = (sat.orbital_position << 16);
445 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
448 case iDVBFrontend::feCable:
450 hash |= (cable.frequency/1000)&0xFFFF;
452 case iDVBFrontend::feTerrestrial:
454 hash |= (terrestrial.frequency/1000000)&0xFFFF;
461 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
465 case iDVBFrontend::feSatellite:
467 /* high symbol rate transponders tune faster, due to
468 requiring less zigzag and giving more symbols faster.
470 5s are definitely not enough on really low SR when
471 zigzag has to find the exact frequency first.
473 if (sat.symbol_rate > 20000000)
475 else if (sat.symbol_rate > 10000000)
481 case iDVBFrontend::feCable:
484 case iDVBFrontend::feTerrestrial:
492 DEFINE_REF(eDVBFrontend);
494 int eDVBFrontend::PriorityOrder=0;
496 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
497 :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
498 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false), m_can_handle_dvbt2(false)
499 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0)
500 #if HAVE_DVB_API_VERSION < 3
504 #if HAVE_DVB_API_VERSION < 3
505 sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe);
506 sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe);
508 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
511 m_timeout = eTimer::create(eApp);
512 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
514 m_tuneTimer = eTimer::create(eApp);
515 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
517 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
520 m_idleInputpower[0]=m_idleInputpower[1]=0;
522 ok = !openFrontend();
526 void eDVBFrontend::reopenFrontend()
533 int eDVBFrontend::openFrontend()
535 if (m_state != stateClosed)
536 return -1; // already opened
541 #if HAVE_DVB_API_VERSION < 3
542 FrontendInfo fe_info;
544 dvb_frontend_info fe_info;
548 eDebug("opening frontend %d", m_dvbid);
551 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
554 eWarning("failed! (%s) %m", m_filename);
559 eWarning("frontend %d already opened", m_dvbid);
562 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
564 eWarning("ioctl FE_GET_INFO failed");
570 switch (fe_info.type)
573 m_type = iDVBFrontend::feSatellite;
576 m_type = iDVBFrontend::feCable;
579 m_type = iDVBFrontend::feTerrestrial;
582 eWarning("unknown frontend type.");
588 m_simulate_fe->m_type = m_type;
589 eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10);
592 #if HAVE_DVB_API_VERSION < 3
593 if (m_type == iDVBFrontend::feSatellite)
599 m_secfd = ::open(m_sec_filename, O_RDWR);
602 eWarning("failed! (%s) %m", m_sec_filename);
610 eWarning("sec %d already opened", m_dvbid);
614 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
615 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
618 setTone(iDVBFrontend::toneOff);
619 setVoltage(iDVBFrontend::voltageOff);
624 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
626 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
628 long tmp = m_data[LINKED_NEXT_PTR];
631 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
632 if (linked_fe->m_inuse)
634 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
635 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
638 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
644 eDebugNoSimulate("close frontend %d", m_dvbid);
645 if (m_data[SATCR] != -1)
649 m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]);
650 m_tuneTimer->start(0, true);
651 if(!m_tuneTimer->isActive())
654 eDebug("[turnOffSatCR] no mainloop");
657 timeout = tuneLoopInt();
660 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
664 eDebug("[turnOffSatCR] running mainloop");
668 m_data[ROTOR_CMD] = -1;
671 setTone(iDVBFrontend::toneOff);
672 setVoltage(iDVBFrontend::voltageOff);
675 if (m_sec && !m_simulate)
676 m_sec->setRotorMoving(m_slotid, false);
680 eWarning("couldnt close frontend %d", m_dvbid);
684 setTone(iDVBFrontend::toneOff);
685 setVoltage(iDVBFrontend::voltageOff);
687 #if HAVE_DVB_API_VERSION < 3
690 if (!::close(m_secfd))
693 eWarning("couldnt close sec %d", m_dvbid);
697 m_state = stateClosed;
702 eDVBFrontend::~eDVBFrontend()
704 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
708 void eDVBFrontend::feEvent(int w)
710 eDVBFrontend *sec_fe = this;
711 long tmp = m_data[LINKED_PREV_PTR];
714 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
715 sec_fe = linked_fe->m_frontend;
716 sec_fe->getData(LINKED_NEXT_PTR, tmp);
720 #if HAVE_DVB_API_VERSION < 3
723 dvb_frontend_event event;
727 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
729 if (res && (errno == EAGAIN))
735 #if HAVE_DVB_API_VERSION < 3
736 if (event.type == FE_COMPLETION_EV)
738 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
739 if (event.status & FE_HAS_LOCK)
747 #if HAVE_DVB_API_VERSION >= 3
748 if (event.status & FE_TIMEDOUT) {
749 eDebug("FE_TIMEDOUT! ..abort");
762 eDebug("stateLostLock");
763 state = stateLostLock;
765 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
768 if (m_state != state)
771 m_stateChanged(this);
776 void eDVBFrontend::timeout()
779 if (m_state == stateTuning)
781 #ifdef BUILD_VUPLUS /* ikseong */
782 eDVBFrontend *sec_fe = this;
783 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
785 m_state = stateFailed;
786 m_stateChanged(this);
790 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
792 /* unsigned 32 bit division */
793 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
795 return (a + b / 2) / b;
798 int eDVBFrontend::readFrontendData(int type)
807 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
808 eDebug("FE_READ_BER failed (%m)");
813 case signalQualitydB: /* this will move into the driver */
815 int sat_max = 1600; // for stv0288 / bsbe2
816 int ret = 0x12345678;
820 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
821 eDebug("FE_READ_SNR failed (%m)");
822 else if (!strcmp(m_description, "BCM4501 (internal)"))
824 float SDS_SNRE = snr << 16;
827 if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
829 static float SNR_COEFF[6] = {
832 197418.0 / 4194304.0,
833 -2602183.0 / 4194304.0,
834 20377212.0 / 4194304.0,
835 -37791203.0 / 4194304.0,
837 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
838 fval2 = pow(10.0, fval1)-1;
839 fval1 = 10.0 * log10(fval2);
843 fval2 = SNR_COEFF[0];
844 for (int i=1; i<6; ++i)
847 fval2 += SNR_COEFF[i];
853 #if HAVE_DVB_API_VERSION >= 3
856 float fval1 = SDS_SNRE / 268435456.0,
859 if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
870 fval4 = -10.0 * log10(fval1);
872 for (int i=0; i < 5; ++i)
873 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
878 ret = (int)(snr_in_db * 100);
880 else if (strstr(m_description, "Alps BSBE1 C01A") ||
881 strstr(m_description, "Alps -S(STV0288)"))
885 else if (snr == 0xFFFF) // i think this should not happen
889 enum { REALVAL, REGVAL };
890 const long CN_lookup[31][2] = {
891 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
892 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
893 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
894 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
895 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
896 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
899 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
900 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
904 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
909 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
914 ret = (((regval - CN_lookup[Imin][REGVAL])
915 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
916 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
917 + CN_lookup[Imin][REALVAL]) * 10;
923 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
924 !strcmp(m_description, "Alps -S") ||
925 !strcmp(m_description, "Philips -S") ||
926 !strcmp(m_description, "LG -S") )
929 ret = (int)((snr-39075)/17.647);
930 } else if (!strcmp(m_description, "Alps BSBE2"))
932 ret = (int)((snr >> 7) * 10);
933 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
935 int mse = (~snr) & 0xFF;
936 switch (parm_u_qam_modulation) {
937 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
938 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
939 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
940 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
941 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
944 } else if (!strcmp(m_description, "Philips TU1216"))
946 snr = 0xFF - (snr & 0xFF);
948 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
950 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
951 ret = (snr * 100) >> 8;
952 else if (!strcmp(m_description, "CXD1981"))
954 int mse = (~snr) & 0xFF;
955 switch (parm_u_qam_modulation) {
958 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
960 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
966 if (type == signalQuality)
968 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
973 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
974 case feCable: // we assume a max of 42db here
975 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
976 case feTerrestrial: // we assume a max of 24db here
977 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
981 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
989 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
990 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
996 #if HAVE_DVB_API_VERSION < 3
997 FrontendStatus status=0;
1003 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1004 eDebug("FE_READ_STATUS failed (%m)");
1005 return !!(status&FE_HAS_LOCK);
1011 #if HAVE_DVB_API_VERSION < 3
1012 FrontendStatus status=0;
1018 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1019 eDebug("FE_READ_STATUS failed (%m)");
1020 return !!(status&FE_HAS_SYNC);
1024 case frontendNumber:
1030 void PutToDict(ePyObject &dict, const char*key, long value)
1032 ePyObject item = PyInt_FromLong(value);
1035 if (PyDict_SetItemString(dict, key, item))
1036 eDebug("put %s to dict failed", key);
1040 eDebug("could not create PyObject for %s", key);
1043 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1047 if (PyDict_SetItemString(dict, key, item))
1048 eDebug("put %s to dict failed", key);
1052 eDebug("invalid PyObject for %s", key);
1055 void PutToDict(ePyObject &dict, const char*key, const char *value)
1057 ePyObject item = PyString_FromString(value);
1060 if (PyDict_SetItemString(dict, key, item))
1061 eDebug("put %s to dict failed", key);
1065 eDebug("could not create PyObject for %s", key);
1068 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1070 PutToDict(dict, "tuner_type", "DVB-S");
1071 PutToDict(dict, "frequency", feparm.frequency);
1072 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1073 PutToDict(dict, "orbital_position", feparm.orbital_position);
1074 PutToDict(dict, "inversion", feparm.inversion);
1075 PutToDict(dict, "fec_inner", feparm.fec);
1076 PutToDict(dict, "modulation", feparm.modulation);
1077 PutToDict(dict, "polarization", feparm.polarisation);
1078 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1080 PutToDict(dict, "rolloff", feparm.rolloff);
1081 PutToDict(dict, "pilot", feparm.pilot);
1083 PutToDict(dict, "system", feparm.system);
1086 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1088 PutToDict(dict, "tuner_type", "DVB-T");
1089 PutToDict(dict, "frequency", feparm.frequency);
1090 PutToDict(dict, "bandwidth", feparm.bandwidth);
1091 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1092 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1093 PutToDict(dict, "constellation", feparm.modulation);
1094 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1095 PutToDict(dict, "guard_interval", feparm.guard_interval);
1096 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1097 PutToDict(dict, "inversion", feparm.inversion);
1098 PutToDict(dict, "system", feparm.system);
1099 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1101 PutToDict(dict, "plp_id", feparm.plpid);
1105 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1107 PutToDict(dict, "tuner_type", "DVB-C");
1108 PutToDict(dict, "frequency", feparm.frequency);
1109 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1110 PutToDict(dict, "modulation", feparm.modulation);
1111 PutToDict(dict, "inversion", feparm.inversion);
1112 PutToDict(dict, "fec_inner", feparm.fec_inner);
1115 #if HAVE_DVB_API_VERSION >= 5
1116 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization)
1119 int frequency = parm_frequency + freq_offset;
1120 PutToDict(dict, "frequency", frequency);
1121 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1122 PutToDict(dict, "orbital_position", orb_pos);
1123 PutToDict(dict, "polarization", polarization);
1125 switch(parm_u_qpsk_fec_inner)
1127 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1128 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1129 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1130 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1131 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1132 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1133 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1134 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1135 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1136 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1137 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1138 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1140 PutToDict(dict, "fec_inner", tmp);
1142 switch (p[0].u.data)
1144 default: eDebug("got unsupported system from frontend! report as DVBS!");
1145 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1148 switch (p[2].u.data)
1150 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1151 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1152 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1153 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1155 PutToDict(dict, "rolloff", tmp);
1157 switch (p[3].u.data)
1159 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1160 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1161 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1163 PutToDict(dict, "pilot", tmp);
1165 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1168 PutToDict(dict, "system", tmp);
1170 switch (p[1].u.data)
1172 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1173 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1174 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1176 PutToDict(dict, "modulation", tmp);
1178 switch(parm_inversion & 3)
1180 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1181 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1182 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1184 PutToDict(dict, "inversion", tmp);
1187 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1191 tmp = p[1].u.data/1000;
1192 PutToDict(dict, "frequency", tmp);
1194 PutToDict(dict, "symbol_rate", p[2].u.data);
1196 switch (p[3].u.data)
1198 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1199 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1200 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1201 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1202 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1203 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1204 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1206 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1208 PutToDict(dict, "fec_inner", tmp);
1210 switch (p[4].u.data)
1212 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1213 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1214 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1215 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1216 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1218 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1220 PutToDict(dict, "modulation", tmp);
1222 switch (p[5].u.data)
1224 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1225 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1227 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1229 PutToDict(dict, "inversion", tmp);
1232 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1236 switch (p[0].u.data)
1238 default: eDebug("got unsupported system from frontend! report as DVBT!");
1239 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1242 #ifdef DTV_DVBT2_PLP_ID
1244 PutToDict(dict, "plp_id", tmp);
1246 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1249 PutToDict(dict, "system", tmp);
1252 PutToDict(dict, "frequency", tmp);
1254 switch (p[2].u.data)
1256 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1257 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1258 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1259 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1260 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1261 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1263 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1265 PutToDict(dict, "bandwidth", tmp);
1267 switch (p[3].u.data)
1269 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1270 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1271 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1272 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1273 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1274 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1275 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1276 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1278 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1280 PutToDict(dict, "code_rate_lp", tmp);
1282 switch (p[4].u.data)
1284 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1285 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1286 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1287 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1288 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1289 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1290 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1291 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1293 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1295 PutToDict(dict, "code_rate_hp", tmp);
1297 switch (p[5].u.data)
1299 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1300 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1301 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1302 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1304 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1306 PutToDict(dict, "constellation", tmp);
1309 switch (p[6].u.data)
1311 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1312 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1313 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1314 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1315 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1316 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1318 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1320 PutToDict(dict, "transmission_mode", tmp);
1322 switch (p[7].u.data)
1324 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1325 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1326 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1327 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1328 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1329 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1330 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1332 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1334 PutToDict(dict, "guard_interval", tmp);
1336 switch (p[8].u.data)
1338 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1339 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1340 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1341 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1343 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1345 PutToDict(dict, "hierarchy_information", tmp);
1347 switch (p[9].u.data)
1349 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1350 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1352 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1354 PutToDict(dict, "inversion", tmp);
1357 #else // #if HAVE_DVB_API_VERSION >= 5
1358 static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization)
1361 int frequency = parm_frequency + freq_offset;
1362 PutToDict(dict, "frequency", frequency);
1363 PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate);
1364 PutToDict(dict, "orbital_position", orb_pos);
1365 PutToDict(dict, "polarization", polarization);
1367 switch((int)parm_u_qpsk_fec_inner)
1369 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1370 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1371 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1372 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1373 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1374 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1376 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1377 #if HAVE_DVB_API_VERSION >=3
1378 case FEC_S2_8PSK_1_2:
1379 case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1380 case FEC_S2_8PSK_2_3:
1381 case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1382 case FEC_S2_8PSK_3_4:
1383 case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1384 case FEC_S2_8PSK_5_6:
1385 case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1386 case FEC_S2_8PSK_7_8:
1387 case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1388 case FEC_S2_8PSK_8_9:
1389 case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1390 case FEC_S2_8PSK_3_5:
1391 case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1392 case FEC_S2_8PSK_4_5:
1393 case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1394 case FEC_S2_8PSK_9_10:
1395 case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1398 PutToDict(dict, "fec_inner", tmp);
1399 #if HAVE_DVB_API_VERSION >=3
1400 PutToDict(dict, "modulation",
1401 parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ?
1402 eDVBFrontendParametersSatellite::Modulation_8PSK :
1403 eDVBFrontendParametersSatellite::Modulation_QPSK );
1404 if (parm_u_qpsk_fec_inner > FEC_AUTO)
1406 switch(parm_inversion & 0xc)
1408 default: // unknown rolloff
1409 case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1410 case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1411 case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1413 PutToDict(dict, "rolloff", tmp);
1414 switch(parm_inversion & 0x30)
1416 case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1417 case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1418 case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1420 PutToDict(dict, "pilot", tmp);
1421 tmp = eDVBFrontendParametersSatellite::System_DVB_S2;
1424 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1426 PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK );
1427 tmp = eDVBFrontendParametersSatellite::System_DVB_S;
1429 PutToDict(dict, "system", tmp);
1432 static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1435 #if HAVE_DVB_API_VERSION < 3
1436 PutToDict(dict, "frequency", parm_frequency);
1438 PutToDict(dict, "frequency", parm_frequency/1000);
1440 PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate);
1441 switch(parm_u_qam_fec_inner)
1443 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1444 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1445 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1446 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1447 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1448 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1449 #if HAVE_DVB_API_VERSION >= 3
1450 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1453 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1455 PutToDict(dict, "fec_inner", tmp);
1456 switch(parm_u_qam_modulation)
1458 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1459 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1460 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1461 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1462 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1464 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1466 PutToDict(dict, "modulation", tmp);
1469 static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm)
1472 PutToDict(dict, "frequency", parm_frequency);
1473 switch (parm_u_ofdm_bandwidth)
1475 case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1476 case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1477 case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1479 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1481 PutToDict(dict, "bandwidth", tmp);
1482 switch (parm_u_ofdm_code_rate_LP)
1484 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1485 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1486 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1487 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1488 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1490 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1492 PutToDict(dict, "code_rate_lp", tmp);
1493 switch (parm_u_ofdm_code_rate_HP)
1495 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1496 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1497 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1498 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1499 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1501 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1503 PutToDict(dict, "code_rate_hp", tmp);
1504 switch (parm_u_ofdm_constellation)
1506 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1507 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1508 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1510 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1512 PutToDict(dict, "constellation", tmp);
1513 switch (parm_u_ofdm_transmission_mode)
1515 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1516 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1518 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1520 PutToDict(dict, "transmission_mode", tmp);
1521 switch (parm_u_ofdm_guard_interval)
1523 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1524 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1525 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1526 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1528 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1530 PutToDict(dict, "guard_interval", tmp);
1531 switch (parm_u_ofdm_hierarchy_information)
1533 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1534 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1535 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1536 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1538 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1540 PutToDict(dict, "hierarchy_information", tmp);
1543 #endif // #if HAVE_DVB_API_VERSION >= 5
1545 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1547 if (dest && PyDict_Check(dest))
1549 const char *tmp = "UNKNOWN";
1570 PutToDict(dest, "tuner_state", tmp);
1571 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1572 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1573 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1574 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1575 int sigQualitydB = readFrontendData(signalQualitydB);
1576 if (sigQualitydB == 0x12345678) // not support yet
1578 ePyObject obj=Py_None;
1580 PutToDict(dest, "tuner_signal_quality_db", obj);
1583 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1584 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1588 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1590 if (dest && PyDict_Check(dest))
1592 FRONTENDPARAMETERS front;
1593 #if HAVE_DVB_API_VERSION >= 5
1594 struct dtv_property p[16];
1595 struct dtv_properties cmdseq;
1601 p[0].cmd = DTV_DELIVERY_SYSTEM;
1602 p[1].cmd = DTV_MODULATION;
1603 p[2].cmd = DTV_ROLLOFF;
1604 p[3].cmd = DTV_PILOT;
1608 p[0].cmd = DTV_DELIVERY_SYSTEM;
1609 p[1].cmd = DTV_FREQUENCY;
1610 p[2].cmd = DTV_SYMBOL_RATE;
1611 p[3].cmd = DTV_INNER_FEC;
1612 p[4].cmd = DTV_MODULATION;
1613 p[5].cmd = DTV_INVERSION;
1617 p[0].cmd = DTV_DELIVERY_SYSTEM;
1618 p[1].cmd = DTV_FREQUENCY;
1619 p[2].cmd = DTV_BANDWIDTH_HZ;
1620 p[3].cmd = DTV_CODE_RATE_LP;
1621 p[4].cmd = DTV_CODE_RATE_HP;
1622 p[5].cmd = DTV_MODULATION;
1623 p[6].cmd = DTV_TRANSMISSION_MODE;
1624 p[7].cmd = DTV_GUARD_INTERVAL;
1625 p[8].cmd = DTV_HIERARCHY;
1626 p[9].cmd = DTV_INVERSION;
1627 #ifdef DTV_DVBT2_PLP_ID
1628 p[10].cmd = DTV_DVBT2_PLP_ID;
1636 if (m_simulate || m_fd == -1 || original)
1640 #if HAVE_DVB_API_VERSION >= 5
1641 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1643 eDebug("FE_GET_PROPERTY failed (%m)");
1646 else if (m_type == feSatellite && // use for DVB-S(2) only
1647 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1649 eDebug("FE_GET_FRONTEND failed (%m)");
1653 else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1655 eDebug("FE_GET_FRONTEND failed (%m)");
1664 PutSatelliteDataToDict(dest, oparm.sat);
1667 PutCableDataToDict(dest, oparm.cab);
1670 PutTerrestrialDataToDict(dest, oparm.ter);
1676 FRONTENDPARAMETERS &parm = front;
1677 #if HAVE_DVB_API_VERSION >= 5
1681 fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1684 fillDictWithCableData(dest, p);
1687 fillDictWithTerrestrialData(dest, p);
1691 long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown;
1692 switch(parm_inversion & 3)
1695 tmp = eDVBFrontendParametersSatellite::Inversion_On;
1698 tmp = eDVBFrontendParametersSatellite::Inversion_Off;
1702 PutToDict(dest, "inversion", tmp);
1706 fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation);
1709 fillDictWithCableData(dest, parm);
1712 fillDictWithTerrestrialData(dest, parm);
1720 void eDVBFrontend::getFrontendData(ePyObject dest)
1722 if (dest && PyDict_Check(dest))
1725 PutToDict(dest, "tuner_number", m_slotid);
1741 PutToDict(dest, "tuner_type", tmp);
1745 #ifndef FP_IOCTL_GET_ID
1746 #define FP_IOCTL_GET_ID 0
1748 int eDVBFrontend::readInputpower()
1752 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1754 char proc_name2[64];
1755 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1756 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1758 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1760 if (fscanf(f, "%d", &power) != 1)
1761 eDebug("read %s failed!! (%m)", proc_name);
1763 eDebug("%s is %d\n", proc_name, power);
1768 // open front prozessor
1769 int fp=::open("/dev/dbox/fp0", O_RDWR);
1772 eDebug("couldn't open fp");
1775 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1776 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1778 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1787 bool eDVBFrontend::setSecSequencePos(int steps)
1789 eDebugNoSimulate("set sequence pos %d", steps);
1794 if (m_sec_sequence.current() != m_sec_sequence.end())
1795 ++m_sec_sequence.current();
1800 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1801 --m_sec_sequence.current();
1807 void eDVBFrontend::tuneLoop()
1812 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1815 eDVBFrontend *sec_fe = this;
1816 eDVBRegisteredFrontend *regFE = 0;
1817 long tmp = m_data[LINKED_PREV_PTR];
1820 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1821 sec_fe = prev->m_frontend;
1822 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1823 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1824 int state = sec_fe->m_state;
1825 // workaround to put the kernel frontend thread into idle state!
1826 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1828 sec_fe->closeFrontend(true);
1829 state = sec_fe->m_state;
1831 // sec_fe is closed... we must reopen it here..
1832 if (state == stateClosed)
1840 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1842 long *sec_fe_data = sec_fe->m_data;
1843 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1845 switch (m_sec_sequence.current()->cmd)
1847 case eSecCommand::SLEEP:
1848 delay = m_sec_sequence.current()++->msec;
1849 eDebugNoSimulate("[SEC] sleep %dms", delay);
1851 case eSecCommand::GOTO:
1852 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1853 ++m_sec_sequence.current();
1855 case eSecCommand::SET_VOLTAGE:
1857 int voltage = m_sec_sequence.current()++->voltage;
1858 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1859 sec_fe->setVoltage(voltage);
1862 case eSecCommand::IF_VOLTAGE_GOTO:
1864 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1865 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1867 ++m_sec_sequence.current();
1870 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1872 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1873 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1875 ++m_sec_sequence.current();
1878 case eSecCommand::IF_TONE_GOTO:
1880 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1881 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1883 ++m_sec_sequence.current();
1886 case eSecCommand::IF_NOT_TONE_GOTO:
1888 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1889 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1891 ++m_sec_sequence.current();
1894 case eSecCommand::SET_TONE:
1895 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1896 sec_fe->setTone(m_sec_sequence.current()++->tone);
1898 case eSecCommand::SEND_DISEQC:
1899 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1900 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1901 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1902 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1903 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1904 eDebugNoSimulate("(DiSEqC reset)");
1905 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1906 eDebugNoSimulate("(DiSEqC peripherial power on)");
1908 eDebugNoSimulate("");
1909 ++m_sec_sequence.current();
1911 case eSecCommand::SEND_TONEBURST:
1912 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1913 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1915 case eSecCommand::SET_FRONTEND:
1917 int enableEvents = (m_sec_sequence.current()++)->val;
1918 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1919 setFrontend(enableEvents);
1922 case eSecCommand::START_TUNE_TIMEOUT:
1924 int tuneTimeout = m_sec_sequence.current()->timeout;
1925 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1927 m_timeout->start(tuneTimeout, 1);
1928 ++m_sec_sequence.current();
1931 case eSecCommand::SET_TIMEOUT:
1932 m_timeoutCount = m_sec_sequence.current()++->val;
1933 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1935 case eSecCommand::IF_TIMEOUT_GOTO:
1936 if (!m_timeoutCount)
1938 eDebugNoSimulate("[SEC] rotor timout");
1939 setSecSequencePos(m_sec_sequence.current()->steps);
1942 ++m_sec_sequence.current();
1944 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1946 int idx = m_sec_sequence.current()++->val;
1947 if ( idx == 0 || idx == 1 )
1949 m_idleInputpower[idx] = sec_fe->readInputpower();
1950 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1953 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1956 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1958 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1959 int idx = compare.val;
1960 if ( !m_simulate && (idx == 0 || idx == 1) )
1962 int idle = sec_fe->readInputpower();
1963 int diff = abs(idle-m_idleInputpower[idx]);
1966 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1967 setSecSequencePos(compare.steps);
1971 ++m_sec_sequence.current();
1974 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1976 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1979 setSecSequencePos(cmd.steps);
1983 int isLocked = readFrontendData(locked);
1984 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1986 if (!m_timeoutCount && m_retryCount > 0)
1988 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1991 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1994 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1996 cmd.lastSignal = signal;
1999 if (cmd.okcount > 4)
2001 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
2002 setSecSequencePos(cmd.steps);
2003 m_state = stateLock;
2004 m_stateChanged(this);
2005 feEvent(-1); // flush events
2013 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
2015 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
2019 ++m_sec_sequence.current();
2022 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
2023 m_runningInputpower = sec_fe->readInputpower();
2024 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
2025 ++m_sec_sequence.current();
2027 case eSecCommand::SET_ROTOR_MOVING:
2029 m_sec->setRotorMoving(m_slotid, true);
2030 ++m_sec_sequence.current();
2032 case eSecCommand::SET_ROTOR_STOPPED:
2034 m_sec->setRotorMoving(m_slotid, false);
2035 ++m_sec_sequence.current();
2037 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
2039 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
2042 setSecSequencePos(cmd.steps);
2045 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
2046 const char *txt = cmd.direction ? "running" : "stopped";
2048 if (!m_timeoutCount && m_retryCount > 0)
2050 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
2052 m_runningInputpower,
2055 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
2056 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
2059 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
2060 if ( cmd.okcount > 6 )
2062 eDebugNoSimulate("[SEC] rotor is %s", txt);
2063 if (setSecSequencePos(cmd.steps))
2069 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
2072 ++m_sec_sequence.current();
2075 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
2076 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
2077 setSecSequencePos(m_sec_sequence.current()->steps);
2079 ++m_sec_sequence.current();
2081 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
2082 eDebugNoSimulate("[SEC] invalidate current switch params");
2083 sec_fe_data[CSW] = -1;
2084 sec_fe_data[UCSW] = -1;
2085 sec_fe_data[TONEBURST] = -1;
2086 ++m_sec_sequence.current();
2088 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
2089 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
2090 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
2091 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
2092 eDebugNoSimulate("[SEC] update current switch params");
2093 ++m_sec_sequence.current();
2095 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
2096 eDebugNoSimulate("[SEC] invalidate current rotorparams");
2097 sec_fe_data[ROTOR_CMD] = -1;
2098 sec_fe_data[ROTOR_POS] = -1;
2099 ++m_sec_sequence.current();
2101 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
2102 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
2103 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
2104 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
2105 ++m_sec_sequence.current();
2107 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
2108 m_retryCount = m_sec_sequence.current()++->val;
2109 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
2111 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
2114 eDebugNoSimulate("[SEC] no more rotor retrys");
2115 setSecSequencePos(m_sec_sequence.current()->steps);
2118 ++m_sec_sequence.current();
2120 case eSecCommand::SET_POWER_LIMITING_MODE:
2125 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
2126 FILE *f=fopen(proc_name, "w");
2127 if (f) // new interface exist?
2129 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
2130 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
2131 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
2133 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
2136 else if (sec_fe->m_need_rotor_workaround)
2139 int slotid = sec_fe->m_slotid;
2140 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
2142 sprintf(dev, "/dev/i2c-%d", slotid);
2143 else if (slotid == 2)
2144 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
2145 else if (slotid == 3)
2146 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
2147 int fd = ::open(dev, O_RDWR);
2149 unsigned char data[2];
2150 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
2151 if(::read(fd, data, 1) != 1)
2152 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2153 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2155 data[0] |= 0x80; // enable static current limiting
2156 eDebugNoSimulate("[SEC] set static current limiting");
2160 data[0] &= ~0x80; // enable dynamic current limiting
2161 eDebugNoSimulate("[SEC] set dynamic current limiting");
2163 if(::write(fd, data, 1) != 1)
2164 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2168 ++m_sec_sequence.current();
2171 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2173 eDebugNoSimulate("[SEC] delayed close frontend");
2174 closeFrontend(false, true);
2175 ++m_sec_sequence.current();
2179 eDebugNoSimulate("[SEC] unhandled sec command %d",
2180 ++m_sec_sequence.current()->cmd);
2181 ++m_sec_sequence.current();
2184 m_tuneTimer->start(delay,true);
2188 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2193 void eDVBFrontend::setFrontend(bool recvEvents)
2197 eDebug("setting frontend %d", m_dvbid);
2200 feEvent(-1); // flush events
2201 #if HAVE_DVB_API_VERSION >= 5
2202 if (m_type == iDVBFrontend::feSatellite)
2204 fe_rolloff_t rolloff = ROLLOFF_35;
2205 fe_pilot_t pilot = PILOT_OFF;
2206 fe_modulation_t modulation = QPSK;
2207 fe_delivery_system_t system = SYS_DVBS;
2208 switch(oparm.sat.system)
2210 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2211 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2213 switch(oparm.sat.modulation)
2215 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2216 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2217 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2219 switch(oparm.sat.pilot)
2221 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2222 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2223 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2225 switch(oparm.sat.rolloff)
2227 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2228 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2229 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2231 struct dtv_property p[10];
2232 struct dtv_properties cmdseq;
2234 p[0].cmd = DTV_CLEAR;
2235 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2236 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2237 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2238 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2239 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2240 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2241 if (system == SYS_DVBS2)
2243 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2244 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2245 p[9].cmd = DTV_TUNE;
2250 p[7].cmd = DTV_TUNE;
2253 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2255 perror("FE_SET_PROPERTY failed");
2259 else if (m_type == iDVBFrontend::feCable)
2261 struct dtv_property p[8];
2262 struct dtv_properties cmdseq;
2264 p[0].cmd = DTV_CLEAR;
2265 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 6
2266 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2268 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2270 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2271 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2272 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2273 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2274 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2275 p[7].cmd = DTV_TUNE;
2277 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2279 perror("FE_SET_PROPERTY failed");
2283 else if (m_type == iDVBFrontend::feTerrestrial)
2285 fe_delivery_system_t system = SYS_DVBT;
2286 switch (oparm.ter.system)
2289 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2290 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2293 switch (oparm.ter.bandwidth)
2295 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2296 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2297 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2299 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2300 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2301 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2302 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2304 struct dtv_property p[13];
2305 struct dtv_properties cmdseq;
2308 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2309 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2310 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2311 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2312 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2313 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2314 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2315 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2316 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2317 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2318 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2319 #ifdef DTV_DVBT2_PLP_ID
2320 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
2322 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2323 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2325 perror("FE_SET_PROPERTY failed");
2332 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2334 perror("FE_SET_FRONTEND failed");
2341 RESULT eDVBFrontend::getFrontendType(int &t)
2349 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2354 eWarning("no SEC module active!");
2357 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2360 #if HAVE_DVB_API_VERSION >= 3
2361 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",
2364 feparm.polarisation,
2368 feparm.orbital_position,
2374 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2377 feparm.polarisation,
2381 feparm.orbital_position);
2383 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2384 switch (feparm.inversion)
2386 case eDVBFrontendParametersSatellite::Inversion_On:
2387 parm_inversion = INVERSION_ON;
2389 case eDVBFrontendParametersSatellite::Inversion_Off:
2390 parm_inversion = INVERSION_OFF;
2393 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2394 parm_inversion = INVERSION_AUTO;
2397 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2401 case eDVBFrontendParametersSatellite::FEC_None:
2402 parm_u_qpsk_fec_inner = FEC_NONE;
2404 case eDVBFrontendParametersSatellite::FEC_1_2:
2405 parm_u_qpsk_fec_inner = FEC_1_2;
2407 case eDVBFrontendParametersSatellite::FEC_2_3:
2408 parm_u_qpsk_fec_inner = FEC_2_3;
2410 case eDVBFrontendParametersSatellite::FEC_3_4:
2411 parm_u_qpsk_fec_inner = FEC_3_4;
2413 case eDVBFrontendParametersSatellite::FEC_5_6:
2414 parm_u_qpsk_fec_inner = FEC_5_6;
2416 case eDVBFrontendParametersSatellite::FEC_7_8:
2417 parm_u_qpsk_fec_inner = FEC_7_8;
2420 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2421 case eDVBFrontendParametersSatellite::FEC_Auto:
2422 parm_u_qpsk_fec_inner = FEC_AUTO;
2426 #if HAVE_DVB_API_VERSION >= 3
2431 case eDVBFrontendParametersSatellite::FEC_1_2:
2432 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2434 case eDVBFrontendParametersSatellite::FEC_2_3:
2435 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2437 case eDVBFrontendParametersSatellite::FEC_3_4:
2438 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2440 case eDVBFrontendParametersSatellite::FEC_3_5:
2441 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2443 case eDVBFrontendParametersSatellite::FEC_4_5:
2444 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2446 case eDVBFrontendParametersSatellite::FEC_5_6:
2447 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2449 case eDVBFrontendParametersSatellite::FEC_7_8:
2450 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2452 case eDVBFrontendParametersSatellite::FEC_8_9:
2453 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2455 case eDVBFrontendParametersSatellite::FEC_9_10:
2456 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2459 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2462 #if HAVE_DVB_API_VERSION < 5
2463 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2464 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2465 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2467 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2468 // 8PSK fec driver values are decimal 9 bigger
2473 // FIXME !!! get frequency range from tuner
2474 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2476 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2479 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2485 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2487 #if HAVE_DVB_API_VERSION < 3
2488 parm_frequency = feparm.frequency;
2490 parm_frequency = feparm.frequency * 1000;
2492 parm_u_qam_symbol_rate = feparm.symbol_rate;
2493 switch (feparm.modulation)
2495 case eDVBFrontendParametersCable::Modulation_QAM16:
2496 parm_u_qam_modulation = QAM_16;
2498 case eDVBFrontendParametersCable::Modulation_QAM32:
2499 parm_u_qam_modulation = QAM_32;
2501 case eDVBFrontendParametersCable::Modulation_QAM64:
2502 parm_u_qam_modulation = QAM_64;
2504 case eDVBFrontendParametersCable::Modulation_QAM128:
2505 parm_u_qam_modulation = QAM_128;
2507 case eDVBFrontendParametersCable::Modulation_QAM256:
2508 parm_u_qam_modulation = QAM_256;
2511 case eDVBFrontendParametersCable::Modulation_Auto:
2512 parm_u_qam_modulation = QAM_AUTO;
2515 switch (feparm.inversion)
2517 case eDVBFrontendParametersCable::Inversion_On:
2518 parm_inversion = INVERSION_ON;
2520 case eDVBFrontendParametersCable::Inversion_Off:
2521 parm_inversion = INVERSION_OFF;
2524 case eDVBFrontendParametersCable::Inversion_Unknown:
2525 parm_inversion = INVERSION_AUTO;
2528 switch (feparm.fec_inner)
2530 case eDVBFrontendParametersCable::FEC_None:
2531 parm_u_qam_fec_inner = FEC_NONE;
2533 case eDVBFrontendParametersCable::FEC_1_2:
2534 parm_u_qam_fec_inner = FEC_1_2;
2536 case eDVBFrontendParametersCable::FEC_2_3:
2537 parm_u_qam_fec_inner = FEC_2_3;
2539 case eDVBFrontendParametersCable::FEC_3_4:
2540 parm_u_qam_fec_inner = FEC_3_4;
2542 case eDVBFrontendParametersCable::FEC_5_6:
2543 parm_u_qam_fec_inner = FEC_5_6;
2545 case eDVBFrontendParametersCable::FEC_7_8:
2546 parm_u_qam_fec_inner = FEC_7_8;
2548 #if HAVE_DVB_API_VERSION >= 3
2549 case eDVBFrontendParametersCable::FEC_8_9:
2550 parm_u_qam_fec_inner = FEC_8_9;
2554 case eDVBFrontendParametersCable::FEC_Auto:
2555 parm_u_qam_fec_inner = FEC_AUTO;
2558 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2559 parm_frequency/1000,
2560 parm_u_qam_symbol_rate,
2561 parm_u_qam_fec_inner,
2562 parm_u_qam_modulation,
2568 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2570 parm_frequency = feparm.frequency;
2572 switch (feparm.bandwidth)
2574 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2575 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2577 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2578 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2580 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2581 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2583 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2584 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2586 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2587 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2589 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2590 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2593 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2594 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2597 switch (feparm.code_rate_LP)
2599 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2600 parm_u_ofdm_code_rate_LP = FEC_1_2;
2602 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2603 parm_u_ofdm_code_rate_LP = FEC_2_3;
2605 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2606 parm_u_ofdm_code_rate_LP = FEC_3_4;
2608 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2609 parm_u_ofdm_code_rate_LP = FEC_5_6;
2611 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2612 parm_u_ofdm_code_rate_LP = FEC_7_8;
2614 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2615 parm_u_ofdm_code_rate_LP = FEC_6_7;
2617 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2618 parm_u_ofdm_code_rate_LP = FEC_8_9;
2621 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2622 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2625 switch (feparm.code_rate_HP)
2627 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2628 parm_u_ofdm_code_rate_HP = FEC_1_2;
2630 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2631 parm_u_ofdm_code_rate_HP = FEC_2_3;
2633 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2634 parm_u_ofdm_code_rate_HP = FEC_3_4;
2636 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2637 parm_u_ofdm_code_rate_HP = FEC_5_6;
2639 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2640 parm_u_ofdm_code_rate_HP = FEC_7_8;
2642 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2643 parm_u_ofdm_code_rate_HP = FEC_6_7;
2645 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2646 parm_u_ofdm_code_rate_HP = FEC_8_9;
2649 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2650 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2653 switch (feparm.modulation)
2655 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2656 parm_u_ofdm_constellation = QPSK;
2658 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2659 parm_u_ofdm_constellation = QAM_16;
2661 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2662 parm_u_ofdm_constellation = QAM_64;
2664 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2665 parm_u_ofdm_constellation = QAM_256;
2668 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2669 parm_u_ofdm_constellation = QAM_AUTO;
2672 switch (feparm.transmission_mode)
2674 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2675 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2677 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2678 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2680 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2681 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2683 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2684 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2686 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2687 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2689 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2690 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2693 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2694 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2697 switch (feparm.guard_interval)
2699 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2700 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2702 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2703 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2705 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2706 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2708 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2709 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2711 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2712 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2714 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2715 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2717 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2718 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2721 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2722 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2725 switch (feparm.hierarchy)
2727 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2728 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2730 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2731 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2733 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2734 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2736 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2737 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2740 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2741 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2744 switch (feparm.inversion)
2746 case eDVBFrontendParametersTerrestrial::Inversion_On:
2747 parm_inversion = INVERSION_ON;
2749 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2750 parm_inversion = INVERSION_OFF;
2753 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2754 parm_inversion = INVERSION_AUTO;
2757 eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d",
2758 parm_frequency/1000,
2759 parm_u_ofdm_bandwidth,
2760 parm_u_ofdm_code_rate_LP,
2761 parm_u_ofdm_code_rate_HP,
2762 parm_u_ofdm_constellation,
2763 parm_u_ofdm_transmission_mode,
2764 parm_u_ofdm_guard_interval,
2765 parm_u_ofdm_hierarchy_information,
2771 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2773 unsigned int timeout = 5000;
2774 eDebugNoSimulate("(%d)tune", m_dvbid);
2780 if (!m_sn && !m_simulate)
2782 eDebug("no frontend device opened... do not try to tune !!!");
2796 m_sec_sequence.clear();
2798 where.calcLockTimeout(timeout);
2804 eDVBFrontendParametersSatellite feparm;
2805 if (where.getDVBS(feparm))
2807 eDebug("no dvbs data!");
2811 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2813 eDVBFrontend *sec_fe = this;
2814 long tmp = m_data[LINKED_PREV_PTR];
2817 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2818 sec_fe = linked_fe->m_frontend;
2819 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2821 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2822 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
2824 m_rotor_mode = feparm.no_rotor_command_on_tune;
2826 m_sec->setRotorMoving(m_slotid, false);
2827 res=prepare_sat(feparm, timeout);
2835 eDVBFrontendParametersCable feparm;
2836 if (where.getDVBC(feparm))
2841 res=prepare_cable(feparm);
2845 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2846 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2851 eDVBFrontendParametersTerrestrial feparm;
2852 if (where.getDVBT(feparm))
2854 eDebug("no -T data");
2858 res=prepare_terrestrial(feparm);
2862 std::string enable_5V;
2863 char configStr[255];
2864 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2865 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2866 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2867 if (enable_5V == "True")
2868 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2870 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2871 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2877 m_sec_sequence.current() = m_sec_sequence.begin();
2881 m_tuneTimer->start(0,true);
2883 if (m_state != stateTuning)
2885 m_state = stateTuning;
2886 m_stateChanged(this);
2895 m_tuneTimer->stop();
2899 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2901 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2905 RESULT eDVBFrontend::setVoltage(int voltage)
2907 if (m_type == feCable)
2909 #if HAVE_DVB_API_VERSION < 3
2912 bool increased=false;
2913 fe_sec_voltage_t vlt;
2915 m_data[CUR_VOLTAGE]=voltage;
2919 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2920 vlt = SEC_VOLTAGE_OFF;
2923 #if HAVE_DVB_API_VERSION < 3
2924 vlt = SEC_VOLTAGE_13_5;
2930 vlt = SEC_VOLTAGE_13;
2933 #if HAVE_DVB_API_VERSION < 3
2934 vlt = SEC_VOLTAGE_18_5;
2940 vlt = SEC_VOLTAGE_18;
2947 #if HAVE_DVB_API_VERSION < 3
2948 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2950 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2951 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2952 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2956 RESULT eDVBFrontend::getState(int &state)
2962 RESULT eDVBFrontend::setTone(int t)
2964 if (m_type != feSatellite)
2966 #if HAVE_DVB_API_VERSION < 3
2969 fe_sec_tone_mode_t tone;
2978 tone = SEC_TONE_OFF;
2985 #if HAVE_DVB_API_VERSION < 3
2986 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2988 return ::ioctl(m_fd, FE_SET_TONE, tone);
2992 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2993 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2996 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
3000 #if HAVE_DVB_API_VERSION < 3
3001 struct secCommand cmd;
3002 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
3003 cmd.u.diseqc.cmdtype = diseqc.data[0];
3004 cmd.u.diseqc.addr = diseqc.data[1];
3005 cmd.u.diseqc.cmd = diseqc.data[2];
3006 cmd.u.diseqc.numParams = diseqc.len-3;
3007 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3008 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3010 struct dvb_diseqc_master_cmd cmd;
3011 memcpy(cmd.msg, diseqc.data, diseqc.len);
3012 cmd.msg_len = diseqc.len;
3013 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3019 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3020 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3022 RESULT eDVBFrontend::sendToneburst(int burst)
3026 #if HAVE_DVB_API_VERSION < 3
3027 secMiniCmd cmd = SEC_MINI_NONE;
3029 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3031 if ( burst == eDVBSatelliteDiseqcParameters::A )
3033 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3035 #if HAVE_DVB_API_VERSION < 3
3036 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3039 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3045 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3051 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3053 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3054 m_sec_sequence.push_back(list);
3056 m_sec_sequence = list;
3060 RESULT eDVBFrontend::getData(int num, long &data)
3062 if ( num < NUM_DATA_ENTRIES )
3070 RESULT eDVBFrontend::setData(int num, long val)
3072 if ( num < NUM_DATA_ENTRIES )
3080 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3083 if (feparm->getSystem(type) || type != m_type || !m_enabled)
3085 if (m_type == eDVBFrontend::feSatellite)
3088 eDVBFrontendParametersSatellite sat_parm;
3089 int ret = feparm->getDVBS(sat_parm);
3091 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
3093 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
3094 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
3098 else if (m_type == eDVBFrontend::feCable)
3099 return 2; // more prio for cable frontends
3100 else if (m_type == eDVBFrontend::feTerrestrial)
3102 eDVBFrontendParametersTerrestrial ter_parm;
3103 if ( feparm->getDVBT(ter_parm) )
3107 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
3109 return m_can_handle_dvbt2 ? 1 : 0;
3113 return m_can_handle_dvbt2 ? 1 : 2;
3119 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3121 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3122 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3124 Id = PyTuple_GET_ITEM(obj, 0);
3125 Descr = PyTuple_GET_ITEM(obj, 1);
3126 Enabled = PyTuple_GET_ITEM(obj, 2);
3127 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3128 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3129 frontendId = PyTuple_GET_ITEM(obj, 5);
3130 m_slotid = PyInt_AsLong(Id);
3131 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3133 strcpy(m_description, PyString_AS_STRING(Descr));
3134 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3135 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3136 // m_slotid, m_description);
3139 m_enabled = Enabled == Py_True;
3140 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3141 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3142 !!strstr(m_description, "Alps BSBE2") ||
3143 !!strstr(m_description, "Alps -S") ||
3144 !!strstr(m_description, "BCM4501");
3145 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
3146 m_can_handle_dvbt2 = IsDVBT2 == Py_True;
3147 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3148 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" );
3151 PyErr_SetString(PyExc_StandardError,
3152 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");