1 #include <linux/dvb/version.h>
3 #include <lib/dvb/dvb.h>
4 #include <lib/dvb/frontendparms.h>
5 #include <lib/base/eerror.h>
6 #include <lib/base/nconfig.h> // access to python config
10 #include <sys/ioctl.h>
12 #ifndef I2C_SLAVE_FORCE
13 #define I2C_SLAVE_FORCE 0x0706
16 #include <linux/dvb/frontend.h>
17 #define parm_frequency parm.frequency
18 #define parm_inversion parm.inversion
19 #define parm_u_qpsk_symbol_rate parm.u.qpsk.symbol_rate
20 #define parm_u_qpsk_fec_inner parm.u.qpsk.fec_inner
21 #define parm_u_qam_symbol_rate parm.u.qam.symbol_rate
22 #define parm_u_qam_fec_inner parm.u.qam.fec_inner
23 #define parm_u_qam_modulation parm.u.qam.modulation
24 #define parm_u_ofdm_bandwidth parm.u.ofdm.bandwidth
25 #define parm_u_ofdm_code_rate_LP parm.u.ofdm.code_rate_LP
26 #define parm_u_ofdm_code_rate_HP parm.u.ofdm.code_rate_HP
27 #define parm_u_ofdm_constellation parm.u.ofdm.constellation
28 #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode
29 #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval
30 #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information
31 #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2)
32 #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3)
33 #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4)
34 #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6)
35 #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8)
36 #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9)
37 #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5)
38 #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5)
39 #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10)
42 #define FEC_S2_QPSK_13_45 (fe_code_rate_t)(FEC_13_45)
44 #include <dvbsi++/satellite_delivery_system_descriptor.h>
45 #include <dvbsi++/cable_delivery_system_descriptor.h>
46 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
48 #define eDebugNoSimulate(x...) \
56 eDebugNoNewLine("SIMULATE:"); \
61 #define eDebugNoSimulateNoNewLine(x...) \
69 eDebugNoNewLine("SIMULATE:"); \
74 void eDVBDiseqcCommand::setCommandString(const char *str)
79 int slen = strlen(str);
82 eDebug("invalid diseqc command string length (not 2 byte aligned)");
85 if (slen > MAX_DISEQC_LENGTH*2)
87 eDebug("invalid diseqc command string length (string is to long)");
91 for (int i=0; i < slen; ++i)
93 unsigned char c = str[i];
96 case '0' ... '9': c-=48; break;
97 case 'a' ... 'f': c-=87; break;
98 case 'A' ... 'F': c-=55; break;
100 eDebug("invalid character in hex string..ignore complete diseqc command !");
114 void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescriptor &descriptor)
116 frequency = descriptor.getFrequency() * 10;
117 symbol_rate = descriptor.getSymbolRate() * 100;
118 polarisation = descriptor.getPolarization();
119 fec = descriptor.getFecInner();
120 if ( fec != eDVBFrontendParametersSatellite::FEC_None && fec > eDVBFrontendParametersSatellite::FEC_9_10 )
121 fec = eDVBFrontendParametersSatellite::FEC_Auto;
122 inversion = eDVBFrontendParametersSatellite::Inversion_Unknown;
123 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
124 orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
125 orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
126 orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
127 orbital_position += ((descriptor.getOrbitalPosition()) & 0xF);
128 if (orbital_position && (!descriptor.getWestEastFlag()))
129 orbital_position = 3600 - orbital_position;
130 system = descriptor.getModulationSystem();
131 modulation = descriptor.getModulation();
132 if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation != eDVBFrontendParametersSatellite::Modulation_QPSK)
134 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
135 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
137 rolloff = descriptor.getRollOff();
138 is_id = NO_STREAM_ID_FILTER;
139 pls_mode = eDVBFrontendParametersSatellite::PLS_Unknown;
141 if (system == eDVBFrontendParametersSatellite::System_DVB_S)
143 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
145 polarisation ? "hor" : "vert",
149 else // System_DVB_S2 or System_DVB_S2X
151 eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d, is_id %d, pls_mode %d, pls_code %d",
153 polarisation ? "hor" : "vert",
164 void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descriptor)
166 frequency = descriptor.getFrequency() / 10;
167 symbol_rate = descriptor.getSymbolRate() * 100;
168 fec_inner = descriptor.getFecInner();
169 if ( fec_inner != eDVBFrontendParametersCable::FEC_None && fec_inner > eDVBFrontendParametersCable::FEC_8_9 )
170 fec_inner = eDVBFrontendParametersCable::FEC_Auto;
171 modulation = descriptor.getModulation();
172 if ( modulation > 0x5 )
173 modulation = eDVBFrontendParametersCable::Modulation_Auto;
174 inversion = eDVBFrontendParametersCable::Inversion_Unknown;
175 eDebug("Cable freq %d, mod %d, sr %d, fec %d",
177 modulation, symbol_rate, fec_inner);
180 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
182 /* EN 300 468 V1.11.1 DVB-SI SPEC */
183 frequency = descriptor.getCentreFrequency() * 10;
184 switch (descriptor.getBandwidth())
186 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
187 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
188 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
189 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
190 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
192 switch (descriptor.getCodeRateHpStream())
194 case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
195 case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
196 case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
197 case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
198 case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
199 default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
201 switch (descriptor.getCodeRateLpStream())
203 case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
204 case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
205 case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
206 case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
207 case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
208 default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
210 switch (descriptor.getTransmissionMode())
212 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
213 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
214 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
215 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
217 switch (descriptor.getGuardInterval())
219 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
220 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
221 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
222 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
223 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
225 // hierarchy = descriptor.getHierarchyInformation();
226 hierarchy = descriptor.getHierarchyInformation()&3;
227 if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
228 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
229 modulation = descriptor.getConstellation();
230 if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
231 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
232 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
233 system = eDVBFrontendParametersTerrestrial::System_DVB_T;
235 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
236 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
237 guard_interval, hierarchy, modulation);
240 void eDVBFrontendParametersTerrestrial::set(const T2DeliverySystemDescriptor &descriptor)
242 switch (descriptor.getBandwidth())
244 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
245 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
246 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
247 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
248 case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
249 case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
250 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
252 switch (descriptor.getTransmissionMode())
254 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
255 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
256 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
257 case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
258 case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
259 case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
260 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
262 switch (descriptor.getGuardInterval())
264 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
265 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
266 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
267 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
268 case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
269 case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
270 case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
271 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
273 plpid = descriptor.getPlpId();
274 code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto;
275 code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto;
276 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
277 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
278 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
279 system = eDVBFrontendParametersTerrestrial::System_DVB_T2;
280 eDebug("T2 bw %d, tm_mode %d, guard %d, plpid %d",
281 bandwidth, transmission_mode, guard_interval, plpid);
284 eDVBFrontendParameters::eDVBFrontendParameters()
285 :m_type(-1), m_flags(0)
289 DEFINE_REF(eDVBFrontendParameters);
291 RESULT eDVBFrontendParameters::getSystem(int &t) const
294 return (m_type == -1) ? -1 : 0;
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 (sat.is_id != osat.is_id)
370 else if (sat.pls_mode != osat.pls_mode)
372 else if (sat.pls_code != osat.pls_code)
374 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
376 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
380 diff = abs(sat.frequency - osat.frequency);
381 diff += abs(sat.symbol_rate - osat.symbol_rate);
385 case iDVBFrontend::feCable:
386 eDVBFrontendParametersCable ocable;
387 if (parm->getDVBC(ocable))
390 if (exact && cable.modulation != ocable.modulation
391 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
392 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
394 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
398 diff = abs(cable.frequency - ocable.frequency);
399 diff += abs(cable.symbol_rate - ocable.symbol_rate);
402 case iDVBFrontend::feTerrestrial:
403 eDVBFrontendParametersTerrestrial oterrestrial;
404 if (parm->getDVBT(oterrestrial))
406 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
407 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
408 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
410 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
411 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
412 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
414 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
415 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
416 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
418 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
419 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
420 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
422 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
423 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
424 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
426 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
427 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
428 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
430 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
431 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
432 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
434 else if (oterrestrial.system != terrestrial.system)
436 else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
437 oterrestrial.plpid != terrestrial.plpid)
440 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
448 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
452 case iDVBFrontend::feSatellite:
454 hash = (sat.orbital_position << 16);
455 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
458 case iDVBFrontend::feCable:
460 hash |= (cable.frequency/1000)&0xFFFF;
462 case iDVBFrontend::feTerrestrial:
464 hash |= (terrestrial.frequency/1000000)&0xFFFF;
471 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
475 case iDVBFrontend::feSatellite:
477 /* high symbol rate transponders tune faster, due to
478 requiring less zigzag and giving more symbols faster.
480 5s are definitely not enough on really low SR when
481 zigzag has to find the exact frequency first.
483 if (sat.symbol_rate > 20000000)
485 else if (sat.symbol_rate > 10000000)
491 case iDVBFrontend::feCable:
494 case iDVBFrontend::feTerrestrial:
502 DEFINE_REF(eDVBFrontend);
504 int eDVBFrontend::PriorityOrder=0;
505 int eDVBFrontend::PreferredFrontendIndex=-1;
508 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
509 :m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
510 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false)
511 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false), m_is_usbtuner(false)
513 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
515 m_timeout = eTimer::create(eApp);
516 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
518 m_tuneTimer = eTimer::create(eApp);
519 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
521 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
524 m_idleInputpower[0]=m_idleInputpower[1]=0;
526 ok = !openFrontend();
530 void eDVBFrontend::reopenFrontend()
537 int eDVBFrontend::openFrontend()
539 if (m_state != stateClosed)
540 return -1; // already opened
547 eDebug("opening frontend %d", m_dvbid);
550 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
553 eWarning("failed! (%s) %m", m_filename);
558 eWarning("frontend %d already opened", m_dvbid);
560 if (m_delsys.empty())
562 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
564 eWarning("ioctl FE_GET_INFO failed");
569 #ifdef DTV_ENUM_DELSYS
570 struct dtv_property p[1];
571 p[0].cmd = DTV_ENUM_DELSYS;
572 struct dtv_properties cmdseq;
575 if (::ioctl(m_fd, FE_GET_PROPERTY, &cmdseq) >= 0)
579 for (i = 0; i < p[0].u.buffer.len ; i++)
581 fe_delivery_system_t delsys = (fe_delivery_system_t)p[0].u.buffer.data[i];
582 m_delsys[delsys] = true;
587 /* no DTV_ENUM_DELSYS support */
591 /* old DVB API, fill delsys map with some defaults */
592 switch (fe_info.type)
596 m_delsys[SYS_DVBS] = true;
597 #if DVB_API_VERSION >= 5
598 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
604 #if defined SYS_DVBC_ANNEX_A
605 m_delsys[SYS_DVBC_ANNEX_A] = true;
607 m_delsys[SYS_DVBC_ANNEX_AC] = true;
613 m_delsys[SYS_DVBT] = true;
614 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
615 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
619 case FE_ATSC: // placeholder to prevent warning
629 m_simulate_fe->m_delsys = m_delsys;
632 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
633 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
637 fe_info.frequency_min = 900000;
638 fe_info.frequency_max = 2200000;
640 eDebug("[eDVBFrontend] opening frontend %d", m_dvbid);
641 int tmp_fd = ::open(m_filename, O_RDONLY | O_NONBLOCK);
644 eWarning("[eDVBFrontend] opening %s failed: %m", m_filename);
648 if (::ioctl(tmp_fd, FE_GET_INFO, &fe_info) < 0)
650 eWarning("[eDVBFrontend] ioctl FE_GET_INFO on frontend %s failed: %m", m_filename);
656 setTone(iDVBFrontend::toneOff);
657 setVoltage(iDVBFrontend::voltageOff);
662 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
664 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
666 long tmp = m_data[LINKED_NEXT_PTR];
669 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
670 if (linked_fe->m_inuse)
672 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
673 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
676 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
682 eDebugNoSimulate("close frontend %d", m_dvbid);
683 if (m_data[SATCR] != -1)
687 m_sec->prepareTurnOffSatCR(*this);
688 m_tuneTimer->start(0, true);
689 if(!m_tuneTimer->isActive())
692 eDebug("[turnOffSatCR] no mainloop");
695 timeout = tuneLoopInt();
698 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
702 eDebug("[turnOffSatCR] running mainloop");
706 m_data[ROTOR_CMD] = -1;
709 setTone(iDVBFrontend::toneOff);
710 setVoltage(iDVBFrontend::voltageOff);
713 if (m_sec && !m_simulate)
714 m_sec->setRotorMoving(m_slotid, false);
718 eWarning("couldnt close frontend %d", m_dvbid);
722 setTone(iDVBFrontend::toneOff);
723 setVoltage(iDVBFrontend::voltageOff);
726 m_state = stateClosed;
731 eDVBFrontend::~eDVBFrontend()
733 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
737 void eDVBFrontend::feEvent(int w)
739 eDVBFrontend *sec_fe = this;
740 long tmp = m_data[LINKED_PREV_PTR];
743 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
744 sec_fe = linked_fe->m_frontend;
745 sec_fe->getData(LINKED_NEXT_PTR, tmp);
749 dvb_frontend_event event;
752 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
754 if (res && (errno == EAGAIN))
760 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
761 if (event.status & FE_HAS_LOCK)
768 if (event.status & FE_TIMEDOUT) {
769 eDebug("FE_TIMEDOUT! ..abort");
778 eDebug("stateLostLock");
779 state = stateLostLock;
782 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
783 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
787 if (m_state != state)
790 m_stateChanged(this);
795 void eDVBFrontend::timeout()
798 if (m_state == stateTuning)
801 eDVBFrontend *sec_fe = this;
802 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
803 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
805 m_state = stateFailed;
806 m_stateChanged(this);
810 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
812 /* unsigned 32 bit division */
813 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
815 return (a + b / 2) / b;
818 int eDVBFrontend::readFrontendData(int type)
827 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
828 eDebug("FE_READ_BER failed (%m)");
833 case signalQualitydB: /* this will move into the driver */
835 int sat_max = 1600; // for stv0288 / bsbe2
836 int ret = 0x12345678;
840 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
841 eDebug("FE_READ_SNR failed (%m)");
842 else if (!strcmp(m_description, "BCM4501 (internal)"))
844 float SDS_SNRE = snr << 16;
847 eDVBFrontendParametersSatellite sparm;
848 oparm.getDVBS(sparm);
850 if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
852 static float SNR_COEFF[6] = {
855 197418.0 / 4194304.0,
856 -2602183.0 / 4194304.0,
857 20377212.0 / 4194304.0,
858 -37791203.0 / 4194304.0,
860 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
861 fval2 = pow(10.0, fval1)-1;
862 fval1 = 10.0 * log10(fval2);
866 fval2 = SNR_COEFF[0];
867 for (int i=1; i<6; ++i)
870 fval2 += SNR_COEFF[i];
878 float fval1 = SDS_SNRE / 268435456.0,
881 if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
892 fval4 = -10.0 * log10(fval1);
894 for (int i=0; i < 5; ++i)
895 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
899 ret = (int)(snr_in_db * 100);
901 else if (strstr(m_description, "Alps BSBE1 C01A") ||
902 strstr(m_description, "Alps -S(STV0288)"))
906 else if (snr == 0xFFFF) // i think this should not happen
910 enum { REALVAL, REGVAL };
911 const long CN_lookup[31][2] = {
912 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
913 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
914 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
915 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
916 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
917 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
920 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
921 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
925 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
930 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
935 ret = (((regval - CN_lookup[Imin][REGVAL])
936 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
937 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
938 + CN_lookup[Imin][REALVAL]) * 10;
944 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
945 !strcmp(m_description, "Alps -S") ||
946 !strcmp(m_description, "Philips -S") ||
947 !strcmp(m_description, "LG -S") )
950 ret = (int)((snr-39075)/17.647);
951 } else if (!strcmp(m_description, "Alps BSBE2"))
953 ret = (int)((snr >> 7) * 10);
954 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
956 int mse = (~snr) & 0xFF;
957 switch (parm_u_qam_modulation) {
958 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
959 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
960 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
961 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
962 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
965 } else if (!strcmp(m_description, "Philips TU1216"))
967 snr = 0xFF - (snr & 0xFF);
969 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
971 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
972 ret = (snr * 100) >> 8;
973 else if (!strcmp(m_description, "CXD1981"))
975 int mse = (~snr) & 0xFF;
976 switch (parm_u_qam_modulation) {
979 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
981 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
987 if (type == signalQuality)
989 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
993 oparm.getSystem(type);
997 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
998 case feCable: // we assume a max of 42db here
999 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
1000 case feTerrestrial: // we assume a max of 24db here
1001 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
1005 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
1010 uint16_t strength=0;
1013 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
1014 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
1023 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1024 eDebug("FE_READ_STATUS failed (%m)");
1025 return !!(status&FE_HAS_LOCK);
1034 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
1035 eDebug("FE_READ_STATUS failed (%m)");
1036 return !!(status&FE_HAS_SYNC);
1040 case frontendNumber:
1043 return m_is_usbtuner;
1048 void PutToDict(ePyObject &dict, const char*key, long value)
1050 ePyObject item = PyInt_FromLong(value);
1053 if (PyDict_SetItemString(dict, key, item))
1054 eDebug("put %s to dict failed", key);
1058 eDebug("could not create PyObject for %s", key);
1061 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1065 if (PyDict_SetItemString(dict, key, item))
1066 eDebug("put %s to dict failed", key);
1070 eDebug("invalid PyObject for %s", key);
1073 void PutToDict(ePyObject &dict, const char*key, const char *value)
1075 ePyObject item = PyString_FromString(value);
1078 if (PyDict_SetItemString(dict, key, item))
1079 eDebug("put %s to dict failed", key);
1083 eDebug("could not create PyObject for %s", key);
1086 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1088 PutToDict(dict, "tuner_type", "DVB-S");
1089 PutToDict(dict, "frequency", feparm.frequency);
1090 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1091 PutToDict(dict, "orbital_position", feparm.orbital_position);
1092 PutToDict(dict, "inversion", feparm.inversion);
1093 PutToDict(dict, "fec_inner", feparm.fec);
1094 PutToDict(dict, "modulation", feparm.modulation);
1095 PutToDict(dict, "polarization", feparm.polarisation);
1096 if ((feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2) || (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2X))
1098 PutToDict(dict, "rolloff", feparm.rolloff);
1099 PutToDict(dict, "pilot", feparm.pilot);
1100 PutToDict(dict, "is_id", feparm.is_id);
1101 PutToDict(dict, "pls_mode", feparm.pls_mode);
1102 PutToDict(dict, "pls_code", feparm.pls_code);
1104 PutToDict(dict, "system", feparm.system);
1107 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1109 PutToDict(dict, "tuner_type", "DVB-T");
1110 PutToDict(dict, "frequency", feparm.frequency);
1111 PutToDict(dict, "bandwidth", feparm.bandwidth);
1112 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1113 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1114 PutToDict(dict, "constellation", feparm.modulation);
1115 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1116 PutToDict(dict, "guard_interval", feparm.guard_interval);
1117 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1118 PutToDict(dict, "inversion", feparm.inversion);
1119 PutToDict(dict, "system", feparm.system);
1120 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1122 PutToDict(dict, "plp_id", feparm.plpid);
1126 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1128 PutToDict(dict, "tuner_type", "DVB-C");
1129 PutToDict(dict, "frequency", feparm.frequency);
1130 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1131 PutToDict(dict, "modulation", feparm.modulation);
1132 PutToDict(dict, "inversion", feparm.inversion);
1133 PutToDict(dict, "fec_inner", feparm.fec_inner);
1136 static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, eDVBFrontendParametersSatellite &feparm)
1139 int p_system = p[0].u.data;
1140 int p_frequency = p[1].u.data;
1141 int p_inversion = p[2].u.data;
1142 int p_modulation = p[3].u.data;
1143 int p_symbolrate = p[4].u.data;
1144 int p_inner_fec = p[5].u.data;
1145 int p_rolloff = p[6].u.data;
1146 int p_pilot = p[7].u.data;
1147 int p_stream_id = p[8].u.data;
1149 int frequency = p_frequency + freq_offset;
1150 PutToDict(dict, "frequency", frequency);
1151 PutToDict(dict, "symbol_rate", p_symbolrate);
1152 PutToDict(dict, "orbital_position", feparm.orbital_position);
1153 PutToDict(dict, "polarization", feparm.polarisation);
1157 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1158 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1159 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1160 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1161 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1162 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1163 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1164 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1165 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1166 case FEC_13_45 ... FEC_26_45_L: tmp = eDVBFrontendParametersSatellite::FEC_13_45 + (long)(p_inner_fec - FEC_13_45); break;
1167 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1168 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1169 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1171 PutToDict(dict, "fec_inner", tmp);
1175 default: eDebug("got unsupported system from frontend! report as DVBS!");
1176 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1177 case SYS_DVBS2: tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1178 case SYS_DVBS2X: tmp = eDVBFrontendParametersSatellite::System_DVB_S2X; break;
1180 PutToDict(dict, "system", tmp);
1182 if ((p_system == SYS_DVBS2) || (p_system == SYS_DVBS2X))
1186 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1187 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1188 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1189 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1191 PutToDict(dict, "rolloff", tmp);
1195 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1196 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1197 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1199 PutToDict(dict, "pilot", tmp);
1201 PutToDict(dict, "is_id", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.is_id : (p_stream_id & 0xFF));
1202 PutToDict(dict, "pls_mode", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.pls_mode : ((p_stream_id >> 26) & 0x3));
1203 PutToDict(dict, "pls_code", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.pls_code : ((p_stream_id >> 8) & 0x3FFFF));
1206 switch (p_modulation)
1208 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1209 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1210 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1211 case APSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8APSK; break;
1212 case APSK_16: tmp = eDVBFrontendParametersSatellite::Modulation_16APSK; break;
1213 case APSK_32: tmp = eDVBFrontendParametersSatellite::Modulation_32APSK; break;
1215 PutToDict(dict, "modulation", tmp);
1219 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1220 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1221 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1223 PutToDict(dict, "inversion", tmp);
1226 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1229 int p_system = p[0].u.data;
1230 int p_frequency = p[1].u.data;
1231 int p_inversion = p[2].u.data;
1232 int p_modulation = p[3].u.data;
1233 int p_symbolrate = p[4].u.data;
1234 int p_inner_fec = p[5].u.data;
1236 tmp = p_frequency/1000;
1237 PutToDict(dict, "frequency", tmp);
1239 PutToDict(dict, "symbol_rate", p_inversion);
1241 switch (p_inner_fec)
1243 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1244 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1245 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1246 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1247 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1248 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1249 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1251 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1253 PutToDict(dict, "fec_inner", tmp);
1255 switch (p_modulation)
1257 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1258 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1259 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1260 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1261 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1263 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1265 PutToDict(dict, "modulation", tmp);
1267 switch (p_inversion)
1269 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1270 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1272 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1274 PutToDict(dict, "inversion", tmp);
1277 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1280 int p_system = p[0].u.data;
1281 int p_frequency = p[1].u.data;
1282 int p_inversion = p[2].u.data;
1283 int p_constellation = p[3].u.data;
1284 int p_bandwidth = p[4].u.data;
1285 int p_coderate_lp = p[5].u.data;
1286 int p_coderate_hp = p[6].u.data;
1287 int p_transmission_mode = p[7].u.data;
1288 int p_guard_interval = p[8].u.data;
1289 int p_hierarchy = p[9].u.data;
1290 #if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID)
1291 int p_plp_id = p[10].u.data;
1297 default: eDebug("got unsupported system from frontend! report as DVBT!");
1298 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1301 #if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID)
1303 PutToDict(dict, "plp_id", tmp);
1305 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1308 PutToDict(dict, "system", tmp);
1311 PutToDict(dict, "frequency", tmp);
1313 switch (p_bandwidth)
1315 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1316 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1317 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1318 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1319 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1320 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1322 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1324 PutToDict(dict, "bandwidth", tmp);
1326 switch (p_coderate_lp)
1328 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1329 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1330 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1331 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1332 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1333 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1334 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1335 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1337 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1339 PutToDict(dict, "code_rate_lp", tmp);
1341 switch (p_coderate_hp)
1343 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1344 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1345 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1346 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1347 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1348 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1349 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1350 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1352 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1354 PutToDict(dict, "code_rate_hp", tmp);
1356 switch (p_constellation)
1358 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1359 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1360 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1361 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1363 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1365 PutToDict(dict, "constellation", tmp);
1368 switch (p_transmission_mode)
1370 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1371 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1372 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1373 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1374 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1375 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1377 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1379 PutToDict(dict, "transmission_mode", tmp);
1381 switch (p_guard_interval)
1383 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1384 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1385 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1386 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1387 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1388 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1389 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1391 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1393 PutToDict(dict, "guard_interval", tmp);
1395 switch (p_hierarchy)
1397 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1398 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1399 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1400 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1402 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1404 PutToDict(dict, "hierarchy_information", tmp);
1406 switch (p_inversion)
1408 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1409 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1411 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1413 PutToDict(dict, "inversion", tmp);
1416 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1418 if (dest && PyDict_Check(dest))
1420 const char *tmp = "UNKNOWN";
1441 PutToDict(dest, "tuner_state", tmp);
1442 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1443 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1444 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1445 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1446 int sigQualitydB = readFrontendData(signalQualitydB);
1447 if (sigQualitydB == 0x12345678) // not support yet
1449 ePyObject obj=Py_None;
1451 PutToDict(dest, "tuner_signal_quality_db", obj);
1454 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1455 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1459 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1461 if (dest && PyDict_Check(dest))
1464 FRONTENDPARAMETERS front;
1465 struct dtv_property p[16];
1466 struct dtv_properties cmdseq;
1469 oparm.getSystem(type);
1471 p[cmdseq.num++].cmd = DTV_DELIVERY_SYSTEM;
1472 p[cmdseq.num++].cmd = DTV_FREQUENCY;
1473 p[cmdseq.num++].cmd = DTV_INVERSION;
1474 p[cmdseq.num++].cmd = DTV_MODULATION;
1475 if(type == feSatellite)
1477 p[cmdseq.num++].cmd = DTV_SYMBOL_RATE;
1478 p[cmdseq.num++].cmd = DTV_INNER_FEC;
1479 p[cmdseq.num++].cmd = DTV_ROLLOFF;
1480 p[cmdseq.num++].cmd = DTV_PILOT;
1481 p[cmdseq.num++].cmd = DTV_STREAM_ID;
1483 else if(type == feCable)
1485 p[cmdseq.num++].cmd = DTV_SYMBOL_RATE;
1486 p[cmdseq.num++].cmd = DTV_INNER_FEC;
1488 else if(type == feTerrestrial)
1490 p[cmdseq.num++].cmd = DTV_BANDWIDTH_HZ;
1491 p[cmdseq.num++].cmd = DTV_CODE_RATE_LP;
1492 p[cmdseq.num++].cmd = DTV_CODE_RATE_HP;
1493 p[cmdseq.num++].cmd = DTV_TRANSMISSION_MODE;
1494 p[cmdseq.num++].cmd = DTV_GUARD_INTERVAL;
1495 p[cmdseq.num++].cmd = DTV_HIERARCHY;
1496 #if defined DTV_STREAM_ID
1497 p[cmdseq.num++].cmd = DTV_STREAM_ID;
1498 #elif defined DTV_DVBT2_PLP_ID
1499 p[cmdseq.num++].cmd = DTV_DVBT2_PLP_ID;
1503 if (m_simulate || m_fd == -1 || original)
1507 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1509 eDebug("FE_GET_PROPERTY failed (%m)");
1512 else if (type == feSatellite && // use for DVB-S(2) only
1513 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1515 eDebug("FE_GET_FRONTEND failed (%m)");
1523 eDVBFrontendParametersSatellite sparm;
1524 oparm.getDVBS(sparm);
1525 PutSatelliteDataToDict(dest, sparm);
1528 eDVBFrontendParametersCable cparm;
1529 oparm.getDVBC(cparm);
1530 PutCableDataToDict(dest, cparm);
1533 eDVBFrontendParametersTerrestrial tparm;
1534 oparm.getDVBT(tparm);
1535 PutTerrestrialDataToDict(dest, tparm);
1544 eDVBFrontendParametersSatellite sparm;
1545 oparm.getDVBS(sparm);
1546 fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm);
1549 fillDictWithCableData(dest, p);
1552 fillDictWithTerrestrialData(dest, p);
1559 void eDVBFrontend::getFrontendData(ePyObject dest)
1561 if (dest && PyDict_Check(dest))
1564 PutToDict(dest, "tuner_number", m_slotid);
1566 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true) || supportsDeliverySystem(SYS_DVBS2X, true))
1570 #if defined SYS_DVBC_ANNEX_A
1571 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1573 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1578 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1586 PutToDict(dest, "tuner_type", tmp);
1590 #ifndef FP_IOCTL_GET_ID
1591 #define FP_IOCTL_GET_ID 0
1593 int eDVBFrontend::readInputpower()
1597 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1599 char proc_name2[64];
1600 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1601 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1603 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1605 if (fscanf(f, "%d", &power) != 1)
1606 eDebug("read %s failed!! (%m)", proc_name);
1608 eDebug("%s is %d\n", proc_name, power);
1613 // open front prozessor
1614 int fp=::open("/dev/dbox/fp0", O_RDWR);
1617 eDebug("couldn't open fp");
1620 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1621 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1623 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1632 bool eDVBFrontend::setSecSequencePos(int steps)
1634 eDebugNoSimulate("set sequence pos %d", steps);
1639 if (m_sec_sequence.current() != m_sec_sequence.end())
1640 ++m_sec_sequence.current();
1645 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1646 --m_sec_sequence.current();
1652 void eDVBFrontend::tuneLoop()
1657 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1660 eDVBFrontend *sec_fe = this;
1661 eDVBRegisteredFrontend *regFE = 0;
1662 long tmp = m_data[LINKED_PREV_PTR];
1665 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1666 sec_fe = prev->m_frontend;
1667 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1668 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1669 int state = sec_fe->m_state;
1670 #if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
1671 // workaround to put the kernel frontend thread into idle state!
1672 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1674 sec_fe->closeFrontend(true);
1675 state = sec_fe->m_state;
1678 // sec_fe is closed... we must reopen it here..
1679 if (state == stateClosed)
1687 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1689 long *sec_fe_data = sec_fe->m_data;
1690 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1692 switch (m_sec_sequence.current()->cmd)
1694 case eSecCommand::SLEEP:
1695 delay = m_sec_sequence.current()++->msec;
1696 eDebugNoSimulate("[SEC] sleep %dms", delay);
1698 case eSecCommand::GOTO:
1699 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1700 ++m_sec_sequence.current();
1702 case eSecCommand::SET_VOLTAGE:
1704 int voltage = m_sec_sequence.current()++->voltage;
1705 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1706 sec_fe->setVoltage(voltage);
1709 case eSecCommand::IF_VOLTAGE_GOTO:
1711 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1712 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1714 ++m_sec_sequence.current();
1717 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1719 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1720 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1722 ++m_sec_sequence.current();
1725 case eSecCommand::IF_TONE_GOTO:
1727 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1728 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1730 ++m_sec_sequence.current();
1733 case eSecCommand::IF_NOT_TONE_GOTO:
1735 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1736 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1738 ++m_sec_sequence.current();
1741 case eSecCommand::SET_TONE:
1742 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1743 sec_fe->setTone(m_sec_sequence.current()++->tone);
1745 case eSecCommand::SEND_DISEQC:
1746 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1747 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1748 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1749 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1750 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1751 eDebugNoSimulate("(DiSEqC reset)");
1752 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1753 eDebugNoSimulate("(DiSEqC peripherial power on)");
1755 eDebugNoSimulate("");
1756 ++m_sec_sequence.current();
1758 case eSecCommand::SEND_TONEBURST:
1759 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1760 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1762 case eSecCommand::SET_FRONTEND:
1764 int enableEvents = (m_sec_sequence.current()++)->val;
1765 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1766 setFrontend(enableEvents);
1769 case eSecCommand::START_TUNE_TIMEOUT:
1771 int tuneTimeout = m_sec_sequence.current()->timeout;
1772 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1774 m_timeout->start(tuneTimeout, 1);
1775 ++m_sec_sequence.current();
1778 case eSecCommand::SET_TIMEOUT:
1779 m_timeoutCount = m_sec_sequence.current()++->val;
1780 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1782 case eSecCommand::IF_TIMEOUT_GOTO:
1783 if (!m_timeoutCount)
1785 eDebugNoSimulate("[SEC] rotor timout");
1786 setSecSequencePos(m_sec_sequence.current()->steps);
1789 ++m_sec_sequence.current();
1791 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1793 int idx = m_sec_sequence.current()++->val;
1794 if ( idx == 0 || idx == 1 )
1796 m_idleInputpower[idx] = sec_fe->readInputpower();
1797 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1800 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1803 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1805 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1806 int idx = compare.val;
1807 if ( !m_simulate && (idx == 0 || idx == 1) )
1809 int idle = sec_fe->readInputpower();
1810 int diff = abs(idle-m_idleInputpower[idx]);
1813 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1814 setSecSequencePos(compare.steps);
1818 ++m_sec_sequence.current();
1821 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1823 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1826 setSecSequencePos(cmd.steps);
1830 int isLocked = readFrontendData(locked);
1831 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1833 if (!m_timeoutCount && m_retryCount > 0)
1835 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1838 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1841 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1843 cmd.lastSignal = signal;
1846 if (cmd.okcount > 4)
1848 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1849 setSecSequencePos(cmd.steps);
1850 m_state = stateLock;
1851 m_stateChanged(this);
1852 feEvent(-1); // flush events
1860 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1862 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1866 ++m_sec_sequence.current();
1869 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1870 m_runningInputpower = sec_fe->readInputpower();
1871 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
1872 ++m_sec_sequence.current();
1874 case eSecCommand::SET_ROTOR_MOVING:
1876 m_sec->setRotorMoving(m_slotid, true);
1877 ++m_sec_sequence.current();
1879 case eSecCommand::SET_ROTOR_STOPPED:
1881 m_sec->setRotorMoving(m_slotid, false);
1882 ++m_sec_sequence.current();
1884 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1886 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1889 setSecSequencePos(cmd.steps);
1892 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
1893 const char *txt = cmd.direction ? "running" : "stopped";
1895 if (!m_timeoutCount && m_retryCount > 0)
1897 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1899 m_runningInputpower,
1902 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1903 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1906 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1907 if ( cmd.okcount > 6 )
1909 eDebugNoSimulate("[SEC] rotor is %s", txt);
1910 if (setSecSequencePos(cmd.steps))
1916 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1919 ++m_sec_sequence.current();
1922 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1923 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
1924 setSecSequencePos(m_sec_sequence.current()->steps);
1926 ++m_sec_sequence.current();
1928 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
1929 eDebugNoSimulate("[SEC] invalidate current switch params");
1930 sec_fe_data[CSW] = -1;
1931 sec_fe_data[UCSW] = -1;
1932 sec_fe_data[TONEBURST] = -1;
1933 ++m_sec_sequence.current();
1935 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
1936 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
1937 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
1938 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
1939 eDebugNoSimulate("[SEC] update current switch params");
1940 ++m_sec_sequence.current();
1942 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1943 eDebugNoSimulate("[SEC] invalidate current rotorparams");
1944 sec_fe_data[ROTOR_CMD] = -1;
1945 sec_fe_data[ROTOR_POS] = -1;
1946 ++m_sec_sequence.current();
1948 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1949 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
1950 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
1951 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
1952 ++m_sec_sequence.current();
1954 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1955 m_retryCount = m_sec_sequence.current()++->val;
1956 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
1958 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1961 eDebugNoSimulate("[SEC] no more rotor retrys");
1962 setSecSequencePos(m_sec_sequence.current()->steps);
1965 ++m_sec_sequence.current();
1967 case eSecCommand::SET_POWER_LIMITING_MODE:
1972 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
1973 FILE *f=fopen(proc_name, "w");
1974 if (f) // new interface exist?
1976 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1977 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1978 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
1980 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1983 else if (sec_fe->m_need_rotor_workaround)
1986 int slotid = sec_fe->m_slotid;
1987 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1989 sprintf(dev, "/dev/i2c-%d", slotid);
1990 else if (slotid == 2)
1991 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
1992 else if (slotid == 3)
1993 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
1994 int fd = ::open(dev, O_RDWR);
1996 unsigned char data[2];
1997 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1998 if(::read(fd, data, 1) != 1)
1999 eDebugNoSimulate("[SEC] error read lnbp (%m)");
2000 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
2002 data[0] |= 0x80; // enable static current limiting
2003 eDebugNoSimulate("[SEC] set static current limiting");
2007 data[0] &= ~0x80; // enable dynamic current limiting
2008 eDebugNoSimulate("[SEC] set dynamic current limiting");
2010 if(::write(fd, data, 1) != 1)
2011 eDebugNoSimulate("[SEC] error write lnbp (%m)");
2015 ++m_sec_sequence.current();
2018 case eSecCommand::DELAYED_CLOSE_FRONTEND:
2020 eDebugNoSimulate("[SEC] delayed close frontend");
2021 closeFrontend(false, true);
2022 ++m_sec_sequence.current();
2026 eDebugNoSimulate("[SEC] unhandled sec command %d",
2027 ++m_sec_sequence.current()->cmd);
2028 ++m_sec_sequence.current();
2031 m_tuneTimer->start(delay,true);
2035 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
2040 void eDVBFrontend::setFrontend(bool recvEvents)
2044 eDebug("setting frontend %d", m_dvbid);
2047 oparm.getSystem(type);
2051 feEvent(-1); // flush events
2052 if (type == iDVBFrontend::feSatellite)
2054 fe_rolloff_t rolloff = ROLLOFF_35;
2055 fe_pilot_t pilot = PILOT_OFF;
2056 fe_modulation_t modulation = QPSK;
2057 fe_delivery_system_t system = SYS_DVBS;
2058 eDVBFrontendParametersSatellite sparm;
2059 oparm.getDVBS(sparm);
2060 switch(sparm.system)
2062 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2063 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2064 case eDVBFrontendParametersSatellite::System_DVB_S2X: system = SYS_DVBS2X; break;
2066 switch(sparm.modulation)
2068 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2069 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2070 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2071 case eDVBFrontendParametersSatellite::Modulation_8APSK: modulation = APSK_8; break;
2072 case eDVBFrontendParametersSatellite::Modulation_16APSK: modulation = APSK_16; break;
2073 case eDVBFrontendParametersSatellite::Modulation_32APSK: modulation = APSK_32; break;
2077 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2078 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2079 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2081 switch(sparm.rolloff)
2083 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2084 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2085 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2087 struct dtv_property p[11];
2088 struct dtv_properties cmdseq;
2090 p[0].cmd = DTV_CLEAR;
2091 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2092 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2093 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2094 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2095 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2096 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2097 if ((system == SYS_DVBS2) || (system == SYS_DVBS2X))
2099 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2100 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2101 p[9].cmd = DTV_STREAM_ID, p[9].u.data = sparm.is_id | (sparm.pls_code << 8) | (sparm.pls_mode << 26);
2102 p[10].cmd = DTV_TUNE;
2107 p[7].cmd = DTV_TUNE;
2110 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2112 perror("FE_SET_PROPERTY failed");
2116 else if (type == iDVBFrontend::feCable)
2118 struct dtv_property p[8];
2119 struct dtv_properties cmdseq;
2121 p[0].cmd = DTV_CLEAR;
2122 #if defined SYS_DVBC_ANNEX_A
2123 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2125 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2127 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2128 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2129 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2130 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2131 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2132 p[7].cmd = DTV_TUNE;
2134 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2136 perror("FE_SET_PROPERTY failed");
2140 else if (type == iDVBFrontend::feTerrestrial)
2142 fe_delivery_system_t system = SYS_DVBT;
2143 eDVBFrontendParametersTerrestrial tparm;
2144 oparm.getDVBT(tparm);
2145 switch (tparm.system)
2148 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2149 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2152 switch (tparm.bandwidth)
2154 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2155 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2156 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2158 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2159 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2160 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2161 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2163 struct dtv_property p[13];
2164 struct dtv_properties cmdseq;
2167 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2168 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2169 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2170 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2171 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2172 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2173 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2174 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2175 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2176 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2177 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2178 #if defined DTV_STREAM_ID
2179 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2180 #elif defined DTV_DVBT2_PLP_ID
2181 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2183 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2184 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2186 perror("FE_SET_PROPERTY failed");
2192 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2194 perror("FE_SET_FRONTEND failed");
2201 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2206 eWarning("no SEC module active!");
2209 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2212 eDebugNoSimulate("prepare_sat Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d, is_id %d, pls_mode %d, pls_code %d",
2214 feparm.polarisation,
2218 feparm.orbital_position,
2226 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2227 switch (feparm.inversion)
2229 case eDVBFrontendParametersSatellite::Inversion_On:
2230 parm_inversion = INVERSION_ON;
2232 case eDVBFrontendParametersSatellite::Inversion_Off:
2233 parm_inversion = INVERSION_OFF;
2236 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2237 parm_inversion = INVERSION_AUTO;
2240 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2244 case eDVBFrontendParametersSatellite::FEC_None:
2245 parm_u_qpsk_fec_inner = FEC_NONE;
2247 case eDVBFrontendParametersSatellite::FEC_1_2:
2248 parm_u_qpsk_fec_inner = FEC_1_2;
2250 case eDVBFrontendParametersSatellite::FEC_2_3:
2251 parm_u_qpsk_fec_inner = FEC_2_3;
2253 case eDVBFrontendParametersSatellite::FEC_3_4:
2254 parm_u_qpsk_fec_inner = FEC_3_4;
2256 case eDVBFrontendParametersSatellite::FEC_5_6:
2257 parm_u_qpsk_fec_inner = FEC_5_6;
2259 case eDVBFrontendParametersSatellite::FEC_7_8:
2260 parm_u_qpsk_fec_inner = FEC_7_8;
2263 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2264 case eDVBFrontendParametersSatellite::FEC_Auto:
2265 parm_u_qpsk_fec_inner = FEC_AUTO;
2269 else if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
2273 case eDVBFrontendParametersSatellite::FEC_1_2:
2274 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2276 case eDVBFrontendParametersSatellite::FEC_2_3:
2277 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2279 case eDVBFrontendParametersSatellite::FEC_3_4:
2280 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2282 case eDVBFrontendParametersSatellite::FEC_3_5:
2283 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2285 case eDVBFrontendParametersSatellite::FEC_4_5:
2286 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2288 case eDVBFrontendParametersSatellite::FEC_5_6:
2289 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2291 case eDVBFrontendParametersSatellite::FEC_7_8:
2292 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2294 case eDVBFrontendParametersSatellite::FEC_8_9:
2295 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2297 case eDVBFrontendParametersSatellite::FEC_9_10:
2298 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2301 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2309 case eDVBFrontendParametersSatellite::FEC_1_2:
2310 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2312 case eDVBFrontendParametersSatellite::FEC_2_3:
2313 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2315 case eDVBFrontendParametersSatellite::FEC_3_4:
2316 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2318 case eDVBFrontendParametersSatellite::FEC_3_5:
2319 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2321 case eDVBFrontendParametersSatellite::FEC_4_5:
2322 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2324 case eDVBFrontendParametersSatellite::FEC_5_6:
2325 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2327 case eDVBFrontendParametersSatellite::FEC_7_8:
2328 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2330 case eDVBFrontendParametersSatellite::FEC_8_9:
2331 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2333 case eDVBFrontendParametersSatellite::FEC_9_10:
2334 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2336 case eDVBFrontendParametersSatellite::FEC_13_45 ... eDVBFrontendParametersSatellite::FEC_26_45_L:
2337 parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)FEC_S2_QPSK_13_45 + (feparm.fec-eDVBFrontendParametersSatellite::FEC_13_45));
2340 eDebugNoSimulate("no valid fec for DVB-S2X set.. abort !!");
2344 // FIXME !!! get frequency range from tuner
2345 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2347 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2350 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2352 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2356 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2358 parm_frequency = feparm.frequency * 1000;
2359 parm_u_qam_symbol_rate = feparm.symbol_rate;
2360 switch (feparm.modulation)
2362 case eDVBFrontendParametersCable::Modulation_QAM16:
2363 parm_u_qam_modulation = QAM_16;
2365 case eDVBFrontendParametersCable::Modulation_QAM32:
2366 parm_u_qam_modulation = QAM_32;
2368 case eDVBFrontendParametersCable::Modulation_QAM64:
2369 parm_u_qam_modulation = QAM_64;
2371 case eDVBFrontendParametersCable::Modulation_QAM128:
2372 parm_u_qam_modulation = QAM_128;
2374 case eDVBFrontendParametersCable::Modulation_QAM256:
2375 parm_u_qam_modulation = QAM_256;
2378 case eDVBFrontendParametersCable::Modulation_Auto:
2379 parm_u_qam_modulation = QAM_AUTO;
2382 switch (feparm.inversion)
2384 case eDVBFrontendParametersCable::Inversion_On:
2385 parm_inversion = INVERSION_ON;
2387 case eDVBFrontendParametersCable::Inversion_Off:
2388 parm_inversion = INVERSION_OFF;
2391 case eDVBFrontendParametersCable::Inversion_Unknown:
2392 parm_inversion = INVERSION_AUTO;
2395 switch (feparm.fec_inner)
2397 case eDVBFrontendParametersCable::FEC_None:
2398 parm_u_qam_fec_inner = FEC_NONE;
2400 case eDVBFrontendParametersCable::FEC_1_2:
2401 parm_u_qam_fec_inner = FEC_1_2;
2403 case eDVBFrontendParametersCable::FEC_2_3:
2404 parm_u_qam_fec_inner = FEC_2_3;
2406 case eDVBFrontendParametersCable::FEC_3_4:
2407 parm_u_qam_fec_inner = FEC_3_4;
2409 case eDVBFrontendParametersCable::FEC_5_6:
2410 parm_u_qam_fec_inner = FEC_5_6;
2412 case eDVBFrontendParametersCable::FEC_7_8:
2413 parm_u_qam_fec_inner = FEC_7_8;
2415 case eDVBFrontendParametersCable::FEC_8_9:
2416 parm_u_qam_fec_inner = FEC_8_9;
2419 case eDVBFrontendParametersCable::FEC_Auto:
2420 parm_u_qam_fec_inner = FEC_AUTO;
2423 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2424 parm_frequency/1000,
2425 parm_u_qam_symbol_rate,
2426 parm_u_qam_fec_inner,
2427 parm_u_qam_modulation,
2429 oparm.setDVBC(feparm);
2433 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2435 parm_frequency = feparm.frequency;
2437 switch (feparm.bandwidth)
2439 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2440 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2442 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2443 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2445 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2446 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2448 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2449 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2451 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2452 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2454 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2455 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2458 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2459 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2462 switch (feparm.code_rate_LP)
2464 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2465 parm_u_ofdm_code_rate_LP = FEC_1_2;
2467 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2468 parm_u_ofdm_code_rate_LP = FEC_2_3;
2470 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2471 parm_u_ofdm_code_rate_LP = FEC_3_4;
2473 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2474 parm_u_ofdm_code_rate_LP = FEC_5_6;
2476 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2477 parm_u_ofdm_code_rate_LP = FEC_7_8;
2479 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2480 parm_u_ofdm_code_rate_LP = FEC_6_7;
2482 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2483 parm_u_ofdm_code_rate_LP = FEC_8_9;
2486 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2487 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2490 switch (feparm.code_rate_HP)
2492 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2493 parm_u_ofdm_code_rate_HP = FEC_1_2;
2495 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2496 parm_u_ofdm_code_rate_HP = FEC_2_3;
2498 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2499 parm_u_ofdm_code_rate_HP = FEC_3_4;
2501 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2502 parm_u_ofdm_code_rate_HP = FEC_5_6;
2504 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2505 parm_u_ofdm_code_rate_HP = FEC_7_8;
2507 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2508 parm_u_ofdm_code_rate_HP = FEC_6_7;
2510 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2511 parm_u_ofdm_code_rate_HP = FEC_8_9;
2514 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2515 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2518 switch (feparm.modulation)
2520 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2521 parm_u_ofdm_constellation = QPSK;
2523 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2524 parm_u_ofdm_constellation = QAM_16;
2526 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2527 parm_u_ofdm_constellation = QAM_64;
2529 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2530 parm_u_ofdm_constellation = QAM_256;
2533 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2534 parm_u_ofdm_constellation = QAM_AUTO;
2537 switch (feparm.transmission_mode)
2539 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2540 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2542 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2543 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2545 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2546 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2548 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2549 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2551 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2552 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2554 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2555 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2558 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2559 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2562 switch (feparm.guard_interval)
2564 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2565 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2567 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2568 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2570 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2571 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2573 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2574 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2576 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2577 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2579 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2580 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2582 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2583 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2586 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2587 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2590 switch (feparm.hierarchy)
2592 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2593 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2595 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2596 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2598 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2599 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2601 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2602 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2605 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2606 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2609 switch (feparm.inversion)
2611 case eDVBFrontendParametersTerrestrial::Inversion_On:
2612 parm_inversion = INVERSION_ON;
2614 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2615 parm_inversion = INVERSION_OFF;
2618 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2619 parm_inversion = INVERSION_AUTO;
2622 eDebug("tuning to %d khz, bandwidth %d, crl %d, crh %d, modulation %d, tm %d, guard %d, hierarchy %d, inversion %d, system %d, plpid %d",
2623 parm_frequency/1000,
2624 parm_u_ofdm_bandwidth,
2625 parm_u_ofdm_code_rate_LP,
2626 parm_u_ofdm_code_rate_HP,
2627 parm_u_ofdm_constellation,
2628 parm_u_ofdm_transmission_mode,
2629 parm_u_ofdm_guard_interval,
2630 parm_u_ofdm_hierarchy_information,
2634 oparm.setDVBT(feparm);
2638 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2640 unsigned int timeout = 5000;
2641 eDebugNoSimulate("(%d)tune", m_dvbid);
2648 if (where.getSystem(type) < 0)
2654 if (!m_sn && !m_simulate)
2656 eDebug("no frontend device opened... do not try to tune !!!");
2664 m_sec_sequence.clear();
2666 where.calcLockTimeout(timeout);
2672 eDVBFrontendParametersSatellite feparm;
2673 if (where.getDVBS(feparm))
2675 eDebug("no dvbs data!");
2679 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2681 eDVBFrontend *sec_fe = this;
2682 long tmp = m_data[LINKED_PREV_PTR];
2685 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2686 sec_fe = linked_fe->m_frontend;
2687 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2689 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2690 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
2692 m_rotor_mode = feparm.no_rotor_command_on_tune;
2694 m_sec->setRotorMoving(m_slotid, false);
2695 res=prepare_sat(feparm, timeout);
2703 eDVBFrontendParametersCable feparm;
2704 if (where.getDVBC(feparm))
2709 res=prepare_cable(feparm);
2713 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2714 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2719 eDVBFrontendParametersTerrestrial feparm;
2720 if (where.getDVBT(feparm))
2722 eDebug("no -T data");
2726 res=prepare_terrestrial(feparm);
2730 std::string enable_5V;
2731 char configStr[255];
2732 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2733 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2734 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2735 if (enable_5V == "True")
2736 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2738 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2739 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2750 m_sec_sequence.current() = m_sec_sequence.begin();
2754 m_tuneTimer->start(0,true);
2756 if (m_state != stateTuning)
2758 m_state = stateTuning;
2759 m_stateChanged(this);
2768 m_tuneTimer->stop();
2772 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2774 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2778 RESULT eDVBFrontend::setVoltage(int voltage)
2780 bool increased=false;
2781 fe_sec_voltage_t vlt;
2782 m_data[CUR_VOLTAGE]=voltage;
2786 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2787 vlt = SEC_VOLTAGE_OFF;
2792 vlt = SEC_VOLTAGE_13;
2797 vlt = SEC_VOLTAGE_18;
2805 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
2806 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2809 RESULT eDVBFrontend::getState(int &state)
2815 RESULT eDVBFrontend::setTone(int t)
2817 fe_sec_tone_mode_t tone;
2825 tone = SEC_TONE_OFF;
2833 return ::ioctl(m_fd, FE_SET_TONE, tone);
2836 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2841 struct dvb_diseqc_master_cmd cmd;
2842 memcpy(cmd.msg, diseqc.data, diseqc.len);
2843 cmd.msg_len = diseqc.len;
2844 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2849 RESULT eDVBFrontend::sendToneburst(int burst)
2853 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2854 if ( burst == eDVBSatelliteDiseqcParameters::A )
2856 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2858 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2863 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2869 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
2871 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
2872 m_sec_sequence.push_back(list);
2874 m_sec_sequence = list;
2878 bool eDVBFrontend::isScheduledSendDiseqc()
2880 bool has_senddiseqc = false;
2881 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
2883 eSecCommandList::iterator cur = m_sec_sequence.current();
2884 while(cur != m_sec_sequence.end())
2886 if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
2888 has_senddiseqc = true;
2893 return has_senddiseqc;
2896 RESULT eDVBFrontend::getData(int num, long &data)
2898 if ( num < NUM_DATA_ENTRIES )
2906 RESULT eDVBFrontend::setData(int num, long val)
2908 if ( num < NUM_DATA_ENTRIES )
2916 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2920 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
2922 if (feparm->getSystem(type) || !m_enabled)
2925 if (type == eDVBFrontend::feSatellite)
2927 eDVBFrontendParametersSatellite sat_parm;
2928 bool can_handle_dvbs, can_handle_dvbs2, can_handle_dvbs2x;
2929 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
2930 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
2931 can_handle_dvbs2x = supportsDeliverySystem(SYS_DVBS2X, true);
2932 if (feparm->getDVBS(sat_parm) < 0)
2936 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2X && !can_handle_dvbs2x)
2940 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
2944 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
2948 bool multistream = (static_cast<unsigned int>(sat_parm.is_id) != NO_STREAM_ID_FILTER || (sat_parm.pls_code & 0x3FFFF) != 0 ||
2949 (sat_parm.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Unknown);
2951 if (((sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2)||(sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2X)) && multistream && !is_multistream())
2955 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
2956 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
2958 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
2961 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && can_handle_dvbs2x)
2963 /* prefer to use a S2 tuner, try to keep S2X free for S2X transponders */
2966 if (score > 1 && is_multistream() && !multistream)
2968 /* prefer to use a non multistream tuner, try to keep multistream tuners free for multistream transponders */
2973 else if (type == eDVBFrontend::feCable)
2975 eDVBFrontendParametersCable cab_parm;
2976 if (feparm->getDVBC(cab_parm) < 0)
2980 #if defined SYS_DVBC_ANNEX_A
2981 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
2983 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
2991 else if (type == eDVBFrontend::feTerrestrial)
2993 eDVBFrontendParametersTerrestrial ter_parm;
2994 bool can_handle_dvbt, can_handle_dvbt2;
2995 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
2996 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
2997 if (feparm->getDVBT(ter_parm) < 0)
3001 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
3005 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
3010 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
3012 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
3017 if (score && preferred)
3019 /* make 'sure' we always prefer this frontend */
3026 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
3028 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
3029 if (it != m_delsys.end() && it->second)
3031 if (obeywhitelist && !m_delsys_whitelist.empty())
3033 it = m_delsys_whitelist.find(sys);
3034 if (it == m_delsys_whitelist.end() || !it->second) return false;
3041 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
3043 m_delsys_whitelist.clear();
3044 for (unsigned int i = 0; i < whitelist.size(); i++)
3046 m_delsys_whitelist[whitelist[i]] = true;
3050 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
3054 bool eDVBFrontend::setSlotInfo(ePyObject obj)
3056 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, IsDVBS2X, frontendId;
3057 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 7)
3059 Id = PyTuple_GET_ITEM(obj, 0);
3060 Descr = PyTuple_GET_ITEM(obj, 1);
3061 Enabled = PyTuple_GET_ITEM(obj, 2);
3062 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
3063 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
3064 IsDVBS2X = PyTuple_GET_ITEM(obj, 5);
3065 frontendId = PyTuple_GET_ITEM(obj, 6);
3066 m_slotid = PyInt_AsLong(Id);
3067 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyBool_Check(IsDVBS2X) || !PyInt_Check(frontendId))
3069 strcpy(m_description, PyString_AS_STRING(Descr));
3070 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
3071 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
3072 // m_slotid, m_description);
3075 m_enabled = (Enabled == Py_True);
3076 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
3077 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
3078 !!strstr(m_description, "Alps BSBE2") ||
3079 !!strstr(m_description, "Alps -S") ||
3080 !!strstr(m_description, "BCM4501");
3081 if (IsDVBS2 == Py_True)
3083 /* HACK for legacy dvb api without DELSYS support */
3084 m_delsys[SYS_DVBS2] = true;
3086 if (IsDVBT2 == Py_True)
3088 /* HACK for legacy dvb api without DELSYS support */
3089 m_delsys[SYS_DVBT2] = true;
3091 if (IsDVBS2X == Py_True)
3093 /* HACK for legacy dvb api without DELSYS support */
3094 m_delsys[SYS_DVBS2X] = true;
3097 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s, DVB-S2X %s",
3098 m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", Enabled == Py_True ? "Yes" : "No", IsDVBS2 == Py_True ? "Yes" : "No", IsDVBT2 == Py_True ? "Yes" : "No", IsDVBS2X == Py_True ? "Yes" : "No");
3101 PyErr_SetString(PyExc_StandardError,
3102 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");
3106 bool eDVBFrontend::is_multistream()
3108 return fe_info.caps & FE_CAN_MULTISTREAM;