implemented DVBFrontendHandle
atx23 [Fri, 28 Nov 2008 08:30:50 +0000 (08:30 +0000)]
git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@986 270642c3-0616-0410-b53a-bc976706d245

Socket/Protocols/DVB/DVBFrontendHandle.cc
Socket/Protocols/DVB/DVBFrontendHandle.hh

index a393eb2..20c8caa 100644 (file)
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include "../../../Utils/Exception.hh"
+#include <poll.h>
+#include <unistd.h>
+#include <fcntl.h>
+
 
 //#include "DVBFrontendHandle.mpp"
 #define prefix_
 
 ///////////////////////////////////////////////////////////////////////////
 // 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;
index 04cc21a..74c58d5 100644 (file)
 
 // Custom includes
 #include <boost/cstdint.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
 #include <linux/dvb/frontend.h>
 #include "../../../Socket/FramingPolicy.hh"
 #include "../../../Socket/CommunicationPolicy.hh"
 #include "../../../Socket/ReadWritePolicy.hh"
 #include "../../../Socket/ProtocolClientSocketHandle.hh"
 #include "../../../Socket/SocketProtocol.hh"
+#include <string>
+#include <fstream>
+
+
 
 //#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<DVBFrontend_Policy, DVBFrontendSocketProtocol>
     {
+    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<struct dvb_frontend_event (const struct dvb_frontend_parameters & frontend)> 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
         ///@{