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 case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
182 case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
183 default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
185 switch (descriptor.getCodeRateHpStream())
187 case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
188 case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
189 case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
190 case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
191 case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
192 default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
194 switch (descriptor.getCodeRateLpStream())
196 case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
197 case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
198 case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
199 case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
200 case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
201 default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
203 switch (descriptor.getTransmissionMode())
205 case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
206 case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
207 case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
208 case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
209 case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
210 case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
211 default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
213 switch (descriptor.getGuardInterval())
215 case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
216 case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
217 case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
218 case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
219 case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
220 case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
221 case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
222 default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
224 // hierarchy = descriptor.getHierarchyInformation();
225 hierarchy = descriptor.getHierarchyInformation()&3;
226 if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4)
227 hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto;
228 modulation = descriptor.getConstellation();
229 if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64)
230 modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto;
231 inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown;
232 system = eDVBFrontendParametersTerrestrial::System_DVB_T;
234 eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d",
235 frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode,
236 guard_interval, hierarchy, modulation);
239 eDVBFrontendParameters::eDVBFrontendParameters()
240 :m_type(-1), m_flags(0)
244 DEFINE_REF(eDVBFrontendParameters);
246 RESULT eDVBFrontendParameters::getSystem(int &t) const
249 return (m_type == -1) ? -1 : 0;
252 RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const
254 if (m_type != iDVBFrontend::feSatellite)
260 RESULT eDVBFrontendParameters::getDVBC(eDVBFrontendParametersCable &p) const
262 if (m_type != iDVBFrontend::feCable)
268 RESULT eDVBFrontendParameters::getDVBT(eDVBFrontendParametersTerrestrial &p) const
270 if (m_type != iDVBFrontend::feTerrestrial)
276 RESULT eDVBFrontendParameters::setDVBS(const eDVBFrontendParametersSatellite &p, bool no_rotor_command_on_tune)
279 sat.no_rotor_command_on_tune = no_rotor_command_on_tune;
280 m_type = iDVBFrontend::feSatellite;
284 RESULT eDVBFrontendParameters::setDVBC(const eDVBFrontendParametersCable &p)
287 m_type = iDVBFrontend::feCable;
291 RESULT eDVBFrontendParameters::setDVBT(const eDVBFrontendParametersTerrestrial &p)
294 m_type = iDVBFrontend::feTerrestrial;
298 RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters *parm, int &diff, bool exact) const
303 if (parm->getSystem(type))
307 diff = 1<<30; // big difference
313 case iDVBFrontend::feSatellite:
315 eDVBFrontendParametersSatellite osat;
316 if (parm->getDVBS(osat))
319 if (sat.orbital_position != osat.orbital_position)
321 else if (sat.polarisation != osat.polarisation)
323 else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
325 else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
329 diff = abs(sat.frequency - osat.frequency);
330 diff += abs(sat.symbol_rate - osat.symbol_rate);
334 case iDVBFrontend::feCable:
335 eDVBFrontendParametersCable ocable;
336 if (parm->getDVBC(ocable))
339 if (exact && cable.modulation != ocable.modulation
340 && cable.modulation != eDVBFrontendParametersCable::Modulation_Auto
341 && ocable.modulation != eDVBFrontendParametersCable::Modulation_Auto)
343 else if (exact && cable.fec_inner != ocable.fec_inner && cable.fec_inner != eDVBFrontendParametersCable::FEC_Auto && ocable.fec_inner != eDVBFrontendParametersCable::FEC_Auto)
347 diff = abs(cable.frequency - ocable.frequency);
348 diff += abs(cable.symbol_rate - ocable.symbol_rate);
351 case iDVBFrontend::feTerrestrial:
352 eDVBFrontendParametersTerrestrial oterrestrial;
353 if (parm->getDVBT(oterrestrial))
355 if (exact && oterrestrial.bandwidth != terrestrial.bandwidth &&
356 oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto &&
357 terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto)
359 else if (exact && oterrestrial.modulation != terrestrial.modulation &&
360 oterrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto &&
361 terrestrial.modulation != eDVBFrontendParametersTerrestrial::Modulation_Auto)
363 else if (exact && oterrestrial.transmission_mode != terrestrial.transmission_mode &&
364 oterrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto &&
365 terrestrial.transmission_mode != eDVBFrontendParametersTerrestrial::TransmissionMode_Auto)
367 else if (exact && oterrestrial.guard_interval != terrestrial.guard_interval &&
368 oterrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto &&
369 terrestrial.guard_interval != eDVBFrontendParametersTerrestrial::GuardInterval_Auto)
371 else if (exact && oterrestrial.hierarchy != terrestrial.hierarchy &&
372 oterrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto &&
373 terrestrial.hierarchy != eDVBFrontendParametersTerrestrial::Hierarchy_Auto)
375 else if (exact && oterrestrial.code_rate_LP != terrestrial.code_rate_LP &&
376 oterrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
377 terrestrial.code_rate_LP != eDVBFrontendParametersTerrestrial::FEC_Auto)
379 else if (exact && oterrestrial.code_rate_HP != terrestrial.code_rate_HP &&
380 oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto &&
381 terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto)
383 else if (oterrestrial.system != terrestrial.system)
385 else if (oterrestrial.system == terrestrial.System_DVB_T2 &&
386 oterrestrial.plpid != terrestrial.plpid)
389 diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000;
397 RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const
401 case iDVBFrontend::feSatellite:
403 hash = (sat.orbital_position << 16);
404 hash |= ((sat.frequency/1000)&0xFFFF)|((sat.polarisation&1) << 15);
407 case iDVBFrontend::feCable:
409 hash |= (cable.frequency/1000)&0xFFFF;
411 case iDVBFrontend::feTerrestrial:
413 hash |= (terrestrial.frequency/1000000)&0xFFFF;
420 RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const
424 case iDVBFrontend::feSatellite:
426 /* high symbol rate transponders tune faster, due to
427 requiring less zigzag and giving more symbols faster.
429 5s are definitely not enough on really low SR when
430 zigzag has to find the exact frequency first.
432 if (sat.symbol_rate > 20000000)
434 else if (sat.symbol_rate > 10000000)
440 case iDVBFrontend::feCable:
443 case iDVBFrontend::feTerrestrial:
451 DEFINE_REF(eDVBFrontend);
453 int eDVBFrontend::PriorityOrder=0;
454 int eDVBFrontend::PreferredFrontendIndex=-1;
457 eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe)
458 :m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe)
459 ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false)
460 ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false), m_is_usbtuner(false)
462 sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe);
464 m_timeout = eTimer::create(eApp);
465 CONNECT(m_timeout->timeout, eDVBFrontend::timeout);
467 m_tuneTimer = eTimer::create(eApp);
468 CONNECT(m_tuneTimer->timeout, eDVBFrontend::tuneLoop);
470 for (int i=0; i<eDVBFrontend::NUM_DATA_ENTRIES; ++i)
473 m_idleInputpower[0]=m_idleInputpower[1]=0;
475 ok = !openFrontend();
479 void eDVBFrontend::reopenFrontend()
486 int eDVBFrontend::openFrontend()
488 if (m_state != stateClosed)
489 return -1; // already opened
494 dvb_frontend_info fe_info;
497 eDebug("opening frontend %d", m_dvbid);
500 m_fd = ::open(m_filename, O_RDWR|O_NONBLOCK);
503 eWarning("failed! (%s) %m", m_filename);
508 eWarning("frontend %d already opened", m_dvbid);
510 if (m_delsys.empty())
512 #ifdef DTV_ENUM_DELSYS
513 struct dtv_property p[1];
514 p[0].cmd = DTV_ENUM_DELSYS;
515 struct dtv_properties cmdseq;
518 if (::ioctl(m_fd, FE_GET_PROPERTY, &cmdseq) >= 0)
522 for (i = 0; i < p[0].u.buffer.len ; i++)
524 fe_delivery_system_t delsys = (fe_delivery_system_t)p[0].u.buffer.data[i];
525 m_delsys[delsys] = true;
529 if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
531 eWarning("ioctl FE_GET_INFO failed");
536 /* old DVB API, fill delsys map with some defaults */
537 switch (fe_info.type)
541 m_delsys[SYS_DVBS] = true;
542 #if DVB_API_VERSION >= 5
543 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
549 #if defined SYS_DVBC_ANNEX_A
550 m_delsys[SYS_DVBC_ANNEX_A] = true;
552 m_delsys[SYS_DVBC_ANNEX_AC] = true;
558 m_delsys[SYS_DVBT] = true;
559 #if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
560 if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
564 case FE_ATSC: // placeholder to prevent warning
574 m_simulate_fe->m_delsys = m_delsys;
577 m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
578 CONNECT(m_sn->activated, eDVBFrontend::feEvent);
581 setTone(iDVBFrontend::toneOff);
582 setVoltage(iDVBFrontend::voltageOff);
587 int eDVBFrontend::closeFrontend(bool force, bool no_delayed)
589 if (!force && m_data[CUR_VOLTAGE] != -1 && m_data[CUR_VOLTAGE] != iDVBFrontend::voltageOff)
591 long tmp = m_data[LINKED_NEXT_PTR];
594 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
595 if (linked_fe->m_inuse)
597 eDebugNoSimulate("dont close frontend %d until the linked frontend %d in slot %d is still in use",
598 m_dvbid, linked_fe->m_frontend->getDVBID(), linked_fe->m_frontend->getSlotID());
601 linked_fe->m_frontend->getData(LINKED_NEXT_PTR, tmp);
607 eDebugNoSimulate("close frontend %d", m_dvbid);
608 if (m_data[SATCR] != -1)
612 m_sec->prepareTurnOffSatCR(*this);
613 m_tuneTimer->start(0, true);
614 if(!m_tuneTimer->isActive())
617 eDebug("[turnOffSatCR] no mainloop");
620 timeout = tuneLoopInt();
623 usleep(timeout*1000); // blockierendes wait.. eTimer gibts ja nicht mehr
627 eDebug("[turnOffSatCR] running mainloop");
631 m_data[ROTOR_CMD] = -1;
634 setTone(iDVBFrontend::toneOff);
635 setVoltage(iDVBFrontend::voltageOff);
638 if (m_sec && !m_simulate)
639 m_sec->setRotorMoving(m_slotid, false);
643 eWarning("couldnt close frontend %d", m_dvbid);
647 setTone(iDVBFrontend::toneOff);
648 setVoltage(iDVBFrontend::voltageOff);
651 m_state = stateClosed;
656 eDVBFrontend::~eDVBFrontend()
658 m_data[LINKED_PREV_PTR] = m_data[LINKED_NEXT_PTR] = -1;
662 void eDVBFrontend::feEvent(int w)
664 eDVBFrontend *sec_fe = this;
665 long tmp = m_data[LINKED_PREV_PTR];
668 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
669 sec_fe = linked_fe->m_frontend;
670 sec_fe->getData(LINKED_NEXT_PTR, tmp);
674 dvb_frontend_event event;
677 res = ::ioctl(m_fd, FE_GET_EVENT, &event);
679 if (res && (errno == EAGAIN))
685 eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning);
686 if (event.status & FE_HAS_LOCK)
693 if (event.status & FE_TIMEDOUT) {
694 eDebug("FE_TIMEDOUT! ..abort");
703 eDebug("stateLostLock");
704 state = stateLostLock;
707 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
708 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
712 if (m_state != state)
715 m_stateChanged(this);
720 void eDVBFrontend::timeout()
723 if (m_state == stateTuning)
726 eDVBFrontend *sec_fe = this;
727 sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc
728 sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1;
730 m_state = stateFailed;
731 m_stateChanged(this);
735 #define INRANGE(X,Y,Z) (((X<=Y) && (Y<=Z))||((Z<=Y) && (Y<=X)) ? 1 : 0)
737 /* unsigned 32 bit division */
738 static inline uint32_t fe_udiv(uint32_t a, uint32_t b)
740 return (a + b / 2) / b;
743 int eDVBFrontend::readFrontendData(int type)
752 if (ioctl(m_fd, FE_READ_BER, &ber) < 0 && errno != ERANGE)
753 eDebug("FE_READ_BER failed (%m)");
758 case signalQualitydB: /* this will move into the driver */
760 int sat_max = 1600; // for stv0288 / bsbe2
761 int ret = 0x12345678;
765 if (ioctl(m_fd, FE_READ_SNR, &snr) < 0 && errno != ERANGE)
766 eDebug("FE_READ_SNR failed (%m)");
767 else if (!strcmp(m_description, "BCM4501 (internal)"))
769 float SDS_SNRE = snr << 16;
772 eDVBFrontendParametersSatellite sparm;
773 oparm.getDVBS(sparm);
775 if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK
777 static float SNR_COEFF[6] = {
780 197418.0 / 4194304.0,
781 -2602183.0 / 4194304.0,
782 20377212.0 / 4194304.0,
783 -37791203.0 / 4194304.0,
785 float fval1 = 12.44714 - (2.0 * log10(SDS_SNRE / 256.0)),
786 fval2 = pow(10.0, fval1)-1;
787 fval1 = 10.0 * log10(fval2);
791 fval2 = SNR_COEFF[0];
792 for (int i=1; i<6; ++i)
795 fval2 += SNR_COEFF[i];
803 float fval1 = SDS_SNRE / 268435456.0,
806 if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
817 fval4 = -10.0 * log10(fval1);
819 for (int i=0; i < 5; ++i)
820 fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2));
824 ret = (int)(snr_in_db * 100);
826 else if (strstr(m_description, "Alps BSBE1 C01A") ||
827 strstr(m_description, "Alps -S(STV0288)"))
831 else if (snr == 0xFFFF) // i think this should not happen
835 enum { REALVAL, REGVAL };
836 const long CN_lookup[31][2] = {
837 {20,8900}, {25,8680}, {30,8420}, {35,8217}, {40,7897},
838 {50,7333}, {60,6747}, {70,6162}, {80,5580}, {90,5029},
839 {100,4529}, {110,4080}, {120,3685}, {130,3316}, {140,2982},
840 {150,2688}, {160,2418}, {170,2188}, {180,1982}, {190,1802},
841 {200,1663}, {210,1520}, {220,1400}, {230,1295}, {240,1201},
842 {250,1123}, {260,1058}, {270,1004}, {280,957}, {290,920},
845 int add=strchr(m_description, '.') ? 0xA250 : 0xA100;
846 long regval = 0xFFFF - ((snr / 3) + add), // revert some dvb api calulations to get the real register value
850 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[Imax][REGVAL]))
855 if(INRANGE(CN_lookup[Imin][REGVAL],regval,CN_lookup[i][REGVAL]))
860 ret = (((regval - CN_lookup[Imin][REGVAL])
861 * (CN_lookup[Imax][REALVAL] - CN_lookup[Imin][REALVAL])
862 / (CN_lookup[Imax][REGVAL] - CN_lookup[Imin][REGVAL]))
863 + CN_lookup[Imin][REALVAL]) * 10;
869 else if (!strcmp(m_description, "Alps BSBE1 702A") || // some frontends with STV0299
870 !strcmp(m_description, "Alps -S") ||
871 !strcmp(m_description, "Philips -S") ||
872 !strcmp(m_description, "LG -S") )
875 ret = (int)((snr-39075)/17.647);
876 } else if (!strcmp(m_description, "Alps BSBE2"))
878 ret = (int)((snr >> 7) * 10);
879 } else if (!strcmp(m_description, "Philips CU1216Mk3"))
881 int mse = (~snr) & 0xFF;
882 switch (parm_u_qam_modulation) {
883 case QAM_16: ret = fe_udiv(1950000, (32 * mse) + 138) + 1000; break;
884 case QAM_32: ret = fe_udiv(2150000, (40 * mse) + 500) + 1350; break;
885 case QAM_64: ret = fe_udiv(2100000, (40 * mse) + 500) + 1250; break;
886 case QAM_128: ret = fe_udiv(1850000, (38 * mse) + 400) + 1380; break;
887 case QAM_256: ret = fe_udiv(1800000, (100 * mse) + 40) + 2030; break;
890 } else if (!strcmp(m_description, "Philips TU1216"))
892 snr = 0xFF - (snr & 0xFF);
894 ret = 10 * (int)(-100 * (log10(snr) - log10(255)));
896 else if (strstr(m_description, "BCM4506") || strstr(m_description, "BCM4505"))
897 ret = (snr * 100) >> 8;
898 else if (!strcmp(m_description, "CXD1981"))
900 int mse = (~snr) & 0xFF;
901 switch (parm_u_qam_modulation) {
904 case QAM_256: ret = (int)(-950 * log(((double)mse) / 760)); break;
906 case QAM_128: ret = (int)(-875 * log(((double)mse) / 650)); break;
912 if (type == signalQuality)
914 if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
918 oparm.getSystem(type);
922 return ret >= sat_max ? 65536 : ret * 65536 / sat_max;
923 case feCable: // we assume a max of 42db here
924 return ret >= 4200 ? 65536 : ret * 65536 / 4200;
925 case feTerrestrial: // we assume a max of 24db here
926 return ret >= 2400 ? 65536 : ret * 65536 / 2400;
930 eDebug("no SNR dB calculation for frontendtype %s yet", m_description); */
938 if (ioctl(m_fd, FE_READ_SIGNAL_STRENGTH, &strength) < 0 && errno != ERANGE)
939 eDebug("FE_READ_SIGNAL_STRENGTH failed (%m)");
948 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
949 eDebug("FE_READ_STATUS failed (%m)");
950 return !!(status&FE_HAS_LOCK);
959 if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE )
960 eDebug("FE_READ_STATUS failed (%m)");
961 return !!(status&FE_HAS_SYNC);
968 return m_is_usbtuner;
973 void PutToDict(ePyObject &dict, const char*key, long value)
975 ePyObject item = PyInt_FromLong(value);
978 if (PyDict_SetItemString(dict, key, item))
979 eDebug("put %s to dict failed", key);
983 eDebug("could not create PyObject for %s", key);
986 void PutToDict(ePyObject &dict, const char*key, ePyObject item)
990 if (PyDict_SetItemString(dict, key, item))
991 eDebug("put %s to dict failed", key);
995 eDebug("invalid PyObject for %s", key);
998 void PutToDict(ePyObject &dict, const char*key, const char *value)
1000 ePyObject item = PyString_FromString(value);
1003 if (PyDict_SetItemString(dict, key, item))
1004 eDebug("put %s to dict failed", key);
1008 eDebug("could not create PyObject for %s", key);
1011 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
1013 PutToDict(dict, "tuner_type", "DVB-S");
1014 PutToDict(dict, "frequency", feparm.frequency);
1015 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1016 PutToDict(dict, "orbital_position", feparm.orbital_position);
1017 PutToDict(dict, "inversion", feparm.inversion);
1018 PutToDict(dict, "fec_inner", feparm.fec);
1019 PutToDict(dict, "modulation", feparm.modulation);
1020 PutToDict(dict, "polarization", feparm.polarisation);
1021 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
1023 PutToDict(dict, "rolloff", feparm.rolloff);
1024 PutToDict(dict, "pilot", feparm.pilot);
1026 PutToDict(dict, "system", feparm.system);
1029 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
1031 PutToDict(dict, "tuner_type", "DVB-T");
1032 PutToDict(dict, "frequency", feparm.frequency);
1033 PutToDict(dict, "bandwidth", feparm.bandwidth);
1034 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
1035 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
1036 PutToDict(dict, "constellation", feparm.modulation);
1037 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
1038 PutToDict(dict, "guard_interval", feparm.guard_interval);
1039 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
1040 PutToDict(dict, "inversion", feparm.inversion);
1041 PutToDict(dict, "system", feparm.system);
1042 if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2)
1044 PutToDict(dict, "plp_id", feparm.plpid);
1048 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
1050 PutToDict(dict, "tuner_type", "DVB-C");
1051 PutToDict(dict, "frequency", feparm.frequency);
1052 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
1053 PutToDict(dict, "modulation", feparm.modulation);
1054 PutToDict(dict, "inversion", feparm.inversion);
1055 PutToDict(dict, "fec_inner", feparm.fec_inner);
1058 static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, int orbital_position, int polarization)
1061 int p_system = p[0].u.data;
1062 int p_frequency = p[1].u.data;
1063 int p_inversion = p[2].u.data;
1064 int p_modulation = p[3].u.data;
1065 int p_symbolrate = p[4].u.data;
1066 int p_inner_fec = p[5].u.data;
1067 int p_rolloff = p[6].u.data;
1068 int p_pilot = p[7].u.data;
1070 int frequency = p_frequency + freq_offset;
1071 PutToDict(dict, "frequency", frequency);
1072 PutToDict(dict, "symbol_rate", p_symbolrate);
1073 PutToDict(dict, "orbital_position", orbital_position);
1074 PutToDict(dict, "polarization", polarization);
1078 case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break;
1079 case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break;
1080 case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break;
1081 case FEC_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break;
1082 case FEC_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break;
1083 case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break;
1084 case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
1085 case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
1086 case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
1087 case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
1088 case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
1089 default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
1091 PutToDict(dict, "fec_inner", tmp);
1095 default: eDebug("got unsupported system from frontend! report as DVBS!");
1096 case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
1101 default: eDebug("got unsupported rolloff from frontend! report as 0_20!");
1102 case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break;
1103 case ROLLOFF_25: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break;
1104 case ROLLOFF_35: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break;
1106 PutToDict(dict, "rolloff", tmp);
1110 case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break;
1111 case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break;
1112 case PILOT_AUTO: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break;
1114 PutToDict(dict, "pilot", tmp);
1116 tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
1119 PutToDict(dict, "system", tmp);
1121 switch (p_modulation)
1123 default: eDebug("got unsupported modulation from frontend! report as QPSK!");
1124 case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
1125 case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
1127 PutToDict(dict, "modulation", tmp);
1131 case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break;
1132 case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break;
1133 default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break;
1135 PutToDict(dict, "inversion", tmp);
1138 static void fillDictWithCableData(ePyObject dict, struct dtv_property *p)
1141 int p_system = p[0].u.data;
1142 int p_frequency = p[1].u.data;
1143 int p_inversion = p[2].u.data;
1144 int p_modulation = p[3].u.data;
1145 int p_symbolrate = p[4].u.data;
1146 int p_inner_fec = p[5].u.data;
1148 tmp = p_frequency/1000;
1149 PutToDict(dict, "frequency", tmp);
1151 PutToDict(dict, "symbol_rate", p_inversion);
1153 switch (p_inner_fec)
1155 case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break;
1156 case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break;
1157 case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break;
1158 case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break;
1159 case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break;
1160 case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break;
1161 case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break;
1163 case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break;
1165 PutToDict(dict, "fec_inner", tmp);
1167 switch (p_modulation)
1169 case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break;
1170 case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break;
1171 case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break;
1172 case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break;
1173 case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break;
1175 case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break;
1177 PutToDict(dict, "modulation", tmp);
1179 switch (p_inversion)
1181 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1182 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1184 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1186 PutToDict(dict, "inversion", tmp);
1189 static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p)
1192 int p_system = p[0].u.data;
1193 int p_frequency = p[1].u.data;
1194 int p_inversion = p[2].u.data;
1195 int p_constellation = p[3].u.data;
1196 int p_bandwidth = p[4].u.data;
1197 int p_coderate_lp = p[5].u.data;
1198 int p_coderate_hp = p[6].u.data;
1199 int p_transmission_mode = p[7].u.data;
1200 int p_guard_interval = p[8].u.data;
1201 int p_hierarchy = p[9].u.data;
1202 #if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID)
1203 int p_plp_id = p[10].u.data;
1209 default: eDebug("got unsupported system from frontend! report as DVBT!");
1210 case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break;
1213 #if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID)
1215 PutToDict(dict, "plp_id", tmp);
1217 tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break;
1220 PutToDict(dict, "system", tmp);
1223 PutToDict(dict, "frequency", tmp);
1225 switch (p_bandwidth)
1227 case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break;
1228 case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break;
1229 case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break;
1230 case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break;
1231 case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break;
1232 case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break;
1234 case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break;
1236 PutToDict(dict, "bandwidth", tmp);
1238 switch (p_coderate_lp)
1240 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1241 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1242 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1243 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1244 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1245 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1246 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1247 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1249 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1251 PutToDict(dict, "code_rate_lp", tmp);
1253 switch (p_coderate_hp)
1255 case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break;
1256 case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break;
1257 case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break;
1258 case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break;
1259 case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break;
1260 case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break;
1261 case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break;
1262 case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break;
1264 case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break;
1266 PutToDict(dict, "code_rate_hp", tmp);
1268 switch (p_constellation)
1270 case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break;
1271 case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break;
1272 case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break;
1273 case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break;
1275 case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break;
1277 PutToDict(dict, "constellation", tmp);
1280 switch (p_transmission_mode)
1282 case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break;
1283 case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break;
1284 case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break;
1285 case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break;
1286 case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break;
1287 case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break;
1289 case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break;
1291 PutToDict(dict, "transmission_mode", tmp);
1293 switch (p_guard_interval)
1295 case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break;
1296 case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break;
1297 case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break;
1298 case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break;
1299 case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break;
1300 case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break;
1301 case GUARD_INTERVAL_1_4: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break;
1303 case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break;
1305 PutToDict(dict, "guard_interval", tmp);
1307 switch (p_hierarchy)
1309 case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break;
1310 case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break;
1311 case HIERARCHY_2: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_2; break;
1312 case HIERARCHY_4: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_4; break;
1314 case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break;
1316 PutToDict(dict, "hierarchy_information", tmp);
1318 switch (p_inversion)
1320 case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break;
1321 case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break;
1323 case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break;
1325 PutToDict(dict, "inversion", tmp);
1328 void eDVBFrontend::getFrontendStatus(ePyObject dest)
1330 if (dest && PyDict_Check(dest))
1332 const char *tmp = "UNKNOWN";
1353 PutToDict(dest, "tuner_state", tmp);
1354 PutToDict(dest, "tuner_locked", readFrontendData(locked));
1355 PutToDict(dest, "tuner_synced", readFrontendData(synced));
1356 PutToDict(dest, "tuner_bit_error_rate", readFrontendData(bitErrorRate));
1357 PutToDict(dest, "tuner_signal_quality", readFrontendData(signalQuality));
1358 int sigQualitydB = readFrontendData(signalQualitydB);
1359 if (sigQualitydB == 0x12345678) // not support yet
1361 ePyObject obj=Py_None;
1363 PutToDict(dest, "tuner_signal_quality_db", obj);
1366 PutToDict(dest, "tuner_signal_quality_db", sigQualitydB);
1367 PutToDict(dest, "tuner_signal_power", readFrontendData(signalPower));
1371 void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
1373 if (dest && PyDict_Check(dest))
1376 FRONTENDPARAMETERS front;
1377 struct dtv_property p[16];
1378 struct dtv_properties cmdseq;
1381 oparm.getSystem(type);
1383 p[cmdseq.num++].cmd = DTV_DELIVERY_SYSTEM;
1384 p[cmdseq.num++].cmd = DTV_FREQUENCY;
1385 p[cmdseq.num++].cmd = DTV_INVERSION;
1386 p[cmdseq.num++].cmd = DTV_MODULATION;
1387 if(type == feSatellite)
1389 p[cmdseq.num++].cmd = DTV_SYMBOL_RATE;
1390 p[cmdseq.num++].cmd = DTV_INNER_FEC;
1391 p[cmdseq.num++].cmd = DTV_ROLLOFF;
1392 p[cmdseq.num++].cmd = DTV_PILOT;
1394 else if(type == feCable)
1396 p[cmdseq.num++].cmd = DTV_SYMBOL_RATE;
1397 p[cmdseq.num++].cmd = DTV_INNER_FEC;
1399 else if(type == feTerrestrial)
1401 p[cmdseq.num++].cmd = DTV_BANDWIDTH_HZ;
1402 p[cmdseq.num++].cmd = DTV_CODE_RATE_LP;
1403 p[cmdseq.num++].cmd = DTV_CODE_RATE_HP;
1404 p[cmdseq.num++].cmd = DTV_TRANSMISSION_MODE;
1405 p[cmdseq.num++].cmd = DTV_GUARD_INTERVAL;
1406 p[cmdseq.num++].cmd = DTV_HIERARCHY;
1407 #if defined DTV_STREAM_ID
1408 p[cmdseq.num++].cmd = DTV_STREAM_ID;
1409 #elif defined DTV_DVBT2_PLP_ID
1410 p[cmdseq.num++].cmd = DTV_DVBT2_PLP_ID;
1414 if (m_simulate || m_fd == -1 || original)
1418 else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0)
1420 eDebug("FE_GET_PROPERTY failed (%m)");
1423 else if (type == feSatellite && // use for DVB-S(2) only
1424 ioctl(m_fd, FE_GET_FRONTEND, &front)<0)
1426 eDebug("FE_GET_FRONTEND failed (%m)");
1434 eDVBFrontendParametersSatellite sparm;
1435 oparm.getDVBS(sparm);
1436 PutSatelliteDataToDict(dest, sparm);
1439 eDVBFrontendParametersCable cparm;
1440 oparm.getDVBC(cparm);
1441 PutCableDataToDict(dest, cparm);
1444 eDVBFrontendParametersTerrestrial tparm;
1445 oparm.getDVBT(tparm);
1446 PutTerrestrialDataToDict(dest, tparm);
1452 FRONTENDPARAMETERS &parm = front;
1456 eDVBFrontendParametersSatellite sparm;
1457 oparm.getDVBS(sparm);
1458 fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
1461 fillDictWithCableData(dest, p);
1464 fillDictWithTerrestrialData(dest, p);
1471 void eDVBFrontend::getFrontendData(ePyObject dest)
1473 if (dest && PyDict_Check(dest))
1476 PutToDict(dest, "tuner_number", m_slotid);
1478 if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
1482 #if defined SYS_DVBC_ANNEX_A
1483 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
1485 else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
1490 else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true))
1498 PutToDict(dest, "tuner_type", tmp);
1502 #ifndef FP_IOCTL_GET_ID
1503 #define FP_IOCTL_GET_ID 0
1505 int eDVBFrontend::readInputpower()
1509 int power=m_slotid; // this is needed for read inputpower from the correct tuner !
1511 char proc_name2[64];
1512 sprintf(proc_name, "/proc/stb/frontend/%d/lnb_sense", m_slotid);
1513 sprintf(proc_name2, "/proc/stb/fp/lnb_sense%d", m_slotid);
1515 if ((f=fopen(proc_name, "r")) || (f=fopen(proc_name2, "r")))
1517 if (fscanf(f, "%d", &power) != 1)
1518 eDebug("read %s failed!! (%m)", proc_name);
1520 eDebug("%s is %d\n", proc_name, power);
1525 // open front prozessor
1526 int fp=::open("/dev/dbox/fp0", O_RDWR);
1529 eDebug("couldn't open fp");
1532 static bool old_fp = (::ioctl(fp, FP_IOCTL_GET_ID) < 0);
1533 if ( ioctl( fp, old_fp ? 9 : 0x100, &power ) < 0 )
1535 eDebug("FP_IOCTL_GET_LNB_CURRENT failed (%m)");
1544 bool eDVBFrontend::setSecSequencePos(int steps)
1546 eDebugNoSimulate("set sequence pos %d", steps);
1551 if (m_sec_sequence.current() != m_sec_sequence.end())
1552 ++m_sec_sequence.current();
1557 if (m_sec_sequence.current() != m_sec_sequence.begin() && m_sec_sequence.current() != m_sec_sequence.end())
1558 --m_sec_sequence.current();
1564 void eDVBFrontend::tuneLoop()
1569 int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer
1572 eDVBFrontend *sec_fe = this;
1573 eDVBRegisteredFrontend *regFE = 0;
1574 long tmp = m_data[LINKED_PREV_PTR];
1577 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)tmp;
1578 sec_fe = prev->m_frontend;
1579 tmp = prev->m_frontend->m_data[LINKED_PREV_PTR];
1580 if (tmp == -1 && sec_fe != this && !prev->m_inuse) {
1581 int state = sec_fe->m_state;
1582 #if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply.
1583 // workaround to put the kernel frontend thread into idle state!
1584 if (state != eDVBFrontend::stateIdle && state != stateClosed)
1586 sec_fe->closeFrontend(true);
1587 state = sec_fe->m_state;
1590 // sec_fe is closed... we must reopen it here..
1591 if (state == stateClosed)
1599 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
1601 long *sec_fe_data = sec_fe->m_data;
1602 // eDebugNoSimulate("tuneLoop %d\n", m_sec_sequence.current()->cmd);
1604 switch (m_sec_sequence.current()->cmd)
1606 case eSecCommand::SLEEP:
1607 delay = m_sec_sequence.current()++->msec;
1608 eDebugNoSimulate("[SEC] sleep %dms", delay);
1610 case eSecCommand::GOTO:
1611 if ( !setSecSequencePos(m_sec_sequence.current()->steps) )
1612 ++m_sec_sequence.current();
1614 case eSecCommand::SET_VOLTAGE:
1616 int voltage = m_sec_sequence.current()++->voltage;
1617 eDebugNoSimulate("[SEC] setVoltage %d", voltage);
1618 sec_fe->setVoltage(voltage);
1621 case eSecCommand::IF_VOLTAGE_GOTO:
1623 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1624 if ( compare.voltage == sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1626 ++m_sec_sequence.current();
1629 case eSecCommand::IF_NOT_VOLTAGE_GOTO:
1631 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1632 if ( compare.voltage != sec_fe_data[CUR_VOLTAGE] && setSecSequencePos(compare.steps) )
1634 ++m_sec_sequence.current();
1637 case eSecCommand::IF_TONE_GOTO:
1639 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1640 if ( compare.tone == sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1642 ++m_sec_sequence.current();
1645 case eSecCommand::IF_NOT_TONE_GOTO:
1647 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1648 if ( compare.tone != sec_fe_data[CUR_TONE] && setSecSequencePos(compare.steps) )
1650 ++m_sec_sequence.current();
1653 case eSecCommand::SET_TONE:
1654 eDebugNoSimulate("[SEC] setTone %d", m_sec_sequence.current()->tone);
1655 sec_fe->setTone(m_sec_sequence.current()++->tone);
1657 case eSecCommand::SEND_DISEQC:
1658 sec_fe->sendDiseqc(m_sec_sequence.current()->diseqc);
1659 eDebugNoSimulateNoNewLine("[SEC] sendDiseqc: ");
1660 for (int i=0; i < m_sec_sequence.current()->diseqc.len; ++i)
1661 eDebugNoSimulateNoNewLine("%02x", m_sec_sequence.current()->diseqc.data[i]);
1662 if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x00", 3))
1663 eDebugNoSimulate("(DiSEqC reset)");
1664 else if (!memcmp(m_sec_sequence.current()->diseqc.data, "\xE0\x00\x03", 3))
1665 eDebugNoSimulate("(DiSEqC peripherial power on)");
1667 eDebugNoSimulate("");
1668 ++m_sec_sequence.current();
1670 case eSecCommand::SEND_TONEBURST:
1671 eDebugNoSimulate("[SEC] sendToneburst: %d", m_sec_sequence.current()->toneburst);
1672 sec_fe->sendToneburst(m_sec_sequence.current()++->toneburst);
1674 case eSecCommand::SET_FRONTEND:
1676 int enableEvents = (m_sec_sequence.current()++)->val;
1677 eDebugNoSimulate("[SEC] setFrontend %d", enableEvents);
1678 setFrontend(enableEvents);
1681 case eSecCommand::START_TUNE_TIMEOUT:
1683 int tuneTimeout = m_sec_sequence.current()->timeout;
1684 eDebugNoSimulate("[SEC] startTuneTimeout %d", tuneTimeout);
1686 m_timeout->start(tuneTimeout, 1);
1687 ++m_sec_sequence.current();
1690 case eSecCommand::SET_TIMEOUT:
1691 m_timeoutCount = m_sec_sequence.current()++->val;
1692 eDebugNoSimulate("[SEC] set timeout %d", m_timeoutCount);
1694 case eSecCommand::IF_TIMEOUT_GOTO:
1695 if (!m_timeoutCount)
1697 eDebugNoSimulate("[SEC] rotor timout");
1698 setSecSequencePos(m_sec_sequence.current()->steps);
1701 ++m_sec_sequence.current();
1703 case eSecCommand::MEASURE_IDLE_INPUTPOWER:
1705 int idx = m_sec_sequence.current()++->val;
1706 if ( idx == 0 || idx == 1 )
1708 m_idleInputpower[idx] = sec_fe->readInputpower();
1709 eDebugNoSimulate("[SEC] idleInputpower[%d] is %d", idx, m_idleInputpower[idx]);
1712 eDebugNoSimulate("[SEC] idleInputpower measure index(%d) out of bound !!!", idx);
1715 case eSecCommand::IF_MEASURE_IDLE_WAS_NOT_OK_GOTO:
1717 eSecCommand::pair &compare = m_sec_sequence.current()->compare;
1718 int idx = compare.val;
1719 if ( !m_simulate && (idx == 0 || idx == 1) )
1721 int idle = sec_fe->readInputpower();
1722 int diff = abs(idle-m_idleInputpower[idx]);
1725 eDebugNoSimulate("measure idle(%d) was not okay.. (%d - %d = %d) retry", idx, m_idleInputpower[idx], idle, diff);
1726 setSecSequencePos(compare.steps);
1730 ++m_sec_sequence.current();
1733 case eSecCommand::IF_TUNER_LOCKED_GOTO:
1735 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1738 setSecSequencePos(cmd.steps);
1742 int isLocked = readFrontendData(locked);
1743 m_idleInputpower[0] = m_idleInputpower[1] = 0;
1745 if (!m_timeoutCount && m_retryCount > 0)
1747 if (isLocked && ((abs((signal = readFrontendData(signalQualitydB)) - cmd.lastSignal) < 40) || !cmd.lastSignal))
1750 eDebugNoSimulate("[SEC] locked step %d ok (%d %d)", cmd.okcount, signal, cmd.lastSignal);
1753 eDebugNoSimulate("[SEC] locked step %d ok", cmd.okcount);
1755 cmd.lastSignal = signal;
1758 if (cmd.okcount > 4)
1760 eDebugNoSimulate("ok > 4 .. goto %d\n", cmd.steps);
1761 setSecSequencePos(cmd.steps);
1762 m_state = stateLock;
1763 m_stateChanged(this);
1764 feEvent(-1); // flush events
1772 eDebugNoSimulate("[SEC] rotor locked step %d failed (oldSignal %d, curSignal %d)", cmd.okcount, signal, cmd.lastSignal);
1774 eDebugNoSimulate("[SEC] rotor locked step %d failed (not locked)", cmd.okcount);
1778 ++m_sec_sequence.current();
1781 case eSecCommand::MEASURE_RUNNING_INPUTPOWER:
1782 m_runningInputpower = sec_fe->readInputpower();
1783 eDebugNoSimulate("[SEC] runningInputpower is %d", m_runningInputpower);
1784 ++m_sec_sequence.current();
1786 case eSecCommand::SET_ROTOR_MOVING:
1788 m_sec->setRotorMoving(m_slotid, true);
1789 ++m_sec_sequence.current();
1791 case eSecCommand::SET_ROTOR_STOPPED:
1793 m_sec->setRotorMoving(m_slotid, false);
1794 ++m_sec_sequence.current();
1796 case eSecCommand::IF_INPUTPOWER_DELTA_GOTO:
1798 eSecCommand::rotor &cmd = m_sec_sequence.current()->measure;
1801 setSecSequencePos(cmd.steps);
1804 int idleInputpower = m_idleInputpower[ (sec_fe_data[CUR_VOLTAGE]&1) ? 0 : 1];
1805 const char *txt = cmd.direction ? "running" : "stopped";
1807 if (!m_timeoutCount && m_retryCount > 0)
1809 eDebugNoSimulate("[SEC] waiting for rotor %s %d, idle %d, delta %d",
1811 m_runningInputpower,
1814 if ( (cmd.direction && abs(m_runningInputpower - idleInputpower) >= cmd.deltaA)
1815 || (!cmd.direction && abs(m_runningInputpower - idleInputpower) <= cmd.deltaA) )
1818 eDebugNoSimulate("[SEC] rotor %s step %d ok", txt, cmd.okcount);
1819 if ( cmd.okcount > 6 )
1821 eDebugNoSimulate("[SEC] rotor is %s", txt);
1822 if (setSecSequencePos(cmd.steps))
1828 eDebugNoSimulate("[SEC] rotor not %s... reset counter.. increase timeout", txt);
1831 ++m_sec_sequence.current();
1834 case eSecCommand::IF_ROTORPOS_VALID_GOTO:
1835 if (sec_fe_data[ROTOR_CMD] != -1 && sec_fe_data[ROTOR_POS] != -1)
1836 setSecSequencePos(m_sec_sequence.current()->steps);
1838 ++m_sec_sequence.current();
1840 case eSecCommand::INVALIDATE_CURRENT_SWITCHPARMS:
1841 eDebugNoSimulate("[SEC] invalidate current switch params");
1842 sec_fe_data[CSW] = -1;
1843 sec_fe_data[UCSW] = -1;
1844 sec_fe_data[TONEBURST] = -1;
1845 ++m_sec_sequence.current();
1847 case eSecCommand::UPDATE_CURRENT_SWITCHPARMS:
1848 sec_fe_data[CSW] = sec_fe_data[NEW_CSW];
1849 sec_fe_data[UCSW] = sec_fe_data[NEW_UCSW];
1850 sec_fe_data[TONEBURST] = sec_fe_data[NEW_TONEBURST];
1851 eDebugNoSimulate("[SEC] update current switch params");
1852 ++m_sec_sequence.current();
1854 case eSecCommand::INVALIDATE_CURRENT_ROTORPARMS:
1855 eDebugNoSimulate("[SEC] invalidate current rotorparams");
1856 sec_fe_data[ROTOR_CMD] = -1;
1857 sec_fe_data[ROTOR_POS] = -1;
1858 ++m_sec_sequence.current();
1860 case eSecCommand::UPDATE_CURRENT_ROTORPARAMS:
1861 sec_fe_data[ROTOR_CMD] = sec_fe_data[NEW_ROTOR_CMD];
1862 sec_fe_data[ROTOR_POS] = sec_fe_data[NEW_ROTOR_POS];
1863 eDebugNoSimulate("[SEC] update current rotorparams %d %04lx %ld", m_timeoutCount, sec_fe_data[ROTOR_CMD], sec_fe_data[ROTOR_POS]);
1864 ++m_sec_sequence.current();
1866 case eSecCommand::SET_ROTOR_DISEQC_RETRYS:
1867 m_retryCount = m_sec_sequence.current()++->val;
1868 eDebugNoSimulate("[SEC] set rotor retries %d", m_retryCount);
1870 case eSecCommand::IF_NO_MORE_ROTOR_DISEQC_RETRYS_GOTO:
1873 eDebugNoSimulate("[SEC] no more rotor retrys");
1874 setSecSequencePos(m_sec_sequence.current()->steps);
1877 ++m_sec_sequence.current();
1879 case eSecCommand::SET_POWER_LIMITING_MODE:
1884 sprintf(proc_name, "/proc/stb/frontend/%d/static_current_limiting", sec_fe->m_dvbid);
1885 FILE *f=fopen(proc_name, "w");
1886 if (f) // new interface exist?
1888 bool slimiting = m_sec_sequence.current()->mode == eSecCommand::modeStatic;
1889 if (fprintf(f, "%s", slimiting ? "on" : "off") <= 0)
1890 eDebugNoSimulate("write %s failed!! (%m)", proc_name);
1892 eDebugNoSimulate("[SEC] set %s current limiting", slimiting ? "static" : "dynamic");
1895 else if (sec_fe->m_need_rotor_workaround)
1898 int slotid = sec_fe->m_slotid;
1899 // FIXMEEEEEE hardcoded i2c devices for dm7025 and dm8000
1901 sprintf(dev, "/dev/i2c-%d", slotid);
1902 else if (slotid == 2)
1903 sprintf(dev, "/dev/i2c-2"); // first nim socket on DM8000 use /dev/i2c-2
1904 else if (slotid == 3)
1905 sprintf(dev, "/dev/i2c-4"); // second nim socket on DM8000 use /dev/i2c-4
1906 int fd = ::open(dev, O_RDWR);
1908 unsigned char data[2];
1909 ::ioctl(fd, I2C_SLAVE_FORCE, 0x10 >> 1);
1910 if(::read(fd, data, 1) != 1)
1911 eDebugNoSimulate("[SEC] error read lnbp (%m)");
1912 if ( m_sec_sequence.current()->mode == eSecCommand::modeStatic )
1914 data[0] |= 0x80; // enable static current limiting
1915 eDebugNoSimulate("[SEC] set static current limiting");
1919 data[0] &= ~0x80; // enable dynamic current limiting
1920 eDebugNoSimulate("[SEC] set dynamic current limiting");
1922 if(::write(fd, data, 1) != 1)
1923 eDebugNoSimulate("[SEC] error write lnbp (%m)");
1927 ++m_sec_sequence.current();
1930 case eSecCommand::DELAYED_CLOSE_FRONTEND:
1932 eDebugNoSimulate("[SEC] delayed close frontend");
1933 closeFrontend(false, true);
1934 ++m_sec_sequence.current();
1938 eDebugNoSimulate("[SEC] unhandled sec command %d",
1939 ++m_sec_sequence.current()->cmd);
1940 ++m_sec_sequence.current();
1943 m_tuneTimer->start(delay,true);
1947 if (m_simulate && m_sec_sequence.current() != m_sec_sequence.end())
1952 void eDVBFrontend::setFrontend(bool recvEvents)
1956 eDebug("setting frontend %d", m_dvbid);
1959 oparm.getSystem(type);
1963 feEvent(-1); // flush events
1964 if (type == iDVBFrontend::feSatellite)
1966 fe_rolloff_t rolloff = ROLLOFF_35;
1967 fe_pilot_t pilot = PILOT_OFF;
1968 fe_modulation_t modulation = QPSK;
1969 fe_delivery_system_t system = SYS_DVBS;
1970 eDVBFrontendParametersSatellite sparm;
1971 oparm.getDVBS(sparm);
1972 switch(sparm.system)
1974 case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
1975 case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
1977 switch(sparm.modulation)
1979 case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
1980 case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
1981 case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
1985 case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break;
1986 case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break;
1987 case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break;
1989 switch(sparm.rolloff)
1991 case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break;
1992 case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
1993 case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
1995 struct dtv_property p[10];
1996 struct dtv_properties cmdseq;
1998 p[0].cmd = DTV_CLEAR;
1999 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2000 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2001 p[3].cmd = DTV_MODULATION, p[3].u.data = modulation;
2002 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
2003 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
2004 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2005 if (system == SYS_DVBS2)
2007 p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
2008 p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
2009 p[9].cmd = DTV_TUNE;
2014 p[7].cmd = DTV_TUNE;
2017 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2019 perror("FE_SET_PROPERTY failed");
2023 else if (type == iDVBFrontend::feCable)
2025 struct dtv_property p[8];
2026 struct dtv_properties cmdseq;
2028 p[0].cmd = DTV_CLEAR;
2029 #if defined SYS_DVBC_ANNEX_A
2030 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A;
2032 p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC;
2034 p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency;
2035 p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation;
2036 p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate;
2037 p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner;
2038 p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
2039 p[7].cmd = DTV_TUNE;
2041 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2043 perror("FE_SET_PROPERTY failed");
2047 else if (type == iDVBFrontend::feTerrestrial)
2049 fe_delivery_system_t system = SYS_DVBT;
2050 eDVBFrontendParametersTerrestrial tparm;
2051 oparm.getDVBT(tparm);
2052 switch (tparm.system)
2055 case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break;
2056 case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break;
2059 switch (tparm.bandwidth)
2061 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break;
2062 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break;
2063 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break;
2065 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break;
2066 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break;
2067 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break;
2068 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break;
2070 struct dtv_property p[13];
2071 struct dtv_properties cmdseq;
2074 p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++;
2075 p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++;
2076 p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++;
2077 p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++;
2078 p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++;
2079 p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++;
2080 p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++;
2081 p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++;
2082 p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++;
2083 p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++;
2084 p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++;
2085 #if defined DTV_STREAM_ID
2086 p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2087 #elif defined DTV_DVBT2_PLP_ID
2088 p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++;
2090 p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++;
2091 if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1)
2093 perror("FE_SET_PROPERTY failed");
2099 if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1)
2101 perror("FE_SET_FRONTEND failed");
2108 RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout)
2113 eWarning("no SEC module active!");
2116 res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
2119 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",
2122 feparm.polarisation,
2126 feparm.orbital_position,
2131 parm_u_qpsk_symbol_rate = feparm.symbol_rate;
2132 switch (feparm.inversion)
2134 case eDVBFrontendParametersSatellite::Inversion_On:
2135 parm_inversion = INVERSION_ON;
2137 case eDVBFrontendParametersSatellite::Inversion_Off:
2138 parm_inversion = INVERSION_OFF;
2141 case eDVBFrontendParametersSatellite::Inversion_Unknown:
2142 parm_inversion = INVERSION_AUTO;
2145 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S)
2149 case eDVBFrontendParametersSatellite::FEC_None:
2150 parm_u_qpsk_fec_inner = FEC_NONE;
2152 case eDVBFrontendParametersSatellite::FEC_1_2:
2153 parm_u_qpsk_fec_inner = FEC_1_2;
2155 case eDVBFrontendParametersSatellite::FEC_2_3:
2156 parm_u_qpsk_fec_inner = FEC_2_3;
2158 case eDVBFrontendParametersSatellite::FEC_3_4:
2159 parm_u_qpsk_fec_inner = FEC_3_4;
2161 case eDVBFrontendParametersSatellite::FEC_5_6:
2162 parm_u_qpsk_fec_inner = FEC_5_6;
2164 case eDVBFrontendParametersSatellite::FEC_7_8:
2165 parm_u_qpsk_fec_inner = FEC_7_8;
2168 eDebugNoSimulate("no valid fec for DVB-S set.. assume auto");
2169 case eDVBFrontendParametersSatellite::FEC_Auto:
2170 parm_u_qpsk_fec_inner = FEC_AUTO;
2178 case eDVBFrontendParametersSatellite::FEC_1_2:
2179 parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
2181 case eDVBFrontendParametersSatellite::FEC_2_3:
2182 parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
2184 case eDVBFrontendParametersSatellite::FEC_3_4:
2185 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
2187 case eDVBFrontendParametersSatellite::FEC_3_5:
2188 parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
2190 case eDVBFrontendParametersSatellite::FEC_4_5:
2191 parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
2193 case eDVBFrontendParametersSatellite::FEC_5_6:
2194 parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
2196 case eDVBFrontendParametersSatellite::FEC_7_8:
2197 parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
2199 case eDVBFrontendParametersSatellite::FEC_8_9:
2200 parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
2202 case eDVBFrontendParametersSatellite::FEC_9_10:
2203 parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
2206 eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!");
2210 // FIXME !!! get frequency range from tuner
2211 if ( parm_frequency < 900000 || parm_frequency > 2200000 )
2213 eDebugNoSimulate("%d mhz out of tuner range.. dont tune", parm_frequency/1000);
2216 eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000);
2218 oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune);
2222 RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm)
2224 parm_frequency = feparm.frequency * 1000;
2225 parm_u_qam_symbol_rate = feparm.symbol_rate;
2226 switch (feparm.modulation)
2228 case eDVBFrontendParametersCable::Modulation_QAM16:
2229 parm_u_qam_modulation = QAM_16;
2231 case eDVBFrontendParametersCable::Modulation_QAM32:
2232 parm_u_qam_modulation = QAM_32;
2234 case eDVBFrontendParametersCable::Modulation_QAM64:
2235 parm_u_qam_modulation = QAM_64;
2237 case eDVBFrontendParametersCable::Modulation_QAM128:
2238 parm_u_qam_modulation = QAM_128;
2240 case eDVBFrontendParametersCable::Modulation_QAM256:
2241 parm_u_qam_modulation = QAM_256;
2244 case eDVBFrontendParametersCable::Modulation_Auto:
2245 parm_u_qam_modulation = QAM_AUTO;
2248 switch (feparm.inversion)
2250 case eDVBFrontendParametersCable::Inversion_On:
2251 parm_inversion = INVERSION_ON;
2253 case eDVBFrontendParametersCable::Inversion_Off:
2254 parm_inversion = INVERSION_OFF;
2257 case eDVBFrontendParametersCable::Inversion_Unknown:
2258 parm_inversion = INVERSION_AUTO;
2261 switch (feparm.fec_inner)
2263 case eDVBFrontendParametersCable::FEC_None:
2264 parm_u_qam_fec_inner = FEC_NONE;
2266 case eDVBFrontendParametersCable::FEC_1_2:
2267 parm_u_qam_fec_inner = FEC_1_2;
2269 case eDVBFrontendParametersCable::FEC_2_3:
2270 parm_u_qam_fec_inner = FEC_2_3;
2272 case eDVBFrontendParametersCable::FEC_3_4:
2273 parm_u_qam_fec_inner = FEC_3_4;
2275 case eDVBFrontendParametersCable::FEC_5_6:
2276 parm_u_qam_fec_inner = FEC_5_6;
2278 case eDVBFrontendParametersCable::FEC_7_8:
2279 parm_u_qam_fec_inner = FEC_7_8;
2281 case eDVBFrontendParametersCable::FEC_8_9:
2282 parm_u_qam_fec_inner = FEC_8_9;
2285 case eDVBFrontendParametersCable::FEC_Auto:
2286 parm_u_qam_fec_inner = FEC_AUTO;
2289 eDebugNoSimulate("tuning to %d khz, sr %d, fec %d, modulation %d, inversion %d",
2290 parm_frequency/1000,
2291 parm_u_qam_symbol_rate,
2292 parm_u_qam_fec_inner,
2293 parm_u_qam_modulation,
2295 oparm.setDVBC(feparm);
2299 RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial &feparm)
2301 parm_frequency = feparm.frequency;
2303 switch (feparm.bandwidth)
2305 case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz:
2306 parm_u_ofdm_bandwidth = BANDWIDTH_8_MHZ;
2308 case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz:
2309 parm_u_ofdm_bandwidth = BANDWIDTH_7_MHZ;
2311 case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz:
2312 parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ;
2314 case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz:
2315 parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ;
2317 case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz:
2318 parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ;
2320 case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz:
2321 parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ;
2324 case eDVBFrontendParametersTerrestrial::Bandwidth_Auto:
2325 parm_u_ofdm_bandwidth = BANDWIDTH_AUTO;
2328 switch (feparm.code_rate_LP)
2330 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2331 parm_u_ofdm_code_rate_LP = FEC_1_2;
2333 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2334 parm_u_ofdm_code_rate_LP = FEC_2_3;
2336 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2337 parm_u_ofdm_code_rate_LP = FEC_3_4;
2339 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2340 parm_u_ofdm_code_rate_LP = FEC_5_6;
2342 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2343 parm_u_ofdm_code_rate_LP = FEC_7_8;
2345 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2346 parm_u_ofdm_code_rate_LP = FEC_6_7;
2348 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2349 parm_u_ofdm_code_rate_LP = FEC_8_9;
2352 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2353 parm_u_ofdm_code_rate_LP = FEC_AUTO;
2356 switch (feparm.code_rate_HP)
2358 case eDVBFrontendParametersTerrestrial::FEC_1_2:
2359 parm_u_ofdm_code_rate_HP = FEC_1_2;
2361 case eDVBFrontendParametersTerrestrial::FEC_2_3:
2362 parm_u_ofdm_code_rate_HP = FEC_2_3;
2364 case eDVBFrontendParametersTerrestrial::FEC_3_4:
2365 parm_u_ofdm_code_rate_HP = FEC_3_4;
2367 case eDVBFrontendParametersTerrestrial::FEC_5_6:
2368 parm_u_ofdm_code_rate_HP = FEC_5_6;
2370 case eDVBFrontendParametersTerrestrial::FEC_7_8:
2371 parm_u_ofdm_code_rate_HP = FEC_7_8;
2373 case eDVBFrontendParametersTerrestrial::FEC_6_7:
2374 parm_u_ofdm_code_rate_HP = FEC_6_7;
2376 case eDVBFrontendParametersTerrestrial::FEC_8_9:
2377 parm_u_ofdm_code_rate_HP = FEC_8_9;
2380 case eDVBFrontendParametersTerrestrial::FEC_Auto:
2381 parm_u_ofdm_code_rate_HP = FEC_AUTO;
2384 switch (feparm.modulation)
2386 case eDVBFrontendParametersTerrestrial::Modulation_QPSK:
2387 parm_u_ofdm_constellation = QPSK;
2389 case eDVBFrontendParametersTerrestrial::Modulation_QAM16:
2390 parm_u_ofdm_constellation = QAM_16;
2392 case eDVBFrontendParametersTerrestrial::Modulation_QAM64:
2393 parm_u_ofdm_constellation = QAM_64;
2395 case eDVBFrontendParametersTerrestrial::Modulation_QAM256:
2396 parm_u_ofdm_constellation = QAM_256;
2399 case eDVBFrontendParametersTerrestrial::Modulation_Auto:
2400 parm_u_ofdm_constellation = QAM_AUTO;
2403 switch (feparm.transmission_mode)
2405 case eDVBFrontendParametersTerrestrial::TransmissionMode_2k:
2406 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_2K;
2408 case eDVBFrontendParametersTerrestrial::TransmissionMode_8k:
2409 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K;
2411 case eDVBFrontendParametersTerrestrial::TransmissionMode_4k:
2412 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K;
2414 case eDVBFrontendParametersTerrestrial::TransmissionMode_1k:
2415 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K;
2417 case eDVBFrontendParametersTerrestrial::TransmissionMode_16k:
2418 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K;
2420 case eDVBFrontendParametersTerrestrial::TransmissionMode_32k:
2421 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K;
2424 case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto:
2425 parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO;
2428 switch (feparm.guard_interval)
2430 case eDVBFrontendParametersTerrestrial::GuardInterval_1_32:
2431 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_32;
2433 case eDVBFrontendParametersTerrestrial::GuardInterval_1_16:
2434 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_16;
2436 case eDVBFrontendParametersTerrestrial::GuardInterval_1_8:
2437 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_8;
2439 case eDVBFrontendParametersTerrestrial::GuardInterval_1_4:
2440 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4;
2442 case eDVBFrontendParametersTerrestrial::GuardInterval_1_128:
2443 parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128;
2445 case eDVBFrontendParametersTerrestrial::GuardInterval_19_128:
2446 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128;
2448 case eDVBFrontendParametersTerrestrial::GuardInterval_19_256:
2449 parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256;
2452 case eDVBFrontendParametersTerrestrial::GuardInterval_Auto:
2453 parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO;
2456 switch (feparm.hierarchy)
2458 case eDVBFrontendParametersTerrestrial::Hierarchy_None:
2459 parm_u_ofdm_hierarchy_information = HIERARCHY_NONE;
2461 case eDVBFrontendParametersTerrestrial::Hierarchy_1:
2462 parm_u_ofdm_hierarchy_information = HIERARCHY_1;
2464 case eDVBFrontendParametersTerrestrial::Hierarchy_2:
2465 parm_u_ofdm_hierarchy_information = HIERARCHY_2;
2467 case eDVBFrontendParametersTerrestrial::Hierarchy_4:
2468 parm_u_ofdm_hierarchy_information = HIERARCHY_4;
2471 case eDVBFrontendParametersTerrestrial::Hierarchy_Auto:
2472 parm_u_ofdm_hierarchy_information = HIERARCHY_AUTO;
2475 switch (feparm.inversion)
2477 case eDVBFrontendParametersTerrestrial::Inversion_On:
2478 parm_inversion = INVERSION_ON;
2480 case eDVBFrontendParametersTerrestrial::Inversion_Off:
2481 parm_inversion = INVERSION_OFF;
2484 case eDVBFrontendParametersTerrestrial::Inversion_Unknown:
2485 parm_inversion = INVERSION_AUTO;
2488 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",
2489 parm_frequency/1000,
2490 parm_u_ofdm_bandwidth,
2491 parm_u_ofdm_code_rate_LP,
2492 parm_u_ofdm_code_rate_HP,
2493 parm_u_ofdm_constellation,
2494 parm_u_ofdm_transmission_mode,
2495 parm_u_ofdm_guard_interval,
2496 parm_u_ofdm_hierarchy_information,
2500 oparm.setDVBT(feparm);
2504 RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where)
2506 unsigned int timeout = 5000;
2507 eDebugNoSimulate("(%d)tune", m_dvbid);
2514 if (where.getSystem(type) < 0)
2520 if (!m_sn && !m_simulate)
2522 eDebug("no frontend device opened... do not try to tune !!!");
2530 m_sec_sequence.clear();
2532 where.calcLockTimeout(timeout);
2538 eDVBFrontendParametersSatellite feparm;
2539 if (where.getDVBS(feparm))
2541 eDebug("no dvbs data!");
2545 if (m_rotor_mode != feparm.no_rotor_command_on_tune && !feparm.no_rotor_command_on_tune)
2547 eDVBFrontend *sec_fe = this;
2548 long tmp = m_data[LINKED_PREV_PTR];
2551 eDVBRegisteredFrontend *linked_fe = (eDVBRegisteredFrontend*)tmp;
2552 sec_fe = linked_fe->m_frontend;
2553 sec_fe->getData(LINKED_NEXT_PTR, tmp);
2555 eDebug("(fe%d) reset diseqc after leave rotor mode!", m_dvbid);
2556 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
2558 m_rotor_mode = feparm.no_rotor_command_on_tune;
2560 m_sec->setRotorMoving(m_slotid, false);
2561 res=prepare_sat(feparm, timeout);
2569 eDVBFrontendParametersCable feparm;
2570 if (where.getDVBC(feparm))
2575 res=prepare_cable(feparm);
2579 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2580 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2585 eDVBFrontendParametersTerrestrial feparm;
2586 if (where.getDVBT(feparm))
2588 eDebug("no -T data");
2592 res=prepare_terrestrial(feparm);
2596 std::string enable_5V;
2597 char configStr[255];
2598 snprintf(configStr, 255, "config.Nims.%d.terrestrial_5V", m_slotid);
2599 m_sec_sequence.push_back( eSecCommand(eSecCommand::START_TUNE_TIMEOUT, timeout) );
2600 ePythonConfigQuery::getConfigValue(configStr, enable_5V);
2601 if (enable_5V == "True")
2602 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
2604 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltageOff) );
2605 m_sec_sequence.push_back( eSecCommand(eSecCommand::SET_FRONTEND, 1) );
2616 m_sec_sequence.current() = m_sec_sequence.begin();
2620 m_tuneTimer->start(0,true);
2622 if (m_state != stateTuning)
2624 m_state = stateTuning;
2625 m_stateChanged(this);
2634 m_tuneTimer->stop();
2638 RESULT eDVBFrontend::connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)
2640 connection = new eConnection(this, m_stateChanged.connect(stateChange));
2644 RESULT eDVBFrontend::setVoltage(int voltage)
2646 bool increased=false;
2647 fe_sec_voltage_t vlt;
2648 m_data[CUR_VOLTAGE]=voltage;
2652 m_data[CSW]=m_data[UCSW]=m_data[TONEBURST]=-1; // reset diseqc
2653 vlt = SEC_VOLTAGE_OFF;
2658 vlt = SEC_VOLTAGE_13;
2663 vlt = SEC_VOLTAGE_18;
2671 ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased);
2672 return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt);
2675 RESULT eDVBFrontend::getState(int &state)
2681 RESULT eDVBFrontend::setTone(int t)
2683 fe_sec_tone_mode_t tone;
2691 tone = SEC_TONE_OFF;
2699 return ::ioctl(m_fd, FE_SET_TONE, tone);
2702 RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc)
2707 struct dvb_diseqc_master_cmd cmd;
2708 memcpy(cmd.msg, diseqc.data, diseqc.len);
2709 cmd.msg_len = diseqc.len;
2710 if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd))
2715 RESULT eDVBFrontend::sendToneburst(int burst)
2719 fe_sec_mini_cmd_t cmd = SEC_MINI_A;
2720 if ( burst == eDVBSatelliteDiseqcParameters::A )
2722 else if ( burst == eDVBSatelliteDiseqcParameters::B )
2724 if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd))
2729 RESULT eDVBFrontend::setSEC(iDVBSatelliteEquipmentControl *sec)
2735 RESULT eDVBFrontend::setSecSequence(eSecCommandList &list)
2737 if (m_data[SATCR] != -1 && m_sec_sequence.current() != m_sec_sequence.end())
2738 m_sec_sequence.push_back(list);
2740 m_sec_sequence = list;
2744 bool eDVBFrontend::isScheduledSendDiseqc()
2746 bool has_senddiseqc = false;
2747 if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() )
2749 eSecCommandList::iterator cur = m_sec_sequence.current();
2750 while(cur != m_sec_sequence.end())
2752 if (((cur++)->cmd == eSecCommand::SEND_DISEQC))
2754 has_senddiseqc = true;
2759 return has_senddiseqc;
2762 RESULT eDVBFrontend::getData(int num, long &data)
2764 if ( num < NUM_DATA_ENTRIES )
2772 RESULT eDVBFrontend::setData(int num, long val)
2774 if ( num < NUM_DATA_ENTRIES )
2782 int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
2786 bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend());
2788 if (feparm->getSystem(type) || !m_enabled)
2791 if (type == eDVBFrontend::feSatellite)
2793 eDVBFrontendParametersSatellite sat_parm;
2794 bool can_handle_dvbs, can_handle_dvbs2;
2795 can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
2796 can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
2797 if (feparm->getDVBS(sat_parm) < 0)
2801 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
2805 if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs)
2809 score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
2810 if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
2812 /* prefer to use a S tuner, try to keep S2 free for S2 transponders */
2817 else if (type == eDVBFrontend::feCable)
2819 eDVBFrontendParametersCable cab_parm;
2820 if (feparm->getDVBC(cab_parm) < 0)
2824 #if defined SYS_DVBC_ANNEX_A
2825 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true))
2827 if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true))
2835 else if (type == eDVBFrontend::feTerrestrial)
2837 eDVBFrontendParametersTerrestrial ter_parm;
2838 bool can_handle_dvbt, can_handle_dvbt2;
2839 can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true);
2840 can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true);
2841 if (feparm->getDVBT(ter_parm) < 0)
2845 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt)
2849 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2)
2854 if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2)
2856 /* prefer to use a T tuner, try to keep T2 free for T2 transponders */
2861 if (score && preferred)
2863 /* make 'sure' we always prefer this frontend */
2870 bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist)
2872 std::map<fe_delivery_system_t, bool>::iterator it = m_delsys.find(sys);
2873 if (it != m_delsys.end() && it->second)
2875 if (obeywhitelist && !m_delsys_whitelist.empty())
2877 it = m_delsys_whitelist.find(sys);
2878 if (it == m_delsys_whitelist.end() || !it->second) return false;
2885 void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_system_t> &whitelist)
2887 m_delsys_whitelist.clear();
2888 for (unsigned int i = 0; i < whitelist.size(); i++)
2890 m_delsys_whitelist[whitelist[i]] = true;
2894 m_simulate_fe->setDeliverySystemWhitelist(whitelist);
2898 bool eDVBFrontend::setSlotInfo(ePyObject obj)
2900 ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
2901 if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
2903 Id = PyTuple_GET_ITEM(obj, 0);
2904 Descr = PyTuple_GET_ITEM(obj, 1);
2905 Enabled = PyTuple_GET_ITEM(obj, 2);
2906 IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
2907 IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
2908 frontendId = PyTuple_GET_ITEM(obj, 5);
2909 m_slotid = PyInt_AsLong(Id);
2910 if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
2912 strcpy(m_description, PyString_AS_STRING(Descr));
2913 if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
2914 // eDebugNoSimulate("skip slotinfo for slotid %d, descr %s",
2915 // m_slotid, m_description);
2918 m_enabled = (Enabled == Py_True);
2919 // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator...
2920 m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") ||
2921 !!strstr(m_description, "Alps BSBE2") ||
2922 !!strstr(m_description, "Alps -S") ||
2923 !!strstr(m_description, "BCM4501");
2924 if (IsDVBS2 == Py_True)
2926 /* HACK for legacy dvb api without DELSYS support */
2927 m_delsys[SYS_DVBS2] = true;
2929 if (IsDVBT2 == Py_True)
2931 /* HACK for legacy dvb api without DELSYS support */
2932 m_delsys[SYS_DVBT2] = true;
2935 eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
2936 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" );
2939 PyErr_SetString(PyExc_StandardError,
2940 "eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");