Utils/Console: Add short help to 'ls' output
[senf.git] / Socket / Protocols / DVB / DVBFrontendHandle.cc
index 20c8caa..bb63f70 100644 (file)
@@ -3,6 +3,7 @@
 // Copyright (C) 2007
 // Fraunhofer Institute for Open Communication Systems (FOKUS)
 // Competence Center NETwork research (NET), St. Augustin, GERMANY
+//     Anton Gillert <atx@berlios.de>
 //     Thorsten Horstmann <tho@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
 // 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 +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"