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[7];
2262 struct dtv_properties cmdseq;
2264 p[0].cmd = DTV_CLEAR;
2265 p[1].cmd = DTV_FREQUENCY, p[1].u.data = parm_frequency;
2266 p[2].cmd = DTV_MODULATION, p[2].u.data = parm_u_qam_modulation;
2267 p[3].cmd = DTV_SYMBOL_RATE, p[3].u.data = parm_u_qam_symbol_rate;
2268 p[4].cmd = DTV_INNER_FEC, p[4].u.data = parm_u_qam_fec_inner;
2269 p[5].cmd = DTV_INVERSION, p[5].u.data = parm_inversion;
2270 p[6].cmd = DTV_TUNE;
2272 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2274 perror("FE_SET_PROPERTY failed");
2278 else if (m_type == iDVBFrontend::feTerrestrial)
2280 fe_delivery_system_t system = SYS_DVBT;
2281 switch (oparm.ter.system)
2284 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2285 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2288 switch (oparm.ter.bandwidth)
2290 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2291 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2292 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2294 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2295 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2296 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2297 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2299 struct dtv_property p[13];
2300 struct dtv_properties cmdseq;
2303 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2304 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2305 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2306 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2307 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2308 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2309 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2310 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2311 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2312 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2313 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2314 #ifdef DTV_DVBT2_PLP_ID
2315 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = oparm.ter.plpid, cmdseq.num++;
2317 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2318 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2320 perror("FE_SET_PROPERTY failed");
2327 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2329 perror("FE_SET_FRONTEND failed");
2336 RESULT eDVBFrontend::getFrontendType(int &t)
2344 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2349 eWarning("no SEC module active!");
2352 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2355 #if HAVE_DVB_API_VERSION >= 3
2356 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",
2359 feparm.polarisation,
2363 feparm.orbital_position,
2369 eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d",
2372 feparm.polarisation,
2376 feparm.orbital_position);
2378 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2379 switch (feparm.inversion)
2381 case eDVBFrontendParametersSatellite::Inversion_On:
2382 parm_inversion = INVERSION_ON;
2384 case eDVBFrontendParametersSatellite::Inversion_Off:
2385 parm_inversion = INVERSION_OFF;
2388 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2389 parm_inversion = INVERSION_AUTO;
2392 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2396 case eDVBFrontendParametersSatellite::FEC_None:
2397 parm_u_qpsk_fec_inner = FEC_NONE;
2399 case eDVBFrontendParametersSatellite::FEC_1_2:
2400 parm_u_qpsk_fec_inner = FEC_1_2;
2402 case eDVBFrontendParametersSatellite::FEC_2_3:
2403 parm_u_qpsk_fec_inner = FEC_2_3;
2405 case eDVBFrontendParametersSatellite::FEC_3_4:
2406 parm_u_qpsk_fec_inner = FEC_3_4;
2408 case eDVBFrontendParametersSatellite::FEC_5_6:
2409 parm_u_qpsk_fec_inner = FEC_5_6;
2411 case eDVBFrontendParametersSatellite::FEC_7_8:
2412 parm_u_qpsk_fec_inner = FEC_7_8;
2415 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2416 case eDVBFrontendParametersSatellite::FEC_Auto:
2417 parm_u_qpsk_fec_inner = FEC_AUTO;
2421 #if HAVE_DVB_API_VERSION >= 3
2426 case eDVBFrontendParametersSatellite::FEC_1_2:
2427 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2429 case eDVBFrontendParametersSatellite::FEC_2_3:
2430 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2432 case eDVBFrontendParametersSatellite::FEC_3_4:
2433 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2435 case eDVBFrontendParametersSatellite::FEC_3_5:
2436 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2438 case eDVBFrontendParametersSatellite::FEC_4_5:
2439 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2441 case eDVBFrontendParametersSatellite::FEC_5_6:
2442 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2444 case eDVBFrontendParametersSatellite::FEC_7_8:
2445 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2447 case eDVBFrontendParametersSatellite::FEC_8_9:
2448 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2450 case eDVBFrontendParametersSatellite::FEC_9_10:
2451 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2454 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2457 #if HAVE_DVB_API_VERSION < 5
2458 parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff
2459 parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot
2460 if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
2462 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9);
2463 // 8PSK fec driver values are decimal 9 bigger
2468 // FIXME !!! get frequency range from tuner
2469 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2471 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2474 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2480 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2482 #if HAVE_DVB_API_VERSION < 3
2483 parm_frequency = feparm.frequency;
2485 parm_frequency = feparm.frequency * 1000;
2487 parm_u_qam_symbol_rate = feparm.symbol_rate;
2488 switch (feparm.modulation)
2490 case eDVBFrontendParametersCable::Modulation_QAM16:
2491 parm_u_qam_modulation = QAM_16;
2493 case eDVBFrontendParametersCable::Modulation_QAM32:
2494 parm_u_qam_modulation = QAM_32;
2496 case eDVBFrontendParametersCable::Modulation_QAM64:
2497 parm_u_qam_modulation = QAM_64;
2499 case eDVBFrontendParametersCable::Modulation_QAM128:
2500 parm_u_qam_modulation = QAM_128;
2502 case eDVBFrontendParametersCable::Modulation_QAM256:
2503 parm_u_qam_modulation = QAM_256;
2506 case eDVBFrontendParametersCable::Modulation_Auto:
2507 parm_u_qam_modulation = QAM_AUTO;
2510 switch (feparm.inversion)
2512 case eDVBFrontendParametersCable::Inversion_On:
2513 parm_inversion = INVERSION_ON;
2515 case eDVBFrontendParametersCable::Inversion_Off:
2516 parm_inversion = INVERSION_OFF;
2519 case eDVBFrontendParametersCable::Inversion_Unknown:
2520 parm_inversion = INVERSION_AUTO;
2523 switch (feparm.fec_inner)
2525 case eDVBFrontendParametersCable::FEC_None:
2526 parm_u_qam_fec_inner = FEC_NONE;
2528 case eDVBFrontendParametersCable::FEC_1_2:
2529 parm_u_qam_fec_inner = FEC_1_2;
2531 case eDVBFrontendParametersCable::FEC_2_3:
2532 parm_u_qam_fec_inner = FEC_2_3;
2534 case eDVBFrontendParametersCable::FEC_3_4:
2535 parm_u_qam_fec_inner = FEC_3_4;
2537 case eDVBFrontendParametersCable::FEC_5_6:
2538 parm_u_qam_fec_inner = FEC_5_6;
2540 case eDVBFrontendParametersCable::FEC_7_8:
2541 parm_u_qam_fec_inner = FEC_7_8;
2543 #if HAVE_DVB_API_VERSION >= 3
2544 case eDVBFrontendParametersCable::FEC_8_9:
2545 parm_u_qam_fec_inner = FEC_8_9;
2549 case eDVBFrontendParametersCable::FEC_Auto:
2550 parm_u_qam_fec_inner = FEC_AUTO;
2553 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2554 parm_frequency/1000,
2555 parm_u_qam_symbol_rate,
2556 parm_u_qam_fec_inner,
2557 parm_u_qam_modulation,
2563 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2565 parm_frequency = feparm.frequency;
2567 switch (feparm.bandwidth)
2569 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2570 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2572 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2573 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2575 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2576 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2578 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2579 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2581 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2582 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2584 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2585 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2588 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2589 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2592 switch (feparm.code_rate_LP)
2594 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2595 parm_u_ofdm_code_rate_LP = FEC_1_2;
2597 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2598 parm_u_ofdm_code_rate_LP = FEC_2_3;
2600 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2601 parm_u_ofdm_code_rate_LP = FEC_3_4;
2603 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2604 parm_u_ofdm_code_rate_LP = FEC_5_6;
2606 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2607 parm_u_ofdm_code_rate_LP = FEC_7_8;
2609 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2610 parm_u_ofdm_code_rate_LP = FEC_6_7;
2612 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2613 parm_u_ofdm_code_rate_LP = FEC_8_9;
2616 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2617 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2620 switch (feparm.code_rate_HP)
2622 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2623 parm_u_ofdm_code_rate_HP = FEC_1_2;
2625 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2626 parm_u_ofdm_code_rate_HP = FEC_2_3;
2628 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2629 parm_u_ofdm_code_rate_HP = FEC_3_4;
2631 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2632 parm_u_ofdm_code_rate_HP = FEC_5_6;
2634 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2635 parm_u_ofdm_code_rate_HP = FEC_7_8;
2637 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2638 parm_u_ofdm_code_rate_HP = FEC_6_7;
2640 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2641 parm_u_ofdm_code_rate_HP = FEC_8_9;
2644 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2645 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2648 switch (feparm.modulation)
2650 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2651 parm_u_ofdm_constellation = QPSK;
2653 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2654 parm_u_ofdm_constellation = QAM_16;
2656 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2657 parm_u_ofdm_constellation = QAM_64;
2659 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2660 parm_u_ofdm_constellation = QAM_256;
2663 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2664 parm_u_ofdm_constellation = QAM_AUTO;
2667 switch (feparm.transmission_mode)
2669 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2670 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2672 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2673 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2675 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2676 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2678 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2679 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2681 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2682 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2684 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2685 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2688 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2689 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2692 switch (feparm.guard_interval)
2694 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2695 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2697 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2698 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2700 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2701 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2703 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2704 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2706 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2707 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2709 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2710 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2712 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2713 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2716 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2717 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2720 switch (feparm.hierarchy)
2722 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2723 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2725 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2726 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2728 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2729 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2731 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2732 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2735 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2736 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2739 switch (feparm.inversion)
2741 case eDVBFrontendParametersTerrestrial::Inversion_On:
2742 parm_inversion = INVERSION_ON;
2744 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2745 parm_inversion = INVERSION_OFF;
2748 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2749 parm_inversion = INVERSION_AUTO;
2752 eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d",
2753 parm_frequency/1000,
2754 parm_u_ofdm_bandwidth,
2755 parm_u_ofdm_code_rate_LP,
2756 parm_u_ofdm_code_rate_HP,
2757 parm_u_ofdm_constellation,
2758 parm_u_ofdm_transmission_mode,
2759 parm_u_ofdm_guard_interval,
2760 parm_u_ofdm_hierarchy_information,
2766 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2768 unsigned int timeout = 5000;
2769 eDebugNoSimulate("(%d)tune", m_dvbid);
2775 if (!m_sn && !m_simulate)
2777 eDebug("no frontend device opened... do not try to tune !!!");
2791 m_sec_sequence.clear();
2793 where.calcLockTimeout(timeout);
2799 eDVBFrontendParametersSatellite feparm;
2800 if (where.getDVBS(feparm))
2802 eDebug("no dvbs data!");
2806 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2808 eDVBFrontend *sec_fe = this;
2809 long tmp = m_data[LINKED_PREV_PTR];
2812 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2813 sec_fe = linked_fe->m_frontend;
2814 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2816 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2817 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
2819 m_rotor_mode = feparm.no_rotor_command_on_tune;
2821 m_sec->setRotorMoving(m_slotid, false);
2822 res=prepare_sat(feparm, timeout);
2830 eDVBFrontendParametersCable feparm;
2831 if (where.getDVBC(feparm))
2836 res=prepare_cable(feparm);
2840 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2841 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2846 eDVBFrontendParametersTerrestrial feparm;
2847 if (where.getDVBT(feparm))
2849 eDebug("no -T data");
2853 res=prepare_terrestrial(feparm);
2857 std::string enable_5V;
2858 char configStr[255];
2859 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2860 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2861 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2862 if (enable_5V == "True")
2863 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2865 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2866 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2872 m_sec_sequence.current() = m_sec_sequence.begin();
2876 m_tuneTimer->start(0,true);
2878 if (m_state != stateTuning)
2880 m_state = stateTuning;
2881 m_stateChanged(this);
2890 m_tuneTimer->stop();
2894 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2896 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2900 RESULT eDVBFrontend::setVoltage(int voltage)
2902 if (m_type == feCable)
2904 #if HAVE_DVB_API_VERSION < 3
2907 bool increased=false;
2908 fe_sec_voltage_t vlt;
2910 m_data[CUR_VOLTAGE]=voltage;
2914 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2915 vlt = SEC_VOLTAGE_OFF;
2918 #if HAVE_DVB_API_VERSION < 3
2919 vlt = SEC_VOLTAGE_13_5;
2925 vlt = SEC_VOLTAGE_13;
2928 #if HAVE_DVB_API_VERSION < 3
2929 vlt = SEC_VOLTAGE_18_5;
2935 vlt = SEC_VOLTAGE_18;
2942 #if HAVE_DVB_API_VERSION < 3
2943 return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt);
2945 if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0)
2946 perror("FE_ENABLE_HIGH_LNB_VOLTAGE");
2947 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2951 RESULT eDVBFrontend::getState(int &state)
2957 RESULT eDVBFrontend::setTone(int t)
2959 if (m_type != feSatellite)
2961 #if HAVE_DVB_API_VERSION < 3
2964 fe_sec_tone_mode_t tone;
2973 tone = SEC_TONE_OFF;
2980 #if HAVE_DVB_API_VERSION < 3
2981 return ::ioctl(m_secfd, SEC_SET_TONE, tone);
2983 return ::ioctl(m_fd, FE_SET_TONE, tone);
2987 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD)
2988 #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *)
2991 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2995 #if HAVE_DVB_API_VERSION < 3
2996 struct secCommand cmd;
2997 cmd.type = SEC_CMDTYPE_DISEQC_RAW;
2998 cmd.u.diseqc.cmdtype = diseqc.data[0];
2999 cmd.u.diseqc.addr = diseqc.data[1];
3000 cmd.u.diseqc.cmd = diseqc.data[2];
3001 cmd.u.diseqc.numParams = diseqc.len-3;
3002 memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3);
3003 if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd))
3005 struct dvb_diseqc_master_cmd cmd;
3006 memcpy(cmd.msg, diseqc.data, diseqc.len);
3007 cmd.msg_len = diseqc.len;
3008 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
3014 #if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST)
3015 #define SEC_DISEQC_SEND_BURST _IO('o', 96)
3017 RESULT eDVBFrontend::sendToneburst(int burst)
3021 #if HAVE_DVB_API_VERSION < 3
3022 secMiniCmd cmd = SEC_MINI_NONE;
3024 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
3026 if ( burst == eDVBSatelliteDiseqcParameters::A )
3028 else if ( burst == eDVBSatelliteDiseqcParameters::B )
3030 #if HAVE_DVB_API_VERSION < 3
3031 if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd))
3034 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
3040 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
3046 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
3048 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
3049 m_sec_sequence.push_back(list);
3051 m_sec_sequence = list;
3055 RESULT eDVBFrontend::getData(int num, long &data)
3057 if ( num < NUM_DATA_ENTRIES )
3065 RESULT eDVBFrontend::setData(int num, long val)
3067 if ( num < NUM_DATA_ENTRIES )
3075 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
3078 if (feparm->getSystem(type) || type != m_type || !m_enabled)
3080 if (m_type == eDVBFrontend::feSatellite)
3083 eDVBFrontendParametersSatellite sat_parm;
3084 int ret = feparm->getDVBS(sat_parm);
3086 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2)
3088 ret = m_sec->canTune(sat_parm, this, 1 << m_slotid);
3089 if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2)
3093 else if (m_type == eDVBFrontend::feCable)
3094 return 2; // more prio for cable frontends
3095 else if (m_type == eDVBFrontend::feTerrestrial)
3097 eDVBFrontendParametersTerrestrial ter_parm;
3098 if ( feparm->getDVBT(ter_parm) )
3102 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
3104 return m_can_handle_dvbt2 ? 1 : 0;
3108 return m_can_handle_dvbt2 ? 1 : 2;
3114 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3116 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
3117 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
3119 Id = PyTuple_GET_ITEM(obj, 0);
3120 Descr = PyTuple_GET_ITEM(obj, 1);
3121 Enabled = PyTuple_GET_ITEM(obj, 2);
3122 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3123 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3124 frontendId = PyTuple_GET_ITEM(obj, 5);
3125 m_slotid = PyInt_AsLong(Id);
3126 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
3128 strcpy(m_description, PyString_AS_STRING(Descr));
3129 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3130 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3131 // m_slotid, m_description);
3134 m_enabled = Enabled == Py_True;
3135 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3136 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3137 !!strstr(m_description, "Alps BSBE2") ||
3138 !!strstr(m_description, "Alps -S") ||
3139 !!strstr(m_description, "BCM4501");
3140 m_can_handle_dvbs2 = IsDVBS2 == Py_True;
3141 m_can_handle_dvbt2 = IsDVBT2 == Py_True;
3142 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
3143 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" );
3146 PyErr_SetString(PyExc_StandardError,
3147 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");