From: atx23 Date: Fri, 28 Nov 2008 08:30:50 +0000 (+0000) Subject: implemented DVBFrontendHandle X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=69bcc009d679b71b816b9a1bfd11dfaf6c980fd1;p=senf.git implemented DVBFrontendHandle git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@986 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Socket/Protocols/DVB/DVBFrontendHandle.cc b/Socket/Protocols/DVB/DVBFrontendHandle.cc index a393eb2..20c8caa 100644 --- a/Socket/Protocols/DVB/DVBFrontendHandle.cc +++ b/Socket/Protocols/DVB/DVBFrontendHandle.cc @@ -32,6 +32,10 @@ #include #include #include "../../../Utils/Exception.hh" +#include +#include +#include + //#include "DVBFrontendHandle.mpp" #define prefix_ @@ -39,17 +43,22 @@ /////////////////////////////////////////////////////////////////////////// // senf::DVBFrontendHandle +using namespace std; -prefix_ void senf::DVBFrontendSocketProtocol::init_client(boost::uint8_t adapter, boost::uint8_t device) - const +prefix_ void senf::DVBFrontendSocketProtocol::init_client(unsigned const short adapter,unsigned const short device) { - std::string devFrontend = str( boost::format( - "/dev/dvb/adapter%d/frontend%d") % adapter % device); + string devFrontend = str( boost::format("/dev/dvb/adapter%d/frontend%d") % adapter % device); int f = open(devFrontend.c_str(), O_RDONLY | O_NONBLOCK); if (f < 0) - SENF_THROW_SYSTEM_EXCEPTION("") - << "Could not open frontend device of DVB adapter " << devFrontend << "."; + SENF_THROW_SYSTEM_EXCEPTION("")<< "Could not open frontend device of DVB adapter " << devFrontend << "."; fd(f); + + // later there will be a decision between waitTune and asyncTune + cb2_X_Tune = boost::bind(&senf::DVBFrontendSocketProtocol::waitTune, this, _1); + + struct dvb_frontend_info info; + ioctl(fd(), FE_GET_INFO, &info); + } prefix_ unsigned senf::DVBFrontendSocketProtocol::available() @@ -64,10 +73,248 @@ prefix_ bool senf::DVBFrontendSocketProtocol::eof() return false; } +prefix_ struct dvb_frontend_event senf::DVBFrontendSocketProtocol::tune(const struct dvb_frontend_parameters & frontend){ + return cb2_X_Tune(frontend); +} +prefix_ struct dvb_frontend_event senf::DVBFrontendSocketProtocol::waitTune(const struct dvb_frontend_parameters & frontend) { + // tuning + if ( ::ioctl(fd(), FE_SET_FRONTEND, &frontend) ) + SENF_THROW_SYSTEM_EXCEPTION("") << "Could not write on frontend device. Socket should initialized with write permissions."; + // getting event + struct dvb_frontend_event ev; + ::ioctl(fd(), FE_GET_EVENT, &ev); + + return ev; +} + +prefix_ struct dvb_frontend_event senf::DVBFrontendSocketProtocol::asyncTune(const struct dvb_frontend_parameters & frontend){ + // tuning + if ( ::ioctl(fd(), FE_SET_FRONTEND, &frontend) ) + SENF_THROW_SYSTEM_EXCEPTION("") << "Could not write on frontend device. Socket should initialized with write permissions."; + + // do something async here + struct dvb_frontend_event ev; + return ev; +} + +prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_T(unsigned int frequency, + fe_spectral_inversion_t inversion, + fe_bandwidth_t bandwidth, + fe_code_rate_t code_rate_HP, /* high priority stream code rate */ + fe_code_rate_t code_rate_LP, /* low priority stream code rate */ + fe_modulation_t constellation, /* modulation type */ + fe_transmit_mode_t transmission_mode, + fe_guard_interval_t guard_interval, + fe_hierarchy_t hierarchy_information + ) +{ + struct dvb_ofdm_parameters ofdm; /* DVB-T Parameters */ + struct dvb_frontend_parameters frontend; + + ofdm.bandwidth = bandwidth; + ofdm.code_rate_HP = code_rate_HP; + ofdm.code_rate_LP = code_rate_LP; + ofdm.constellation = constellation; + ofdm.guard_interval = guard_interval; + ofdm.hierarchy_information = hierarchy_information; + + frontend.frequency = frequency; + frontend.inversion = inversion; + frontend.u.ofdm = ofdm; + + tune(frontend); + +} +prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_S(unsigned int frequency, + fe_spectral_inversion_t inversion, + unsigned int symbole_rate, /* symbol rate in Symbols per second */ + fe_code_rate_t fec_inner) /* forward error correction (see above) */ +{ + struct dvb_qpsk_parameters qpsk; /* DVB-S Parameters*/ + struct dvb_frontend_parameters frontend; + + qpsk.symbol_rate = symbole_rate; + qpsk.fec_inner = fec_inner; + + frontend.frequency = frequency; + frontend.inversion = inversion; + frontend.u.qpsk = qpsk; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_C(unsigned int frequency, + fe_spectral_inversion_t inversion, + unsigned int symbol_rate, + fe_code_rate_t fec_inner, + fe_modulation_t modulation) +{ + struct dvb_qam_parameters qam; /* DVB-C Parameters*/ + struct dvb_frontend_parameters frontend; + + qam.symbol_rate = symbol_rate; + qam.fec_inner = fec_inner; + qam.modulation = modulation; + + + frontend.frequency = frequency; + frontend.inversion = inversion; + frontend.u.qam = qam; + + tune(frontend); +} +prefix_ struct dvb_frontend_info senf::DVBFrontendSocketProtocol::getInfo() + const +{ + struct dvb_frontend_info info; + if( ::ioctl(fd(), FE_GET_INFO, &info) ) { + SENF_THROW_SYSTEM_EXCEPTION("") << "Could not read on fildescriptor."; + } + return info; +} + +prefix_ struct dvb_frontend_parameters senf::DVBFrontendSocketProtocol::getFrontendParam() const { + struct dvb_frontend_parameters frontend; + + if ( ::ioctl(fd(), FE_GET_FRONTEND, &frontend) ) + SENF_THROW_SYSTEM_EXCEPTION("") << "Could not read from frontend device, read-only access to the device is sufficient."; + return frontend; +} + +prefix_ void senf::DVBFrontendSocketProtocol::setFrequency(unsigned int frequency){ + + struct dvb_frontend_parameters frontend = getFrontendParam(); + + frontend.frequency = frequency; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setInversion(fe_spectral_inversion_t inversion){ + + struct dvb_frontend_parameters frontend = getFrontendParam(); + + frontend.inversion = inversion; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setCodeRate(fe_code_rate_t fec_inner){ + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + if( type == FE_QPSK ){ /* DVB-S */ + frontend.u.qpsk.fec_inner = fec_inner; + } + if( type == FE_QAM ){ /* DVB-C */ + frontend.u.qam.fec_inner = fec_inner; + } + if( type == FE_OFDM ){ /* DVB-T ATTENTION sets high and low priority code rate!*/ + frontend.u.ofdm.code_rate_HP = fec_inner; + frontend.u.ofdm.code_rate_LP = fec_inner; + } + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setSymbolRate(unsigned int symbol_rate){ + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + + if (! ( type == FE_QPSK || type == FE_QAM ) ) + SENF_THROW_SYSTEM_EXCEPTION("Symbole rate can only be set for DVB-S or DVB-C devices."); + if( type == FE_QPSK ) /* DVB-S */ + frontend.u.qpsk.symbol_rate = symbol_rate; + + if( type == FE_QAM ) /* DVB-C */ + frontend.u.qam.symbol_rate = symbol_rate; + + tune(frontend); +} +prefix_ void senf::DVBFrontendSocketProtocol::setModulation(fe_modulation_t modulation){ + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + + if (! ( type == FE_OFDM || type == FE_QAM ) ) + SENF_THROW_SYSTEM_EXCEPTION("Symbole rate can only be set for DVB-T or DVB-C devices."); + if( type == FE_QAM ) /* DVB-C */ + frontend.u.qam.modulation = modulation; + if( type == FE_OFDM ) /* DVB-T */ + frontend.u.ofdm.constellation = modulation; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setBandwidth(fe_bandwidth_t bandwidth) { + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + + if (type != FE_OFDM) + SENF_THROW_SYSTEM_EXCEPTION("") << "Bandwidth can only be set for DVB-T devices."; + + frontend.u.ofdm.bandwidth = bandwidth; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setHighPriorityCodeRate(fe_code_rate_t code_rate_HP) { + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + + if (type != FE_OFDM) + SENF_THROW_SYSTEM_EXCEPTION("") << "High priority bandwidth can only be set for DVB-T devices."; + + frontend.u.ofdm.code_rate_HP = code_rate_HP; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setLowPriorityCodeRate(fe_code_rate_t code_rate_LP) { + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + + if (type != FE_OFDM) + SENF_THROW_SYSTEM_EXCEPTION("") << "Low priority bandwidth can only be set for DVB-T devices."; + + frontend.u.ofdm.code_rate_LP = code_rate_LP; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setGuardInterval(fe_guard_interval_t guard_interval) { + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + + if (type != FE_OFDM) + SENF_THROW_SYSTEM_EXCEPTION("") << "Guard interval can only be set for DVB-T devices."; + + frontend.u.ofdm.guard_interval = guard_interval; + + tune(frontend); +} + +prefix_ void senf::DVBFrontendSocketProtocol::setHierarchyInformation(fe_hierarchy_t hierarchy_information) { + + fe_type_t type = getInfo().type; + struct dvb_frontend_parameters frontend = getFrontendParam(); + + if (type != FE_OFDM) + SENF_THROW_SYSTEM_EXCEPTION("") << "Hierachy information can only be set for DVB-T devices."; + + frontend.u.ofdm.hierarchy_information = hierarchy_information; + + tune(frontend); +} + prefix_ int16_t senf::DVBFrontendSocketProtocol::signalStrength() const { - int16_t strength; + int16_t strength; if (::ioctl(fd(), FE_READ_SIGNAL_STRENGTH, &strength) < 0) SENF_THROW_SYSTEM_EXCEPTION("Could not get signal strength of DVB adapter."); return strength; diff --git a/Socket/Protocols/DVB/DVBFrontendHandle.hh b/Socket/Protocols/DVB/DVBFrontendHandle.hh index 04cc21a..74c58d5 100644 --- a/Socket/Protocols/DVB/DVBFrontendHandle.hh +++ b/Socket/Protocols/DVB/DVBFrontendHandle.hh @@ -28,12 +28,18 @@ // Custom includes #include +#include +#include #include #include "../../../Socket/FramingPolicy.hh" #include "../../../Socket/CommunicationPolicy.hh" #include "../../../Socket/ReadWritePolicy.hh" #include "../../../Socket/ProtocolClientSocketHandle.hh" #include "../../../Socket/SocketProtocol.hh" +#include +#include + + //#include "DVBFrontendHandle.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -49,29 +55,94 @@ namespace senf { UnconnectedCommunicationPolicy, NotReadablePolicy, NotWriteablePolicy - >::policy DVBFrontend_Policy; ///< Socket Policy for DVBFrontendSocketProtocol +> ::policy DVBFrontend_Policy; ///< Socket Policy for DVBFrontendSocketProtocol + /** \brief SocketProtocol for the dvb frontend device The DVB frontend device controls the tuner and DVB demodulator hardware. */ + class DVBFrontendSocketProtocol : public ConcreteSocketProtocol { + private: + dvb_frontend_event tune(const struct dvb_frontend_parameters & frontend); + struct dvb_frontend_event waitTune(const struct dvb_frontend_parameters & frontend); + struct dvb_frontend_event asyncTune(const struct dvb_frontend_parameters & frontend); + boost::function cb2_X_Tune; public: /////////////////////////////////////////////////////////////////////////// // internal interface ///\name Constructors ///@{ - - void init_client(boost::uint8_t adapter=0, boost::uint8_t device=0) const; + void init_client(unsigned const short adapter = 0, unsigned const short device = 0); ///< Opens the specified frontend device in read-only mode. /**< \note This member is implicitly called from the ProtocolClientSocketHandle::ProtocolClientSocketHandle() constructor */ ///@} + + void tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate); + ///< Tunes a DVB-C device + /**< Tunes a DVB-C device. Needs full configuration */ + void tuneDVB_T(unsigned int frequency, + fe_spectral_inversion_t inversion, + fe_bandwidth_t bandwidth, + fe_code_rate_t code_rate_HP, /* high priority stream code rate */ + fe_code_rate_t code_rate_LP, /* low priority stream code rate */ + fe_modulation_t constellation, /* modulation type (see above) */ + fe_transmit_mode_t transmission_mode, + fe_guard_interval_t guard_interval, + fe_hierarchy_t hierarchy_information + ); ///< Tunes a DVB-T device + /**< Tunes a DVB-T device. Needs full configuration */ + void tuneDVB_C(unsigned int frequency, + fe_spectral_inversion_t inversion, + unsigned int symbol_rate, + fe_code_rate_t fec_inner, + fe_modulation_t modulation); + ///< Tunes a DVB-C device + /**< Tunes a DVB-C device. Needs full configuration */ + struct dvb_frontend_info getInfo() const; ///< Returns information struct. + /**< Returns information struct, which contains information + about the device which is associated with the current frontend.*/ + struct dvb_frontend_parameters getFrontendParam() const; ///< Returns dvb_frontend_parameters struct. + /**< Returns dvb_frontend_parameters struct, which contains the actual + configuration of the device.*/ + void setFrequency(unsigned int frequency); ///< Sets frequency + /**< Sets frequency. This can be done for all device types.*/ + void setInversion(fe_spectral_inversion_t inversion); ///< Sets inversion + /**< Sets inversion. This can be done for all device types.*/ + void setCodeRate(fe_code_rate_t fec_inner); ///< Sets code rate + /**< Sets code rate. This can be done for all device types. Attention + for DVB-T devices the high and low priority stream code rate will be set to + the given value.*/ + void setSymbolRate(unsigned int symbol_rate); ///< Sets symbol rate + /**< Sets symbol rate. This can only be done for DVB-S or DVB-C devices. + Other attempts will throw an exception.*/ + void setModulation(fe_modulation_t modulation); ///< Sets modulation + /**< Sets modulation. This can only be done for DVB-T or DVB-C devices. + Other attempts will throw an exception.*/ + void setBandwidth(fe_bandwidth_t bandwidth); ///< Sets bandwidth + /**< Sets bandwidth. This can only be done for DVB-T devices. + Other attempts will throw an exception.*/ + void setHighPriorityCodeRate(fe_code_rate_t code_rate_HP); ///< Sets high priority stream code rate + /**< Sets high priority stream code rate. This can only be done for DVB-T devices. + Other attempts will throw an exception.*/ + void setLowPriorityCodeRate(fe_code_rate_t code_rate_LP); ///< Sets low priority stream code rate + /**< Sets low priority stream code rate. This can only be done for DVB-T devices. + Other attempts will throw an exception.*/ + void setGuardInterval(fe_guard_interval_t guard_interval); ///< Sets guard interval + /**< Sets guard interval. This can only be done for DVB-T devices. + Other attempts will throw an exception.*/ + void setHierarchyInformation(fe_hierarchy_t hierarchy_information); ///< Sets hierarchy information + /**< Sets hierarchy information. This can only be done for DVB-T devices. + Other attempts will throw an exception.*/ + + ///\name Abstract Interface Implementation ///@{