--- /dev/null
+#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;
+}
--- /dev/null
+// $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_*/
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.");
}
// ----------------------------------------------------------------
///@}
- 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;
// 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()
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,
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;
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;
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;
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()
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"
#include "../../../Socket/ReadWritePolicy.hh"
#include "../../../Socket/ProtocolClientSocketHandle.hh"
#include "../../../Socket/SocketProtocol.hh"
-#include <string>
-#include <fstream>
-
-
-
+#include <fcntl.h>
//#include "DVBFrontendHandle.mpp"
///////////////////////////////hh.p////////////////////////////////////////
/** \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,
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
/**< 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;
--- /dev/null
+#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");
+}
--- /dev/null
+#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_*/