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)
41 #include <dvbsi++/satellite_delivery_system_descriptor.h>
42 #include <dvbsi++/cable_delivery_system_descriptor.h>
43 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
45 #define eDebugNoSimulate(x...) \
53 eDebugNoNewLine("SIMULATE:"); \
58 #define eDebugNoSimulateNoNewLine(x...) \
66 eDebugNoNewLine("SIMULATE:"); \
71 void eDVBDiseqcCommand::setCommandString(const char *str)
76 int slen = strlen(str);
79 eDebug("invalid diseqc command string length (not 2 byte aligned)");
82 if (slen > MAX_DISEQC_LENGTH*2)
84 eDebug("invalid diseqc command string length (string is to long)");
88 for (int i=0; i < slen; ++i)
90 unsigned char c = str[i];
93 case '0' ... '9': c-=48; break;
94 case 'a' ... 'f': c-=87; break;
95 case 'A' ... 'F': c-=55; break;
97 eDebug("invalid character in hex string..ignore complete diseqc command !");
111 void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescriptor &descriptor)
113 frequency = descriptor.getFrequency() * 10;
114 symbol_rate = descriptor.getSymbolRate() * 100;
115 polarisation = descriptor.getPolarization();
116 fec = descriptor.getFecInner();
117 if ( fec != eDVBFrontendParametersSatellite::FEC_None && fec > eDVBFrontendParametersSatellite::FEC_9_10 )
118 fec = eDVBFrontendParametersSatellite::FEC_Auto;
119 inversion = eDVBFrontendParametersSatellite::Inversion_Unknown;
120 pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
121 orbital_position = ((descriptor.getOrbitalPosition() >> 12) & 0xF) * 1000;
122 orbital_position += ((descriptor.getOrbitalPosition() >> 8) & 0xF) * 100;
123 orbital_position += ((descriptor.getOrbitalPosition() >> 4) & 0xF) * 10;
124 orbital_position += ((descriptor.getOrbitalPosition()) & 0xF);
125 if (orbital_position && (!descriptor.getWestEastFlag()))
126 orbital_position = 3600 - orbital_position;
127 system = descriptor.getModulationSystem();
128 modulation = descriptor.getModulation();
129 if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
131 eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
132 modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
134 rolloff = descriptor.getRollOff();
135 if (system == eDVBFrontendParametersSatellite::System_DVB_S2)
137 eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
139 polarisation ? "hor" : "vert",
147 eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
149 polarisation ? "hor" : "vert",
155 void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descriptor)
157 frequency = descriptor.getFrequency() / 10;
158 symbol_rate = descriptor.getSymbolRate() * 100;
159 fec_inner = descriptor.getFecInner();
160 if ( fec_inner != eDVBFrontendParametersCable::FEC_None && fec_inner > eDVBFrontendParametersCable::FEC_8_9 )
161 fec_inner = eDVBFrontendParametersCable::FEC_Auto;
162 modulation = descriptor.getModulation();
163 if ( modulation > 0x5 )
164 modulation = eDVBFrontendParametersCable::Modulation_Auto;
165 inversion = eDVBFrontendParametersCable::Inversion_Unknown;
166 eDebug("Cable freq %d, mod %d, sr %d, fec %d",
168 modulation, symbol_rate, fec_inner);
171 void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor)
173 /* EN 300 468 V1.11.1 DVB-SI SPEC */
174 frequency = descriptor.getCentreFrequency() * 10;
175 switch (descriptor.getBandwidth())
177 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
178 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
179 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
180 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
181 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
183 switch (descriptor.getCodeRateHpStream())
185 case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
186 case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
187 case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
188 case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
189 case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
190 default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
192 switch (descriptor.getCodeRateLpStream())
194 case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
195 case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
196 case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
197 case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
198 case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
199 default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
201 switch (descriptor.getTransmissionMode())
203 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
204 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
205 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
206 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
208 switch (descriptor.getGuardInterval())
210 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
211 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
212 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
213 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
214 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
216 // hierarchy = descriptor.getHierarchyInformation();
217 hierarchy = descriptor.getHierarchyInformation()&3;
218 if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
219 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
220 modulation = descriptor.getConstellation();
221 if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
222 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
223 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
224 system = eDVBFrontendParametersTerrestrial::System_DVB_T;
226 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
227 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
228 guard_interval, hierarchy, modulation);
231 void eDVBFrontendParametersTerrestrial::set(const T2DeliverySystemDescriptor &descriptor)
233 switch (descriptor.getBandwidth())
235 case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
236 case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
237 case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
238 case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
239 case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
240 case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
241 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
243 switch (descriptor.getTransmissionMode())
245 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
246 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
247 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
248 case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
249 case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
250 case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
251 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
253 switch (descriptor.getGuardInterval())
255 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
256 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
257 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
258 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
259 case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
260 case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
261 case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
262 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
264 plpid = descriptor.getPlpId();
265 code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto;
266 code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto;
267 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
268 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
269 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
270 system = eDVBFrontendParametersTerrestrial::System_DVB_T2;
271 eDebug("T2 bw %d, tm_mode %d, guard %d, plpid %d",
272 bandwidth, transmission_mode, guard_interval, plpid);
275 eDVBFrontendParameters::eDVBFrontendParameters()
276 :m_type(-1), m_flags(0)
280 DEFINE_REF(eDVBFrontendParameters);
282 RESULT eDVBFrontendParameters::getSystem(int &t) const
285 return (m_type == -1) ? -1 : 0;
288 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
290 if (m_type != iDVBFrontend::feSatellite)
296 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
298 if (m_type != iDVBFrontend::feCable)
304 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
306 if (m_type != iDVBFrontend::feTerrestrial)
312 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
315 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
316 m_type = iDVBFrontend::feSatellite;
320 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
323 m_type = iDVBFrontend::feCable;
327 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
330 m_type = iDVBFrontend::feTerrestrial;
334 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
339 if (parm->getSystem(type))
343 diff = 1<<30; // big difference
349 case iDVBFrontend::feSatellite:
351 eDVBFrontendParametersSatellite osat;
352 if (parm->getDVBS(osat))
355 if (sat.orbital_position != osat.orbital_position)
357 else if (sat.polarisation != osat.polarisation)
359 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
361 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
365 diff = abs(sat.frequency - osat.frequency);
366 diff += abs(sat.symbol_rate - osat.symbol_rate);
370 case iDVBFrontend::feCable:
371 eDVBFrontendParametersCable ocable;
372 if (parm->getDVBC(ocable))
375 if (exact && cable.modulation != ocable.modulation
376 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
377 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
379 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
383 diff = abs(cable.frequency - ocable.frequency);
384 diff += abs(cable.symbol_rate - ocable.symbol_rate);
387 case iDVBFrontend::feTerrestrial:
388 eDVBFrontendParametersTerrestrial oterrestrial;
389 if (parm->getDVBT(oterrestrial))
391 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
392 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
393 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
395 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
396 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
397 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
399 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
400 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
401 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
403 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
404 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
405 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
407 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
408 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
409 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
411 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
412 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
413 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
415 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
416 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
417 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
419 else if (oterrestrial.system != terrestrial.system)
421 else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
422 oterrestrial.plpid != terrestrial.plpid)
425 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
433 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
437 case iDVBFrontend::feSatellite:
439 hash = (sat.orbital_position << 16);
440 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
443 case iDVBFrontend::feCable:
445 hash |= (cable.frequency/1000)&0xFFFF;
447 case iDVBFrontend::feTerrestrial:
449 hash |= (terrestrial.frequency/1000000)&0xFFFF;
456 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
460 case iDVBFrontend::feSatellite:
462 /* high symbol rate transponders tune faster, due to
463 requiring less zigzag and giving more symbols faster.
465 5s are definitely not enough on really low SR when
466 zigzag has to find the exact frequency first.
468 if (sat.symbol_rate > 20000000)
470 else if (sat.symbol_rate > 10000000)
476 case iDVBFrontend::feCable:
479 case iDVBFrontend::feTerrestrial:
487 DEFINE_REF(eDVBFrontend);
489 int eDVBFrontend::PriorityOrder=0;
490 int eDVBFrontend::PreferredFrontendIndex=-1;
493 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
494 :m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
495 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false)
496 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false), m_is_usbtuner(false)
498 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
500 m_timeout = eTimer::create(eApp);
501 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
503 m_tuneTimer = eTimer::create(eApp);
504 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
506 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
509 m_idleInputpower[0]=m_idleInputpower[1]=0;
511 ok = !openFrontend();
515 void eDVBFrontend::reopenFrontend()
522 int eDVBFrontend::openFrontend()
524 if (m_state != stateClosed)
525 return -1; // already opened
530 dvb_frontend_info fe_info;
533 eDebug("opening frontend %d", m_dvbid);
536 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
539 eWarning("failed! (%s) %m", m_filename);
544 eWarning("frontend %d already opened", m_dvbid);
546 if (m_delsys.empty())
548 #ifdef DTV_ENUM_DELSYS
549 struct dtv_property p[1];
550 p[0].cmd = DTV_ENUM_DELSYS;
551 struct dtv_properties cmdseq;
554 if (::ioctl(m_fd, FE_GET_PROPERTY, &cmdseq) >= 0)
558 for (i = 0; i < p[0].u.buffer.len ; i++)
560 fe_delivery_system_t delsys = (fe_delivery_system_t)p[0].u.buffer.data[i];
561 m_delsys[delsys] = true;
565 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
567 eWarning("ioctl FE_GET_INFO failed");
572 /* old DVB API, fill delsys map with some defaults */
573 switch (fe_info.type)
577 m_delsys[SYS_DVBS] = true;
578 #if DVB_API_VERSION >= 5
579 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
585 #if defined SYS_DVBC_ANNEX_A
586 m_delsys[SYS_DVBC_ANNEX_A] = true;
588 m_delsys[SYS_DVBC_ANNEX_AC] = true;
594 m_delsys[SYS_DVBT] = true;
595 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
596 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
600 case FE_ATSC: // placeholder to prevent warning
610 m_simulate_fe->m_delsys = m_delsys;
613 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
614 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
617 setTone(iDVBFrontend::toneOff);
618 setVoltage(iDVBFrontend::voltageOff);
623 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
625 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
627 long tmp = m_data[LINKED_NEXT_PTR];
630 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
631 if (linked_fe->m_inuse)
633 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
634 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
637 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
643 eDebugNoSimulate("close frontend %d", m_dvbid);
644 if (m_data[SATCR] != -1)
648 m_sec->prepareTurnOffSatCR(*this);
649 m_tuneTimer->start(0, true);
650 if(!m_tuneTimer->isActive())
653 eDebug("[turnOffSatCR] no mainloop");
656 timeout = tuneLoopInt();
659 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
663 eDebug("[turnOffSatCR] running mainloop");
667 m_data[ROTOR_CMD] = -1;
670 setTone(iDVBFrontend::toneOff);
671 setVoltage(iDVBFrontend::voltageOff);
674 if (m_sec && !m_simulate)
675 m_sec->setRotorMoving(m_slotid, false);
679 eWarning("couldnt close frontend %d", m_dvbid);
683 setTone(iDVBFrontend::toneOff);
684 setVoltage(iDVBFrontend::voltageOff);
687 m_state = stateClosed;
692 eDVBFrontend::~eDVBFrontend()
694 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
698 void eDVBFrontend::feEvent(int w)
700 eDVBFrontend *sec_fe = this;
701 long tmp = m_data[LINKED_PREV_PTR];
704 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
705 sec_fe = linked_fe->m_frontend;
706 sec_fe->getData(LINKED_NEXT_PTR, tmp);
710 dvb_frontend_event event;
713 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
715 if (res && (errno == EAGAIN))
721 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
722 if (event.status & FE_HAS_LOCK)
729 if (event.status & FE_TIMEDOUT) {
730 eDebug("FE_TIMEDOUT! ..abort");
739 eDebug("stateLostLock");
740 state = stateLostLock;
743 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
744 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
748 if (m_state != state)
751 m_stateChanged(this);
756 void eDVBFrontend::timeout()
759 if (m_state == stateTuning)
762 eDVBFrontend *sec_fe = this;
763 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
764 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
766 m_state = stateFailed;
767 m_stateChanged(this);
771 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
773 /* unsigned 32 bit division */
774 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
776 return (a + b / 2) / b;
779 int eDVBFrontend::readFrontendData(int type)
788 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
789 eDebug("FE_READ_BER failed (%m)");
794 case signalQualitydB: /* this will move into the driver */
796 int sat_max = 1600; // for stv0288 / bsbe2
797 int ret = 0x12345678;
801 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
802 eDebug("FE_READ_SNR failed (%m)");
803 else if (!strcmp(m_description, "BCM4501 (internal)"))
805 float SDS_SNRE = snr << 16;
808 eDVBFrontendParametersSatellite sparm;
809 oparm.getDVBS(sparm);
811 if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
813 static float SNR_COEFF[6] = {
816 197418.0 / 4194304.0,
817 -2602183.0 / 4194304.0,
818 20377212.0 / 4194304.0,
819 -37791203.0 / 4194304.0,
821 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
822 fval2 = pow(10.0, fval1)-1;
823 fval1 = 10.0 * log10(fval2);
827 fval2 = SNR_COEFF[0];
828 for (int i=1; i<6; ++i)
831 fval2 += SNR_COEFF[i];
839 float fval1 = SDS_SNRE / 268435456.0,
842 if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
853 fval4 = -10.0 * log10(fval1);
855 for (int i=0; i < 5; ++i)
856 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
860 ret = (int)(snr_in_db * 100);
862 else if (strstr(m_description, "Alps BSBE1 C01A") ||
863 strstr(m_description, "Alps -S(STV0288)"))
867 else if (snr == 0xFFFF) // i think this should not happen
871 enum { REALVAL, REGVAL };
872 const long CN_lookup[31][2] = {
873 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
874 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
875 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
876 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
877 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
878 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
881 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
882 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
886 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
891 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
896 ret = (((regval - CN_lookup[Imin][REGVAL])
897 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
898 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
899 + CN_lookup[Imin][REALVAL]) * 10;
905 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
906 !strcmp(m_description, "Alps -S") ||
907 !strcmp(m_description, "Philips -S") ||
908 !strcmp(m_description, "LG -S") )
911 ret = (int)((snr-39075)/17.647);
912 } else if (!strcmp(m_description, "Alps BSBE2"))
914 ret = (int)((snr >> 7) * 10);
915 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
917 int mse = (~snr) & 0xFF;
918 switch (parm_u_qam_modulation) {
919 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
920 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
921 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
922 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
923 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
926 } else if (!strcmp(m_description, "Philips TU1216"))
928 snr = 0xFF - (snr & 0xFF);
930 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
932 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
933 ret = (snr * 100) >> 8;
934 else if (!strcmp(m_description, "CXD1981"))
936 int mse = (~snr) & 0xFF;
937 switch (parm_u_qam_modulation) {
940 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
942 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
948 if (type == signalQuality)
950 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
954 oparm.getSystem(type);
958 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
959 case feCable: // we assume a max of 42db here
960 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
961 case feTerrestrial: // we assume a max of 24db here
962 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
966 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
974 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
975 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
984 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
985 eDebug("FE_READ_STATUS failed (%m)");
986 return !!(status&FE_HAS_LOCK);
995 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
996 eDebug("FE_READ_STATUS failed (%m)");
997 return !!(status&FE_HAS_SYNC);
1001 case frontendNumber:
1004 return m_is_usbtuner;
1009 void PutToDict(ePyObject &dict, const char*key, long value)
1011 ePyObject item = PyInt_FromLong(value);
1014 if (PyDict_SetItemString(dict, key, item))
1015 eDebug("put %s to dict failed", key);
1019 eDebug("could not create PyObject for %s", key);
1022 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
1026 if (PyDict_SetItemString(dict, key, item))
1027 eDebug("put %s to dict failed", key);
1031 eDebug("invalid PyObject for %s", key);
1034 void PutToDict(ePyObject &dict, const char*key, const char *value)
1036 ePyObject item = PyString_FromString(value);
1039 if (PyDict_SetItemString(dict, key, item))
1040 eDebug("put %s to dict failed", key);
1044 eDebug("could not create PyObject for %s", key);
1047 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1049 PutToDict(dict, "tuner_type", "DVB-S");
1050 PutToDict(dict, "frequency", feparm.frequency);
1051 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1052 PutToDict(dict, "orbital_position", feparm.orbital_position);
1053 PutToDict(dict, "inversion", feparm.inversion);
1054 PutToDict(dict, "fec_inner", feparm.fec);
1055 PutToDict(dict, "modulation", feparm.modulation);
1056 PutToDict(dict, "polarization", feparm.polarisation);
1057 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1059 PutToDict(dict, "rolloff", feparm.rolloff);
1060 PutToDict(dict, "pilot", feparm.pilot);
1062 PutToDict(dict, "system", feparm.system);
1065 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1067 PutToDict(dict, "tuner_type", "DVB-T");
1068 PutToDict(dict, "frequency", feparm.frequency);
1069 PutToDict(dict, "bandwidth", feparm.bandwidth);
1070 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1071 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1072 PutToDict(dict, "constellation", feparm.modulation);
1073 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1074 PutToDict(dict, "guard_interval", feparm.guard_interval);
1075 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1076 PutToDict(dict, "inversion", feparm.inversion);
1077 PutToDict(dict, "system", feparm.system);
1078 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1080 PutToDict(dict, "plp_id", feparm.plpid);
1084 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1086 PutToDict(dict, "tuner_type", "DVB-C");
1087 PutToDict(dict, "frequency", feparm.frequency);
1088 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1089 PutToDict(dict, "modulation", feparm.modulation);
1090 PutToDict(dict, "inversion", feparm.inversion);
1091 PutToDict(dict, "fec_inner", feparm.fec_inner);
1094 static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, int orbital_position, int polarization)
1097 int p_system = p[0].u.data;
1098 int p_frequency = p[1].u.data;
1099 int p_inversion = p[2].u.data;
1100 int p_modulation = p[3].u.data;
1101 int p_symbolrate = p[4].u.data;
1102 int p_inner_fec = p[5].u.data;
1103 int p_rolloff = p[6].u.data;
1104 int p_pilot = p[7].u.data;
1106 int frequency = p_frequency + freq_offset;
1107 PutToDict(dict, "frequency", frequency);
1108 PutToDict(dict, "symbol_rate", p_symbolrate);
1109 PutToDict(dict, "orbital_position", orbital_position);
1110 PutToDict(dict, "polarization", polarization);
1114 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1115 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1116 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1117 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1118 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1119 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1120 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1121 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1122 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1123 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1124 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1125 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1127 PutToDict(dict, "fec_inner", tmp);
1131 default: eDebug("got unsupported system from frontend! report as DVBS!");
1132 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1137 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1138 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1139 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1140 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1142 PutToDict(dict, "rolloff", tmp);
1146 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1147 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1148 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1150 PutToDict(dict, "pilot", tmp);
1152 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1155 PutToDict(dict, "system", tmp);
1157 switch (p_modulation)
1159 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1160 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1161 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1163 PutToDict(dict, "modulation", tmp);
1167 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1168 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1169 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1171 PutToDict(dict, "inversion", tmp);
1174 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1177 int p_system = p[0].u.data;
1178 int p_frequency = p[1].u.data;
1179 int p_inversion = p[2].u.data;
1180 int p_modulation = p[3].u.data;
1181 int p_symbolrate = p[4].u.data;
1182 int p_inner_fec = p[5].u.data;
1184 tmp = p_frequency/1000;
1185 PutToDict(dict, "frequency", tmp);
1187 PutToDict(dict, "symbol_rate", p_inversion);
1189 switch (p_inner_fec)
1191 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1192 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1193 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1194 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1195 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1196 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1197 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1199 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1201 PutToDict(dict, "fec_inner", tmp);
1203 switch (p_modulation)
1205 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1206 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1207 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1208 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1209 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1211 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1213 PutToDict(dict, "modulation", tmp);
1215 switch (p_inversion)
1217 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1218 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1220 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1222 PutToDict(dict, "inversion", tmp);
1225 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1228 int p_system = p[0].u.data;
1229 int p_frequency = p[1].u.data;
1230 int p_inversion = p[2].u.data;
1231 int p_constellation = p[3].u.data;
1232 int p_bandwidth = p[4].u.data;
1233 int p_coderate_lp = p[5].u.data;
1234 int p_coderate_hp = p[6].u.data;
1235 int p_transmission_mode = p[7].u.data;
1236 int p_guard_interval = p[8].u.data;
1237 int p_hierarchy = p[9].u.data;
1238 #if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID)
1239 int p_plp_id = p[10].u.data;
1245 default: eDebug("got unsupported system from frontend! report as DVBT!");
1246 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1249 #if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID)
1251 PutToDict(dict, "plp_id", tmp);
1253 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1256 PutToDict(dict, "system", tmp);
1259 PutToDict(dict, "frequency", tmp);
1261 switch (p_bandwidth)
1263 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1264 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1265 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1266 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1267 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1268 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1270 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1272 PutToDict(dict, "bandwidth", tmp);
1274 switch (p_coderate_lp)
1276 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1277 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1278 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1279 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1280 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1281 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1282 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1283 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1285 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1287 PutToDict(dict, "code_rate_lp", tmp);
1289 switch (p_coderate_hp)
1291 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1292 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1293 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1294 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1295 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1296 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1297 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1298 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1300 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1302 PutToDict(dict, "code_rate_hp", tmp);
1304 switch (p_constellation)
1306 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1307 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1308 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1309 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1311 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1313 PutToDict(dict, "constellation", tmp);
1316 switch (p_transmission_mode)
1318 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1319 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1320 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1321 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1322 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1323 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1325 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1327 PutToDict(dict, "transmission_mode", tmp);
1329 switch (p_guard_interval)
1331 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1332 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1333 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1334 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1335 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1336 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1337 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1339 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1341 PutToDict(dict, "guard_interval", tmp);
1343 switch (p_hierarchy)
1345 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1346 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1347 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1348 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1350 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1352 PutToDict(dict, "hierarchy_information", tmp);
1354 switch (p_inversion)
1356 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1357 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1359 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1361 PutToDict(dict, "inversion", tmp);
1364 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1366 if (dest && PyDict_Check(dest))
1368 const char *tmp = "UNKNOWN";
1389 PutToDict(dest, "tuner_state", tmp);
1390 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1391 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1392 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1393 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1394 int sigQualitydB = readFrontendData(signalQualitydB);
1395 if (sigQualitydB == 0x12345678) // not support yet
1397 ePyObject obj=Py_None;
1399 PutToDict(dest, "tuner_signal_quality_db", obj);
1402 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1403 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1407 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1409 if (dest && PyDict_Check(dest))
1412 FRONTENDPARAMETERS front;
1413 struct dtv_property p[16];
1414 struct dtv_properties cmdseq;
1417 oparm.getSystem(type);
1419 p[cmdseq.num++].cmd = DTV_DELIVERY_SYSTEM;
1420 p[cmdseq.num++].cmd = DTV_FREQUENCY;
1421 p[cmdseq.num++].cmd = DTV_INVERSION;
1422 p[cmdseq.num++].cmd = DTV_MODULATION;
1423 if(type == feSatellite)
1425 p[cmdseq.num++].cmd = DTV_SYMBOL_RATE;
1426 p[cmdseq.num++].cmd = DTV_INNER_FEC;
1427 p[cmdseq.num++].cmd = DTV_ROLLOFF;
1428 p[cmdseq.num++].cmd = DTV_PILOT;
1430 else if(type == feCable)
1432 p[cmdseq.num++].cmd = DTV_SYMBOL_RATE;
1433 p[cmdseq.num++].cmd = DTV_INNER_FEC;
1435 else if(type == feTerrestrial)
1437 p[cmdseq.num++].cmd = DTV_BANDWIDTH_HZ;
1438 p[cmdseq.num++].cmd = DTV_CODE_RATE_LP;
1439 p[cmdseq.num++].cmd = DTV_CODE_RATE_HP;
1440 p[cmdseq.num++].cmd = DTV_TRANSMISSION_MODE;
1441 p[cmdseq.num++].cmd = DTV_GUARD_INTERVAL;
1442 p[cmdseq.num++].cmd = DTV_HIERARCHY;
1443 #if defined DTV_STREAM_ID
1444 p[cmdseq.num++].cmd = DTV_STREAM_ID;
1445 #elif defined DTV_DVBT2_PLP_ID
1446 p[cmdseq.num++].cmd = DTV_DVBT2_PLP_ID;
1450 if (m_simulate || m_fd == -1 || original)
1454 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1456 eDebug("FE_GET_PROPERTY failed (%m)");
1459 else if (type == feSatellite && // use for DVB-S(2) only
1460 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1462 eDebug("FE_GET_FRONTEND failed (%m)");
1470 eDVBFrontendParametersSatellite sparm;
1471 oparm.getDVBS(sparm);
1472 PutSatelliteDataToDict(dest, sparm);
1475 eDVBFrontendParametersCable cparm;
1476 oparm.getDVBC(cparm);
1477 PutCableDataToDict(dest, cparm);
1480 eDVBFrontendParametersTerrestrial tparm;
1481 oparm.getDVBT(tparm);
1482 PutTerrestrialDataToDict(dest, tparm);
1488 FRONTENDPARAMETERS &parm = front;
1492 eDVBFrontendParametersSatellite sparm;
1493 oparm.getDVBS(sparm);
1494 fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1497 fillDictWithCableData(dest, p);
1500 fillDictWithTerrestrialData(dest, p);
1507 void eDVBFrontend::getFrontendData(ePyObject dest)
1509 if (dest && PyDict_Check(dest))
1512 PutToDict(dest, "tuner_number", m_slotid);
1514 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
1518 #if defined SYS_DVBC_ANNEX_A
1519 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1521 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1526 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1534 PutToDict(dest, "tuner_type", tmp);
1538 #ifndef FP_IOCTL_GET_ID
1539 #define FP_IOCTL_GET_ID 0
1541 int eDVBFrontend::readInputpower()
1545 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1547 char proc_name2[64];
1548 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1549 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1551 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1553 if (fscanf(f, "%d", &power) != 1)
1554 eDebug("read %s failed!! (%m)", proc_name);
1556 eDebug("%s is %d\n", proc_name, power);
1561 // open front prozessor
1562 int fp=::open("/dev/dbox/fp0", O_RDWR);
1565 eDebug("couldn't open fp");
1568 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1569 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1571 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1580 bool eDVBFrontend::setSecSequencePos(int steps)
1582 eDebugNoSimulate("set sequence pos %d", steps);
1587 if (m_sec_sequence.current() != m_sec_sequence.end())
1588 ++m_sec_sequence.current();
1593 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1594 --m_sec_sequence.current();
1600 void eDVBFrontend::tuneLoop()
1605 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1608 eDVBFrontend *sec_fe = this;
1609 eDVBRegisteredFrontend *regFE = 0;
1610 long tmp = m_data[LINKED_PREV_PTR];
1613 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1614 sec_fe = prev->m_frontend;
1615 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1616 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1617 int state = sec_fe->m_state;
1618 #if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
1619 // workaround to put the kernel frontend thread into idle state!
1620 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1622 sec_fe->closeFrontend(true);
1623 state = sec_fe->m_state;
1626 // sec_fe is closed... we must reopen it here..
1627 if (state == stateClosed)
1635 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1637 long *sec_fe_data = sec_fe->m_data;
1638 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1640 switch (m_sec_sequence.current()->cmd)
1642 case eSecCommand::SLEEP:
1643 delay = m_sec_sequence.current()++->msec;
1644 eDebugNoSimulate("[SEC] sleep %dms", delay);
1646 case eSecCommand::GOTO:
1647 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1648 ++m_sec_sequence.current();
1650 case eSecCommand::SET_VOLTAGE:
1652 int voltage = m_sec_sequence.current()++->voltage;
1653 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1654 sec_fe->setVoltage(voltage);
1657 case eSecCommand::IF_VOLTAGE_GOTO:
1659 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1660 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1662 ++m_sec_sequence.current();
1665 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1667 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1668 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1670 ++m_sec_sequence.current();
1673 case eSecCommand::IF_TONE_GOTO:
1675 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1676 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1678 ++m_sec_sequence.current();
1681 case eSecCommand::IF_NOT_TONE_GOTO:
1683 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1684 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1686 ++m_sec_sequence.current();
1689 case eSecCommand::SET_TONE:
1690 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1691 sec_fe->setTone(m_sec_sequence.current()++->tone);
1693 case eSecCommand::SEND_DISEQC:
1694 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1695 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1696 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1697 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1698 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1699 eDebugNoSimulate("(DiSEqC reset)");
1700 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1701 eDebugNoSimulate("(DiSEqC peripherial power on)");
1703 eDebugNoSimulate("");
1704 ++m_sec_sequence.current();
1706 case eSecCommand::SEND_TONEBURST:
1707 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1708 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1710 case eSecCommand::SET_FRONTEND:
1712 int enableEvents = (m_sec_sequence.current()++)->val;
1713 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1714 setFrontend(enableEvents);
1717 case eSecCommand::START_TUNE_TIMEOUT:
1719 int tuneTimeout = m_sec_sequence.current()->timeout;
1720 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1722 m_timeout->start(tuneTimeout, 1);
1723 ++m_sec_sequence.current();
1726 case eSecCommand::SET_TIMEOUT:
1727 m_timeoutCount = m_sec_sequence.current()++->val;
1728 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1730 case eSecCommand::IF_TIMEOUT_GOTO:
1731 if (!m_timeoutCount)
1733 eDebugNoSimulate("[SEC] rotor timout");
1734 setSecSequencePos(m_sec_sequence.current()->steps);
1737 ++m_sec_sequence.current();
1739 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1741 int idx = m_sec_sequence.current()++->val;
1742 if ( idx == 0 || idx == 1 )
1744 m_idleInputpower[idx] = sec_fe->readInputpower();
1745 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1748 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1751 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1753 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1754 int idx = compare.val;
1755 if ( !m_simulate && (idx == 0 || idx == 1) )
1757 int idle = sec_fe->readInputpower();
1758 int diff = abs(idle-m_idleInputpower[idx]);
1761 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1762 setSecSequencePos(compare.steps);
1766 ++m_sec_sequence.current();
1769 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1771 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1774 setSecSequencePos(cmd.steps);
1778 int isLocked = readFrontendData(locked);
1779 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1781 if (!m_timeoutCount && m_retryCount > 0)
1783 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1786 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1789 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1791 cmd.lastSignal = signal;
1794 if (cmd.okcount > 4)
1796 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1797 setSecSequencePos(cmd.steps);
1798 m_state = stateLock;
1799 m_stateChanged(this);
1800 feEvent(-1); // flush events
1808 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1810 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1814 ++m_sec_sequence.current();
1817 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1818 m_runningInputpower = sec_fe->readInputpower();
1819 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
1820 ++m_sec_sequence.current();
1822 case eSecCommand::SET_ROTOR_MOVING:
1824 m_sec->setRotorMoving(m_slotid, true);
1825 ++m_sec_sequence.current();
1827 case eSecCommand::SET_ROTOR_STOPPED:
1829 m_sec->setRotorMoving(m_slotid, false);
1830 ++m_sec_sequence.current();
1832 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1834 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1837 setSecSequencePos(cmd.steps);
1840 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
1841 const char *txt = cmd.direction ? "running" : "stopped";
1843 if (!m_timeoutCount && m_retryCount > 0)
1845 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1847 m_runningInputpower,
1850 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1851 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1854 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1855 if ( cmd.okcount > 6 )
1857 eDebugNoSimulate("[SEC] rotor is %s", txt);
1858 if (setSecSequencePos(cmd.steps))
1864 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1867 ++m_sec_sequence.current();
1870 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1871 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
1872 setSecSequencePos(m_sec_sequence.current()->steps);
1874 ++m_sec_sequence.current();
1876 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
1877 eDebugNoSimulate("[SEC] invalidate current switch params");
1878 sec_fe_data[CSW] = -1;
1879 sec_fe_data[UCSW] = -1;
1880 sec_fe_data[TONEBURST] = -1;
1881 ++m_sec_sequence.current();
1883 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
1884 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
1885 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
1886 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
1887 eDebugNoSimulate("[SEC] update current switch params");
1888 ++m_sec_sequence.current();
1890 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1891 eDebugNoSimulate("[SEC] invalidate current rotorparams");
1892 sec_fe_data[ROTOR_CMD] = -1;
1893 sec_fe_data[ROTOR_POS] = -1;
1894 ++m_sec_sequence.current();
1896 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1897 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
1898 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
1899 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
1900 ++m_sec_sequence.current();
1902 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1903 m_retryCount = m_sec_sequence.current()++->val;
1904 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
1906 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1909 eDebugNoSimulate("[SEC] no more rotor retrys");
1910 setSecSequencePos(m_sec_sequence.current()->steps);
1913 ++m_sec_sequence.current();
1915 case eSecCommand::SET_POWER_LIMITING_MODE:
1920 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
1921 FILE *f=fopen(proc_name, "w");
1922 if (f) // new interface exist?
1924 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1925 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1926 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
1928 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1931 else if (sec_fe->m_need_rotor_workaround)
1934 int slotid = sec_fe->m_slotid;
1935 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1937 sprintf(dev, "/dev/i2c-%d", slotid);
1938 else if (slotid == 2)
1939 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
1940 else if (slotid == 3)
1941 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
1942 int fd = ::open(dev, O_RDWR);
1944 unsigned char data[2];
1945 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1946 if(::read(fd, data, 1) != 1)
1947 eDebugNoSimulate("[SEC] error read lnbp (%m)");
1948 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
1950 data[0] |= 0x80; // enable static current limiting
1951 eDebugNoSimulate("[SEC] set static current limiting");
1955 data[0] &= ~0x80; // enable dynamic current limiting
1956 eDebugNoSimulate("[SEC] set dynamic current limiting");
1958 if(::write(fd, data, 1) != 1)
1959 eDebugNoSimulate("[SEC] error write lnbp (%m)");
1963 ++m_sec_sequence.current();
1966 case eSecCommand::DELAYED_CLOSE_FRONTEND:
1968 eDebugNoSimulate("[SEC] delayed close frontend");
1969 closeFrontend(false, true);
1970 ++m_sec_sequence.current();
1974 eDebugNoSimulate("[SEC] unhandled sec command %d",
1975 ++m_sec_sequence.current()->cmd);
1976 ++m_sec_sequence.current();
1979 m_tuneTimer->start(delay,true);
1983 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
1988 void eDVBFrontend::setFrontend(bool recvEvents)
1992 eDebug("setting frontend %d", m_dvbid);
1995 oparm.getSystem(type);
1999 feEvent(-1); // flush events
2000 if (type == iDVBFrontend::feSatellite)
2002 fe_rolloff_t rolloff = ROLLOFF_35;
2003 fe_pilot_t pilot = PILOT_OFF;
2004 fe_modulation_t modulation = QPSK;
2005 fe_delivery_system_t system = SYS_DVBS;
2006 eDVBFrontendParametersSatellite sparm;
2007 oparm.getDVBS(sparm);
2008 switch(sparm.system)
2010 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
2011 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
2013 switch(sparm.modulation)
2015 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
2016 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
2017 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
2021 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
2022 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
2023 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
2025 switch(sparm.rolloff)
2027 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
2028 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
2029 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
2031 struct dtv_property p[10];
2032 struct dtv_properties cmdseq;
2034 p[0].cmd = DTV_CLEAR;
2035 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2036 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2037 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2038 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2039 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2040 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2041 if (system == SYS_DVBS2)
2043 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2044 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2045 p[9].cmd = DTV_TUNE;
2050 p[7].cmd = DTV_TUNE;
2053 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2055 perror("FE_SET_PROPERTY failed");
2059 else if (type == iDVBFrontend::feCable)
2061 struct dtv_property p[8];
2062 struct dtv_properties cmdseq;
2064 p[0].cmd = DTV_CLEAR;
2065 #if defined SYS_DVBC_ANNEX_A
2066 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2068 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2070 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2071 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2072 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2073 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2074 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2075 p[7].cmd = DTV_TUNE;
2077 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2079 perror("FE_SET_PROPERTY failed");
2083 else if (type == iDVBFrontend::feTerrestrial)
2085 fe_delivery_system_t system = SYS_DVBT;
2086 eDVBFrontendParametersTerrestrial tparm;
2087 oparm.getDVBT(tparm);
2088 switch (tparm.system)
2091 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2092 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2095 switch (tparm.bandwidth)
2097 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2098 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2099 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2101 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2102 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2103 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2104 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2106 struct dtv_property p[13];
2107 struct dtv_properties cmdseq;
2110 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2111 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2112 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2113 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2114 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2115 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2116 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2117 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2118 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2119 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2120 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2121 #if defined DTV_STREAM_ID
2122 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2123 #elif defined DTV_DVBT2_PLP_ID
2124 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2126 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2127 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2129 perror("FE_SET_PROPERTY failed");
2135 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2137 perror("FE_SET_FRONTEND failed");
2144 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2149 eWarning("no SEC module active!");
2152 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2155 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",
2158 feparm.polarisation,
2162 feparm.orbital_position,
2167 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2168 switch (feparm.inversion)
2170 case eDVBFrontendParametersSatellite::Inversion_On:
2171 parm_inversion = INVERSION_ON;
2173 case eDVBFrontendParametersSatellite::Inversion_Off:
2174 parm_inversion = INVERSION_OFF;
2177 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2178 parm_inversion = INVERSION_AUTO;
2181 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2185 case eDVBFrontendParametersSatellite::FEC_None:
2186 parm_u_qpsk_fec_inner = FEC_NONE;
2188 case eDVBFrontendParametersSatellite::FEC_1_2:
2189 parm_u_qpsk_fec_inner = FEC_1_2;
2191 case eDVBFrontendParametersSatellite::FEC_2_3:
2192 parm_u_qpsk_fec_inner = FEC_2_3;
2194 case eDVBFrontendParametersSatellite::FEC_3_4:
2195 parm_u_qpsk_fec_inner = FEC_3_4;
2197 case eDVBFrontendParametersSatellite::FEC_5_6:
2198 parm_u_qpsk_fec_inner = FEC_5_6;
2200 case eDVBFrontendParametersSatellite::FEC_7_8:
2201 parm_u_qpsk_fec_inner = FEC_7_8;
2204 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2205 case eDVBFrontendParametersSatellite::FEC_Auto:
2206 parm_u_qpsk_fec_inner = FEC_AUTO;
2214 case eDVBFrontendParametersSatellite::FEC_1_2:
2215 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2217 case eDVBFrontendParametersSatellite::FEC_2_3:
2218 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2220 case eDVBFrontendParametersSatellite::FEC_3_4:
2221 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2223 case eDVBFrontendParametersSatellite::FEC_3_5:
2224 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2226 case eDVBFrontendParametersSatellite::FEC_4_5:
2227 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2229 case eDVBFrontendParametersSatellite::FEC_5_6:
2230 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2232 case eDVBFrontendParametersSatellite::FEC_7_8:
2233 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2235 case eDVBFrontendParametersSatellite::FEC_8_9:
2236 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2238 case eDVBFrontendParametersSatellite::FEC_9_10:
2239 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2242 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2246 // FIXME !!! get frequency range from tuner
2247 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2249 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2252 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2254 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2258 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2260 parm_frequency = feparm.frequency * 1000;
2261 parm_u_qam_symbol_rate = feparm.symbol_rate;
2262 switch (feparm.modulation)
2264 case eDVBFrontendParametersCable::Modulation_QAM16:
2265 parm_u_qam_modulation = QAM_16;
2267 case eDVBFrontendParametersCable::Modulation_QAM32:
2268 parm_u_qam_modulation = QAM_32;
2270 case eDVBFrontendParametersCable::Modulation_QAM64:
2271 parm_u_qam_modulation = QAM_64;
2273 case eDVBFrontendParametersCable::Modulation_QAM128:
2274 parm_u_qam_modulation = QAM_128;
2276 case eDVBFrontendParametersCable::Modulation_QAM256:
2277 parm_u_qam_modulation = QAM_256;
2280 case eDVBFrontendParametersCable::Modulation_Auto:
2281 parm_u_qam_modulation = QAM_AUTO;
2284 switch (feparm.inversion)
2286 case eDVBFrontendParametersCable::Inversion_On:
2287 parm_inversion = INVERSION_ON;
2289 case eDVBFrontendParametersCable::Inversion_Off:
2290 parm_inversion = INVERSION_OFF;
2293 case eDVBFrontendParametersCable::Inversion_Unknown:
2294 parm_inversion = INVERSION_AUTO;
2297 switch (feparm.fec_inner)
2299 case eDVBFrontendParametersCable::FEC_None:
2300 parm_u_qam_fec_inner = FEC_NONE;
2302 case eDVBFrontendParametersCable::FEC_1_2:
2303 parm_u_qam_fec_inner = FEC_1_2;
2305 case eDVBFrontendParametersCable::FEC_2_3:
2306 parm_u_qam_fec_inner = FEC_2_3;
2308 case eDVBFrontendParametersCable::FEC_3_4:
2309 parm_u_qam_fec_inner = FEC_3_4;
2311 case eDVBFrontendParametersCable::FEC_5_6:
2312 parm_u_qam_fec_inner = FEC_5_6;
2314 case eDVBFrontendParametersCable::FEC_7_8:
2315 parm_u_qam_fec_inner = FEC_7_8;
2317 case eDVBFrontendParametersCable::FEC_8_9:
2318 parm_u_qam_fec_inner = FEC_8_9;
2321 case eDVBFrontendParametersCable::FEC_Auto:
2322 parm_u_qam_fec_inner = FEC_AUTO;
2325 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2326 parm_frequency/1000,
2327 parm_u_qam_symbol_rate,
2328 parm_u_qam_fec_inner,
2329 parm_u_qam_modulation,
2331 oparm.setDVBC(feparm);
2335 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2337 parm_frequency = feparm.frequency;
2339 switch (feparm.bandwidth)
2341 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2342 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2344 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2345 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2347 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2348 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2350 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2351 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2353 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2354 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2356 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2357 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2360 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2361 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2364 switch (feparm.code_rate_LP)
2366 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2367 parm_u_ofdm_code_rate_LP = FEC_1_2;
2369 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2370 parm_u_ofdm_code_rate_LP = FEC_2_3;
2372 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2373 parm_u_ofdm_code_rate_LP = FEC_3_4;
2375 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2376 parm_u_ofdm_code_rate_LP = FEC_5_6;
2378 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2379 parm_u_ofdm_code_rate_LP = FEC_7_8;
2381 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2382 parm_u_ofdm_code_rate_LP = FEC_6_7;
2384 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2385 parm_u_ofdm_code_rate_LP = FEC_8_9;
2388 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2389 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2392 switch (feparm.code_rate_HP)
2394 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2395 parm_u_ofdm_code_rate_HP = FEC_1_2;
2397 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2398 parm_u_ofdm_code_rate_HP = FEC_2_3;
2400 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2401 parm_u_ofdm_code_rate_HP = FEC_3_4;
2403 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2404 parm_u_ofdm_code_rate_HP = FEC_5_6;
2406 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2407 parm_u_ofdm_code_rate_HP = FEC_7_8;
2409 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2410 parm_u_ofdm_code_rate_HP = FEC_6_7;
2412 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2413 parm_u_ofdm_code_rate_HP = FEC_8_9;
2416 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2417 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2420 switch (feparm.modulation)
2422 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2423 parm_u_ofdm_constellation = QPSK;
2425 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2426 parm_u_ofdm_constellation = QAM_16;
2428 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2429 parm_u_ofdm_constellation = QAM_64;
2431 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2432 parm_u_ofdm_constellation = QAM_256;
2435 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2436 parm_u_ofdm_constellation = QAM_AUTO;
2439 switch (feparm.transmission_mode)
2441 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2442 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2444 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2445 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2447 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2448 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2450 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2451 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2453 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2454 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2456 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2457 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2460 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2461 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2464 switch (feparm.guard_interval)
2466 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2467 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2469 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2470 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2472 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2473 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2475 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2476 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2478 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2479 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2481 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2482 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2484 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2485 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2488 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2489 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2492 switch (feparm.hierarchy)
2494 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2495 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2497 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2498 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2500 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2501 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2503 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2504 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2507 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2508 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2511 switch (feparm.inversion)
2513 case eDVBFrontendParametersTerrestrial::Inversion_On:
2514 parm_inversion = INVERSION_ON;
2516 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2517 parm_inversion = INVERSION_OFF;
2520 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2521 parm_inversion = INVERSION_AUTO;
2524 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",
2525 parm_frequency/1000,
2526 parm_u_ofdm_bandwidth,
2527 parm_u_ofdm_code_rate_LP,
2528 parm_u_ofdm_code_rate_HP,
2529 parm_u_ofdm_constellation,
2530 parm_u_ofdm_transmission_mode,
2531 parm_u_ofdm_guard_interval,
2532 parm_u_ofdm_hierarchy_information,
2536 oparm.setDVBT(feparm);
2540 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2542 unsigned int timeout = 5000;
2543 eDebugNoSimulate("(%d)tune", m_dvbid);
2550 if (where.getSystem(type) < 0)
2556 if (!m_sn && !m_simulate)
2558 eDebug("no frontend device opened... do not try to tune !!!");
2566 m_sec_sequence.clear();
2568 where.calcLockTimeout(timeout);
2574 eDVBFrontendParametersSatellite feparm;
2575 if (where.getDVBS(feparm))
2577 eDebug("no dvbs data!");
2581 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2583 eDVBFrontend *sec_fe = this;
2584 long tmp = m_data[LINKED_PREV_PTR];
2587 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2588 sec_fe = linked_fe->m_frontend;
2589 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2591 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2592 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
2594 m_rotor_mode = feparm.no_rotor_command_on_tune;
2596 m_sec->setRotorMoving(m_slotid, false);
2597 res=prepare_sat(feparm, timeout);
2605 eDVBFrontendParametersCable feparm;
2606 if (where.getDVBC(feparm))
2611 res=prepare_cable(feparm);
2615 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2616 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2621 eDVBFrontendParametersTerrestrial feparm;
2622 if (where.getDVBT(feparm))
2624 eDebug("no -T data");
2628 res=prepare_terrestrial(feparm);
2632 std::string enable_5V;
2633 char configStr[255];
2634 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2635 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2636 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2637 if (enable_5V == "True")
2638 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2640 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2641 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2652 m_sec_sequence.current() = m_sec_sequence.begin();
2656 m_tuneTimer->start(0,true);
2658 if (m_state != stateTuning)
2660 m_state = stateTuning;
2661 m_stateChanged(this);
2670 m_tuneTimer->stop();
2674 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2676 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2680 RESULT eDVBFrontend::setVoltage(int voltage)
2682 bool increased=false;
2683 fe_sec_voltage_t vlt;
2684 m_data[CUR_VOLTAGE]=voltage;
2688 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2689 vlt = SEC_VOLTAGE_OFF;
2694 vlt = SEC_VOLTAGE_13;
2699 vlt = SEC_VOLTAGE_18;
2707 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
2708 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2711 RESULT eDVBFrontend::getState(int &state)
2717 RESULT eDVBFrontend::setTone(int t)
2719 fe_sec_tone_mode_t tone;
2727 tone = SEC_TONE_OFF;
2735 return ::ioctl(m_fd, FE_SET_TONE, tone);
2738 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2743 struct dvb_diseqc_master_cmd cmd;
2744 memcpy(cmd.msg, diseqc.data, diseqc.len);
2745 cmd.msg_len = diseqc.len;
2746 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2751 RESULT eDVBFrontend::sendToneburst(int burst)
2755 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2756 if ( burst == eDVBSatelliteDiseqcParameters::A )
2758 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2760 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2765 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2771 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
2773 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
2774 m_sec_sequence.push_back(list);
2776 m_sec_sequence = list;
2780 bool eDVBFrontend::isScheduledSendDiseqc()
2782 bool has_senddiseqc = false;
2783 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
2785 eSecCommandList::iterator cur = m_sec_sequence.current();
2786 while(cur != m_sec_sequence.end())
2788 if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
2790 has_senddiseqc = true;
2795 return has_senddiseqc;
2798 RESULT eDVBFrontend::getData(int num, long &data)
2800 if ( num < NUM_DATA_ENTRIES )
2808 RESULT eDVBFrontend::setData(int num, long val)
2810 if ( num < NUM_DATA_ENTRIES )
2818 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2822 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
2824 if (feparm->getSystem(type) || !m_enabled)
2827 if (type == eDVBFrontend::feSatellite)
2829 eDVBFrontendParametersSatellite sat_parm;
2830 bool can_handle_dvbs, can_handle_dvbs2;
2831 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
2832 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
2833 if (feparm->getDVBS(sat_parm) < 0)
2837 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
2841 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
2845 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
2846 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
2848 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
2853 else if (type == eDVBFrontend::feCable)
2855 eDVBFrontendParametersCable cab_parm;
2856 if (feparm->getDVBC(cab_parm) < 0)
2860 #if defined SYS_DVBC_ANNEX_A
2861 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
2863 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
2871 else if (type == eDVBFrontend::feTerrestrial)
2873 eDVBFrontendParametersTerrestrial ter_parm;
2874 bool can_handle_dvbt, can_handle_dvbt2;
2875 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
2876 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
2877 if (feparm->getDVBT(ter_parm) < 0)
2881 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
2885 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
2890 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
2892 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
2897 if (score && preferred)
2899 /* make 'sure' we always prefer this frontend */
2906 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
2908 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
2909 if (it != m_delsys.end() && it->second)
2911 if (obeywhitelist && !m_delsys_whitelist.empty())
2913 it = m_delsys_whitelist.find(sys);
2914 if (it == m_delsys_whitelist.end() || !it->second) return false;
2921 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
2923 m_delsys_whitelist.clear();
2924 for (unsigned int i = 0; i < whitelist.size(); i++)
2926 m_delsys_whitelist[whitelist[i]] = true;
2930 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
2934 bool eDVBFrontend::setSlotInfo(ePyObject obj)
2936 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
2937 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
2939 Id = PyTuple_GET_ITEM(obj, 0);
2940 Descr = PyTuple_GET_ITEM(obj, 1);
2941 Enabled = PyTuple_GET_ITEM(obj, 2);
2942 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
2943 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
2944 frontendId = PyTuple_GET_ITEM(obj, 5);
2945 m_slotid = PyInt_AsLong(Id);
2946 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
2948 strcpy(m_description, PyString_AS_STRING(Descr));
2949 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
2950 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
2951 // m_slotid, m_description);
2954 m_enabled = (Enabled == Py_True);
2955 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
2956 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
2957 !!strstr(m_description, "Alps BSBE2") ||
2958 !!strstr(m_description, "Alps -S") ||
2959 !!strstr(m_description, "BCM4501");
2960 if (IsDVBS2 == Py_True)
2962 /* HACK for legacy dvb api without DELSYS support */
2963 m_delsys[SYS_DVBS2] = true;
2965 if (IsDVBT2 == Py_True)
2967 /* HACK for legacy dvb api without DELSYS support */
2968 m_delsys[SYS_DVBT2] = true;
2971 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
2972 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" );
2975 PyErr_SetString(PyExc_StandardError,
2976 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");