X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Ffrontend.cpp;h=91c866c94b0b3098462a8e4bc36b8e1808a8c625;hp=e9801696d593f154d131436cd34884a91673b356;hb=d8e08fe0a7304ed06b3de0b9ad6d4265ec8063b8;hpb=377c2adbf11ed3b293bced1a4195cefd8aa6110f diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp old mode 100644 new mode 100755 index e980169..91c866c --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -11,29 +13,6 @@ #define I2C_SLAVE_FORCE 0x0706 #endif -#if HAVE_DVB_API_VERSION < 3 -#include -#include -#define QAM_AUTO (Modulation)6 -#define TRANSMISSION_MODE_AUTO (TransmitMode)2 -#define BANDWIDTH_AUTO (BandWidth)3 -#define GUARD_INTERVAL_AUTO (GuardInterval)4 -#define HIERARCHY_AUTO (Hierarchy)4 -#define parm_frequency parm.Frequency -#define parm_inversion parm.Inversion -#define parm_u_qpsk_symbol_rate parm.u.qpsk.SymbolRate -#define parm_u_qpsk_fec_inner parm.u.qpsk.FEC_inner -#define parm_u_qam_symbol_rate parm.u.qam.SymbolRate -#define parm_u_qam_fec_inner parm.u.qam.FEC_inner -#define parm_u_qam_modulation parm.u.qam.QAM -#define parm_u_ofdm_bandwidth parm.u.ofdm.bandWidth -#define parm_u_ofdm_code_rate_LP parm.u.ofdm.LP_CodeRate -#define parm_u_ofdm_code_rate_HP parm.u.ofdm.HP_CodeRate -#define parm_u_ofdm_constellation parm.u.ofdm.Constellation -#define parm_u_ofdm_transmission_mode parm.u.ofdm.TransmissionMode -#define parm_u_ofdm_guard_interval parm.u.ofdm.guardInterval -#define parm_u_ofdm_hierarchy_information parm.u.ofdm.HierarchyInformation -#else #include #define parm_frequency parm.frequency #define parm_inversion parm.inversion @@ -49,37 +28,15 @@ #define parm_u_ofdm_transmission_mode parm.u.ofdm.transmission_mode #define parm_u_ofdm_guard_interval parm.u.ofdm.guard_interval #define parm_u_ofdm_hierarchy_information parm.u.ofdm.hierarchy_information -#if HAVE_DVB_API_VERSION < 5 - #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_AUTO+1) - #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_S2_QPSK_1_2+1) - #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_S2_QPSK_2_3+1) - #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_S2_QPSK_3_4+1) - #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_S2_QPSK_5_6+1) - #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_S2_QPSK_7_8+1) - #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_S2_QPSK_8_9+1) - #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_S2_QPSK_3_5+1) - #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_S2_QPSK_4_5+1) - #define FEC_S2_8PSK_1_2 (fe_code_rate_t)(FEC_S2_QPSK_9_10+1) - #define FEC_S2_8PSK_2_3 (fe_code_rate_t)(FEC_S2_8PSK_1_2+1) - #define FEC_S2_8PSK_3_4 (fe_code_rate_t)(FEC_S2_8PSK_2_3+1) - #define FEC_S2_8PSK_5_6 (fe_code_rate_t)(FEC_S2_8PSK_3_4+1) - #define FEC_S2_8PSK_7_8 (fe_code_rate_t)(FEC_S2_8PSK_5_6+1) - #define FEC_S2_8PSK_8_9 (fe_code_rate_t)(FEC_S2_8PSK_7_8+1) - #define FEC_S2_8PSK_3_5 (fe_code_rate_t)(FEC_S2_8PSK_8_9+1) - #define FEC_S2_8PSK_4_5 (fe_code_rate_t)(FEC_S2_8PSK_3_5+1) - #define FEC_S2_8PSK_9_10 (fe_code_rate_t)(FEC_S2_8PSK_4_5+1) -#else - #define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2) - #define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3) - #define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4) - #define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6) - #define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8) - #define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9) - #define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5) - #define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5) - #define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10) -#endif -#endif +#define FEC_S2_QPSK_1_2 (fe_code_rate_t)(FEC_1_2) +#define FEC_S2_QPSK_2_3 (fe_code_rate_t)(FEC_2_3) +#define FEC_S2_QPSK_3_4 (fe_code_rate_t)(FEC_3_4) +#define FEC_S2_QPSK_5_6 (fe_code_rate_t)(FEC_5_6) +#define FEC_S2_QPSK_7_8 (fe_code_rate_t)(FEC_7_8) +#define FEC_S2_QPSK_8_9 (fe_code_rate_t)(FEC_8_9) +#define FEC_S2_QPSK_3_5 (fe_code_rate_t)(FEC_3_5) +#define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5) +#define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10) #include #include @@ -213,27 +170,67 @@ void eDVBFrontendParametersCable::set(const CableDeliverySystemDescriptor &descr void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescriptor &descriptor) { + /* EN 300 468 V1.11.1 DVB-SI SPEC */ frequency = descriptor.getCentreFrequency() * 10; - bandwidth = descriptor.getBandwidth(); - if ( bandwidth > 2 ) // 5Mhz forced to auto - bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; - code_rate_HP = descriptor.getCodeRateHpStream(); - if (code_rate_HP > 4) - code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; - code_rate_LP = descriptor.getCodeRateLpStream(); - if (code_rate_LP > 4) - code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; - transmission_mode = descriptor.getTransmissionMode(); - if (transmission_mode > 1) // TM4k forced to auto - transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; - guard_interval = descriptor.getGuardInterval(); - if (guard_interval > 3) - guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; + switch (descriptor.getBandwidth()) + { + case 0: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break; + case 1: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break; + case 2: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break; + case 3: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break; + case 4: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break; + case 5: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break; + default: bandwidth = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break; + } + switch (descriptor.getCodeRateHpStream()) + { + case 0: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_1_2; break; + case 1: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_2_3; break; + case 2: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_3_4; break; + case 3: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_5_6; break; + case 4: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_7_8; break; + default: code_rate_HP = eDVBFrontendParametersTerrestrial::FEC_Auto; break; + } + switch (descriptor.getCodeRateLpStream()) + { + case 0: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_1_2; break; + case 1: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_2_3; break; + case 2: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_3_4; break; + case 3: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_5_6; break; + case 4: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_7_8; break; + default: code_rate_LP = eDVBFrontendParametersTerrestrial::FEC_Auto; break; + } + switch (descriptor.getTransmissionMode()) + { + case 0: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break; + case 1: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break; + case 2: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break; + case 3: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break; + case 4: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break; + case 5: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break; + default: transmission_mode = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break; + } + switch (descriptor.getGuardInterval()) + { + case 0: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break; + case 1: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break; + case 2: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break; + case 3: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_4; break; + case 4: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break; + case 5: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break; + case 6: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break; + default: guard_interval = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break; + } +// hierarchy = descriptor.getHierarchyInformation(); hierarchy = descriptor.getHierarchyInformation()&3; + if (hierarchy > eDVBFrontendParametersTerrestrial::Hierarchy_4) + hierarchy = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; modulation = descriptor.getConstellation(); - if (modulation > 2) + if (modulation > eDVBFrontendParametersTerrestrial::Modulation_QAM64) modulation = eDVBFrontendParametersTerrestrial::Modulation_Auto; inversion = eDVBFrontendParametersTerrestrial::Inversion_Unknown; + system = eDVBFrontendParametersTerrestrial::System_DVB_T; + plpid = 0; eDebug("Terr freq %d, bw %d, cr_hp %d, cr_lp %d, tm_mode %d, guard %d, hierarchy %d, const %d", frequency, bandwidth, code_rate_HP, code_rate_LP, transmission_mode, guard_interval, hierarchy, modulation); @@ -248,10 +245,8 @@ DEFINE_REF(eDVBFrontendParameters); RESULT eDVBFrontendParameters::getSystem(int &t) const { - if (m_type == -1) - return -1; t = m_type; - return 0; + return (m_type == -1) ? -1 : 0; } RESULT eDVBFrontendParameters::getDVBS(eDVBFrontendParametersSatellite &p) const @@ -357,7 +352,6 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters eDVBFrontendParametersTerrestrial oterrestrial; if (parm->getDVBT(oterrestrial)) return -2; - if (exact && oterrestrial.bandwidth != terrestrial.bandwidth && oterrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto && terrestrial.bandwidth != eDVBFrontendParametersTerrestrial::Bandwidth_Auto) @@ -386,6 +380,11 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters oterrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto && terrestrial.code_rate_HP != eDVBFrontendParametersTerrestrial::FEC_Auto) diff = 1 << 30; + else if (oterrestrial.system != terrestrial.system) + diff = 1 << 30; + else if (oterrestrial.system == terrestrial.System_DVB_T2 && + oterrestrial.plpid != terrestrial.plpid) + diff = 1 << 30; else diff = abs(terrestrial.frequency - oterrestrial.frequency) / 1000; return 0; @@ -452,21 +451,15 @@ RESULT eDVBFrontendParameters::calcLockTimeout(unsigned int &timeout) const DEFINE_REF(eDVBFrontend); int eDVBFrontend::PriorityOrder=0; +int eDVBFrontend::PreferredFrontendIndex=-1; + eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFrontend *simulate_fe) - :m_simulate(simulate), m_enabled(false), m_type(-1), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe) - ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false), m_can_handle_dvbs2(false) - ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0) -#if HAVE_DVB_API_VERSION < 3 - ,m_secfd(-1) -#endif + :m_simulate(simulate), m_enabled(false), m_simulate_fe(simulate_fe), m_dvbid(fe), m_slotid(fe) + ,m_fd(-1), m_rotor_mode(false), m_need_rotor_workaround(false) + ,m_state(stateClosed), m_timeout(0), m_tuneTimer(0), m_fbc(false), m_is_usbtuner(false) { -#if HAVE_DVB_API_VERSION < 3 - sprintf(m_filename, "/dev/dvb/card%d/frontend%d", adap, fe); - sprintf(m_sec_filename, "/dev/dvb/card%d/sec%d", adap, fe); -#else sprintf(m_filename, "/dev/dvb/adapter%d/frontend%d", adap, fe); -#endif m_timeout = eTimer::create(eApp); CONNECT(m_timeout->timeout, eDVBFrontend::timeout); @@ -486,7 +479,7 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok, bool simulate, eDVBFronten void eDVBFrontend::reopenFrontend() { sleep(1); - m_type = -1; + m_delsys.clear(); openFrontend(); } @@ -498,11 +491,7 @@ int eDVBFrontend::openFrontend() m_state=stateIdle; m_tuning=0; -#if HAVE_DVB_API_VERSION < 3 - FrontendInfo fe_info; -#else dvb_frontend_info fe_info; -#endif if (!m_simulate) { eDebug("opening frontend %d", m_dvbid); @@ -517,8 +506,26 @@ int eDVBFrontend::openFrontend() } else eWarning("frontend %d already opened", m_dvbid); - if (m_type == -1) + + if (m_delsys.empty()) { +#ifdef DTV_ENUM_DELSYS + struct dtv_property p[1]; + p[0].cmd = DTV_ENUM_DELSYS; + struct dtv_properties cmdseq; + cmdseq.num = 1; + cmdseq.props = p; + if (::ioctl(m_fd, FE_GET_PROPERTY, &cmdseq) >= 0) + { + m_delsys.clear(); + unsigned int i; + for (i = 0; i < p[0].u.buffer.len ; i++) + { + fe_delivery_system_t delsys = (fe_delivery_system_t)p[0].u.buffer.data[i]; + m_delsys[delsys] = true; + } + } +#else if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0) { eWarning("ioctl FE_GET_INFO failed"); @@ -526,50 +533,46 @@ int eDVBFrontend::openFrontend() m_fd = -1; return -1; } - + /* old DVB API, fill delsys map with some defaults */ switch (fe_info.type) { - case FE_QPSK: - m_type = iDVBFrontend::feSatellite; - break; - case FE_QAM: - m_type = iDVBFrontend::feCable; - break; - case FE_OFDM: - m_type = iDVBFrontend::feTerrestrial; - break; - default: - eWarning("unknown frontend type."); - ::close(m_fd); - m_fd = -1; - return -1; + case FE_QPSK: + { + m_delsys[SYS_DVBS] = true; +#if DVB_API_VERSION >= 5 + if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true; +#endif + break; + } + case FE_QAM: + { +#if defined SYS_DVBC_ANNEX_A + m_delsys[SYS_DVBC_ANNEX_A] = true; +#else + m_delsys[SYS_DVBC_ANNEX_AC] = true; +#endif + break; + } + case FE_OFDM: + { + m_delsys[SYS_DVBT] = true; +#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3 + if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true; +#endif + break; + } + case FE_ATSC: // placeholder to prevent warning + { + break; + } } - if (m_simulate_fe) - m_simulate_fe->m_type = m_type; - eDebugNoSimulate("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*10); +#endif } -#if HAVE_DVB_API_VERSION < 3 - if (m_type == iDVBFrontend::feSatellite) + if (m_simulate_fe) { - if (m_secfd < 0) - { - if (!m_simulate) - { - m_secfd = ::open(m_sec_filename, O_RDWR); - if (m_secfd < 0) - { - eWarning("failed! (%s) %m", m_sec_filename); - ::close(m_fd); - m_fd=-1; - return -1; - } - } - } - else - eWarning("sec %d already opened", m_dvbid); + m_simulate_fe->m_delsys = m_delsys; } -#endif m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false); CONNECT(m_sn->activated, eDVBFrontend::feEvent); @@ -606,7 +609,7 @@ int eDVBFrontend::closeFrontend(bool force, bool no_delayed) { if (!no_delayed) { - m_sec->prepareTurnOffSatCR(*this, m_data[SATCR]); + m_sec->prepareTurnOffSatCR(*this); m_tuneTimer->start(0, true); if(!m_tuneTimer->isActive()) { @@ -644,15 +647,6 @@ int eDVBFrontend::closeFrontend(bool force, bool no_delayed) setTone(iDVBFrontend::toneOff); setVoltage(iDVBFrontend::voltageOff); } -#if HAVE_DVB_API_VERSION < 3 - if (m_secfd >= 0) - { - if (!::close(m_secfd)) - m_secfd=-1; - else - eWarning("couldnt close sec %d", m_dvbid); - } -#endif m_sn=0; m_state = stateClosed; @@ -677,11 +671,7 @@ void eDVBFrontend::feEvent(int w) } while (1) { -#if HAVE_DVB_API_VERSION < 3 - FrontendEvent event; -#else dvb_frontend_event event; -#endif int res; int state; res = ::ioctl(m_fd, FE_GET_EVENT, &event); @@ -692,19 +682,14 @@ void eDVBFrontend::feEvent(int w) if (w < 0) continue; -#if HAVE_DVB_API_VERSION < 3 - if (event.type == FE_COMPLETION_EV) -#else eDebug("(%d)fe event: status %x, inversion %s, m_tuning %d", m_dvbid, event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off", m_tuning); if (event.status & FE_HAS_LOCK) -#endif { state = stateLock; } else { if (m_tuning) { state = stateTuning; -#if HAVE_DVB_API_VERSION >= 3 if (event.status & FE_TIMEDOUT) { eDebug("FE_TIMEDOUT! ..abort"); m_tuneTimer->stop(); @@ -712,17 +697,16 @@ void eDVBFrontend::feEvent(int w) return; } ++m_tuning; -#else - m_tuneTimer->stop(); - timeout(); -#endif } else { eDebug("stateLostLock"); state = stateLostLock; if (!m_rotor_mode) + { sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc + sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1; + } } } if (m_state != state) @@ -738,9 +722,10 @@ void eDVBFrontend::timeout() m_tuning = 0; if (m_state == stateTuning) { -#ifdef BUILD_VUPLUS /* ikseong */ +#ifdef BUILD_VUPLUS eDVBFrontend *sec_fe = this; sec_fe->m_data[CSW] = sec_fe->m_data[UCSW] = sec_fe->m_data[TONEBURST] = -1; // reset diseqc + sec_fe->m_data[LINKABLE_CSW] = sec_fe->m_data[LINKABLE_UCSW] = sec_fe->m_data[LINKABLE_TONEBURST] = -1; #endif m_state = stateFailed; m_stateChanged(this); @@ -784,7 +769,10 @@ int eDVBFrontend::readFrontendData(int type) float SDS_SNRE = snr << 16; float snr_in_db; - if (oparm.sat.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK + eDVBFrontendParametersSatellite sparm; + oparm.getDVBS(sparm); + + if (sparm.system == eDVBFrontendParametersSatellite::System_DVB_S) // DVB-S1 / QPSK { static float SNR_COEFF[6] = { 100.0 / 4194304.0, @@ -810,13 +798,12 @@ int eDVBFrontend::readFrontendData(int type) } snr_in_db = fval1; } -#if HAVE_DVB_API_VERSION >= 3 else { float fval1 = SDS_SNRE / 268435456.0, fval2, fval3, fval4; - if (oparm.sat.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK) + if (sparm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK) { fval2 = 6.76; fval3 = 4.35; @@ -833,7 +820,6 @@ int eDVBFrontend::readFrontendData(int type) fval1 = fval4 - fval2 * log10(1.0+pow(10.0, (fval3-fval1)/fval2)); snr_in_db = fval1; } -#endif sat_max = 1750; ret = (int)(snr_in_db * 100); } @@ -927,7 +913,10 @@ int eDVBFrontend::readFrontendData(int type) { if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value.. return snr; - switch(m_type) + + int type = -1; + oparm.getSystem(type); + switch(type) { case feSatellite: return ret >= sat_max ? 65536 : ret * 65536 / sat_max; @@ -953,11 +942,7 @@ int eDVBFrontend::readFrontendData(int type) } case locked: { -#if HAVE_DVB_API_VERSION < 3 - FrontendStatus status=0; -#else fe_status_t status; -#endif if (!m_simulate) { if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE ) @@ -968,11 +953,7 @@ int eDVBFrontend::readFrontendData(int type) } case synced: { -#if HAVE_DVB_API_VERSION < 3 - FrontendStatus status=0; -#else fe_status_t status; -#endif if (!m_simulate) { if ( ioctl(m_fd, FE_READ_STATUS, &status) < 0 && errno != ERANGE ) @@ -983,6 +964,8 @@ int eDVBFrontend::readFrontendData(int type) } case frontendNumber: return m_slotid; + case isUsbTuner: + return m_is_usbtuner; } return 0; } @@ -1055,6 +1038,11 @@ void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial PutToDict(dict, "guard_interval", feparm.guard_interval); PutToDict(dict, "hierarchy_information", feparm.hierarchy); PutToDict(dict, "inversion", feparm.inversion); + PutToDict(dict, "system", feparm.system); + if (feparm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2) + { + PutToDict(dict, "plp_id", feparm.plpid); + } } void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm) @@ -1067,17 +1055,25 @@ void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm) PutToDict(dict, "fec_inner", feparm.fec_inner); } -#if HAVE_DVB_API_VERSION >= 5 -static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, struct dtv_property *p, long freq_offset, int orb_pos, int polarization) +static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, int orbital_position, int polarization) { long tmp=0; - int frequency = parm_frequency + freq_offset; + int p_system = p[0].u.data; + int p_frequency = p[1].u.data; + int p_inversion = p[2].u.data; + int p_modulation = p[3].u.data; + int p_symbolrate = p[4].u.data; + int p_inner_fec = p[5].u.data; + int p_rolloff = p[6].u.data; + int p_pilot = p[7].u.data; + + int frequency = p_frequency + freq_offset; PutToDict(dict, "frequency", frequency); - PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate); - PutToDict(dict, "orbital_position", orb_pos); + PutToDict(dict, "symbol_rate", p_symbolrate); + PutToDict(dict, "orbital_position", orbital_position); PutToDict(dict, "polarization", polarization); - switch(parm_u_qpsk_fec_inner) + switch(p_inner_fec) { case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break; case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break; @@ -1094,13 +1090,13 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS & } PutToDict(dict, "fec_inner", tmp); - switch (p[0].u.data) + switch (p_system) { default: eDebug("got unsupported system from frontend! report as DVBS!"); case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break; case SYS_DVBS2: { - switch (p[2].u.data) + switch (p_rolloff) { default: eDebug("got unsupported rolloff from frontend! report as 0_20!"); case ROLLOFF_20: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break; @@ -1109,7 +1105,7 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS & } PutToDict(dict, "rolloff", tmp); - switch (p[3].u.data) + switch (p_pilot) { case PILOT_OFF: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break; case PILOT_ON: tmp = eDVBFrontendParametersSatellite::Pilot_On; break; @@ -1122,182 +1118,183 @@ static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS & } PutToDict(dict, "system", tmp); - switch (p[1].u.data) + switch (p_modulation) { default: eDebug("got unsupported modulation from frontend! report as QPSK!"); case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break; case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break; } PutToDict(dict, "modulation", tmp); -} -#else -static void fillDictWithSatelliteData(ePyObject dict, const FRONTENDPARAMETERS &parm, long freq_offset, int orb_pos, int polarization) -{ - long tmp=0; - int frequency = parm_frequency + freq_offset; - PutToDict(dict, "frequency", frequency); - PutToDict(dict, "symbol_rate", parm_u_qpsk_symbol_rate); - PutToDict(dict, "orbital_position", orb_pos); - PutToDict(dict, "polarization", polarization); - - switch((int)parm_u_qpsk_fec_inner) + switch(p_inversion) { - case FEC_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break; - case FEC_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break; - case FEC_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break; - case FEC_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break; - case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break; - case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break; - default: - case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break; -#if HAVE_DVB_API_VERSION >=3 - case FEC_S2_8PSK_1_2: - case FEC_S2_QPSK_1_2: tmp = eDVBFrontendParametersSatellite::FEC_1_2; break; - case FEC_S2_8PSK_2_3: - case FEC_S2_QPSK_2_3: tmp = eDVBFrontendParametersSatellite::FEC_2_3; break; - case FEC_S2_8PSK_3_4: - case FEC_S2_QPSK_3_4: tmp = eDVBFrontendParametersSatellite::FEC_3_4; break; - case FEC_S2_8PSK_5_6: - case FEC_S2_QPSK_5_6: tmp = eDVBFrontendParametersSatellite::FEC_5_6; break; - case FEC_S2_8PSK_7_8: - case FEC_S2_QPSK_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break; - case FEC_S2_8PSK_8_9: - case FEC_S2_QPSK_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break; - case FEC_S2_8PSK_3_5: - case FEC_S2_QPSK_3_5: tmp = eDVBFrontendParametersSatellite::FEC_3_5; break; - case FEC_S2_8PSK_4_5: - case FEC_S2_QPSK_4_5: tmp = eDVBFrontendParametersSatellite::FEC_4_5; break; - case FEC_S2_8PSK_9_10: - case FEC_S2_QPSK_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break; -#endif + case INVERSION_ON: tmp = eDVBFrontendParametersSatellite::Inversion_On; break; + case INVERSION_OFF: tmp = eDVBFrontendParametersSatellite::Inversion_Off; break; + default: tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; break; } - PutToDict(dict, "fec_inner", tmp); -#if HAVE_DVB_API_VERSION >=3 - PutToDict(dict, "modulation", - parm_u_qpsk_fec_inner > FEC_S2_QPSK_9_10 ? - eDVBFrontendParametersSatellite::Modulation_8PSK : - eDVBFrontendParametersSatellite::Modulation_QPSK ); - if (parm_u_qpsk_fec_inner > FEC_AUTO) - { - switch(parm_inversion & 0xc) - { - default: // unknown rolloff - case 0: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_35; break; - case 4: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_25; break; - case 8: tmp = eDVBFrontendParametersSatellite::RollOff_alpha_0_20; break; - } - PutToDict(dict, "rolloff", tmp); - switch(parm_inversion & 0x30) - { - case 0: tmp = eDVBFrontendParametersSatellite::Pilot_Off; break; - case 0x10: tmp = eDVBFrontendParametersSatellite::Pilot_On; break; - case 0x20: tmp = eDVBFrontendParametersSatellite::Pilot_Unknown; break; - } - PutToDict(dict, "pilot", tmp); - tmp = eDVBFrontendParametersSatellite::System_DVB_S2; - } - else - tmp = eDVBFrontendParametersSatellite::System_DVB_S; -#else - PutToDict(dict, "modulation", eDVBFrontendParametersSatellite::Modulation_QPSK ); - tmp = eDVBFrontendParametersSatellite::System_DVB_S; -#endif - PutToDict(dict, "system", tmp); + PutToDict(dict, "inversion", tmp); } -#endif -static void fillDictWithCableData(ePyObject dict, const FRONTENDPARAMETERS &parm) +static void fillDictWithCableData(ePyObject dict, struct dtv_property *p) { - long tmp=0; -#if HAVE_DVB_API_VERSION < 3 - PutToDict(dict, "frequency", parm_frequency); -#else - PutToDict(dict, "frequency", parm_frequency/1000); -#endif - PutToDict(dict, "symbol_rate", parm_u_qam_symbol_rate); - switch(parm_u_qam_fec_inner) - { - case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break; - case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break; - case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break; - case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break; - case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break; - case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break; -#if HAVE_DVB_API_VERSION >= 3 - case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_7_8; break; -#endif - default: - case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break; + long tmp = 0; + int p_system = p[0].u.data; + int p_frequency = p[1].u.data; + int p_inversion = p[2].u.data; + int p_modulation = p[3].u.data; + int p_symbolrate = p[4].u.data; + int p_inner_fec = p[5].u.data; +// frequency + tmp = p_frequency/1000; + PutToDict(dict, "frequency", tmp); +// sysbolrate + PutToDict(dict, "symbol_rate", p_inversion); +// inner fec + switch (p_inner_fec) + { + case FEC_NONE: tmp = eDVBFrontendParametersCable::FEC_None; break; + case FEC_1_2: tmp = eDVBFrontendParametersCable::FEC_1_2; break; + case FEC_2_3: tmp = eDVBFrontendParametersCable::FEC_2_3; break; + case FEC_3_4: tmp = eDVBFrontendParametersCable::FEC_3_4; break; + case FEC_5_6: tmp = eDVBFrontendParametersCable::FEC_5_6; break; + case FEC_7_8: tmp = eDVBFrontendParametersCable::FEC_7_8; break; + case FEC_8_9: tmp = eDVBFrontendParametersCable::FEC_8_9; break; + default: + case FEC_AUTO: tmp = eDVBFrontendParametersCable::FEC_Auto; break; } PutToDict(dict, "fec_inner", tmp); - switch(parm_u_qam_modulation) - { - case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break; - case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break; - case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break; - case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break; - case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break; - default: - case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break; +// modulation + switch (p_modulation) + { + case QAM_16: tmp = eDVBFrontendParametersCable::Modulation_QAM16; break; + case QAM_32: tmp = eDVBFrontendParametersCable::Modulation_QAM32; break; + case QAM_64: tmp = eDVBFrontendParametersCable::Modulation_QAM64; break; + case QAM_128: tmp = eDVBFrontendParametersCable::Modulation_QAM128; break; + case QAM_256: tmp = eDVBFrontendParametersCable::Modulation_QAM256; break; + default: + case QAM_AUTO: tmp = eDVBFrontendParametersCable::Modulation_Auto; break; } PutToDict(dict, "modulation", tmp); +// inversion + switch (p_inversion) + { + case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break; + case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break; + default: + case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break; + } + PutToDict(dict, "inversion", tmp); } -static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS &parm) +static void fillDictWithTerrestrialData(ePyObject dict, struct dtv_property *p) { - long tmp=0; - PutToDict(dict, "frequency", parm_frequency); - switch (parm_u_ofdm_bandwidth) + long tmp =0; + int p_system = p[0].u.data; + int p_frequency = p[1].u.data; + int p_inversion = p[2].u.data; + int p_constellation = p[3].u.data; + int p_bandwidth = p[4].u.data; + int p_coderate_lp = p[5].u.data; + int p_coderate_hp = p[6].u.data; + int p_transmission_mode = p[7].u.data; + int p_guard_interval = p[8].u.data; + int p_hierarchy = p[9].u.data; +#if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID) + int p_plp_id = p[10].u.data; +#endif + +// system + switch (p_system) { - case BANDWIDTH_8_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break; - case BANDWIDTH_7_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break; - case BANDWIDTH_6_MHZ: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break; - default: - case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break; + default: eDebug("got unsupported system from frontend! report as DVBT!"); + case SYS_DVBT: tmp = eDVBFrontendParametersTerrestrial::System_DVB_T; break; + case SYS_DVBT2: + { +#if (defined DTV_STREAM_ID) || (defined DTV_DVBT2_PLP_ID) + tmp = p_plp_id; + PutToDict(dict, "plp_id", tmp); +#endif + tmp = eDVBFrontendParametersTerrestrial::System_DVB_T2; break; + } + } + PutToDict(dict, "system", tmp); +// frequency + tmp = p_frequency; + PutToDict(dict, "frequency", tmp); +// bandwidth + switch (p_bandwidth) + { + case 8000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_8MHz; break; + case 7000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_7MHz; break; + case 6000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_6MHz; break; + case 5000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_5MHz; break; + case 10000000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_10MHz; break; + case 1712000: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz; break; + default: + case BANDWIDTH_AUTO: tmp = eDVBFrontendParametersTerrestrial::Bandwidth_Auto; break; } PutToDict(dict, "bandwidth", tmp); - switch (parm_u_ofdm_code_rate_LP) - { - case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break; - case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break; - case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break; - case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break; - case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break; - default: - case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break; +// code rate LP + switch (p_coderate_lp) + { + case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break; + case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break; + case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break; + case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break; + case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break; + case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break; + case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break; + case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break; + default: + case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break; } PutToDict(dict, "code_rate_lp", tmp); - switch (parm_u_ofdm_code_rate_HP) - { - case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break; - case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break; - case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break; - case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break; - case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break; - default: - case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break; +// code rate HP + switch (p_coderate_hp) + { + case FEC_1_2: tmp = eDVBFrontendParametersTerrestrial::FEC_1_2; break; + case FEC_2_3: tmp = eDVBFrontendParametersTerrestrial::FEC_2_3; break; + case FEC_3_4: tmp = eDVBFrontendParametersTerrestrial::FEC_3_4; break; + case FEC_4_5: tmp = eDVBFrontendParametersTerrestrial::FEC_4_5; break; + case FEC_5_6: tmp = eDVBFrontendParametersTerrestrial::FEC_5_6; break; + case FEC_6_7: tmp = eDVBFrontendParametersTerrestrial::FEC_6_7; break; + case FEC_7_8: tmp = eDVBFrontendParametersTerrestrial::FEC_7_8; break; + case FEC_8_9: tmp = eDVBFrontendParametersTerrestrial::FEC_8_9; break; + default: + case FEC_AUTO: tmp = eDVBFrontendParametersTerrestrial::FEC_Auto; break; } PutToDict(dict, "code_rate_hp", tmp); - switch (parm_u_ofdm_constellation) +// constellation + switch (p_constellation) { - case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break; - case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break; - case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break; - default: - case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break; + case QPSK: tmp = eDVBFrontendParametersTerrestrial::Modulation_QPSK; break; + case QAM_16: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM16; break; + case QAM_64: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM64; break; + case QAM_256: tmp = eDVBFrontendParametersTerrestrial::Modulation_QAM256; break; + default: + case QAM_AUTO: tmp = eDVBFrontendParametersTerrestrial::Modulation_Auto; break; } PutToDict(dict, "constellation", tmp); - switch (parm_u_ofdm_transmission_mode) + +// transmission + switch (p_transmission_mode) { + case TRANSMISSION_MODE_1K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_1k; break; case TRANSMISSION_MODE_2K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_2k; break; + case TRANSMISSION_MODE_4K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_4k; break; case TRANSMISSION_MODE_8K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_8k; break; + case TRANSMISSION_MODE_16K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_16k; break; + case TRANSMISSION_MODE_32K: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_32k; break; default: case TRANSMISSION_MODE_AUTO: tmp = eDVBFrontendParametersTerrestrial::TransmissionMode_Auto; break; } PutToDict(dict, "transmission_mode", tmp); - switch (parm_u_ofdm_guard_interval) +// guard interval + switch (p_guard_interval) { + case GUARD_INTERVAL_19_256: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_256; break; + case GUARD_INTERVAL_19_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_19_128; break; + case GUARD_INTERVAL_1_128: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_128; break; case GUARD_INTERVAL_1_32: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_32; break; case GUARD_INTERVAL_1_16: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_16; break; case GUARD_INTERVAL_1_8: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_1_8; break; @@ -1306,7 +1303,8 @@ static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS case GUARD_INTERVAL_AUTO: tmp = eDVBFrontendParametersTerrestrial::GuardInterval_Auto; break; } PutToDict(dict, "guard_interval", tmp); - switch (parm_u_ofdm_hierarchy_information) +// hierarchy + switch (p_hierarchy) { case HIERARCHY_NONE: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_None; break; case HIERARCHY_1: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_1; break; @@ -1316,6 +1314,15 @@ static void fillDictWithTerrestrialData(ePyObject dict, const FRONTENDPARAMETERS case HIERARCHY_AUTO: tmp = eDVBFrontendParametersTerrestrial::Hierarchy_Auto; break; } PutToDict(dict, "hierarchy_information", tmp); +// inversion + switch (p_inversion) + { + case INVERSION_OFF: tmp = eDVBFrontendParametersTerrestrial::Inversion_Off; break; + case INVERSION_ON: tmp = eDVBFrontendParametersTerrestrial::Inversion_On; break; + default: + case INVERSION_AUTO: tmp = eDVBFrontendParametersTerrestrial::Inversion_Unknown; break; + } + PutToDict(dict, "inversion", tmp); } void eDVBFrontend::getFrontendStatus(ePyObject dest) @@ -1365,76 +1372,96 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original) { if (dest && PyDict_Check(dest)) { + int type = -1; FRONTENDPARAMETERS front; -#if HAVE_DVB_API_VERSION >= 5 - struct dtv_property p[4]; + struct dtv_property p[16]; struct dtv_properties cmdseq; cmdseq.props = p; - cmdseq.num = 4; - p[0].cmd = DTV_DELIVERY_SYSTEM; - p[1].cmd = DTV_MODULATION; - p[2].cmd = DTV_ROLLOFF; - p[3].cmd = DTV_PILOT; + cmdseq.num = 0; + oparm.getSystem(type); + + p[cmdseq.num++].cmd = DTV_DELIVERY_SYSTEM; + p[cmdseq.num++].cmd = DTV_FREQUENCY; + p[cmdseq.num++].cmd = DTV_INVERSION; + p[cmdseq.num++].cmd = DTV_MODULATION; + if(type == feSatellite) + { + p[cmdseq.num++].cmd = DTV_SYMBOL_RATE; + p[cmdseq.num++].cmd = DTV_INNER_FEC; + p[cmdseq.num++].cmd = DTV_ROLLOFF; + p[cmdseq.num++].cmd = DTV_PILOT; + } + else if(type == feCable) + { + p[cmdseq.num++].cmd = DTV_SYMBOL_RATE; + p[cmdseq.num++].cmd = DTV_INNER_FEC; + } + else if(type == feTerrestrial) + { + p[cmdseq.num++].cmd = DTV_BANDWIDTH_HZ; + p[cmdseq.num++].cmd = DTV_CODE_RATE_LP; + p[cmdseq.num++].cmd = DTV_CODE_RATE_HP; + p[cmdseq.num++].cmd = DTV_TRANSMISSION_MODE; + p[cmdseq.num++].cmd = DTV_GUARD_INTERVAL; + p[cmdseq.num++].cmd = DTV_HIERARCHY; +#if defined DTV_STREAM_ID + p[cmdseq.num++].cmd = DTV_STREAM_ID; +#elif defined DTV_DVBT2_PLP_ID + p[cmdseq.num++].cmd = DTV_DVBT2_PLP_ID; #endif + } + if (m_simulate || m_fd == -1 || original) + { original = true; -#if HAVE_DVB_API_VERSION >= 5 - else if (m_type == feSatellite && // yet just use new api for DVB-S(2) only - ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0) + } + else if (ioctl(m_fd, FE_GET_PROPERTY, &cmdseq)<0) { eDebug("FE_GET_PROPERTY failed (%m)"); original = true; } -#endif - else if (ioctl(m_fd, FE_GET_FRONTEND, &front)<0) + else if (type == feSatellite && // use for DVB-S(2) only + ioctl(m_fd, FE_GET_FRONTEND, &front)<0) { eDebug("FE_GET_FRONTEND failed (%m)"); original = true; } if (original) { - switch(m_type) + switch(type) { case feSatellite: - PutSatelliteDataToDict(dest, oparm.sat); + eDVBFrontendParametersSatellite sparm; + oparm.getDVBS(sparm); + PutSatelliteDataToDict(dest, sparm); break; case feCable: - PutCableDataToDict(dest, oparm.cab); + eDVBFrontendParametersCable cparm; + oparm.getDVBC(cparm); + PutCableDataToDict(dest, cparm); break; case feTerrestrial: - PutTerrestrialDataToDict(dest, oparm.ter); + eDVBFrontendParametersTerrestrial tparm; + oparm.getDVBT(tparm); + PutTerrestrialDataToDict(dest, tparm); break; } } else { FRONTENDPARAMETERS &parm = front; - long tmp = eDVBFrontendParametersSatellite::Inversion_Unknown; - switch(parm_inversion & 3) - { - case INVERSION_ON: - tmp = eDVBFrontendParametersSatellite::Inversion_On; - break; - case INVERSION_OFF: - tmp = eDVBFrontendParametersSatellite::Inversion_Off; - default: - break; - } - PutToDict(dest, "inversion", tmp); - switch(m_type) + switch(type) { case feSatellite: -#if HAVE_DVB_API_VERSION >= 5 - fillDictWithSatelliteData(dest, parm, p, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation); -#else - fillDictWithSatelliteData(dest, parm, m_data[FREQ_OFFSET], oparm.sat.orbital_position, oparm.sat.polarisation); -#endif + eDVBFrontendParametersSatellite sparm; + oparm.getDVBS(sparm); + fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation); break; case feCable: - fillDictWithCableData(dest, parm); + fillDictWithCableData(dest, p); break; case feTerrestrial: - fillDictWithTerrestrialData(dest, parm); + fillDictWithTerrestrialData(dest, p); break; } } @@ -1447,20 +1474,26 @@ void eDVBFrontend::getFrontendData(ePyObject dest) { const char *tmp=0; PutToDict(dest, "tuner_number", m_slotid); - switch(m_type) + + if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true)) { - case feSatellite: - tmp = "DVB-S"; - break; - case feCable: - tmp = "DVB-C"; - break; - case feTerrestrial: - tmp = "DVB-T"; - break; - default: - tmp = "UNKNOWN"; - break; + tmp = "DVB-S"; + } +#if defined SYS_DVBC_ANNEX_A + else if (supportsDeliverySystem(SYS_DVBC_ANNEX_A, true)) +#else + else if (supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true)) +#endif + { + tmp = "DVB-C"; + } + else if (supportsDeliverySystem(SYS_DVBT, true) || supportsDeliverySystem(SYS_DVBT2, true)) + { + tmp = "DVB-T"; + } + else + { + tmp = "UNKNOWN"; } PutToDict(dest, "tuner_type", tmp); } @@ -1546,12 +1579,14 @@ int eDVBFrontend::tuneLoopInt() // called by m_tuneTimer tmp = prev->m_frontend->m_data[LINKED_PREV_PTR]; if (tmp == -1 && sec_fe != this && !prev->m_inuse) { int state = sec_fe->m_state; +#if 0 // Since following code causes lock fail for linked tuners in certain conditions, it does not apply. // workaround to put the kernel frontend thread into idle state! if (state != eDVBFrontend::stateIdle && state != stateClosed) { sec_fe->closeFrontend(true); state = sec_fe->m_state; } +#endif // sec_fe is closed... we must reopen it here.. if (state == stateClosed) { @@ -1919,34 +1954,39 @@ void eDVBFrontend::setFrontend(bool recvEvents) if (!m_simulate) { eDebug("setting frontend %d", m_dvbid); + + int type = -1; + oparm.getSystem(type); + if (recvEvents) m_sn->start(); feEvent(-1); // flush events -#if HAVE_DVB_API_VERSION >= 5 - if (m_type == iDVBFrontend::feSatellite) + if (type == iDVBFrontend::feSatellite) { fe_rolloff_t rolloff = ROLLOFF_35; fe_pilot_t pilot = PILOT_OFF; fe_modulation_t modulation = QPSK; fe_delivery_system_t system = SYS_DVBS; - switch(oparm.sat.system) + eDVBFrontendParametersSatellite sparm; + oparm.getDVBS(sparm); + switch(sparm.system) { case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break; case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break; }; - switch(oparm.sat.modulation) + switch(sparm.modulation) { case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break; case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break; case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break; }; - switch(oparm.sat.pilot) + switch(sparm.pilot) { case eDVBFrontendParametersSatellite::Pilot_Off: pilot = PILOT_OFF; break; case eDVBFrontendParametersSatellite::Pilot_On: pilot = PILOT_ON; break; case eDVBFrontendParametersSatellite::Pilot_Unknown: pilot = PILOT_AUTO; break; }; - switch(oparm.sat.rolloff) + switch(sparm.rolloff) { case eDVBFrontendParametersSatellite::RollOff_alpha_0_20: rolloff = ROLLOFF_20; break; case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break; @@ -1980,8 +2020,81 @@ void eDVBFrontend::setFrontend(bool recvEvents) return; } } - else + else if (type == iDVBFrontend::feCable) + { + struct dtv_property p[8]; + struct dtv_properties cmdseq; + cmdseq.props = p; + p[0].cmd = DTV_CLEAR; +#if defined SYS_DVBC_ANNEX_A + p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_A; +#else + p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = SYS_DVBC_ANNEX_AC; #endif + p[2].cmd = DTV_FREQUENCY, p[2].u.data = parm_frequency; + p[3].cmd = DTV_MODULATION, p[3].u.data = parm_u_qam_modulation; + p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qam_symbol_rate; + p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qam_fec_inner; + p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion; + p[7].cmd = DTV_TUNE; + cmdseq.num = 8; + if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1) + { + perror("FE_SET_PROPERTY failed"); + return; + } + } + else if (type == iDVBFrontend::feTerrestrial) + { + fe_delivery_system_t system = SYS_DVBT; + eDVBFrontendParametersTerrestrial tparm; + oparm.getDVBT(tparm); + switch (tparm.system) + { + default: + case eDVBFrontendParametersTerrestrial::System_DVB_T: system = SYS_DVBT; break; + case eDVBFrontendParametersTerrestrial::System_DVB_T2: system = SYS_DVBT2; break; + } + int bandwidth = 0; + switch (tparm.bandwidth) + { + case eDVBFrontendParametersTerrestrial::Bandwidth_8MHz: bandwidth = 8000000; break; + case eDVBFrontendParametersTerrestrial::Bandwidth_7MHz: bandwidth = 7000000; break; + case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: bandwidth = 6000000; break; + default: + case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: bandwidth = 0; break; + case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: bandwidth = 5000000; break; + case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: bandwidth = 10000000; break; + case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: bandwidth = 1712000; break; + } + struct dtv_property p[13]; + struct dtv_properties cmdseq; + cmdseq.props = p; + cmdseq.num = 0; + p[cmdseq.num].cmd = DTV_CLEAR, cmdseq.num++; + p[cmdseq.num].cmd = DTV_DELIVERY_SYSTEM, p[cmdseq.num].u.data = system, cmdseq.num++; + p[cmdseq.num].cmd = DTV_FREQUENCY, p[cmdseq.num].u.data = parm_frequency, cmdseq.num++; + p[cmdseq.num].cmd = DTV_CODE_RATE_LP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_LP, cmdseq.num++; + p[cmdseq.num].cmd = DTV_CODE_RATE_HP, p[cmdseq.num].u.data = parm_u_ofdm_code_rate_HP, cmdseq.num++; + p[cmdseq.num].cmd = DTV_MODULATION, p[cmdseq.num].u.data = parm_u_ofdm_constellation, cmdseq.num++; + p[cmdseq.num].cmd = DTV_TRANSMISSION_MODE, p[cmdseq.num].u.data = parm_u_ofdm_transmission_mode, cmdseq.num++; + p[cmdseq.num].cmd = DTV_GUARD_INTERVAL, p[cmdseq.num].u.data = parm_u_ofdm_guard_interval, cmdseq.num++; + p[cmdseq.num].cmd = DTV_HIERARCHY, p[cmdseq.num].u.data = parm_u_ofdm_hierarchy_information, cmdseq.num++; + p[cmdseq.num].cmd = DTV_BANDWIDTH_HZ, p[cmdseq.num].u.data = bandwidth, cmdseq.num++; + p[cmdseq.num].cmd = DTV_INVERSION, p[cmdseq.num].u.data = parm_inversion, cmdseq.num++; +#if defined DTV_STREAM_ID + p[cmdseq.num].cmd = DTV_STREAM_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++; +#elif defined DTV_DVBT2_PLP_ID + p[cmdseq.num].cmd = DTV_DVBT2_PLP_ID , p[cmdseq.num].u.data = tparm.plpid, cmdseq.num++; +#endif + p[cmdseq.num].cmd = DTV_TUNE, cmdseq.num++; + if (ioctl(m_fd, FE_SET_PROPERTY, &cmdseq) == -1) + { + perror("FE_SET_PROPERTY failed"); + return; + } + } + else { if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) { @@ -1992,14 +2105,6 @@ void eDVBFrontend::setFrontend(bool recvEvents) } } -RESULT eDVBFrontend::getFrontendType(int &t) -{ - if (m_type == -1) - return -ENODEV; - t = m_type; - return 0; -} - RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, unsigned int tunetimeout) { int res; @@ -2011,7 +2116,6 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout); if (!res) { -#if HAVE_DVB_API_VERSION >= 3 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", feparm.system, feparm.frequency, @@ -2024,16 +2128,6 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, feparm.modulation, feparm.pilot, feparm.rolloff); -#else - eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d", - feparm.system, - feparm.frequency, - feparm.polarisation, - feparm.symbol_rate, - feparm.inversion, - feparm.fec, - feparm.orbital_position); -#endif parm_u_qpsk_symbol_rate = feparm.symbol_rate; switch (feparm.inversion) { @@ -2077,7 +2171,6 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, break; } } -#if HAVE_DVB_API_VERSION >= 3 else // DVB_S2 { switch (feparm.fec) @@ -2113,17 +2206,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, eDebugNoSimulate("no valid fec for DVB-S2 set.. abort !!"); return -EINVAL; } -#if HAVE_DVB_API_VERSION < 5 - parm_inversion = (fe_spectral_inversion_t)((feparm.rolloff << 2) | parm_inversion); // Hack.. we use bit 2..3 of inversion param for rolloff - parm_inversion = (fe_spectral_inversion_t)((feparm.pilot << 4) | parm_inversion); // Hack.. we use bit 4..5 of inversion param for pilot - if (feparm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK) - { - parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)parm_u_qpsk_fec_inner+9); - // 8PSK fec driver values are decimal 9 bigger - } -#endif } -#endif // FIXME !!! get frequency range from tuner if ( parm_frequency < 900000 || parm_frequency > 2200000 ) { @@ -2132,17 +2215,13 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm, } eDebugNoSimulate("tuning to %d mhz", parm_frequency/1000); } - oparm.sat = feparm; + oparm.setDVBS(feparm, feparm.no_rotor_command_on_tune); return res; } RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm) { -#if HAVE_DVB_API_VERSION < 3 - parm_frequency = feparm.frequency; -#else parm_frequency = feparm.frequency * 1000; -#endif parm_u_qam_symbol_rate = feparm.symbol_rate; switch (feparm.modulation) { @@ -2199,11 +2278,9 @@ RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm) case eDVBFrontendParametersCable::FEC_7_8: parm_u_qam_fec_inner = FEC_7_8; break; -#if HAVE_DVB_API_VERSION >= 3 case eDVBFrontendParametersCable::FEC_8_9: parm_u_qam_fec_inner = FEC_8_9; break; -#endif default: case eDVBFrontendParametersCable::FEC_Auto: parm_u_qam_fec_inner = FEC_AUTO; @@ -2215,7 +2292,7 @@ RESULT eDVBFrontend::prepare_cable(const eDVBFrontendParametersCable &feparm) parm_u_qam_fec_inner, parm_u_qam_modulation, parm_inversion); - oparm.cab = feparm; + oparm.setDVBC(feparm); return 0; } @@ -2234,6 +2311,15 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial case eDVBFrontendParametersTerrestrial::Bandwidth_6MHz: parm_u_ofdm_bandwidth = BANDWIDTH_6_MHZ; break; + case eDVBFrontendParametersTerrestrial::Bandwidth_5MHz: + parm_u_ofdm_bandwidth = BANDWIDTH_5_MHZ; + break; + case eDVBFrontendParametersTerrestrial::Bandwidth_10MHz: + parm_u_ofdm_bandwidth = BANDWIDTH_10_MHZ; + break; + case eDVBFrontendParametersTerrestrial::Bandwidth_1_712MHz: + parm_u_ofdm_bandwidth = BANDWIDTH_1_712_MHZ; + break; default: case eDVBFrontendParametersTerrestrial::Bandwidth_Auto: parm_u_ofdm_bandwidth = BANDWIDTH_AUTO; @@ -2256,6 +2342,12 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial case eDVBFrontendParametersTerrestrial::FEC_7_8: parm_u_ofdm_code_rate_LP = FEC_7_8; break; + case eDVBFrontendParametersTerrestrial::FEC_6_7: + parm_u_ofdm_code_rate_LP = FEC_6_7; + break; + case eDVBFrontendParametersTerrestrial::FEC_8_9: + parm_u_ofdm_code_rate_LP = FEC_8_9; + break; default: case eDVBFrontendParametersTerrestrial::FEC_Auto: parm_u_ofdm_code_rate_LP = FEC_AUTO; @@ -2278,6 +2370,12 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial case eDVBFrontendParametersTerrestrial::FEC_7_8: parm_u_ofdm_code_rate_HP = FEC_7_8; break; + case eDVBFrontendParametersTerrestrial::FEC_6_7: + parm_u_ofdm_code_rate_HP = FEC_6_7; + break; + case eDVBFrontendParametersTerrestrial::FEC_8_9: + parm_u_ofdm_code_rate_HP = FEC_8_9; + break; default: case eDVBFrontendParametersTerrestrial::FEC_Auto: parm_u_ofdm_code_rate_HP = FEC_AUTO; @@ -2294,6 +2392,9 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial case eDVBFrontendParametersTerrestrial::Modulation_QAM64: parm_u_ofdm_constellation = QAM_64; break; + case eDVBFrontendParametersTerrestrial::Modulation_QAM256: + parm_u_ofdm_constellation = QAM_256; + break; default: case eDVBFrontendParametersTerrestrial::Modulation_Auto: parm_u_ofdm_constellation = QAM_AUTO; @@ -2307,6 +2408,18 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial case eDVBFrontendParametersTerrestrial::TransmissionMode_8k: parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_8K; break; + case eDVBFrontendParametersTerrestrial::TransmissionMode_4k: + parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_4K; + break; + case eDVBFrontendParametersTerrestrial::TransmissionMode_1k: + parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_1K; + break; + case eDVBFrontendParametersTerrestrial::TransmissionMode_16k: + parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_16K; + break; + case eDVBFrontendParametersTerrestrial::TransmissionMode_32k: + parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_32K; + break; default: case eDVBFrontendParametersTerrestrial::TransmissionMode_Auto: parm_u_ofdm_transmission_mode = TRANSMISSION_MODE_AUTO; @@ -2326,6 +2439,15 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial case eDVBFrontendParametersTerrestrial::GuardInterval_1_4: parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_4; break; + case eDVBFrontendParametersTerrestrial::GuardInterval_1_128: + parm_u_ofdm_guard_interval = GUARD_INTERVAL_1_128; + break; + case eDVBFrontendParametersTerrestrial::GuardInterval_19_128: + parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_128; + break; + case eDVBFrontendParametersTerrestrial::GuardInterval_19_256: + parm_u_ofdm_guard_interval = GUARD_INTERVAL_19_256; + break; default: case eDVBFrontendParametersTerrestrial::GuardInterval_Auto: parm_u_ofdm_guard_interval = GUARD_INTERVAL_AUTO; @@ -2363,7 +2485,19 @@ RESULT eDVBFrontend::prepare_terrestrial(const eDVBFrontendParametersTerrestrial parm_inversion = INVERSION_AUTO; break; } - oparm.ter = feparm; + 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", + parm_frequency/1000, + parm_u_ofdm_bandwidth, + parm_u_ofdm_code_rate_LP, + parm_u_ofdm_code_rate_HP, + parm_u_ofdm_constellation, + parm_u_ofdm_transmission_mode, + parm_u_ofdm_guard_interval, + parm_u_ofdm_hierarchy_information, + parm_inversion, + feparm.system, + feparm.plpid); + oparm.setDVBT(feparm); return 0; } @@ -2376,15 +2510,16 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) int res=0; - if (!m_sn && !m_simulate) + int type; + if (where.getSystem(type) < 0) { - eDebug("no frontend device opened... do not try to tune !!!"); - res = -ENODEV; + res = -EINVAL; goto tune_error; } - if (m_type == -1) + if (!m_sn && !m_simulate) { + eDebug("no frontend device opened... do not try to tune !!!"); res = -ENODEV; goto tune_error; } @@ -2396,7 +2531,7 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) where.calcLockTimeout(timeout); - switch (m_type) + switch (type) { case feSatellite: { @@ -2471,6 +2606,11 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) break; } + default: + { + res = -EINVAL; + goto tune_error; + } } m_sec_sequence.current() = m_sec_sequence.begin(); @@ -2503,14 +2643,8 @@ RESULT eDVBFrontend::connectStateChange(const Slot1 &stateCh RESULT eDVBFrontend::setVoltage(int voltage) { - if (m_type == feCable) - return -1; -#if HAVE_DVB_API_VERSION < 3 - secVoltage vlt; -#else bool increased=false; fe_sec_voltage_t vlt; -#endif m_data[CUR_VOLTAGE]=voltage; switch (voltage) { @@ -2519,22 +2653,12 @@ RESULT eDVBFrontend::setVoltage(int voltage) vlt = SEC_VOLTAGE_OFF; break; case voltage13_5: -#if HAVE_DVB_API_VERSION < 3 - vlt = SEC_VOLTAGE_13_5; - break; -#else increased = true; -#endif case voltage13: vlt = SEC_VOLTAGE_13; break; case voltage18_5: -#if HAVE_DVB_API_VERSION < 3 - vlt = SEC_VOLTAGE_18_5; - break; -#else increased = true; -#endif case voltage18: vlt = SEC_VOLTAGE_18; break; @@ -2543,13 +2667,9 @@ RESULT eDVBFrontend::setVoltage(int voltage) } if (m_simulate) return 0; -#if HAVE_DVB_API_VERSION < 3 - return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt); -#else - if (m_type == feSatellite && ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased) < 0) - perror("FE_ENABLE_HIGH_LNB_VOLTAGE"); + + ::ioctl(m_fd, FE_ENABLE_HIGH_LNB_VOLTAGE, increased); return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt); -#endif } RESULT eDVBFrontend::getState(int &state) @@ -2560,13 +2680,7 @@ RESULT eDVBFrontend::getState(int &state) RESULT eDVBFrontend::setTone(int t) { - if (m_type != feSatellite) - return -1; -#if HAVE_DVB_API_VERSION < 3 - secToneMode_t tone; -#else fe_sec_tone_mode_t tone; -#endif m_data[CUR_TONE]=t; switch (t) { @@ -2581,63 +2695,34 @@ RESULT eDVBFrontend::setTone(int t) } if (m_simulate) return 0; -#if HAVE_DVB_API_VERSION < 3 - return ::ioctl(m_secfd, SEC_SET_TONE, tone); -#else + return ::ioctl(m_fd, FE_SET_TONE, tone); -#endif } -#if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_MASTER_CMD) - #define SEC_DISEQC_SEND_MASTER_CMD _IOW('o', 97, struct secCommand *) -#endif - RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc) { if (m_simulate) return 0; -#if HAVE_DVB_API_VERSION < 3 - struct secCommand cmd; - cmd.type = SEC_CMDTYPE_DISEQC_RAW; - cmd.u.diseqc.cmdtype = diseqc.data[0]; - cmd.u.diseqc.addr = diseqc.data[1]; - cmd.u.diseqc.cmd = diseqc.data[2]; - cmd.u.diseqc.numParams = diseqc.len-3; - memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3); - if (::ioctl(m_secfd, SEC_DISEQC_SEND_MASTER_CMD, &cmd)) -#else + struct dvb_diseqc_master_cmd cmd; memcpy(cmd.msg, diseqc.data, diseqc.len); cmd.msg_len = diseqc.len; if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd)) -#endif return -EINVAL; return 0; } -#if HAVE_DVB_API_VERSION < 3 && !defined(SEC_DISEQC_SEND_BURST) - #define SEC_DISEQC_SEND_BURST _IO('o', 96) -#endif RESULT eDVBFrontend::sendToneburst(int burst) { if (m_simulate) return 0; -#if HAVE_DVB_API_VERSION < 3 - secMiniCmd cmd = SEC_MINI_NONE; -#else fe_sec_mini_cmd_t cmd = SEC_MINI_A; -#endif if ( burst == eDVBSatelliteDiseqcParameters::A ) cmd = SEC_MINI_A; else if ( burst == eDVBSatelliteDiseqcParameters::B ) cmd = SEC_MINI_B; -#if HAVE_DVB_API_VERSION < 3 - if (::ioctl(m_secfd, SEC_DISEQC_SEND_BURST, cmd)) - return -EINVAL; -#else if (::ioctl(m_fd, FE_DISEQC_SEND_BURST, cmd)) return -EINVAL; -#endif return 0; } @@ -2656,6 +2741,24 @@ RESULT eDVBFrontend::setSecSequence(eSecCommandList &list) return 0; } +bool eDVBFrontend::isScheduledSendDiseqc() +{ + bool has_senddiseqc = false; + if ( m_sec_sequence && m_sec_sequence.current() != m_sec_sequence.end() ) + { + eSecCommandList::iterator cur = m_sec_sequence.current(); + while(cur != m_sec_sequence.end()) + { + if (((cur++)->cmd == eSecCommand::SEND_DISEQC)) + { + has_senddiseqc = true; + break; + } + } + } + return has_senddiseqc; +} + RESULT eDVBFrontend::getData(int num, long &data) { if ( num < NUM_DATA_ENTRIES ) @@ -2679,40 +2782,132 @@ RESULT eDVBFrontend::setData(int num, long val) int eDVBFrontend::isCompatibleWith(ePtr &feparm) { int type; - if (feparm->getSystem(type) || type != m_type || !m_enabled) + int score = 0; + bool preferred = (eDVBFrontend::getPreferredFrontend() >= 0 && m_slotid == eDVBFrontend::getPreferredFrontend()); + + if (feparm->getSystem(type) || !m_enabled) return 0; - if (m_type == eDVBFrontend::feSatellite) + + if (type == eDVBFrontend::feSatellite) { - ASSERT(m_sec); eDVBFrontendParametersSatellite sat_parm; - int ret = feparm->getDVBS(sat_parm); - ASSERT(!ret); - if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !m_can_handle_dvbs2) + bool can_handle_dvbs, can_handle_dvbs2; + can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true); + can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true); + if (feparm->getDVBS(sat_parm) < 0) + { return 0; - ret = m_sec->canTune(sat_parm, this, 1 << m_slotid); - if (ret > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && m_can_handle_dvbs2) - ret -= 1; - return ret; - } - else if (m_type == eDVBFrontend::feCable) - return 2; // more prio for cable frontends - else if (m_type == eDVBFrontend::feTerrestrial) - return 1; - return 0; + } + if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2) + { + return 0; + } + if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && !can_handle_dvbs) + { + return 0; + } + score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0; + if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2) + { + /* prefer to use a S tuner, try to keep S2 free for S2 transponders */ + score--; + } + } + + else if (type == eDVBFrontend::feCable) + { + eDVBFrontendParametersCable cab_parm; + if (feparm->getDVBC(cab_parm) < 0) + { + return 0; + } +#if defined SYS_DVBC_ANNEX_A + if (!supportsDeliverySystem(SYS_DVBC_ANNEX_A, true)) +#else + if (!supportsDeliverySystem(SYS_DVBC_ANNEX_AC, true)) +#endif + { + return 0; + } + score = 2; + } + + else if (type == eDVBFrontend::feTerrestrial) + { + eDVBFrontendParametersTerrestrial ter_parm; + bool can_handle_dvbt, can_handle_dvbt2; + can_handle_dvbt = supportsDeliverySystem(SYS_DVBT, true); + can_handle_dvbt2 = supportsDeliverySystem(SYS_DVBT2, true); + if (feparm->getDVBT(ter_parm) < 0) + { + return 0; + } + if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && !can_handle_dvbt) + { + return 0; + } + if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T2 && !can_handle_dvbt2) + { + return 0; + } + score = 2; + if (ter_parm.system == eDVBFrontendParametersTerrestrial::System_DVB_T && can_handle_dvbt2) + { + /* prefer to use a T tuner, try to keep T2 free for T2 transponders */ + score--; + } + } + + if (score && preferred) + { + /* make 'sure' we always prefer this frontend */ + score += 100000; + } + + return score; +} + +bool eDVBFrontend::supportsDeliverySystem(const fe_delivery_system_t &sys, bool obeywhitelist) +{ + std::map::iterator it = m_delsys.find(sys); + if (it != m_delsys.end() && it->second) + { + if (obeywhitelist && !m_delsys_whitelist.empty()) + { + it = m_delsys_whitelist.find(sys); + if (it == m_delsys_whitelist.end() || !it->second) return false; + } + return true; + } + return false; +} + +void eDVBFrontend::setDeliverySystemWhitelist(const std::vector &whitelist) +{ + m_delsys_whitelist.clear(); + for (unsigned int i = 0; i < whitelist.size(); i++) + { + m_delsys_whitelist[whitelist[i]] = true; + } + if (m_simulate_fe) + { + m_simulate_fe->setDeliverySystemWhitelist(whitelist); + } } bool eDVBFrontend::setSlotInfo(ePyObject obj) { - ePyObject Id, Descr, Enabled, IsDVBS2, frontendId; - if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5) + ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId; + if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6) goto arg_error; Id = PyTuple_GET_ITEM(obj, 0); Descr = PyTuple_GET_ITEM(obj, 1); Enabled = PyTuple_GET_ITEM(obj, 2); IsDVBS2 = PyTuple_GET_ITEM(obj, 3); - frontendId = PyTuple_GET_ITEM(obj, 4); + IsDVBT2 = PyTuple_GET_ITEM(obj, 4); + frontendId = PyTuple_GET_ITEM(obj, 5); m_slotid = PyInt_AsLong(Id); - if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId)) + if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId)) goto arg_error; strcpy(m_description, PyString_AS_STRING(Descr)); if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) { @@ -2720,15 +2915,25 @@ bool eDVBFrontend::setSlotInfo(ePyObject obj) // m_slotid, m_description); return false; } - m_enabled = Enabled == Py_True; + m_enabled = (Enabled == Py_True); // HACK.. the rotor workaround is neede for all NIMs with LNBP21 voltage regulator... m_need_rotor_workaround = !!strstr(m_description, "Alps BSBE1") || !!strstr(m_description, "Alps BSBE2") || !!strstr(m_description, "Alps -S") || !!strstr(m_description, "BCM4501"); - m_can_handle_dvbs2 = IsDVBS2 == Py_True; - eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s", - m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", m_enabled ? "Yes" : "No", m_can_handle_dvbs2 ? "Yes" : "No" ); + if (IsDVBS2 == Py_True) + { + /* HACK for legacy dvb api without DELSYS support */ + m_delsys[SYS_DVBS2] = true; + } + if (IsDVBT2 == Py_True) + { + /* HACK for legacy dvb api without DELSYS support */ + m_delsys[SYS_DVBT2] = true; + } + + eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s", + 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" ); return true; arg_error: PyErr_SetString(PyExc_StandardError,