Changed API of DVBDemuxSectionHandle !
atx23 [Wed, 17 Dec 2008 14:08:35 +0000 (14:08 +0000)]
Changed API of DVBFrontendHandle !
Added DVBSocketController

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1020 270642c3-0616-0410-b53a-bc976706d245

Socket/Protocols/DVB/DVBConfigParser.cc [new file with mode: 0644]
Socket/Protocols/DVB/DVBConfigParser.hh [new file with mode: 0644]
Socket/Protocols/DVB/DVBDemuxHandles.cc
Socket/Protocols/DVB/DVBDemuxHandles.hh
Socket/Protocols/DVB/DVBFrontendHandle.cc
Socket/Protocols/DVB/DVBFrontendHandle.hh
Socket/Protocols/DVB/DVBSocketController.cc [new file with mode: 0644]
Socket/Protocols/DVB/DVBSocketController.hh [new file with mode: 0644]

diff --git a/Socket/Protocols/DVB/DVBConfigParser.cc b/Socket/Protocols/DVB/DVBConfigParser.cc
new file mode 100644 (file)
index 0000000..aa45acb
--- /dev/null
@@ -0,0 +1,257 @@
+#include "DVBConfigParser.hh"
+#include <boost/assign/std/map.hpp>
+#include "../../../Utils/Exception.hh"
+
+using namespace std;
+#define prefix_
+
+senf::DVBConfigParser::DVBParams const senf::DVBConfigParser::params;
+
+prefix_ senf::DVBConfigParser::DVBParams::DVBParams()
+{
+    
+    boost::assign::insert(inversion) 
+    (   "INVERSION_OFF", INVERSION_OFF )
+    (   "INVERSION_ON", INVERSION_ON ) 
+    (   "INVERSION_AUTO", INVERSION_AUTO );
+    boost::assign::insert(bandwidth) 
+    (   "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ)
+    (   "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ)
+    (   "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ);
+    boost::assign::insert(code_rate) 
+    (   "FEC_1_2", FEC_1_2)
+    (   "FEC_2_3", FEC_2_3)
+    (   "FEC_3_4", FEC_3_4)
+    (   "FEC_4_5", FEC_4_5)
+    (   "FEC_5_6", FEC_5_6)
+    (   "FEC_6_7", FEC_6_7)
+    (   "FEC_7_8", FEC_7_8)
+    (   "FEC_8_9", FEC_8_9)
+    (   "FEC_AUTO", FEC_AUTO)
+    (   "FEC_NONE", FEC_NONE);
+    boost::assign::insert(guard_interval) 
+    (   "GUARD_INTERVAL_1_16", GUARD_INTERVAL_1_16)
+    (   "GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32)
+    (   "GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4)
+    (   "GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8);
+    boost::assign::insert(hierarchy) 
+    (   "HIERARCHY_1", HIERARCHY_1)
+    (   "HIERARCHY_2", HIERARCHY_2)
+    (   "HIERARCHY_4", HIERARCHY_4)
+    (   "HIERARCHY_NONE", HIERARCHY_NONE);
+    boost::assign::insert(modulation) 
+    (   "QPSK", QPSK)
+    (   "QAM_128", QAM_128)
+    (   "QAM_16", QAM_16)
+    (   "QAM_256", QAM_256)
+    (   "QAM_32", QAM_32)
+    (   "QAM_64", QAM_64);
+    boost::assign::insert(transmit_mode) 
+    (   "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K)
+    (   "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K);
+}
+
+senf::DVBConfigParser::DVBConfigParser(fe_type_t type_, const string & configFilePath_) :  
+    type(type_), 
+    configFile()
+{
+    initConfigFile(configFilePath_);
+}
+
+senf::DVBConfigParser::~DVBConfigParser()
+{
+    configFile.close();
+}
+prefix_ void senf::DVBConfigParser::initConfigFile(string configFilePath_){
+    if (configFilePath_.size() == 0) {
+        if ( !(::getenv ("HOME")) )
+            SENF_THROW_SYSTEM_EXCEPTION("$HOME not set! You need it to use default configfile.");
+        string configPath(::getenv ("HOME"));
+        switch(type) {
+            case FE_QPSK :
+                configPath += string("/.szap/channels.conf");
+                break;
+            case FE_QAM :
+                configPath += string("/.czap/channels.conf");
+                break;
+            case FE_OFDM :
+                configPath += string("/.tzap/channels.conf");
+                break;
+            default:
+                SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
+        }
+        configFilePath_ = configPath;
+    }
+    configFile.open( configFilePath_.c_str(), ios_base::in);
+    if(configFile.bad())
+        SENF_THROW_SYSTEM_EXCEPTION("Could not read configfile: ") << configFilePath_ << ".";
+}
+prefix_ string senf::DVBConfigParser::getConfigLine(string channel)
+{
+    string configLine;
+    size_t pos;
+    transform(channel.begin(), channel.end(), channel.begin(), ::toupper);
+    if(configFile.bad()) 
+        SENF_THROW_SYSTEM_EXCEPTION("Could not read file.");
+    while (configFile.good()){
+        getline( configFile, configLine );
+        transform(configLine.begin(), configLine.end(), configLine.begin(), ::toupper);
+        pos = configLine.find(channel);
+        
+        if(pos != string::npos && pos == 0){ // only first matching number should be interpreted as channel number 
+            configFile.seekg(0);
+            return configLine; // Line found!
+        }
+    }
+    SENF_THROW_SYSTEM_EXCEPTION("Channel \"")<< channel << "\" not found!";
+    return channel;
+}
+
+prefix_ dvb_frontend_parameters senf::DVBConfigParser::getFrontendParam(string configLine){
+    struct dvb_frontend_parameters frontend;
+    transform(configLine.begin(), configLine.end(), configLine.begin(), ::toupper);
+    boost::char_separator<char> sep(":");
+    tokenizer tokens(configLine, sep);
+    switch (type) {
+        case FE_QPSK:
+            frontend = getFrontendParamDVB_S(tokens);
+            break;
+        case FE_QAM:
+            frontend = getFrontendParamDVB_C(tokens);
+            break;
+        case FE_OFDM:
+            frontend = getFrontendParamDVB_T(tokens);
+            break;
+        default:
+            SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
+    }
+    return frontend;
+}
+
+prefix_ dvb_frontend_parameters senf::DVBConfigParser::getFrontendParamDVB_T( const tokenizer & tokens){
+    
+    struct dvb_frontend_parameters frontend;
+    istringstream isst;
+    int number;
+    enum { p_Frequency=1, p_Inversion, p_Bandwidth, p_hp_code_rate, p_lp_code_rate, p_Mudualtion, p_Transmission, p_guard, p_hierarchy};
+    vector<string> words( tokens.begin(), tokens.end() );
+    
+    ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
+    
+    /*if(words.size() < 10)
+        SENF_THROW_SYSTEM_EXCEPTION("Too few arguments! There must be at least 10, but there are only: ") << words.size();*/
+    
+    isst.str(words[p_Frequency]);
+    isst >> number;
+    if(isst.fail())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse frequency");
+    frontend.frequency = number;
+    
+    if( params.inversion.find(words[p_Inversion]) == params.inversion.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse inversion");
+    frontend.inversion = params.inversion.find(words[p_Inversion])->second;
+    
+    if( params.bandwidth.find(words[p_Bandwidth]) == params.bandwidth.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse bandwidth");
+    frontend.u.ofdm.bandwidth = params.bandwidth.find(words[p_Bandwidth])->second;
+    
+    if( params.code_rate.find(words[p_hp_code_rate]) == params.code_rate.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse high priority stream code rate");
+    frontend.u.ofdm.code_rate_HP = params.code_rate.find(words[p_hp_code_rate])->second;
+    
+    if( params.code_rate.find(words[p_lp_code_rate]) == params.code_rate.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse low priority stream code rate");
+    frontend.u.ofdm.code_rate_LP = params.code_rate.find(words[p_lp_code_rate])->second;
+    
+    if( params.modulation.find(words[p_Mudualtion]) == params.modulation.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse modulation");
+    frontend.u.ofdm.constellation = params.modulation.find(words[p_Mudualtion])->second;
+    
+    if( params.transmit_mode.find(words[p_Transmission]) == params.transmit_mode.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse transmission mode");
+    frontend.u.ofdm.transmission_mode = params.transmit_mode.find(words[p_Transmission])->second;
+    
+    if( params.guard_interval.find(words[p_guard]) == params.guard_interval.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse guard interval");
+    frontend.u.ofdm.guard_interval = params.guard_interval.find(words[p_guard])->second;  
+    
+    if( params.hierarchy.find(words[p_hierarchy]) == params.hierarchy.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse hierarchy");
+    frontend.u.ofdm.hierarchy_information = params.hierarchy.find(words[p_hierarchy])->second;
+    
+    return frontend;
+}
+
+prefix_ dvb_frontend_parameters senf::DVBConfigParser::getFrontendParamDVB_S( const  tokenizer & tokens){
+    struct dvb_frontend_parameters frontend;
+    istringstream isst;
+    int number;
+    enum { p_Frequency=1, p_Inversion, p_Symbole, p_code_rate};
+    vector<string> words( tokens.begin(), tokens.end() ) ;
+    
+    ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
+    
+    if(words.size() < 5)
+                SENF_THROW_SYSTEM_EXCEPTION("Too few arguments! There must be at least 5, but there are only: ") << words.size();
+    
+    isst.str(words[p_Frequency]);
+    isst >> number;
+    if (isst.fail())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse frequency");
+    frontend.frequency = number;
+    
+    if (params.inversion.find(words[p_Inversion]) == params.inversion.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse inversion");
+    frontend.inversion = params.inversion.find(words[p_Inversion])->second;
+    
+    isst.str(words[p_Symbole]);
+    isst >> number;
+    if (isst.fail())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse symbole rate");
+    frontend.u.qpsk.symbol_rate = number;
+
+    if (params.code_rate.find(words[p_code_rate]) == params.code_rate.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse code rate");
+    frontend.u.qpsk.fec_inner = params.code_rate.find(words[p_code_rate])->second;
+    
+    return frontend;
+}
+
+prefix_ dvb_frontend_parameters senf::DVBConfigParser::getFrontendParamDVB_C( const  tokenizer & tokens){
+    struct dvb_frontend_parameters frontend;
+    istringstream isst;
+    int number;
+    enum { p_Frequency=1, p_Inversion, p_Symbole, p_code_rate, p_modulation};
+    vector<string> words( ++tokens.begin(), tokens.end() ) ; 
+  
+    ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
+    
+    if(words.size() < 6)
+        SENF_THROW_SYSTEM_EXCEPTION("Too few arguments! There must be at least 6, but there are only: ") << words.size();
+    
+    isst.str(words[p_Frequency]);
+    isst >> number;
+    if (isst.fail())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse frequency");
+    frontend.frequency = number;
+    
+    if (params.inversion.find(words[p_Inversion]) == params.inversion.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse inversion");
+    frontend.inversion = params.inversion.find(words[p_Inversion])->second;
+    
+    isst.str(words[p_Symbole]);
+    isst >> number;
+    if (isst.fail())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse symbole rate");
+    frontend.u.qam.symbol_rate = number;
+    
+    if (params.code_rate.find(words[p_code_rate]) == params.code_rate.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse code rate");
+    frontend.u.qam.fec_inner = params.code_rate.find(words[p_code_rate])->second;
+    
+    if (params.modulation.find(words[p_modulation]) == params.modulation.end())
+        SENF_THROW_SYSTEM_EXCEPTION("Cant parse modulation");
+    frontend.u.qam.modulation = params.modulation.find(words[p_modulation])->second;
+    
+    return frontend;
+}
diff --git a/Socket/Protocols/DVB/DVBConfigParser.hh b/Socket/Protocols/DVB/DVBConfigParser.hh
new file mode 100644 (file)
index 0000000..1fa99f6
--- /dev/null
@@ -0,0 +1,73 @@
+// $Id: DVBConfigParser.hh 965 2008-11-18 16:04:20Z g0dil $
+//
+// Copyright (C) 2007
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Anton Gillert <atx23@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+/** \file
+    \brief DVBDemuxHandles public header */
+
+#ifndef DVBCONFIGPARSER_HH_
+#define DVBCONFIGPARSER_HH_
+
+#include <string>
+#include <vector>
+#include <map>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <boost/tokenizer.hpp>
+#include <linux/dvb/frontend.h>
+namespace senf {
+class DVBConfigParser 
+{
+    struct DVBParams {
+                std::map<std::string, fe_spectral_inversion_t> inversion;
+                std::map<std::string, fe_bandwidth_t> bandwidth;
+                std::map<std::string, fe_code_rate_t> code_rate;
+                std::map<std::string, fe_guard_interval_t> guard_interval;
+                std::map<std::string, fe_hierarchy_t> hierarchy;
+                std::map<std::string, fe_modulation_t> modulation;
+                std::map<std::string, fe_transmit_mode_t> transmit_mode;
+                DVBParams(); };
+    static const DVBParams params;
+    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+    
+public:
+       DVBConfigParser(fe_type_t type_, const std::string & configFilePath = "");
+       ~DVBConfigParser();
+       
+       std::string getConfigLine(std::string channel);
+           
+       dvb_frontend_parameters parseCMDInput(std::string input);
+       dvb_frontend_parameters getFrontendParam(std::string configLine);
+       
+private:
+       
+       fe_type_t type;
+       std::ifstream configFile;
+       void initConfigFile(std::string _configFilePath);
+       
+       dvb_frontend_parameters getFrontendParamDVB_T( const tokenizer & tokens);
+       dvb_frontend_parameters getFrontendParamDVB_C( const tokenizer & tokens);
+       dvb_frontend_parameters getFrontendParamDVB_S( const tokenizer & tokens);
+       
+};
+}
+#endif /*DVBCONFIGPARSER_H_*/
index d5343e3..3a66a06 100644 (file)
@@ -58,11 +58,20 @@ prefix_ unsigned senf::DVBDemuxSectionSocketProtocol::available()
     return 4096;
 }
 
-prefix_ void senf::DVBDemuxSectionSocketProtocol::setSectionFilter(struct dmx_sct_filter_params *filter)
+prefix_ void senf::DVBDemuxSectionSocketProtocol::setSectionFilter(unsigned short int pid, unsigned int timeout, unsigned int flags, unsigned char filter, unsigned char mask, unsigned char mode)
     const
 {
-    if (::ioctl(fd(), DMX_SET_FILTER, filter) < 0)
-        SENF_THROW_SYSTEM_EXCEPTION("Could not set section filter of DVB adapter.");
+    struct dmx_sct_filter_params sec_filter;
+    ::memset(&sec_filter, 0, sizeof(struct dmx_sct_filter_params));
+    
+       sec_filter.pid = pid;
+       sec_filter.filter.filter[0] = filter;
+       sec_filter.filter.mask[0] = mask;
+       sec_filter.filter.mode[0] = mode;
+       sec_filter.flags = flags;
+       
+       if (::ioctl(fd(), DMX_SET_FILTER, filter) < 0)
+           SENF_THROW_SYSTEM_EXCEPTION("Could not set section filter of DVB adapter.");
 }
 
 // ----------------------------------------------------------------
index d146830..dd24d7b 100644 (file)
@@ -75,7 +75,12 @@ namespace senf {
 
         ///@}
         
-        void setSectionFilter(struct dmx_sct_filter_params *filter) const;    
+        void setSectionFilter(unsigned short int pid, 
+                unsigned int timeout, 
+                unsigned int flags, 
+                unsigned char filter, 
+                unsigned char mask, 
+                unsigned char mode) const;    
     };
 
     typedef ProtocolClientSocketHandle<DVBDemuxSectionSocketProtocol> DVBDemuxSectionHandle;
index 20c8caa..3b01f22 100644 (file)
 // Custom includes
 #include <boost/format.hpp>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
 #include "../../../Utils/Exception.hh"
-#include <poll.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include <sys/ioctl.h>
 
 
 //#include "DVBFrontendHandle.mpp"
 // senf::DVBFrontendHandle
 using namespace std;
 
-prefix_ void senf::DVBFrontendSocketProtocol::init_client(unsigned const short adapter,unsigned const short device)
+prefix_ void senf::DVBFrontendSocketProtocol::init_client(unsigned short adapter, unsigned short device, int flags)
+    const
 {
     string devFrontend = str( boost::format("/dev/dvb/adapter%d/frontend%d") % adapter % device);
-    int f = open(devFrontend.c_str(), O_RDONLY | O_NONBLOCK);
+    int f = open(devFrontend.c_str(), flags);
     if (f < 0)
         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()
@@ -73,28 +63,12 @@ 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){
+prefix_ void senf::DVBFrontendSocketProtocol::tune(const struct dvb_frontend_parameters & frontend)
+    const 
+{
     // 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;
+    if (::ioctl(fd(), FE_SET_FRONTEND, &frontend) )
+        SENF_THROW_SYSTEM_EXCEPTION("") << "ioctl FE_SET_FRONTEND failed. Socket should initialized with r/w permissions.";;
 }
 
 prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_T(unsigned int frequency, 
@@ -107,10 +81,14 @@ prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_T(unsigned int frequency,
         fe_guard_interval_t guard_interval,
         fe_hierarchy_t hierarchy_information
         )
+    const
 {
     struct dvb_ofdm_parameters ofdm; /* DVB-T Parameters */
     struct dvb_frontend_parameters frontend;
     
+    ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
+    ::memset(&ofdm, 0, sizeof(struct dvb_ofdm_parameters));
+    
     ofdm.bandwidth = bandwidth;
     ofdm.code_rate_HP = code_rate_HP;
     ofdm.code_rate_LP = code_rate_LP;
@@ -128,11 +106,16 @@ prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_T(unsigned int frequency,
 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) */
+        fe_code_rate_t fec_inner /* forward error correction (see above) */
+    )
+    const
 {
     struct dvb_qpsk_parameters qpsk; /* DVB-S Parameters*/
     struct dvb_frontend_parameters frontend;
     
+    ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
+    ::memset(&qpsk, 0, sizeof(struct dvb_qpsk_parameters));
+    
     qpsk.symbol_rate = symbole_rate;
     qpsk.fec_inner = fec_inner;
     
@@ -147,11 +130,16 @@ 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)
+        fe_modulation_t modulation
+        )
+const
 {
     struct dvb_qam_parameters qam; /* DVB-C Parameters*/
     struct dvb_frontend_parameters frontend;
     
+    ::memset(&frontend, 0, sizeof(struct dvb_frontend_parameters));
+    ::memset(&qam, 0, sizeof(struct dvb_qam_parameters));
+    
     qam.symbol_rate = symbol_rate;
     qam.fec_inner = fec_inner;
     qam.modulation = modulation;
@@ -163,152 +151,66 @@ prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_C(unsigned int frequency,
        
     tune(frontend);
 }
-prefix_ struct dvb_frontend_info senf::DVBFrontendSocketProtocol::getInfo()
+prefix_ void senf::DVBFrontendSocketProtocol::setNonBlock(bool on) const{
+   if(on)
+       ::fcntl(fd(), F_SETFL, ::fcntl(fd(), F_GETFL) | O_NONBLOCK);
+   else
+       ::fcntl(fd(), F_SETFL, ::fcntl(fd(), F_GETFL) & ~O_NONBLOCK);
+
+}
+prefix_ dvb_frontend_info senf::DVBFrontendSocketProtocol::getInfo()
     const
 {
     struct dvb_frontend_info info;
+    ::memset(&info, 0, sizeof(struct dvb_frontend_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;
+prefix_ dvb_frontend_parameters senf::DVBFrontendSocketProtocol::getFrontendParam() const {
+    struct dvb_frontend_parameters frontend_;
+    
+    ::memset(&frontend_, 0, sizeof(struct dvb_frontend_parameters));
+    
+    if(::ioctl(fd(), FE_GET_FRONTEND, &frontend_)) {
+        switch(errno) {
+            case EBADF:
+                SENF_THROW_SYSTEM_EXCEPTION("fd is not a valid open file descriptor.");
+                break;
+            case EFAULT:
+                SENF_THROW_SYSTEM_EXCEPTION( "frontend_ points to invalid address." );
+                break;
+            case EINVAL:
+                SENF_THROW_SYSTEM_EXCEPTION( "Maximum supported symbol rate reached. This call may not be implemented by kernel driver!" );
+                break;
+            default:
+                SENF_THROW_SYSTEM_EXCEPTION("Errno: ") << errno;
+        }
     }
-    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);
+    return 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_ dvb_frontend_event senf::DVBFrontendSocketProtocol::getEvent() const{
+    struct dvb_frontend_event ev ;
+    
+    ::memset(&ev, 0, sizeof(struct dvb_frontend_event));
+    
+    if(::ioctl(fd(), FE_GET_EVENT, &ev)) {
+        switch(errno) {
+            case EBADF:
+                SENF_THROW_SYSTEM_EXCEPTION("Could not read from frontend device, read-only access to the device is sufficient.");
+                break;
+            case EWOULDBLOCK:
+                SENF_THROW_SYSTEM_EXCEPTION( "No event pending and device is in nonblocking mode." );
+                break;
+            default:
+                SENF_THROW_SYSTEM_EXCEPTION("Errno: ") << errno;
+        }
+    }
+    return ev;
 }
 
 prefix_ int16_t senf::DVBFrontendSocketProtocol::signalStrength()
@@ -338,6 +240,26 @@ prefix_ uint32_t senf::DVBFrontendSocketProtocol::bitErrorRate()
     return ber;
 }
 
+prefix_ uint32_t senf::DVBFrontendSocketProtocol::uncorrectedBlocks()
+    const
+{
+    uint32_t uncorrected_blocks;
+    if (::ioctl(fd(), FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) < 0)
+        SENF_THROW_SYSTEM_EXCEPTION("Could not get bit error rate of DVB adapter.");
+    return uncorrected_blocks;
+}
+
+
+prefix_ fe_status_t senf::DVBFrontendSocketProtocol::status()
+    const
+{
+    fe_status_t status;
+    if (::ioctl(fd(), FE_READ_STATUS, &status) < 0)
+        SENF_THROW_SYSTEM_EXCEPTION("Could not get bit error rate of DVB adapter.");
+    return status;
+}
+
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 //#include "DVBFrontendHandle.mpp"
index 74c58d5..f128f64 100644 (file)
 #include "../../../Socket/ReadWritePolicy.hh"
 #include "../../../Socket/ProtocolClientSocketHandle.hh"
 #include "../../../Socket/SocketProtocol.hh"
-#include <string>
-#include <fstream>
-
-
-
+#include <fcntl.h>
 //#include "DVBFrontendHandle.mpp"
 ///////////////////////////////hh.p////////////////////////////////////////
 
@@ -61,33 +57,39 @@ namespace senf {
     /** \brief SocketProtocol for the dvb frontend device
 
         The DVB frontend device controls the tuner and DVB demodulator hardware.
+        ATTENTION!
+        Some calls are not supported by real life drivers, known issues:
+        
+        Cinergy T² getParameter is not supported
+        Cinergy T² in getEvent fe_status_t will be set but dvb_frontend_parameters will be stay untouched
+        Cinergy DT XS bitErrorRate is not supported
+        
+        This dues to the lack of driver implementation. There could be restrictions also for other DVB devices!
      */
     
     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;
+        void tune(const struct dvb_frontend_parameters & frontend) const;
     public:
         ///////////////////////////////////////////////////////////////////////////
         // internal interface
 
         ///\name Constructors
         ///@{
-        void init_client(unsigned const short adapter = 0, unsigned const short device = 0);
+        void init_client(unsigned short adapter = 0, unsigned short device = 0, int flags = (O_RDWR | O_NONBLOCK) ) const;
                                         ///< 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 setNonBlock(bool on = true) const;
+       
+        void tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate) const;
+                                                                        ///< Tunes a DVB-S device
+                                                                        /**< Tunes a DVB-S device. Needs full configuration */
         void tuneDVB_T(unsigned int frequency, 
                 fe_spectral_inversion_t inversion,
                 fe_bandwidth_t bandwidth, 
@@ -97,54 +99,27 @@ namespace senf {
                 fe_transmit_mode_t transmission_mode, 
                 fe_guard_interval_t guard_interval,
                 fe_hierarchy_t hierarchy_information
-                );                                                      ///< Tunes a DVB-T device
+                ) const;                                                ///< 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);        
+                fe_modulation_t modulation
+                ) const;        
                                                                         ///< Tunes a DVB-C device
                                                                         /**< Tunes a DVB-C device. Needs full configuration */
-        struct dvb_frontend_info getInfo() const;                     ///< Returns information 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
         ///@{
+        
+        dvb_frontend_event getEvent() const;
+        
 
         unsigned available() const;     ///< Returns always <tt>0</tt>
                                         /**< Returns always <tt>0</tt>, since the DVB frontend
@@ -170,6 +145,20 @@ namespace senf {
                                         /**< Returns the bit error rate for the signal currently
                                              received/demodulated by the front-end. For this method,
                                              read-only access to the device is sufficient. */
+        uint32_t uncorrectedBlocks() const; ///< Returns the number of uncorrected blocks 
+                                            /**< Returns the number of uncorrected blocks 
+                                             * detected by the device driver during its lifetime.
+                                             *  For meaningful measurements, the increment in block 
+                                             * count during a specific time interval should be calculated. 
+                                             * For this command, read-only access to the device is sufficient.
+                                             *  Note that the counter will wrap to zero after its maximum count 
+                                             * has been reached.*/
+        
+        fe_status_t status() const;         ///< This ioctl call returns status information about the front-end.
+                                            /**< This ioctl call returns status information about the 
+                                             * front-end. This call only requires read-only access 
+                                             * to the device.*/
+               
     };
 
     typedef ProtocolClientSocketHandle<DVBFrontendSocketProtocol> DVBFrontendHandle;
diff --git a/Socket/Protocols/DVB/DVBSocketController.cc b/Socket/Protocols/DVB/DVBSocketController.cc
new file mode 100644 (file)
index 0000000..1242ff2
--- /dev/null
@@ -0,0 +1,405 @@
+#include "../../../Utils/Exception.hh"
+#include "../../../Utils/Logger/Logger.hh"
+#include <../../../Utils/membind.hh>
+
+#include "DVBSocketController.hh"
+#include <sstream>
+using namespace std;
+#define prefix_
+
+
+
+senf::DVBSocketController::DVBSocketController(DVBFrontendHandle frontendHandle_, DVBDemuxSectionHandle sectionHandle_ , const Callback & cb_) :
+    dir( this ),
+    frontendHandle( frontendHandle_ ),
+    sectionHandle( sectionHandle_ ),
+    type( frontendHandle.protocol().getInfo().type ),
+    parser( type ),
+    cb( cb_ ),
+    event( "senf::DVBSocketController::readEvent", senf::membind(&DVBSocketController::readEvent, this), frontendHandle, senf::scheduler::FdEvent::EV_PRIO, false )
+{
+    initConsole();
+}
+
+prefix_ senf::DVBSocketController::~DVBSocketController()
+{
+}
+prefix_ string senf::DVBSocketController::tuneToCMD(const string & configLine, const string & mode){
+    struct dvb_frontend_parameters frontend;
+    
+  
+    // no valid configline, so it will be treaten like a channel name
+    if (configLine.find(":")==string::npos){
+        if (mode.c_str()[0]=='a'){
+            tuneTo(configLine);
+            return "async readConfFile";
+        }
+        else{
+            tuneTo_sync(configLine);
+            return "sync readConfFile";
+        }
+        
+    }
+    // add psydo name to complete configline syntax
+    frontend = parser.getFrontendParam("foo:"+configLine);
+    
+    if (mode.c_str()[0]=='a'){
+        switch (type) {
+            case FE_QPSK:
+                tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
+                break;
+            case FE_QAM:
+                tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
+                break;
+            case FE_OFDM:
+                tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
+                break;
+            default:
+                SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
+        }
+        return "async get directly";
+    }
+    else {
+        switch (type) {
+            case FE_QPSK: if (mode.c_str()[0]=='a')
+                tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
+                break;
+            case FE_QAM:
+                tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
+                break;
+            case FE_OFDM:
+                tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
+                break;
+            default:
+                SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
+        }
+        return "sync get directly";
+    }
+}
+
+prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
+{
+    struct dvb_frontend_parameters frontend;
+   
+    string configLine = parser.getConfigLine(channel);
+    
+    SENF_LOG((senf::log::MESSAGE) ("async: configline found: " << channel) );
+    frontend = parser.getFrontendParam(configLine);
+    switch (type) {
+        case FE_QPSK:
+            tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
+            break;
+        case FE_QAM:
+            tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
+            break;
+        case FE_OFDM:
+            tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
+            break;
+        default:
+            SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
+    }    
+}
+
+prefix_ void senf::DVBSocketController::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
+                )
+{
+    if(type != FE_OFDM)
+        SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
+    event.enable();
+    frontendHandle.protocol().setNonBlock();
+    frontendHandle.protocol().tuneDVB_T(frequency, 
+                inversion, 
+                bandwidth, 
+                code_rate_HP, 
+                code_rate_LP, 
+                constellation, 
+                transmission_mode, 
+                guard_interval, 
+                hierarchy_information);
+}
+
+prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate){
+    if(type != FE_QPSK)
+        SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
+    event.enable();
+    frontendHandle.protocol().setNonBlock();
+    frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
+}
+
+prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency, 
+                fe_spectral_inversion_t inversion,
+                unsigned int symbol_rate,
+                fe_code_rate_t fec_inner,
+                fe_modulation_t modulation
+                )
+{   
+    if(type != FE_QAM)
+        SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
+    
+    event.enable();
+    frontendHandle.protocol().setNonBlock();
+    
+    frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
+}
+
+prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
+{
+    struct dvb_frontend_parameters frontend;
+    dvb_frontend_event ev;
+    string configLine = parser.getConfigLine(channel);
+    
+    SENF_LOG((senf::log::MESSAGE) ("sync: configline found: " << channel) );
+    frontend = parser.getFrontendParam(configLine);
+    switch (type) {
+        case FE_QPSK:
+            ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
+            break;
+        case FE_QAM:
+            ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
+            break;
+        case FE_OFDM:
+            ev = tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
+            break;
+        default:
+            SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
+    }
+    return ev;
+}
+
+prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(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
+                )
+{
+    if(type != FE_OFDM)
+        SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
+    event.disable();
+    frontendHandle.protocol().setNonBlock(false);
+    
+    frontendHandle.protocol().tuneDVB_T(frequency, 
+            inversion, 
+            bandwidth, 
+            code_rate_HP, 
+            code_rate_LP, 
+            constellation, 
+            transmission_mode, 
+            guard_interval, 
+            hierarchy_information);
+    
+    if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
+        SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
+    
+    return frontendHandle.protocol().getEvent();
+}
+
+prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_S_sync(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate){
+    if(type != FE_QPSK)
+        SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
+    event.disable();
+    frontendHandle.protocol().setNonBlock(false);
+    frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
+    
+    if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
+        SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
+    return frontendHandle.protocol().getEvent();
+}
+
+prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency, 
+                fe_spectral_inversion_t inversion,
+                unsigned int symbol_rate,
+                fe_code_rate_t fec_inner,
+                fe_modulation_t modulation
+                )
+{   
+    if(type != FE_QAM)
+        SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
+    
+    event.disable();
+    frontendHandle.protocol().setNonBlock(false);
+    frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
+    if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
+        SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
+
+    return frontendHandle.protocol().getEvent();
+}
+
+
+prefix_ string senf::DVBSocketController::getTypeString(){
+    switch (type) {
+        case FE_QPSK:
+            return "DVB-S";
+        case FE_QAM:
+            return "DVB-C";
+        case FE_OFDM:
+            return "DVB-T";
+        default:
+            SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
+    }
+    
+}
+prefix_ unsigned int senf::DVBSocketController::bitErrorRate(){ 
+    return frontendHandle.protocol().bitErrorRate();
+}
+
+prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio(){ 
+    return frontendHandle.protocol().signalNoiseRatio();
+}
+
+prefix_ unsigned int senf::DVBSocketController::signalStrength(){ 
+    return frontendHandle.protocol().signalStrength();
+}
+
+prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf){
+    const char* cConf = conf.c_str();
+    stringstream info;
+    
+    fe_status_t status;
+    uint16_t snr, signal;
+    uint32_t ber, uncorrected_blocks;
+    status = frontendHandle.protocol().status();
+    snr = frontendHandle.protocol().signalNoiseRatio();
+    signal = frontendHandle.protocol().signalStrength();
+    ber = frontendHandle.protocol().bitErrorRate();
+    uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
+    
+    info << hex;
+    
+    for(unsigned int i = 0; i < conf.size(); ++i){
+        switch(cConf[i]){
+            case 'S' :
+                info << " | signal " << signal;
+                break;
+            case 's' : 
+                info << " | snr " << snr;
+                break;
+            case 'b' :
+                info << " | ber " << ber;
+                break;
+            case 'u' :
+                info << " | unc " << uncorrected_blocks;
+                break;
+            case 'f' :
+                info << " | status: " << status2String(status);
+                break;
+            default:
+                break;
+        }
+    }
+    return info.str();
+}
+prefix_ string senf::DVBSocketController::status2String(fe_status_t status){
+   string s("");
+    if (status & FE_HAS_LOCK)
+        return s += "|HAS LOCK"; 
+    if (status & FE_HAS_CARRIER)
+        s += "|HAS CARRIER";
+    if (status & FE_HAS_VITERBI)
+        s += "|HAS VITERBI";
+    if (status & FE_HAS_SYNC)
+        s += "|HAS SYNC";
+    if (status & FE_HAS_SIGNAL)
+        s += "|HAS SIGNAL";
+    if (status & FE_TIMEDOUT)
+        s += "|TIMED OUT";
+    if (status & FE_REINIT)
+        s += "|REINIT";
+
+    return s;
+}
+
+prefix_ void senf::DVBSocketController::setSectionFilter(unsigned short int pid, 
+        unsigned char filter,
+        unsigned int flags, 
+        unsigned char mask, 
+        unsigned char mode,
+        unsigned int timeout)
+{
+    sectionHandle.protocol().setSectionFilter(pid, timeout, flags, filter, mask, mode);
+    
+}
+
+prefix_ void senf::DVBSocketController::setBufferSize(unsigned long size)
+{
+    sectionHandle.protocol().setBufferSize(size);
+}
+
+prefix_ void senf::DVBSocketController::startFiltering()
+{
+    sectionHandle.protocol().startFiltering();
+}
+
+prefix_ void senf::DVBSocketController::stopFiltering()
+{
+    sectionHandle.protocol().stopFiltering();
+}
+
+
+prefix_ fe_type_t senf::DVBSocketController::getType(){
+    return type;
+}
+
+prefix_ void senf::DVBSocketController::readEvent(int event){
+    cb(frontendHandle.protocol().getEvent());
+}
+
+prefix_ void senf::DVBSocketController::initConsole(){
+    // binding functions to console
+    namespace kw = senf::console::kw;
+    dir.doc("DVB Controller");
+    
+    dir.add("type", &DVBSocketController::getTypeString)
+    .doc("Shows actual type of card DVB-{T, S, C}");
+    
+    dir.add("info", &DVBSocketController::getTuneInfo)
+    .doc("Returns a string which shows actual tuning status.\n\
+            \"S\" prints signal strength (in hex)\n\
+            \"s\" prints singal to noise ration (in hex)\n\
+            \"b\" prints bit error rate (in hex)\n\
+            \"u\" prints uncorrected blocks (in hex)\n\
+            \"f\" prints readable overal status e.g. \"Has Lock\"\n\n\
+            These characters can be used to form the output. Be aware, some\n\
+            features may not be supported be your current driver implementation\n\
+            and could end in throwing an exception!")
+    .arg("conf", "Ssbuf", kw::default_value = "Ssbuf");
+    
+    dir.add("tuneTo", &DVBSocketController::tuneToCMD)
+        .doc("tunes to channel listet in the configfile.")
+        .arg("channel", "channel to tune")
+        .arg("mode", "mode \"sync\" or \"async\"", kw::default_value = "async");
+    
+    dir.add("buffersize", &DVBSocketController::setBufferSize)
+        .doc("Set the size of the circular buffer used for filtered data.")
+        .arg("size", "in byte");
+    
+    dir.add("start", &DVBSocketController::startFiltering)
+        .doc("Starts filtering");
+        
+    dir.add("stop", &DVBSocketController::setBufferSize)
+        .doc("Stops filtering");
+    
+    dir.add("filter", &DVBSocketController::setSectionFilter)
+        .arg("pid", "pid to filter")
+        .arg("filter", "filter", kw::default_value = 62)
+        .arg("flags", "or-able: DMX_CHECK_CRC(0x01), DMX_ONESHOT(0x02), DMX_IMMEDIATE_START(0x04), DMX_KERNEL_CLIENT(0x8000)", kw::default_value = DMX_IMMEDIATE_START | DMX_CHECK_CRC)
+        .arg("mask", "mask", kw::default_value = 0xff)
+        .arg("mode", "mode", kw::default_value = 0)
+        .arg("timeout", "timeout", kw::default_value = 0)
+        .doc("Sets parameters for section filter.");
+       
+    dir.add("stop", &DVBSocketController::setBufferSize)
+            .doc("Stops filtering");
+}
diff --git a/Socket/Protocols/DVB/DVBSocketController.hh b/Socket/Protocols/DVB/DVBSocketController.hh
new file mode 100644 (file)
index 0000000..12e018a
--- /dev/null
@@ -0,0 +1,112 @@
+#ifndef DVBSOCKETCONTROLLER_HH_
+#define DVBSOCKETCONTROLLER_HH_
+
+#include "DVBFrontendHandle.hh"
+#include "DVBDemuxHandles.hh"
+// Custom includes
+#include <string>
+#include <linux/dvb/frontend.h>
+#include <senf/Scheduler/Scheduler.hh>
+#include "DVBConfigParser.hh"
+#include <senf/Console.hh>
+namespace senf {
+    std::string status2String(fe_status_t status);
+class DVBSocketController : boost::noncopyable
+{
+public:
+    senf::console::ScopedDirectory<DVBSocketController> dir;
+    
+    typedef boost::function<void (const struct dvb_frontend_event & )> Callback;
+        
+    DVBSocketController(DVBFrontendHandle frontendHandle_ = DVBFrontendHandle(0,0), DVBDemuxSectionHandle sectionHandle_ = DVBDemuxSectionHandle(0,0), const Callback & cb = NULL);
+       ~DVBSocketController();
+       
+       std::string tuneToCMD( const std::string & channel, const std::string & mode = "async");
+       
+       void tuneTo(const std::string & channel);
+       
+       void tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate);
+                                                                                       ///< Tunes a DVB-S device
+                                                                                       /**< Tunes a DVB-S 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); 
+       
+       dvb_frontend_event tuneTo_sync( const std::string & channel );
+       
+       dvb_frontend_event tuneDVB_S_sync(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate);
+                                                                                ///< Tunes a DVB-S device
+                                                                                /**< Tunes a DVB-S device. Needs full configuration */
+    dvb_frontend_event tuneDVB_T_sync(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 hierarsourcechy_information);                                                      ///< Tunes a DVB-T device
+                                                                                /**< Tunes a DVB-T device. Needs full configuration */
+    dvb_frontend_event tuneDVB_C_sync(unsigned int frequency,
+                fe_spectral_inversion_t inversion, unsigned int symbol_rate,
+                fe_code_rate_t fec_inner, fe_modulation_t modulation); 
+    
+    fe_type_t getType();
+    
+    std::string getTypeString();
+    
+    std::string status2String(fe_status_t status);
+    unsigned int bitErrorRate();
+    unsigned int signalToNoiseRatio();
+    unsigned int signalStrength();
+    
+    void setSectionFilter(unsigned short int pid, 
+               unsigned char filter = 62,
+               unsigned int flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC,
+               unsigned char mask = 0xff, 
+               unsigned char mode = 0,
+               unsigned int timeout = 0);
+    
+    void setBufferSize(unsigned long size); 
+                            ///< set the size of the circular buffer used for filtered data.
+                            /**< The default size is two maximum sized sections, i.e. if this
+                                 function is not called a buffer size of 2 * 4096 bytes will
+                                 be used.
+                                 \param[in] size Size of circular buffer. */
+    
+    void startFiltering();
+    
+    void stopFiltering();
+    
+    std::string getTuneInfo(const std::string & conf ="Ssbuf"); ///< Returns a string which shows actual tuning status
+                                                                /**< Returns a string which shows actual tuning status. 
+                                                                "S" prints signal strength (in hex)
+                                                                "s" prints singal to noise ration (in hex)
+                                                                "b" prints bit error rate (in hex)
+                                                                "u" prints uncorrected blocks (in hex) 
+                                                                "f" prints readable overal status e.g. "Has Lock"
+                                                                These characters can be used to form the output. Be aware, some 
+                                                                features may not be supported be your current driver implementation and 
+                                                                could end in throwing an exception!*/
+private:
+    DVBFrontendHandle frontendHandle;
+    senf::DVBDemuxSectionHandle sectionHandle;
+    fe_type_t type;
+    DVBConfigParser parser;
+    Callback cb;
+    senf::scheduler::FdEvent event;
+    
+    void readEvent(int i);
+    void initConsole();
+};
+
+}
+#endif /*DVBSOCKETCONTROLLER_HH_*/