X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/02da1f586ef7945fef385e6d4743ef53441bc2fa..18ee5e9c8a01b3ddd899a6aeea40ab0a6ce3da7d:/lib/dvb/frontend.cpp diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 8948f194..411e118f 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,7 +6,22 @@ #include #include +#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 constellation Constellation +#define guard_interval guardInterval +#define hierarchy_information HierarchyInformation +#define code_rate_HP HP_CodeRate +#define code_rate_LP LP_CodeRate +#else #include +#endif #include #include @@ -73,7 +89,7 @@ void eDVBFrontendParametersTerrestrial::set(const TerrestrialDeliverySystemDescr eFatal("nyi"); } -eDVBFrontendParameters::eDVBFrontendParameters(): ref(0), m_type(-1) +eDVBFrontendParameters::eDVBFrontendParameters(): m_type(-1) { } @@ -188,16 +204,36 @@ RESULT eDVBFrontendParameters::getHash(unsigned long &hash) const DEFINE_REF(eDVBFrontend); -eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): ref(0), m_type(-1) +eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): m_type(-1) { +#if HAVE_DVB_API_VERSION < 3 + char sec_filename[128]; +#endif char filename[128]; + int result; - dvb_frontend_info fe_info; - + m_sn = 0; m_timeout = 0; - + +#if HAVE_DVB_API_VERSION < 3 + sprintf(sec_filename, "/dev/dvb/card%d/sec%d", adap, fe); + m_secfd = ::open(sec_filename, O_RDWR); + if (m_secfd < 0) + { + eWarning("failed! (%s) %m", sec_filename); + ok = 0; + return; + } + else + eDebug("m_secfd is %d", m_secfd); + + FrontendInfo fe_info; + sprintf(filename, "/dev/dvb/card%d/frontend%d", adap, fe); +#else + dvb_frontend_info fe_info; sprintf(filename, "/dev/dvb/adapter%d/frontend%d", adap, fe); +#endif eDebug("opening frontend."); m_fd = ::open(filename, O_RDWR|O_NONBLOCK); if (m_fd < 0) @@ -206,7 +242,7 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): ref(0), m_type(-1) ok = 0; return; } - + result = ::ioctl(m_fd, FE_GET_INFO, &fe_info); if (result < 0) { @@ -235,7 +271,7 @@ eDVBFrontend::eDVBFrontend(int adap, int fe, int &ok): ref(0), m_type(-1) ok = 0; return; } - eDebug("detected %s frontend", "satellite\0cable\0 terrestrial"+feSatellite*9); + eDebug("detected %s frontend", "satellite\0cable\0 terrestrial"+fe_info.type*9); ok = 1; m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Read); @@ -262,7 +298,11 @@ 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); @@ -278,9 +318,13 @@ void eDVBFrontend::feEvent(int w) if (w < 0) continue; - + +#if HAVE_DVB_API_VERSION < 3 + if (event.type == FE_COMPLETION_EV) +#else eDebug("fe event: status %x, inversion %s", event.status, (event.parameters.inversion == INVERSION_ON) ? "on" : "off"); if (event.status & FE_HAS_LOCK) +#endif { state = stateLock; } else @@ -327,10 +371,12 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) if (m_type == -1) return -ENODEV; - dvb_frontend_parameters parm; - + FRONTENDPARAMETERS parm; + feEvent(-1); + eDebug("eDVBFrontend::tune. type: %d", m_type); + switch (m_type) { case feSatellite: @@ -351,8 +397,11 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) res = m_sec->prepare(*this, parm, feparm); if (res) return res; - +#if HAVE_DVB_API_VERSION < 3 + eDebug("tuning to %d mhz", parm.Frequency/1000); +#else eDebug("tuning to %d mhz", parm.frequency/1000); +#endif break; } case feCable: @@ -366,11 +415,113 @@ RESULT eDVBFrontend::tune(const iDVBFrontendParameters &where) { eDVBFrontendParametersTerrestrial feparm; if (where.getDVBT(feparm)) + { + eDebug("no -T data"); + return -EINVAL; + } +#if HAVE_DVB_API_VERSION < 3 + parm.Frequency = feparm.frequency; +#else + parm.frequency = feparm.frequency; +#endif + + switch (feparm.bandwidth) + { + case eDVBFrontendParametersTerrestrial::Bandwidth::Bw8MHz: +#if HAVE_DVB_API_VERSION < 3 + parm.u.ofdm.bandWidth = +#else + parm.u.ofdm.bandwidth = +#endif + BANDWIDTH_8_MHZ; + break; + case eDVBFrontendParametersTerrestrial::Bandwidth::Bw7MHz: +#if HAVE_DVB_API_VERSION < 3 + parm.u.ofdm.bandWidth = +#else + parm.u.ofdm.bandwidth = +#endif + BANDWIDTH_7_MHZ; + break; + case eDVBFrontendParametersTerrestrial::Bandwidth::Bw6MHz: +#if HAVE_DVB_API_VERSION < 3 + parm.u.ofdm.bandWidth = +#else + parm.u.ofdm.bandwidth = +#endif + BANDWIDTH_6_MHZ; + break; + case eDVBFrontendParametersTerrestrial::Bandwidth::BwAuto: +#if HAVE_DVB_API_VERSION < 3 + parm.u.ofdm.bandWidth = +#else + parm.u.ofdm.bandwidth = +#endif + BANDWIDTH_AUTO; + break; + default: + eWarning("invalid OFDM bandwith"); return -EINVAL; - eFatal("terrestrial tuning nyi"); + } + + parm.u.ofdm.code_rate_HP = FEC_AUTO; + parm.u.ofdm.code_rate_LP = FEC_AUTO; + + switch (feparm.modulation) + { + case eDVBFrontendParametersTerrestrial::Modulation::QPSK: + parm.u.ofdm.constellation = QPSK; + break; + case eDVBFrontendParametersTerrestrial::Modulation::QAM16: + parm.u.ofdm.constellation = QAM_16; + break; + case eDVBFrontendParametersTerrestrial::Modulation::Auto: + parm.u.ofdm.constellation = QAM_AUTO; + break; + } + + switch (feparm.transmission_mode) + { + case eDVBFrontendParametersTerrestrial::TransmissionMode::TM2k: +#if HAVE_DVB_API_VERSION < 3 + parm.u.ofdm.TransmissionMode = +#else + parm.u.ofdm.transmission_mode = +#endif + TRANSMISSION_MODE_2K; + break; + case eDVBFrontendParametersTerrestrial::TransmissionMode::TM8k: +#if HAVE_DVB_API_VERSION < 3 + parm.u.ofdm.TransmissionMode = +#else + parm.u.ofdm.transmission_mode = +#endif + TRANSMISSION_MODE_8K; + break; + case eDVBFrontendParametersTerrestrial::TransmissionMode::TMAuto: +#if HAVE_DVB_API_VERSION < 3 + parm.u.ofdm.TransmissionMode = +#else + parm.u.ofdm.transmission_mode = +#endif + TRANSMISSION_MODE_AUTO; + break; + } + + parm.u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; + parm.u.ofdm.hierarchy_information = HIERARCHY_AUTO; +#if HAVE_DVB_API_VERSION < 3 + parm.Inversion = +#else + parm.inversion = +#endif + INVERSION_AUTO; + break; } } + eDebug("setting frontend..\n"); + if (ioctl(m_fd, FE_SET_FRONTEND, &parm) == -1) { perror("FE_SET_FRONTEND failed"); @@ -397,8 +548,12 @@ RESULT eDVBFrontend::connectStateChange(const Slot1 &stateCh RESULT eDVBFrontend::setVoltage(int voltage) { +#if HAVE_DVB_API_VERSION < 3 + secVoltage vlt; +#else fe_sec_voltage_t vlt; - +#endif + switch (voltage) { case voltageOff: @@ -413,8 +568,11 @@ RESULT eDVBFrontend::setVoltage(int voltage) default: return -ENODEV; } - +#if HAVE_DVB_API_VERSION < 3 + return ::ioctl(m_secfd, SEC_SET_VOLTAGE, vlt); +#else return ::ioctl(m_fd, FE_SET_VOLTAGE, vlt); +#endif } RESULT eDVBFrontend::getState(int &state) @@ -425,8 +583,12 @@ RESULT eDVBFrontend::getState(int &state) RESULT eDVBFrontend::setTone(int t) { +#if HAVE_DVB_API_VERSION < 3 + secToneMode_t tone; +#else fe_sec_tone_mode_t tone; - +#endif + switch (t) { case toneOn: @@ -438,12 +600,48 @@ RESULT eDVBFrontend::setTone(int t) default: return -ENODEV; } - - return ::ioctl(m_fd, FE_SET_TONE, tone); +#if HAVE_DVB_API_VERSION < 3 + return ::ioctl(m_secfd, SEC_SET_TONE, tone); +#else + return ::ioctl(m_fd, FE_SET_TONE, tone); +#endif } RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc) { +#if HAVE_DVB_API_VERSION < 3 + secCmdSequence seq; + secCommand cmd; + + cmd.type = SEC_CMDTYPE_DISEQC_RAW; + cmd.u.diseqc.cmdtype = diseqc.data[0]; + eDebug("cmdtype is %02x", diseqc.data[0]); + cmd.u.diseqc.addr = diseqc.data[1]; + eDebug("cmdaddr is %02x", diseqc.data[1]); + cmd.u.diseqc.cmd = diseqc.data[2]; + eDebug("cmd is %02x", diseqc.data[2]); + cmd.u.diseqc.numParams = diseqc.len-3; + eDebug("numparams %d", diseqc.len-3); + + memcpy(cmd.u.diseqc.params, diseqc.data+3, diseqc.len-3); + for (int i=0; i < diseqc.len-3; ++i ) + eDebugNoNewLine("%02x ", diseqc.data[3+i]); + eDebug(""); + + seq.continuousTone = SEC_TONE_OFF; + seq.voltage = SEC_VOLTAGE_13; + seq.miniCommand = SEC_MINI_NONE; + seq.commands=&cmd; + seq.numCommands=1; + + + if ( ioctl(m_secfd, SEC_SEND_SEQUENCE, &seq) < 0 ) + { + eDebug("SEC_SEND_SEQUENCE failed ( %m )"); + return -EINVAL; + } + return 0; +#else struct dvb_diseqc_master_cmd cmd; if (::ioctl(m_fd, FE_SET_TONE, SEC_TONE_OFF)) return -EINVAL; @@ -454,6 +652,7 @@ RESULT eDVBFrontend::sendDiseqc(const eDVBDiseqcCommand &diseqc) if (::ioctl(m_fd, FE_DISEQC_SEND_MASTER_CMD, &cmd)) return -EINVAL; usleep(15 * 1000); +#endif eDebug("diseqc ok"); return 0; }