X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Socket%2FProtocols%2FDVB%2FDVBFrontendHandle.cc;h=bb63f70cb7531f8ef65cd9e6b738428b3e269250;hb=532240d72e09e19e57fac9bb55c2560b9c9e5b97;hp=20c8caae2e66776e66bf2b607b8fb22ef7c6f9c8;hpb=69bcc009d679b71b816b9a1bfd11dfaf6c980fd1;p=senf.git diff --git a/Socket/Protocols/DVB/DVBFrontendHandle.cc b/Socket/Protocols/DVB/DVBFrontendHandle.cc index 20c8caa..bb63f70 100644 --- a/Socket/Protocols/DVB/DVBFrontendHandle.cc +++ b/Socket/Protocols/DVB/DVBFrontendHandle.cc @@ -3,6 +3,7 @@ // Copyright (C) 2007 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY +// Anton Gillert // Thorsten Horstmann // // This program is free software; you can redistribute it and/or modify @@ -29,12 +30,8 @@ // Custom includes #include #include -#include -#include #include "../../../Utils/Exception.hh" -#include -#include -#include +#include //#include "DVBFrontendHandle.mpp" @@ -45,20 +42,14 @@ // 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 +64,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 +82,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 +107,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 +131,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 +152,68 @@ 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); + return frontend_; } -prefix_ void senf::DVBFrontendSocketProtocol::setSymbolRate(unsigned int symbol_rate){ - - fe_type_t type = getInfo().type; - struct dvb_frontend_parameters frontend = getFrontendParam(); - - if (! ( type == FE_QPSK || type == FE_QAM ) ) - SENF_THROW_SYSTEM_EXCEPTION("Symbole rate can only be set for DVB-S or DVB-C devices."); - if( type == FE_QPSK ) /* DVB-S */ - frontend.u.qpsk.symbol_rate = symbol_rate; - - if( type == FE_QAM ) /* DVB-C */ - frontend.u.qam.symbol_rate = symbol_rate; - - tune(frontend); -} -prefix_ void senf::DVBFrontendSocketProtocol::setModulation(fe_modulation_t modulation){ - - fe_type_t type = getInfo().type; - struct dvb_frontend_parameters frontend = getFrontendParam(); - - if (! ( type == FE_OFDM || type == FE_QAM ) ) - SENF_THROW_SYSTEM_EXCEPTION("Symbole rate can only be set for DVB-T or DVB-C devices."); - if( type == FE_QAM ) /* DVB-C */ - frontend.u.qam.modulation = modulation; - if( type == FE_OFDM ) /* DVB-T */ - frontend.u.ofdm.constellation = modulation; - - tune(frontend); -} - -prefix_ void senf::DVBFrontendSocketProtocol::setBandwidth(fe_bandwidth_t bandwidth) { - - fe_type_t type = getInfo().type; - struct dvb_frontend_parameters frontend = getFrontendParam(); - - if (type != FE_OFDM) - SENF_THROW_SYSTEM_EXCEPTION("") << "Bandwidth can only be set for DVB-T devices."; - - frontend.u.ofdm.bandwidth = bandwidth; - - tune(frontend); -} - -prefix_ void senf::DVBFrontendSocketProtocol::setHighPriorityCodeRate(fe_code_rate_t code_rate_HP) { - - fe_type_t type = getInfo().type; - struct dvb_frontend_parameters frontend = getFrontendParam(); - - if (type != FE_OFDM) - SENF_THROW_SYSTEM_EXCEPTION("") << "High priority bandwidth can only be set for DVB-T devices."; - - frontend.u.ofdm.code_rate_HP = code_rate_HP; - - tune(frontend); -} - -prefix_ void senf::DVBFrontendSocketProtocol::setLowPriorityCodeRate(fe_code_rate_t code_rate_LP) { - - fe_type_t type = getInfo().type; - struct dvb_frontend_parameters frontend = getFrontendParam(); - - if (type != FE_OFDM) - SENF_THROW_SYSTEM_EXCEPTION("") << "Low priority bandwidth can only be set for DVB-T devices."; - - frontend.u.ofdm.code_rate_LP = code_rate_LP; - - tune(frontend); -} - -prefix_ void senf::DVBFrontendSocketProtocol::setGuardInterval(fe_guard_interval_t guard_interval) { - - fe_type_t type = getInfo().type; - struct dvb_frontend_parameters frontend = getFrontendParam(); - - if (type != FE_OFDM) - SENF_THROW_SYSTEM_EXCEPTION("") << "Guard interval can only be set for DVB-T devices."; - - frontend.u.ofdm.guard_interval = guard_interval; - - tune(frontend); -} - -prefix_ void senf::DVBFrontendSocketProtocol::setHierarchyInformation(fe_hierarchy_t hierarchy_information) { - - fe_type_t type = getInfo().type; - struct dvb_frontend_parameters frontend = getFrontendParam(); - - if (type != FE_OFDM) - SENF_THROW_SYSTEM_EXCEPTION("") << "Hierachy information can only be set for DVB-T devices."; - - frontend.u.ofdm.hierarchy_information = hierarchy_information; - - tune(frontend); +prefix_ 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() @@ -321,7 +226,7 @@ prefix_ int16_t senf::DVBFrontendSocketProtocol::signalStrength() } prefix_ int16_t senf::DVBFrontendSocketProtocol::signalNoiseRatio() - const + const { int16_t snr; if (::ioctl(fd(), FE_READ_SNR, &snr) < 0) @@ -338,6 +243,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"