diff options
Diffstat (limited to 'src')
58 files changed, 1076 insertions, 4292 deletions
diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index fa12521..1b6093e 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -48,29 +48,16 @@  #include <map>  #include <cstring>  #include "dabOutput/dabOutput.h" -#include "dabInput.h" +#include "input/inputs.h"  #include "utils.h" -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" -#include "dabInputMpegFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputDabplusFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputEnhancedPacketFile.h" -#include "dabInputEnhancedFifo.h" -#include "dabInputUdp.h" -#include "dabInputBridgeUdp.h" -#include "dabInputTest.h" -#include "dabInputPrbs.h" -#include "dabInputRawFile.h" -#include "dabInputRawFifo.h" -#include "dabInputDmbFile.h" -#include "dabInputDmbUdp.h" -#include "dabInputZmq.h"  #include "DabMux.h"  #include "ManagementServer.h" +#include "input/Prbs.h" +#include "input/Zmq.h" +#include "input/File.h" +#include "input/Udp.h" +  #ifdef _WIN32  #   pragma warning ( disable : 4103 ) @@ -112,24 +99,6 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,          std::shared_ptr<dabEnsemble> ensemble,          const string& subchanuid); -/* a helper class to parse hexadecimal ids */ -static int hexparse(std::string input) -{ -    int value; -    if (input.find("0x") == 0) { -        value = strtoll(input.c_str() + 2, nullptr, 16); -    } -    else { -        value = strtoll(input.c_str(), nullptr, 10); -    } - -    if (errno == ERANGE) { -        throw runtime_error("hex conversion: value out of range"); -    } - -    return value; -} -  static uint16_t get_announcement_flag_from_ptree(          boost::property_tree::ptree& pt          ) @@ -490,7 +459,7 @@ void parse_ptree(          catch (runtime_error &e) {              etiLog.log(error,                      "%s\n", e.what()); -            throw e; +            throw;          } @@ -649,13 +618,13 @@ void parse_ptree(      parse_linkage(pt, ensemble);  } -static dab_input_zmq_config_t setup_zmq_input( +static Inputs::dab_input_zmq_config_t setup_zmq_input(          const boost::property_tree::ptree &pt,          const std::string& subchanuid)  {      using boost::property_tree::ptree_error; -    dab_input_zmq_config_t zmqconfig; +    Inputs::dab_input_zmq_config_t zmqconfig;      try {          zmqconfig.buffer_size = pt.get<int>("zmq-buffer"); @@ -702,20 +671,19 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,          throw runtime_error(ss.str());      } -    string inputUri = ""; -    // fail if no inputUri given unless type is test -    if (type != "test") { -        inputUri = pt.get<string>("inputuri", ""); +    /* Both inputfile and inputuri are supported, and are equivalent. +     * inputuri has precedence +     */ +    string inputUri = pt.get<string>("inputuri", ""); -        if (inputUri == "") { -            try { -                inputUri = pt.get<string>("inputfile"); -            } -            catch (ptree_error &e) { -                stringstream ss; -                ss << "Subchannel with uid " << subchanuid << " has no inputUri defined!"; -                throw runtime_error(ss.str()); -            } +    if (inputUri == "") { +        try { +            inputUri = pt.get<string>("inputfile"); +        } +        catch (ptree_error &e) { +            stringstream ss; +            ss << "Subchannel with uid " << subchanuid << " has no inputUri defined!"; +            throw runtime_error(ss.str());          }      } @@ -730,80 +698,44 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,      subchan->inputUri = inputUri; -    /* The input is of the old_style type, -     * with the struct of function pointers, -     * and needs to be a DabInputCompatible -     */ -    bool input_is_old_style = true; -    dabInputOperations operations;      dabProtection* protection = &subchan->protection; +    const bool nonblock = pt.get("nonblock", false); +    if (nonblock) { +        etiLog.level(warn) << "The nonblock option is not supported"; +    } -    if (0) { -#if defined(HAVE_FORMAT_MPEG) -    } else if (type == "audio") { +    if (type == "dabplus" or type == "audio") {          subchan->type = subchannel_type_t::Audio;          subchan->bitrate = 0; -        if (0) { -#if defined(HAVE_INPUT_FILE) -        } else if (proto == "file") { -            operations = dabInputMpegFileOperations; -#endif // defined(HAVE_INPUT_FILE) -#if defined(HAVE_INPUT_ZEROMQ) -        } -        else if (proto == "tcp"  || -                 proto == "epgm" || -                 proto == "ipc") { -            input_is_old_style = false; - -            auto zmqconfig = setup_zmq_input(pt, subchanuid); - -            DabInputZmqMPEG* inzmq = -                new DabInputZmqMPEG(subchanuid, zmqconfig); -            rcs.enrol(inzmq); -            subchan->input     = inzmq; - -            if (proto == "epgm") { -                etiLog.level(warn) << "Using untested epgm:// zeromq input"; +        if (proto == "file") { +            if (type == "audio") { +                subchan->input = make_shared<Inputs::MPEGFile>();              } -            else if (proto == "ipc") { -                etiLog.level(warn) << "Using untested ipc:// zeromq input"; +            else if (type == "dabplus") { +                subchan->input = make_shared<Inputs::RawFile>(); +            } +            else { +                throw logic_error("Incomplete handling of file input");              } - -#endif // defined(HAVE_INPUT_ZEROMQ) -        } else { -            stringstream ss; -            ss << "Subchannel with uid " << subchanuid << -                ": Invalid protocol for MPEG input (" << -                proto << ")" << endl; -            throw runtime_error(ss.str()); -        } -#endif // defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_MPEG) -#if defined(HAVE_FORMAT_DABPLUS) -    } else if (type == "dabplus") { -        subchan->type = subchannel_type_t::Audio; -        subchan->bitrate = 32; - -        if (0) { -#if defined(HAVE_INPUT_FILE) -        } else if (proto == "file") { -            operations = dabInputDabplusFileOperations; -#endif // defined(HAVE_INPUT_FILE) -#if defined(HAVE_INPUT_ZEROMQ)          }          else if (proto == "tcp"  ||                   proto == "epgm" ||                   proto == "ipc") { -            input_is_old_style = false;              auto zmqconfig = setup_zmq_input(pt, subchanuid); -            DabInputZmqAAC* inzmq = -                new DabInputZmqAAC(subchanuid, zmqconfig); - -            rcs.enrol(inzmq); -            subchan->input     = inzmq; +            if (type == "audio") { +                auto inzmq = make_shared<Inputs::ZmqMPEG>(subchanuid, zmqconfig); +                rcs.enrol(inzmq.get()); +                subchan->input = inzmq; +            } +            else if (type == "dabplus") { +                auto inzmq = make_shared<Inputs::ZmqAAC>(subchanuid, zmqconfig); +                rcs.enrol(inzmq.get()); +                subchan->input = inzmq; +            }              if (proto == "epgm") {                  etiLog.level(warn) << "Using untested epgm:// zeromq input"; @@ -811,44 +743,25 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,              else if (proto == "ipc") {                  etiLog.level(warn) << "Using untested ipc:// zeromq input";              } -#endif // defined(HAVE_INPUT_ZEROMQ) -        } else { +        } +        else {              stringstream ss;              ss << "Subchannel with uid " << subchanuid << -                ": Invalid protocol for DAB+ input (" << +                ": Invalid protocol for " << type << " input (" <<                  proto << ")" << endl;              throw runtime_error(ss.str());          } -#endif // defined(HAVE_FORMAT_DABPLUS) -    } else if (type == "bridge") { -        // TODO default proto should be udp:// -        if (0) { -#if defined(HAVE_FORMAT_BRIDGE) -#if defined(HAVE_INPUT_UDP) -        } else if (proto == "udp") { -            operations = dabInputBridgeUdpOperations; -#endif // defined(HAVE_INPUT_UDP) -#endif // defined(HAVE_FORMAT_BRIDGE) -        } -    } else if (type == "data" and proto == "prbs") { -        input_is_old_style = false; - -        subchan->input = new DabInputPrbs(); +    } +    else if (type == "data" and proto == "prbs") { +        subchan->input = make_shared<Inputs::Prbs>();          subchan->type = subchannel_type_t::DataDmb;          subchan->bitrate = DEFAULT_DATA_BITRATE; -    } else if (type == "data") { -        // TODO default proto should be udp:// -        if (0) { -#if defined(HAVE_INPUT_UDP) -        } else if (proto == "udp") { -            operations = dabInputUdpOperations; -#endif -#if defined(HAVE_INPUT_FILE) && defined(HAVE_FORMAT_RAW) -        } else if (proto == "file") { -            operations = dabInputRawFileOperations; -#endif -        } else if (proto == "fifo") { -            operations = dabInputRawFifoOperations; +    } +    else if (type == "data" or type == "dmb") { +        if (proto == "udp") { +            subchan->input = make_shared<Inputs::Udp>(); +        } else if (proto == "file" or proto == "fifo") { +            subchan->input = make_shared<Inputs::RawFile>();          } else {              stringstream ss;              ss << "Subchannel with uid " << subchanuid << @@ -859,52 +772,23 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,          subchan->type = subchannel_type_t::DataDmb;          subchan->bitrate = DEFAULT_DATA_BITRATE; -#if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW) -    } else if (type == "test") { -        subchan->type = subchannel_type_t::DataDmb; -        subchan->bitrate = DEFAULT_DATA_BITRATE; -        operations = dabInputTestOperations; -#endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW) -#ifdef HAVE_FORMAT_PACKET -    } else if (type == "packet") { -        subchan->type = subchannel_type_t::Packet; -        subchan->bitrate = DEFAULT_PACKET_BITRATE; -#ifdef HAVE_INPUT_FILE -        operations = dabInputPacketFileOperations; -#elif defined(HAVE_INPUT_FIFO) -        operations = dabInputFifoOperations; -#else -#   pragma error("Must define at least one packet input") -#endif // defined(HAVE_INPUT_FILE) -#ifdef HAVE_FORMAT_EPM -    } else if (type == "enhancedpacket") { + +        if (type == "dmb") { +            /* The old dmb input took care of interleaving and Reed-Solomon encoding. This +             * code is unported. +             * See dabInputDmbFile.cpp +             */ +            etiLog.level(warn) << "uid " << subchanuid << " of type Dmb uses RAW input"; +        } +    } +    else if (type == "packet" or type == "enhancedpacket") {          subchan->type = subchannel_type_t::Packet;          subchan->bitrate = DEFAULT_PACKET_BITRATE; -        operations = dabInputEnhancedPacketFileOperations; -#endif // defined(HAVE_FORMAT_EPM) -#endif // defined(HAVE_FORMAT_PACKET) -#ifdef HAVE_FORMAT_DMB -    } else if (type == "dmb") { -        // TODO default proto should be UDP -        if (0) { -#if defined(HAVE_INPUT_UDP) -        } else if (proto == "udp") { -            operations = dabInputDmbUdpOperations; -#endif -        } else if (proto == "file") { -            operations = dabInputDmbFileOperations; -        } else { -            stringstream ss; -            ss << "Subchannel with uid " << subchanuid <<  -                ": Invalid protocol for DMB input (" << -                proto << ")" << endl; -            throw runtime_error(ss.str()); -        } -        subchan->type = subchannel_type_t::DataDmb; -        subchan->bitrate = DEFAULT_DATA_BITRATE; -#endif -    } else { +        bool enhanced = (type == "enhancedpacket"); +        subchan->input = make_shared<Inputs::PacketFile>(enhanced); +    } +    else {          stringstream ss;          ss << "Subchannel with uid " << subchanuid << " has unknown type!";          throw runtime_error(ss.str()); @@ -915,7 +799,8 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,          protection->form = UEP;          protection->level = 2;          protection->uep.tableIndex = 0; -    } else { +    } +    else {          protection->level = 2;          protection->form = EEP;          protection->eep.profile = EEP_A; @@ -937,55 +822,7 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,          throw runtime_error(ss.str());      } -#if defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE) -    /* Get nonblock */ -    bool nonblock = pt.get("nonblock", false); -    if (nonblock) { -        switch (subchan->type) { -#ifdef HAVE_FORMAT_PACKET -            case subchannel_type_t::Packet: -                if (operations == dabInputPacketFileOperations) { -                    operations = dabInputFifoOperations; -#ifdef HAVE_FORMAT_EPM -                } else if (operations == dabInputEnhancedPacketFileOperations) { -                    operations = dabInputEnhancedFifoOperations; -#endif // defined(HAVE_FORMAT_EPM) -                } else { -                    stringstream ss; -                    ss << "Error, wrong packet operations for subchannel " << -                        subchanuid; -                    throw runtime_error(ss.str()); -                } -                break; -#endif // defined(HAVE_FORMAT_PACKET) -#ifdef HAVE_FORMAT_MPEG -            case subchannel_type_t::Audio: -                if (operations == dabInputMpegFileOperations) { -                    operations = dabInputMpegFifoOperations; -                } else if (operations == dabInputDabplusFileOperations) { -                    operations = dabInputDabplusFifoOperations; -                } else { -                    stringstream ss; -                    ss << "Error, wrong audio operations for subchannel " << -                        subchanuid; -                    throw runtime_error(ss.str()); -                } -                break; -#endif // defined(HAVE_FORMAT_MPEG) -            case subchannel_type_t::DataDmb: -            case subchannel_type_t::Fidc: -            default: -                stringstream ss; -                ss << "Subchannel with uid " << subchanuid << -                    " non-blocking I/O only available for audio or packet services!"; -                throw runtime_error(ss.str()); -        } -#endif // defined(HAVE_INPUT_FIFO) && defined(HAVE_INPUT_FILE) -    } - -      /* Get id */ -      try {          subchan->id = hexparse(pt.get<std::string>("id"));      } @@ -1045,11 +882,5 @@ static void setup_subchannel_from_ptree(DabSubchannel* subchan,              ": protection level undefined!";          throw runtime_error(ss.str());      } - -    /* Create object */ -    if (input_is_old_style) { -        subchan->input = new DabInputCompatible(operations); -    } -    // else { it's already been created! }  } diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 2af58c5..04d1980 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -94,24 +94,8 @@ typedef DWORD32 uint32_t;  #   include "Eti.h"  #endif -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" -#include "dabInputMpegFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputDabplusFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputEnhancedPacketFile.h" -#include "dabInputEnhancedFifo.h" -#include "dabInputUdp.h" -#include "dabInputBridgeUdp.h" -#include "dabInputTest.h" -#include "dabInputPrbs.h" -#include "dabInputRawFile.h" -#include "dabInputRawFifo.h" -#include "dabInputDmbFile.h" -#include "dabInputDmbUdp.h" - +#include "input/Prbs.h" +#include "input/Zmq.h"  #include "dabOutput/dabOutput.h"  #include "dabOutput/edi/TagItems.h" @@ -411,7 +395,7 @@ int main(int argc, char *argv[])          if (outputs.size() == 0) { -            etiLog.log(emerg, "no output defined"); +            etiLog.log(alert, "no output defined");              throw MuxInitException();          } @@ -491,7 +475,7 @@ int main(int argc, char *argv[])      outputs.clear();      if (returnCode != 0) { -        etiLog.log(emerg, "...aborting\n"); +        etiLog.log(alert, "...aborting\n");      } else {          etiLog.log(debug, "...done\n");      } diff --git a/src/DabMux.h b/src/DabMux.h index 5dda759..80b4881 100644 --- a/src/DabMux.h +++ b/src/DabMux.h @@ -25,8 +25,7 @@     You should have received a copy of the GNU General Public License     along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>.  */ -#ifndef _DABMUX_H -#define _DABMUX_H +#pragma once  #include <stdint.h>  #include <string> @@ -34,7 +33,7 @@  #include "DabMultiplexer.h"  #include "RemoteControl.h"  #include "dabOutput/dabOutput.h" -#include "dabInput.h" +#include "input/inputs.h"  #include "Eti.h"  #include "MuxElements.h" @@ -44,5 +43,3 @@  #   include <sys/time.h>  #endif -#endif - diff --git a/src/Makefile.am b/src/Makefile.am index 1d33231..de2aa37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -47,25 +47,11 @@ odr_dabmux_LDADD    =$(ZMQ_LIBS) $(CURL_LIBS) \  odr_dabmux_SOURCES  =DabMux.cpp DabMux.h \  					 DabMultiplexer.cpp DabMultiplexer.h \ -					 dabInput.h dabInput.cpp \ -					 dabInputBridgeUdp.h dabInputBridgeUdp.cpp \ -					 dabInputDabplusFifo.h dabInputDabplusFifo.cpp \ -					 dabInputDabplusFile.h dabInputDabplusFile.cpp \ -					 dabInputDmbFile.h dabInputDmbFile.cpp \ -					 dabInputDmbUdp.h dabInputDmbUdp.cpp \ -					 dabInputEnhancedFifo.h dabInputEnhancedFifo.cpp \ -					 dabInputEnhancedPacketFile.h dabInputEnhancedPacketFile.cpp \ -					 dabInputFifo.h dabInputFifo.cpp \ -					 dabInputFile.h dabInputFile.cpp \ -					 dabInputMpegFifo.h dabInputMpegFifo.cpp \ -					 dabInputMpegFile.h dabInputMpegFile.cpp \ -					 dabInputPacketFile.h dabInputPacketFile.cpp \ -					 dabInputPrbs.h dabInputPrbs.cpp \ -					 dabInputRawFile.h dabInputRawFile.cpp \ -					 dabInputRawFifo.h dabInputRawFifo.cpp \ -					 dabInputTest.h dabInputTest.cpp \ -					 dabInputUdp.h dabInputUdp.cpp \ -					 dabInputZmq.h dabInputZmq.cpp \ +					 input/inputs.h \ +					 input/Prbs.cpp input/Prbs.h \ +					 input/Zmq.cpp input/Zmq.h \ +					 input/File.cpp input/File.h \ +					 input/Udp.cpp input/Udp.h \  					 dabOutput/dabOutput.h \  					 dabOutput/dabOutputFile.cpp \  					 dabOutput/dabOutputFifo.cpp \ @@ -80,7 +66,6 @@ odr_dabmux_SOURCES  =DabMux.cpp DabMux.h \  					 dabOutput/edi/PFT.cpp dabOutput/edi/PFT.h \  					 ClockTAI.h ClockTAI.cpp \  					 ConfigParser.cpp ConfigParser.h \ -					 Dmb.h Dmb.cpp \  					 Eti.h Eti.cpp \  					 InetAddress.h InetAddress.cpp \  					 Interleaver.h Interleaver.cpp \ @@ -93,7 +78,6 @@ odr_dabmux_SOURCES  =DabMux.cpp DabMux.h \  					 TcpSocket.h TcpSocket.cpp \  					 UdpSocket.h UdpSocket.cpp \  					 ThreadsafeQueue.h \ -					 bridge.h bridge.c \  					 crc.h crc.c \  					 fig/FIG.h fig/FIG.cpp \  					 fig/FIG0.h fig/FIG0structs.h \ diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp index 2215bda..7f92652 100644 --- a/src/MuxElements.cpp +++ b/src/MuxElements.cpp @@ -385,7 +385,7 @@ void DabComponent::set_parameter(const string& parameter,                  throw ParameterError(ss.str());              default:                  ss << m_name << " short label definition: program error !"; -                etiLog.level(emerg) << ss.str(); +                etiLog.level(alert) << ss.str();                  throw ParameterError(ss.str());          }      } @@ -500,7 +500,7 @@ void DabService::set_parameter(const string& parameter,                  throw ParameterError(ss.str());              default:                  ss << m_name << " short label definition: program error !"; -                etiLog.level(emerg) << ss.str(); +                etiLog.level(alert) << ss.str();                  throw ParameterError(ss.str());          }      } diff --git a/src/MuxElements.h b/src/MuxElements.h index 79100a9..7ff23a6 100644 --- a/src/MuxElements.h +++ b/src/MuxElements.h @@ -40,7 +40,7 @@  #include <boost/optional.hpp>  #include <stdint.h>  #include "dabOutput/dabOutput.h" -#include "dabInput.h" +#include "input/inputs.h"  #include "RemoteControl.h"  #include "Eti.h" @@ -297,7 +297,7 @@ public:      std::string uid;      std::string inputUri; -    DabInputBase* input; +    std::shared_ptr<Inputs::InputBase> input;      unsigned char id;      subchannel_type_t type;      uint16_t startAddress; diff --git a/src/TcpSocket.cpp b/src/TcpSocket.cpp index 433e5c1..b9824fa 100644 --- a/src/TcpSocket.cpp +++ b/src/TcpSocket.cpp @@ -39,31 +39,30 @@ using namespace std;  TcpSocket::TcpSocket() :      m_sock(INVALID_SOCKET)  { -    if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { -        throw std::runtime_error("Can't create socket"); -    }  }  TcpSocket::TcpSocket(int port, const string& name) :      m_sock(INVALID_SOCKET)  { -    if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { -        throw std::runtime_error("Can't create socket"); -    } +    if (port) { +        if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { +            throw std::runtime_error("Can't create socket"); +        } -    reuseopt_t reuse = 1; -    if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) -            == SOCKET_ERROR) { -        throw std::runtime_error("Can't reuse address"); -    } +        reuseopt_t reuse = 1; +        if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) +                == SOCKET_ERROR) { +            throw std::runtime_error("Can't reuse address"); +        } -    m_own_address.setAddress(name); -    m_own_address.setPort(port); +        m_own_address.setAddress(name); +        m_own_address.setPort(port); -    if (bind(m_sock, m_own_address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) { -        ::close(m_sock); -        m_sock = INVALID_SOCKET; -        throw std::runtime_error("Can't bind socket"); +        if (bind(m_sock, m_own_address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) { +            ::close(m_sock); +            m_sock = INVALID_SOCKET; +            throw std::runtime_error("Can't bind socket"); +        }      }  } @@ -116,6 +115,11 @@ TcpSocket::~TcpSocket()      close();  } +bool TcpSocket::isValid() +{ +    return m_sock != INVALID_SOCKET; +} +  ssize_t TcpSocket::recv(void* data, size_t size)  {      ssize_t ret = ::recv(m_sock, (char*)data, size, 0); @@ -167,7 +171,7 @@ TcpSocket TcpSocket::accept()      }  } -boost::optional<TcpSocket> TcpSocket::accept(int timeout_ms) +TcpSocket TcpSocket::accept(int timeout_ms)  {      struct pollfd fds[1];      fds[0].fd = m_sock; @@ -184,7 +188,8 @@ boost::optional<TcpSocket> TcpSocket::accept(int timeout_ms)          return accept();      }      else { -        return boost::none; +        TcpSocket invalidsock(0, ""); +        return invalidsock;      }  } diff --git a/src/TcpSocket.h b/src/TcpSocket.h index 5a4a808..660515d 100644 --- a/src/TcpSocket.h +++ b/src/TcpSocket.h @@ -46,7 +46,7 @@  #include <iostream>  #include <string> -#include <boost/optional.hpp> +#include <memory>  /**   *  This class represents a TCP socket. @@ -67,8 +67,12 @@ class TcpSocket          ~TcpSocket();          TcpSocket(TcpSocket&& other);          TcpSocket& operator=(TcpSocket&& other); +        TcpSocket(const TcpSocket& other) = delete; +        TcpSocket& operator=(const TcpSocket& other) = delete; -        int close(); +        bool isValid(void); + +        int close(void);          /** Send data over the TCP connection.           *  @param data The buffer that will be sent. @@ -86,7 +90,12 @@ class TcpSocket          void listen(void);          TcpSocket accept(void); -        boost::optional<TcpSocket> accept(int timeout_ms); + +        /* Returns either valid socket if a connection was +         * accepted before the timeout expired, or an invalid +         * socket otherwise. +         */ +        TcpSocket accept(int timeout_ms);          /** Retrieve address this socket is bound to */          InetAddress getOwnAddress() const; @@ -94,8 +103,6 @@ class TcpSocket      private:          TcpSocket(SOCKET sock, InetAddress own, InetAddress remote); -        TcpSocket(const TcpSocket& other) = delete; -        TcpSocket& operator=(const TcpSocket& other) = delete;          /// The address on which the socket is bound.          InetAddress m_own_address; diff --git a/src/UdpSocket.cpp b/src/UdpSocket.cpp index 020e3f5..ccdd7ed 100644 --- a/src/UdpSocket.cpp +++ b/src/UdpSocket.cpp @@ -37,19 +37,19 @@ using namespace std;  UdpSocket::UdpSocket() :      listenSocket(INVALID_SOCKET)  { -    init_sock(0, ""); +    reinit(0, "");  }  UdpSocket::UdpSocket(int port) :      listenSocket(INVALID_SOCKET)  { -    init_sock(port, ""); +    reinit(port, "");  }  UdpSocket::UdpSocket(int port, const std::string& name) :      listenSocket(INVALID_SOCKET)  { -    init_sock(port, name); +    reinit(port, name);  } @@ -67,7 +67,7 @@ int UdpSocket::setBlocking(bool block)      return 0;  } -int UdpSocket::init_sock(int port, const std::string& name) +int UdpSocket::reinit(int port, const std::string& name)  {      if (listenSocket != INVALID_SOCKET) {          ::close(listenSocket); @@ -98,6 +98,16 @@ int UdpSocket::init_sock(int port, const std::string& name)      return 0;  } +int UdpSocket::close() +{ +    if (listenSocket != INVALID_SOCKET) { +        ::close(listenSocket); +    } + +    listenSocket = INVALID_SOCKET; + +    return 0; +}  UdpSocket::~UdpSocket()  { diff --git a/src/UdpSocket.h b/src/UdpSocket.h index 535499e..dfeaac1 100644 --- a/src/UdpSocket.h +++ b/src/UdpSocket.h @@ -80,6 +80,15 @@ class UdpSocket          UdpSocket(const UdpSocket& other) = delete;          const UdpSocket& operator=(const UdpSocket& other) = delete; +        /** reinitialise socket. Close the already open socket, and +         * create a new one +         */ +        int reinit(int port, const std::string& name); + +        /** Close the socket +         */ +        int close(void); +          /** Send an UDP packet.           *  @param packet The UDP packet to be sent. It includes the data and the           *                destination address @@ -111,7 +120,6 @@ class UdpSocket          int setBlocking(bool block);      protected: -        int init_sock(int port, const std::string& name);          /// The address on which the socket is bound.          InetAddress address; diff --git a/src/bridge.c b/src/bridge.c deleted file mode 100644 index d66a7b2..0000000 --- a/src/bridge.c +++ /dev/null @@ -1,515 +0,0 @@ -/* -   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the -   Queen in Right of Canada (Communications Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include <stdio.h> -#ifdef _WIN32 -#  include <winsock2.h> -#else -#  include <netinet/in.h> -#endif // _WIN32 -#include <string.h> -#include "bridge.h" -#include "crc.h" - -#include <assert.h> -#include "PcDebug.h" - -#ifdef _WIN32 -#  ifdef _DEBUG -     int bridgeVerbosity = 0; -#  endif -#else -#  ifdef DEBUG -     int bridgeVerbosity = 0; -#  endif -#endif - -void printStats(struct bridgeInfo* info, FILE* out) -{ -    struct bridgeStats stats = getStats(info); -    fprintf(out, "frames     : %lu\n", stats.frames); -    fprintf(out, " valids    : %lu\n", stats.valids); -    fprintf(out, " invalids  : %lu\n", stats.invalids); -    fprintf(out, " bytes     : %lu\n", stats.bytes); -    fprintf(out, " packets   : %lu\n", stats.packets); -    fprintf(out, " errors    : %lu\n", stats.errors); -    fprintf(out, "  missings : %lu\n", stats.missings); -    fprintf(out, "  dropped  : %lu\n", stats.dropped); -    fprintf(out, "  crc      : %lu\n", stats.crc); -    fprintf(out, "  overruns : %lu\n", stats.overruns); -} - - -void resetStats(struct bridgeInfo* info) -{ -    memset(&info->stats, 0, sizeof(info->stats)); -} - - -struct bridgeStats getStats(struct bridgeInfo* info) -{ -    return info->stats; -} - - -void bridgeInitInfo(struct bridgeInfo* info) -{ -    memset(info, 0, sizeof(*info)); -    info->transmitted = -8; -}; - - -int writePacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, -        struct bridgeInfo* info) -{ -    static struct bridgeHdr header = { 0 }; - -    PDEBUG4_VERBOSE(1, bridgeVerbosity, "writePacket\n sizeIn: %i, sizeOut: %i, " -            "offset: %i, transmitted: %i\n", -            sizeIn, sizeOut, info->offset, info->transmitted); - -    assert(info->transmitted < sizeIn); - -    if ((info->offset == 0) && (sizeIn > 0)) { -        ((unsigned short*)dataOut)[0] = 0xb486; -        info->offset = 2; -    } -    if (sizeIn == 0) { -        memset((unsigned char*)dataOut + info->offset, 0, sizeOut - info->offset); -        info->offset = 0; -        info->transmitted = -8; -        PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (sizeIn == 0)\n", -                sizeOut); -        return 0; -    } - -    while (info->offset < sizeOut) { -        switch (info->transmitted) { -        case (-8): -            ((unsigned char*)dataOut)[info->offset++] = 0xcb; -            ++info->transmitted; -            break; -        case (-7): -            ((unsigned char*)dataOut)[info->offset++] = 0x28; -            ++info->transmitted; -            break; -        case (-6): -            header.size = htons((unsigned short)sizeIn); -            header.crc = htons((unsigned short)(crc16(0xffff, &header, 4) ^ 0xffff)); -            ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[0]; -            ++info->transmitted; -            break; -        case (-5): -            ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[1]; -            ++info->transmitted; -            break; -        case (-4): -            ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[2]; -            ++info->transmitted; -            break; -        case (-3): -            ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[3]; -            ++info->transmitted; -            break; -        case (-2): -            ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[4]; -            ++info->transmitted; -            break; -        case (-1): -            ((unsigned char*)dataOut)[info->offset++] = ((char*)&header)[5]; -            ++info->transmitted; -            header.seqNb = htons((unsigned short)(ntohs(header.seqNb) + 1)); -            break; -        default: -            ((unsigned char*)dataOut)[info->offset++] = -                ((unsigned char*)dataIn)[info->transmitted++]; -            if (info->transmitted == sizeIn) { -                PDEBUG2_VERBOSE(1, bridgeVerbosity, -                        " Packet done, %i bytes at offset %i\n", -                        info->transmitted, info->offset); -                PDEBUG1_VERBOSE(1, bridgeVerbosity, -                        " return %i (sizeIn == transmitted)\n", info->offset); -                info->transmitted = -8; -                return info->offset; -            } -        } -    } - -    PDEBUG1_VERBOSE(1, bridgeVerbosity, " return %i (offset >= sizeOut)\n", -            info->offset); -    info->offset = 0; -    return 0; -} - - -int getPacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, -        struct bridgeInfo* info, char async) -{ -    unsigned char* in = (unsigned char*)dataIn; -    unsigned char* out = (unsigned char*)dataOut; -    unsigned char ch; -    unsigned short crc; -    unsigned short diff; - -    PDEBUG3_VERBOSE(1, bridgeVerbosity, -            "getPacket\n pos\t%i\n state\t%i\n received\t%i\n", -            info->pos, info->state, info->received); - -    if (info->pos == 0) { -        ++info->stats.frames; -        if (((unsigned short*)dataIn)[0] != 0xb486) { -            if (((unsigned short*)dataIn)[0] != 0) { -                ++info->stats.invalids; -                printf("WARNING: processing frame with invalid magic " -                        "number!\n"); -            } else { -                PDEBUG0_VERBOSE(1, bridgeVerbosity, -                        "getPacket: not a valid frame\n"); -                return 0; -            } -        } else { -            PDEBUG0_VERBOSE(2, bridgeVerbosity, "Valid frame\n"); -            info->pos += 2; -            ++info->stats.valids; -        } -        info->stats.bytes += sizeIn; -    } -    while (info->pos < sizeIn) { -        ch = in[info->pos++]; -        switch (info->state) { -        case 0:  // sync search -            info->sync <<= 8; -            info->sync |= ch; -            if (info->sync == 0xcb28) { -                PDEBUG0_VERBOSE(2, bridgeVerbosity, "Sync found\n"); -                ++info->stats.packets; -                info->received = 0; -                info->state = 1; -            } -            if (info->sync == 0) {		// Padding -                info->pos = 0; -                return 0; -            } -            break; -        case 1:  // header search -            ((char*)&info->header)[info->received++] = ch; -            if (info->received == sizeof(struct bridgeHdr)) { -                PDEBUG0_VERBOSE(2, bridgeVerbosity, "Header found\n"); -                out = (unsigned char*)dataOut; -                info->received = 0; -                info->state = 2; -                crc = crc16(0xffff, &info->header, 4); -                crc ^= 0xffff; -                info->header.size = ntohs(info->header.size); -                info->header.seqNb = ntohs(info->header.seqNb); -                info->header.crc = ntohs(info->header.crc); -                PDEBUG4_VERBOSE(2, bridgeVerbosity, -                        " size\t%i\n seq\t%i\n crc\t0x%.4x (0x%.4x)\n", -                        info->header.size, info->header.seqNb, -                        info->header.crc, crc); -                if (crc != info->header.crc) { -                    PDEBUG0_VERBOSE(2, bridgeVerbosity, "CRC error\n"); -                    ++info->stats.errors; -                    ++info->stats.crc; -                    info->state = 0; -                    if (info->pos < sizeof(struct bridgeHdr) + 2 + 2) { -                        info->pos = 2; -                    } -                } else { -                    if (!info->initSeq) { -                        info->lastSeq = info->header.seqNb; -                        info->initSeq = 1; -                    } else { -                        if (info->header.seqNb > info->lastSeq) { -                            diff = (info->header.seqNb - info->lastSeq) - 1; -                        } else { -                            diff = ((short)info->lastSeq - -                                    (short)info->header.seqNb) - 1; -                        } -                        info->stats.errors += diff; -                        info->stats.missings += diff; -                        info->lastSeq = info->header.seqNb; -                    } -                } -            } -            break; -        case 2:  // data -            out[info->received++] = ch; -            if (info->received == info->header.size) { -                PDEBUG0_VERBOSE(2, bridgeVerbosity, "data found\n"); -                info->state = 0; -                return info->received; -            } -            if (info->received == sizeOut) { -                PDEBUG1_VERBOSE(1, bridgeVerbosity, "To much data: %i\n", -                        info->received); -                ++info->stats.errors; -                ++info->stats.overruns; -                info->sync = 0; -                info->state = 0; -                return -1; -            } -            break; -        case 3:  // Padding or sync -            if (ch == 0) {			// Padding -                info->pos = 0; -                return 0; -            } -            if (ch != 0xcb) {		// error -                info->sync = ch; -                info->state = 0; -            } else { -                info->state = 4; -            } -            break; -        case 4: // Low byte sync -            if (ch != 28) {			// error -                info->sync <<= 8; -                info->sync |= ch; -                info->state = 0; -            } else { -                info->state = 2; -            } -            break; -        } -    } -    info->pos = 0; -    return 0; -} - - -void dump(void* data, int size, FILE* stream) -{ -    int i; -    fprintf(stream, "%i bytes\n", size); -    for (i = 0; i < size; ++i) { -        fprintf(stream, " 0x%.2x", ((unsigned char*)data)[i]); -        if (i % 8 == 7) -            fprintf(stream, "\n"); -    } -    fprintf(stream, "\n"); -} - - -#ifdef BRIDGE_TEST -#include <stdlib.h> - - -int test(const unsigned char* data) -{ -    unsigned char bridgeSize = data[0]; -    unsigned char nbInput = data[1]; -    unsigned char nbBridge = 1; -    struct bridgeInfo info; - -    int i, j; -    int index = 0; -    int max = 0; -    int nbBytes; - -    unsigned char** inputData; -    unsigned char** bridgeData; -    unsigned char* outputData; - -    inputData =  malloc(nbInput * 4); -    bridgeData = malloc(nbBridge * 4); -    for (i = 0; i < nbInput; ++i) { -        if (data[i + 2] > 0) -            inputData[i] = malloc(data[i + 2]); -        if (data[i + 2] > max) { -            max = data[i + 2]; -        } -        for (j = 0; j < data[i + 2]; ++j) { -            inputData[i][j] = index++; -        } -    } -    bridgeData[0] = malloc(bridgeSize); -    memset(bridgeData[0], 0, bridgeSize); -    outputData = malloc(max); -    bridgeInitInfo(&info); - -    // Write packets -    index = 0; -    while (1) { -        if (data[index + 2] == 0) { -            if (++index == nbInput) -                break; -        } -        while ((nbBytes = writePacket(inputData[index], data[index + 2], -                        bridgeData[nbBridge - 1], bridgeSize, &info)) -                != 0) { -            if (++index == nbInput) { -                break; -            } -        } -        if (index == nbInput) -            break; -        // TODO check null -        bridgeData = realloc(bridgeData, (++nbBridge) * 4); -        bridgeData[nbBridge - 1] = malloc(bridgeSize); -        memset(bridgeData[nbBridge - 1], 0, bridgeSize); -    } -//    if (nbBytes != bridgeSize) { -        writePacket(NULL, 0, bridgeData[nbBridge - 1], bridgeSize, &info); -//    } - -    // read packets -    index = 0; -    for (i = 0; i < nbBridge; ++i) { -        while ((nbBytes = getPacket(bridgeData[i], bridgeSize, outputData, max, -                        &info, 0)) != 0) { -            while (data[index + 2] == 0) { -                ++index; -            } -            if (nbBytes != data[index + 2]) { -                printf("FAILED\n"); -                printf("Invalid size at bridge %i, data %i: %i != %i\n", -                        i, index, nbBytes, data[index + 2]); -                for (i = 0; i < nbInput; ++i) { -                    printf("Input %i: ", i); -                    dump(inputData[i], data[i + 2], stdout); -                } -                for (i = 0; i < nbBridge; ++i) { -                    printf("Bridge %i: ", i); -                    dump(bridgeData[i], bridgeSize, stdout); -                } -                printf("Output %i: ", index); -                dump(outputData, nbBytes, stdout); -                return -1; -            } -            if (memcmp(outputData, inputData[index], data[index + 2]) != 0) { -                printf("FAILED\n"); -                printf("output != input\n"); -                for (i = 0; i < nbInput; ++i) { -                    printf("Input %i: ", i); -                    dump(inputData[i], data[i + 2], stdout); -                } -                for (i = 0; i < nbBridge; ++i) { -                    printf("Bridge %i: ", i); -                    dump(bridgeData[i], bridgeSize, stdout); -                } -                printf("Output %i: ", index); -                dump(outputData, nbBytes, stdout); -            } -            ++index; -        } -    } - -    printf("SUCCESS\n"); - -    for (i = 0; i < nbInput; ++i) { -        if (data[i + 2] > 0) -            free(inputData[i]); -    } -    free(inputData); -    free(outputData); -    for (i = 0; i < nbBridge; ++i) { -        free(bridgeData[i]); -    } -    free(bridgeData); - -    return -1; -} - - -int main(int argc, char* argv[]) -{ -    int i; -    // test: bridgesize, nbinput [, input1, input2, ... ] -    const unsigned char complete[] = { 32, 1, 16 }; -    const unsigned char split[] = { 32, 1, 48 }; -    const unsigned char twice[] = {32, 2, 8, 4 }; -    const unsigned char secondSplit[] = { 32, 2, 16, 16 }; -    const unsigned char headerSplit[][4] = { -        { 32, 2, 23, 16 }, -        { 32, 2, 22, 16 }, -        { 32, 2, 21, 16 }, -        { 32, 2, 20, 16 }, -        { 32, 2, 19, 16 }, -        { 32, 2, 18, 16 }, -        { 32, 2, 17, 16 } -    }; -    const unsigned char two[] = { 32, 3, 16, 0, 16 }; -    const unsigned char doubleSplit[] = { 32, 2, 32, 32 }; -    const unsigned char full[] = { 32, 2, 24, 12 }; -    const unsigned char empty[] = { 32, 3, 0, 0, 5 }; - -#ifdef _WIN32 -  #ifdef _DEBUG -    bridgeVerbosity = argc - 1; -  #endif // DEBUG -#else -  #ifdef DEBUG -    bridgeVerbosity = argc - 1; -  #endif // DEBUG -#endif // _WIN32 - -    printf("Complete:     "); -    test(complete); -    //	printStats(stdout); -    fflush(stdout); - -    printf("split:        "); -    test(split); -    //	printStats(stdout); -    fflush(stdout); - -    printf("twice:        "); -    test(twice); -    //	printStats(stdout); -    fflush(stdout); - -    printf("second split: "); -    test(secondSplit); -    //	printStats(stdout); -    fflush(stdout); - -    for (i = 0; i < sizeof(headerSplit) / sizeof(headerSplit[0]); ++i) { -        printf("headerSplit%i: ", i); -        test(headerSplit[i]); -        //	printStats(stdout); -        fflush(stdout); -    } - -    printf("two:          "); -    test(two); -    //	printStats(stdout); -    fflush(stdout); - -    printf("doubleSplit:  "); -    test(doubleSplit); -    //	printStats(stdout); -    fflush(stdout); - -    printf("full:         "); -    test(full); -    //	printStats(stdout); -    fflush(stdout); - -    printf("empty:        "); -    test(empty); -    //	printStats(stdout); -    fflush(stdout); - -    return 0; -} - -#endif // BRIDGE_TEST diff --git a/src/bridge.h b/src/bridge.h deleted file mode 100644 index 0bae007..0000000 --- a/src/bridge.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the -   Queen in Right of Canada (Communications Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef _BRIDGE -#define _BRIDGE - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif - -#include <stdio.h> - - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _WIN32 -#  ifdef _DEBUG -     extern int bridgeVerbosity; -#  endif // _DEBUG -#else -#  ifndef DEBUG -#   ifndef NDEBUG -#    define NDEBUG -#   endif -#  else -     extern int bridgeVerbosity; -#  endif // DEBUG -#endif // _WIN32 - -struct bridgeStats { -	unsigned long frames;		// Number of frames analyzed -	unsigned long valids;		// Nb of frames with a good magic number -	unsigned long invalids;		// Nb of frames with a good magic number -	unsigned long bytes;		// Nb of data bytes -	unsigned long packets;		// Nb of packets found -	unsigned long errors; -	unsigned long missings; -	unsigned long dropped; -	unsigned long crc;		// Nb of crc errors -	unsigned long overruns;		// Nb of packet too big -}; - - -struct bridgeHdr { -    unsigned short size; -    unsigned short seqNb; -    unsigned short crc; -}; - - -struct bridgeInfo { -    // Tx -    int transmitted;        // Nb bytes written -    int offset;             // Offset of the next byte to write -    // Rx -    int received; -    int pos; -    int state; -    unsigned short lastSeq; -    unsigned short sync; -    char initSeq; -    // General -    struct bridgeHdr header; -    struct bridgeStats stats; -}; - - - -void dump(void* data, int size, FILE* stream); - -/* - * Example of usae: - * if (data.length == 0) - *     read(data) - * while (writePacket() != 0) - *     read(read) - * ... - */ -int writePacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, struct bridgeInfo* info); - -int getPacket(void* dataIn, int sizeIn, void* dataOut, int sizeOut, struct bridgeInfo* info, char async); - -void bridgeInitInfo(struct bridgeInfo* info); -struct bridgeStats getStats(struct bridgeInfo* info); -void resetStats(struct bridgeInfo* info); -void printStats(struct bridgeInfo* info, FILE* out); - -#ifdef __cplusplus -} -#endif - -#endif // _BRIDGE diff --git a/src/dabInput.h b/src/dabInput.h deleted file mode 100644 index f1b4348..0000000 --- a/src/dabInput.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in -   Right of Canada (Communications Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_H -#define DAB_INPUT_H - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "Log.h" -#include "RemoteControl.h" -#include <string> - -extern Logger etiLog; - -// TODO replace usage of dabInputOperations by a -// class hierarchy -struct dabInputOperations { -    int (*init)(void** args); -    int (*open)(void* args, const char* name); -    int (*setbuf)(void* args, int size); -    int (*read)(void* args, void* buffer, int size); -    int (*lock)(void* args); -    int (*unlock)(void* args); -    int (*readFrame)(dabInputOperations* ops, void* args, void* buffer, int size); -    int (*setBitrate)(dabInputOperations* ops, void* args, int bitrate); -    int (*close)(void* args); -    int (*clean)(void** args); -    int (*rewind)(void* args); -    bool operator==(const dabInputOperations&); -}; - -/* New input object base */ -class DabInputBase { -    public: -        virtual int open(const std::string name) = 0; -        virtual int readFrame(void* buffer, int size) = 0; -        virtual int setBitrate(int bitrate) = 0; -        virtual int close() = 0; - -        virtual ~DabInputBase() {} -    protected: -        DabInputBase() {} -}; - -/* Wrapper class for old-style dabInputOperations inputs */ -class DabInputCompatible : public DabInputBase { -    public: -        DabInputCompatible(dabInputOperations ops) -            : m_ops(ops) -        { m_ops.init(&args); } - -        virtual ~DabInputCompatible() -        { m_ops.clean(&args); } - -        virtual int open(const std::string name) -        { return m_ops.open(args, name.c_str()); } - -        virtual int setbuf(int size) -        { return m_ops.setbuf(args, size); } - -        virtual int readFrame(void* buffer, int size) -        { -            if (m_ops.lock) { -                m_ops.lock(args); -            } -            int result = m_ops.readFrame(&m_ops, args, buffer, size); -            if (m_ops.unlock) { -                m_ops.unlock(args); -            } -            return result; -        } - -        virtual int setBitrate(int bitrate) -        { return m_ops.setBitrate(&m_ops, args, bitrate); } - -        virtual int close() -        { return m_ops.close(args); } - -        virtual int rewind() -        { return m_ops.rewind(args); } - -        virtual int read(void* buffer, int size) -        { return m_ops.read(args, buffer, size); } - -        virtual dabInputOperations getOpts() { return m_ops; } - -    private: -        DabInputCompatible& operator=(const DabInputCompatible& other); -        DabInputCompatible(const DabInputCompatible& other); - -        dabInputOperations m_ops; -        void* args; -}; - -int dabInputSetbuf(void* args, int size); -int dabInputSetbitrate(dabInputOperations* ops, void* args, int bitrate); - - -#endif // DAB_INPUT_H diff --git a/src/dabInputBridgeUdp.cpp b/src/dabInputBridgeUdp.cpp deleted file mode 100644 index fdf3d1f..0000000 --- a/src/dabInputBridgeUdp.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputBridgeUdp.h" -#include "dabInputUdp.h" -#include "bridge.h" - -#ifdef HAVE_FORMAT_BRIDGE -#   ifdef HAVE_INPUT_UDP - -struct dabInputBridgeUdpData { -    dabInputUdpData* udpData; -    bridgeInfo* info; -}; - - -struct dabInputOperations dabInputBridgeUdpOperations = { -    dabInputBridgeUdpInit, -    dabInputBridgeUdpOpen, -    dabInputSetbuf, -    NULL, -    NULL, -    NULL, -    dabInputBridgeUdpRead, -    dabInputSetbitrate, -    dabInputBridgeUdpClose, -    dabInputBridgeUdpClean, -    NULL -}; - - -int dabInputBridgeUdpInit(void** args) -{ -    dabInputBridgeUdpData* input = new dabInputBridgeUdpData; -    dabInputUdpInit((void**)&input->udpData); -    input->info = new bridgeInfo; -    bridgeInitInfo(input->info); -    *args = input; - -    return 0; -} - - -int dabInputBridgeUdpOpen(void* args, const char* inputName) -{ -    dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args; - -    return dabInputUdpOpen(input->udpData, inputName); -} - - -int dabInputBridgeUdpRead(dabInputOperations* ops, void* args, void* buffer, int size) -{ -    int nbBytes = 0; -    dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args; -    dabInputFifoStats* stats = (dabInputFifoStats*)&input->udpData->stats; - -    stats->frameRecords[stats->frameCount].curSize = 0; -    stats->frameRecords[stats->frameCount].maxSize = size; - -    if (input->udpData->packet->getSize() == 0) { -        input->udpData->socket->receive(*input->udpData->packet); -    } -    while ((nbBytes = writePacket(input->udpData->packet->getData(), -                    input->udpData->packet->getSize(), buffer, size, -                    input->info)) -            != 0) { -        stats->frameRecords[stats->frameCount].curSize = nbBytes; -        input->udpData->socket->receive(*input->udpData->packet); -    } - -    if (input->udpData->packet->getSize() != 0) { -        stats->frameRecords[stats->frameCount].curSize = size; -    } - -    if (++stats->frameCount == NB_RECORDS) { -        etiLog.log(info, "Data subchannel usage: (%i)", -                stats->id); -        for (int i = 0; i < stats->frameCount; ++i) { -            etiLog.log(info, " %i/%i", -                    stats->frameRecords[i].curSize, -                    stats->frameRecords[i].maxSize); -        } -        etiLog.log(info, "\n"); -        stats->frameCount = 0; -    } -    return size; -} - - -int dabInputBridgeUdpClose(void* args) -{ -    dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)args; - -    return dabInputUdpClose(input->udpData); -} - - -int dabInputBridgeUdpClean(void** args) -{ -    dabInputBridgeUdpData* input = (dabInputBridgeUdpData*)(*args); -    dabInputUdpClean((void**)&input->udpData); -    delete input->info; -    delete input; -    return 0; -} - - -#   endif // HAVE_INPUT_UDP -#endif // HAVE_FORMAT_BRIDGE - diff --git a/src/dabInputBridgeUdp.h b/src/dabInputBridgeUdp.h deleted file mode 100644 index ed00952..0000000 --- a/src/dabInputBridgeUdp.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_BRIDGE_UDP_H -#define DAB_INPUT_BRIDGE_UDP_H - - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_BRIDGE -#   ifdef HAVE_INPUT_UDP - - -extern struct dabInputOperations dabInputBridgeUdpOperations; - -int dabInputBridgeUdpInit(void** args); -int dabInputBridgeUdpOpen(void* args, const char* inputName); -int dabInputBridgeUdpRead(dabInputOperations* ops, void* args, void* buffer, int size); -int dabInputBridgeUdpClose(void* args); -int dabInputBridgeUdpClean(void** args); - - -#   endif -#endif - - -#endif // DAB_INPUT_BRIDGE_UDP_H diff --git a/src/dabInputDabplusFifo.cpp b/src/dabInputDabplusFifo.cpp deleted file mode 100644 index 94aec13..0000000 --- a/src/dabInputDabplusFifo.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputDabplusFifo.h" -#include "dabInputDabplusFile.h" -#include "dabInputFifo.h" -#include "dabInput.h" - -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#ifndef _WIN32 -#   define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_DABPLUS -#   ifdef HAVE_INPUT_FILE - - -struct dabInputDabplusFifoData { -    void* fifoData; -    uint8_t* buffer; -    size_t bufferSize; -    size_t bufferIndex; -    size_t bufferOffset; -}; - - -struct dabInputOperations dabInputDabplusFifoOperations = { -    dabInputDabplusFifoInit, -    dabInputDabplusFifoOpen, -    dabInputDabplusFifoSetbuf, -    dabInputDabplusFifoRead, -    dabInputDabplusFifoLock, -    dabInputDabplusFifoUnlock, -    dabInputDabplusFileReadFrame, -    dabInputSetbitrate, -    dabInputDabplusFifoClose, -    dabInputDabplusFifoClean, -    dabInputDabplusFifoRewind -}; - - -int dabInputDabplusFifoInit(void** args) -{ -    dabInputDabplusFifoData* data = new dabInputDabplusFifoData; - -    dabInputFifoInit(&data->fifoData); -    data->buffer = nullptr; -    data->bufferSize = 0; -    data->bufferIndex = 0; -    data->bufferOffset = 0; - -    *args = data; - -    return 0; -} - - -int dabInputDabplusFifoOpen(void* args, const char* filename) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    return dabInputFifoOpen(data->fifoData, filename); -} - - -int dabInputDabplusFifoSetbuf(void* args, int size) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    return dabInputFifoSetbuf(data->fifoData, size); -} - - -int dabInputDabplusFifoRead(void* args, void* buffer, int size) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    if (data->bufferSize != (size_t)size * 5) { -        if (data->buffer != nullptr) { -            delete[] data->buffer; -        } -        data->buffer = new uint8_t[size * 5]; -        data->bufferSize = size * 5; -        data->bufferIndex = 0; -    } - -    if (data->bufferOffset < data->bufferSize) { -        int ret = dabInputFifoRead(data->fifoData, -                &data->buffer[data->bufferOffset], -                data->bufferSize - data->bufferOffset); -        if (ret < 0) { -            return ret; -        } -        data->bufferOffset += ret; -        if (data->bufferOffset != data->bufferSize) { -            etiLog.log(alert, "ERROR: Incomplete DAB+ frame!\n"); -            return 0; -        } -    } - -    memcpy(buffer, &data->buffer[data->bufferIndex], size); -    data->bufferIndex += size; -    if (data->bufferIndex >= data->bufferSize) { -        data->bufferIndex = 0; -        data->bufferOffset = 0; -    } -    return size; -} - - -int dabInputDabplusFifoLock(void* args) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    return dabInputFifoLock(data->fifoData); -} - - -int dabInputDabplusFifoUnlock(void* args) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    return dabInputFifoUnlock(data->fifoData); -} - - -int dabInputDabplusFifoReadFrame(dabInputOperations* ops, void* args, -        void* buffer, int size) -{ -    return ops->read(args, buffer, size); -} - - -int dabInputDabplusFifoClose(void* args) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    return dabInputFifoClose(data->fifoData); -} - - -int dabInputDabplusFifoClean(void** args) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    dabInputFifoClean(&data->fifoData); -    delete data; - -    return 0; -} - - -int dabInputDabplusFifoRewind(void* args) -{ -    dabInputDabplusFifoData* data = (dabInputDabplusFifoData*)args; - -    return dabInputFifoRewind(data->fifoData); -} - - -#   endif -#endif diff --git a/src/dabInputDabplusFifo.h b/src/dabInputDabplusFifo.h deleted file mode 100644 index 83368d6..0000000 --- a/src/dabInputDabplusFifo.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_DABPLUS_FIFO_H -#define DAB_INPUT_DABPLUS_FIFO_H - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif - - -#ifdef HAVE_FORMAT_DABPLUS -#   ifdef HAVE_INPUT_FIFO - - -extern struct dabInputOperations dabInputDabplusFifoOperations; - - -int dabInputDabplusFifoInit(void** args); -int dabInputDabplusFifoOpen(void* args, const char* filename); -int dabInputDabplusFifoSetbuf(void* args, int size); -int dabInputDabplusFifoRead(void* args, void* buffer, int size); -int dabInputDabplusFifoLock(void* args); -int dabInputDabplusFifoUnlock(void* args); -int dabInputDabplusFifoReadFrame(dabInputOperations* ops, void* args, -        void* buffer, int size); -int dabInputDabplusFifoClose(void* args); -int dabInputDabplusFifoClean(void** args); -int dabInputDabplusFifoRewind(void* args); - - -#   endif -#endif - - -#endif // DAB_INPUT_DABPLUS_FIFO_H diff --git a/src/dabInputDabplusFile.cpp b/src/dabInputDabplusFile.cpp deleted file mode 100644 index 64b7f07..0000000 --- a/src/dabInputDabplusFile.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputDabplusFile.h" -#include "dabInput.h" - -#include <stdio.h> -#include <string.h> -#include <fcntl.h> - -#ifndef _WIN32 -#   define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_DABPLUS -#   ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputDabplusFileOperations = { -    dabInputDabplusFileInit, -    dabInputDabplusFileOpen, -    dabInputSetbuf, -    dabInputDabplusFileRead, -    nullptr, -    nullptr, -    dabInputDabplusFileReadFrame, -    dabInputSetbitrate, -    dabInputDabplusFileClose, -    dabInputDabplusFileClean, -    dabInputDabplusFileRewind -}; - - -int dabInputDabplusFileInit(void** args) -{ -    dabInputDabplusFileData* data = new dabInputDabplusFileData; -    data->file = -1; -    data->buffer = nullptr; -    data->bufferSize = 0; -    data->bufferIndex = 0; - -    *args = data; -    return 0; -} - - -int dabInputDabplusFileOpen(void* args, const char* filename) -{ -    dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; -    data->file = open(filename, O_RDONLY | O_BINARY); -    if (data->file == -1) { -        perror(filename); -        return -1; -    } - -    return 0; -} - - -int dabInputDabplusFileRead(void* args, void* buffer, int size) -{ -    dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; -    if (data->bufferSize != (size_t)size * 5) { -        if (data->buffer == nullptr) { -            delete[] data->buffer; -        } -        data->buffer = new uint8_t[size * 5]; -        memset(data->buffer, 0, size * 5); -        data->bufferSize = size * 5; -        data->bufferIndex = 0; -    } - -    if (data->bufferIndex + size > data->bufferSize) { -        int ret = read(data->file, data->buffer, data->bufferSize); -        if (ret != (int)data->bufferSize) { -            if (ret != 0) { -                etiLog.log(alert, "ERROR: Incomplete DAB+ frame!\n"); -            } -            return 0; -        } -        data->bufferIndex = 0; -    } - -    memcpy(buffer, &data->buffer[data->bufferIndex], size); -    data->bufferIndex += size; - -    return size; -} - - -int dabInputDabplusFileReadFrame(dabInputOperations* ops, void* args, -        void* buffer, int size) -{ -    //dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; -    int result; -    uint8_t* dataOut = reinterpret_cast<uint8_t*>(buffer); - -    result = ops->read(args, dataOut, size); -    if (result == -1) { -        etiLog.log(alert, "ERROR: Can't read file\n"); -        perror(""); -        return -1; -    } -    if (result < size) { -        int sizeOut = result; -        etiLog.log(info, "reach end of file -> rewinding\n"); -        if (ops->rewind(args) == -1) { -            etiLog.log(alert, "ERROR: Can't rewind file\n"); -            return -1; -        } - -        result = ops->read(args, dataOut + sizeOut, size - sizeOut); -        if (result == -1) { -            etiLog.log(alert, "ERROR: Can't read file\n"); -            perror(""); -            return -1; -        } - -        if (result < size) { -            etiLog.log(alert, "ERROR: Not enought data in file\n"); -            return -1; -        } -    } - -    return size; -} - - -int dabInputDabplusFileClose(void* args) -{ -    dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; -    if (data->file != -1) { -        close(data->file); -    } -    return 0; -} - - -int dabInputDabplusFileClean(void** args) -{ -    dabInputDabplusFileData* data = (dabInputDabplusFileData*)*args; -    if (data->buffer != nullptr) { -        delete[] data->buffer; -    } -    delete data; -    return 0; -} - - -int dabInputDabplusFileRewind(void* args) -{ -    dabInputDabplusFileData* data = (dabInputDabplusFileData*)args; -    return lseek(data->file, 0, SEEK_SET); -} - - -#   endif -#endif diff --git a/src/dabInputDabplusFile.h b/src/dabInputDabplusFile.h deleted file mode 100644 index 5fe2dec..0000000 --- a/src/dabInputDabplusFile.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_DABPLUS_FILE_H -#define DAB_INPUT_DABPLUS_FILE_H - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif - -#include <stdint.h> -#include <unistd.h> - - -#ifdef HAVE_FORMAT_DABPLUS -#   ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputDabplusFileOperations; - - -struct dabInputDabplusFileData { -    int file; -    uint8_t* buffer; -    size_t bufferSize; -    size_t bufferIndex; -}; - - -int dabInputDabplusFileInit(void** args); -int dabInputDabplusFileOpen(void* args, const char* filename); -int dabInputDabplusFileRead(void* args, void* buffer, int size); -int dabInputDabplusFileReadFrame(dabInputOperations* ops, void* args, -        void* buffer, int size); -int dabInputDabplusFileClose(void* args); -int dabInputDabplusFileClean(void** args); -int dabInputDabplusFileRewind(void* args); - - -#   endif -#endif - - -#endif // DAB_INPUT_DABPLUS_FILE_H diff --git a/src/dabInputEnhancedFifo.cpp b/src/dabInputEnhancedFifo.cpp deleted file mode 100644 index 3a8a27c..0000000 --- a/src/dabInputEnhancedFifo.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputEnhancedFifo.h" -#include "dabInputPacketFile.h" -#include "dabInputFifo.h" - - -#ifdef HAVE_FORMAT_PACKET -#   ifdef HAVE_FORMAT_EPM -#       ifdef HAVE_INPUT_FIFO - - -struct dabInputOperations dabInputEnhancedFifoOperations = { -    dabInputEnhancedFifoInit, -    dabInputFifoOpen, -    dabInputFifoSetbuf, -    dabInputFifoRead, -    dabInputFifoLock, -    dabInputFifoUnlock, -    dabInputPacketFileRead, -    dabInputSetbitrate, -    dabInputFifoClose, -    dabInputFifoClean, -    dabInputFifoRewind -}; - - -int dabInputEnhancedFifoInit(void** args) -{ -    dabInputFifoInit(args); -    dabInputFifoData* data = (dabInputFifoData*)*args; - -    data->packetData = new unsigned char[96]; -    data->enhancedPacketData = new unsigned char*[12]; -    for (int i = 0; i < 12; ++i) { -        data->enhancedPacketData[i] = new unsigned char[204]; -    } - -    return 0; -} - - -#       endif -#   endif -#endif diff --git a/src/dabInputEnhancedFifo.h b/src/dabInputEnhancedFifo.h deleted file mode 100644 index 4c87e24..0000000 --- a/src/dabInputEnhancedFifo.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_ENHANCED_FIFO_H -#define DAB_INPUT_ENHANCED_FIFO_H - - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_PACKET -#   ifdef HAVE_FORMAT_EPM -#       ifdef HAVE_INPUT_FIFO - - -extern struct dabInputOperations dabInputEnhancedFifoOperations; -int dabInputEnhancedFifoInit(void** args); - - -#       endif -#   endif -#endif - - -#endif // DAB_INPUT_ENHANCED_FIFO_H diff --git a/src/dabInputEnhancedPacketFile.cpp b/src/dabInputEnhancedPacketFile.cpp deleted file mode 100644 index 3b12e0b..0000000 --- a/src/dabInputEnhancedPacketFile.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputEnhancedPacketFile.h" -#include "dabInputPacketFile.h" -#include "dabInputFile.h" - - -struct dabInputOperations dabInputEnhancedPacketFileOperations = { -    dabInputEnhancedFileInit, -    dabInputFileOpen, -    dabInputSetbuf, -    dabInputFileRead, -    nullptr, -    nullptr, -    dabInputPacketFileRead, -    dabInputSetbitrate, -    dabInputFileClose, -    dabInputFileClean, -    dabInputFileRewind -}; - - -int dabInputEnhancedFileInit(void** args) -{ -    dabInputFileInit(args); -    dabInputFileData* data = (dabInputFileData*)*args; - -    data->enhancedPacketData = new unsigned char*[12]; -    for (int i = 0; i < 12; ++i) { -        data->enhancedPacketData[i] = new unsigned char[204]; -    } - -    return 0; -} diff --git a/src/dabInputEnhancedPacketFile.h b/src/dabInputEnhancedPacketFile.h deleted file mode 100644 index 74f59de..0000000 --- a/src/dabInputEnhancedPacketFile.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_ENHANCED_PACKET_FILE_H -#define DAB_INPUT_ENHANCED_PACKET_FILE_H - - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_PACKET -#   ifdef HAVE_FORMAT_EPM -#       ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputEnhancedPacketFileOperations; - -int dabInputEnhancedFileInit(void** args); - - -#       endif -#   endif -#endif - - -#endif // DAB_INPUT_ENHANCED_PACKET_FILE_H diff --git a/src/dabInputFifo.cpp b/src/dabInputFifo.cpp deleted file mode 100644 index 6fa3aad..0000000 --- a/src/dabInputFifo.cpp +++ /dev/null @@ -1,518 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) - -   Copyright (C) 2016 -   Matthias P. Braendli, matthias.braendli@mpb.li - -    http://www.opendigitalradio.org -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputFifo.h" -#include "dabInputPacketFile.h" -#include "dabInput.h" - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> - - -#ifdef HAVE_FORMAT_PACKET -#   ifdef HAVE_INPUT_FIFO - - -int dabInputFifoData::nb = 0; - - -struct dabInputOperations dabInputFifoOperations = { -    dabInputFifoInit, -    dabInputFifoOpen, -    dabInputFifoSetbuf, -    dabInputFifoRead, -    dabInputFifoLock, -    dabInputFifoUnlock, -    dabInputPacketFileRead, -    dabInputSetbitrate, -    dabInputFifoClose, -    dabInputFifoClean, -    dabInputFifoRewind -}; - - -int dabInputFifoInit(void** args) -{ -    dabInputFifoData* data = new dabInputFifoData; -    memset(data, 0, sizeof(*data)); -    data->stats.id = dabInputFifoData::nb++; -    data->maxSize = 0; -    data->curSize = 0; -    data->head = 0; -    data->tail = 0; -    data->buffer = nullptr; -    data->packetData = nullptr; -    data->enhancedPacketData = nullptr; -    data->packetLength = 0; -    data->enhancedPacketLength = 0; -    data->enhancedPacketWaiting = 0; -    data->full = false; -    data->running = true; -    data->thread = (pthread_t)NULL; -#ifdef _WIN32 -    char semName[32]; -    sprintf(semName, "semInfo%i", data->stats.id); -    data->semInfo = CreateSemaphore(NULL, 1, 1, semName); -    if (data->semInfo == NULL) { -        fprintf(stderr, "Can't init FIFO data semaphore %s\n", semName); -        return -1; -    } -    sprintf(semName, "semBuffer%i", data->stats.id); -    data->semBuffer = CreateSemaphore(NULL, 1, 1, semName); -    if (data->semBuffer == NULL) { -        fprintf(stderr, "Can't init FIFO buffer semaphore %s\n", semName); -        return -1; -    } -    sprintf(semName, "semFull%i", data->stats.id); -    data->semFull = CreateSemaphore(NULL, 1, 1, semName); -    if (data->semFull == NULL) { -        fprintf(stderr, "Can't init FIFO semaphore %s\n", semName); -        return -1; -    } -#else -    if (sem_init(&data->semInfo, 0, 1) == -1) { -        perror("Can't init FIFO data semaphore"); -        return -1; -    } -    if (sem_init(&data->semBuffer, 0, 0) == -1) { -        perror("Can't init fIFO buffer semaphore"); -        return -1; -    } -    if (sem_init(&data->semFull, 0, 0) == -1) { -        perror("Can't init FIFO semaphore"); -        return -1; -    } -#endif - -    if (data->maxSize > 0) { -#ifdef _WIN32 -        ReleaseSemaphore(data->semBuffer, 1, NULL); -#else -        sem_post(&data->semBuffer); -#endif -    } -    *args = data; -    return 0; -} - - -int dabInputFifoOpen(void* args, const char* filename) -{ -    dabInputFifoData* data = (dabInputFifoData*)args; -    data->file = open(filename, O_RDONLY | O_BINARY | O_NONBLOCK); -    if (data->file == -1) { -        perror(filename); -        return -1; -    } -#ifdef _WIN32 -#else -    int flags = fcntl(data->file, F_GETFL); -    if (flags == -1) { -        perror(filename); -        return -1; -    } -    if (fcntl(data->file, F_SETFL, flags & ~O_NONBLOCK) == -1) { -        perror(filename); -        return -1; -    } -#endif - -#ifdef _WIN32 -    data->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)dabInputFifoThread, data, 0, NULL); -    if (data->thread == NULL) { -        fprintf(stderr, "Can't create FIFO child\n"); -        return -1; -    } -#else -    if (pthread_create(&data->thread, nullptr, dabInputFifoThread, data)) { -        perror("Can't create FIFO child"); -        return -1; -    } -#endif - -    return 0; -} - - -int dabInputFifoSetbuf(void* args, int size) -{ -    dabInputFifoData* data = (dabInputFifoData*)args; - -    if (data->maxSize > 0) { -#ifdef _WIN32 -        WaitForSingleObject(data->semBuffer, INFINITE); -#else -        sem_wait(&data->semBuffer); -#endif -    } -    if (data->buffer != nullptr) { -        delete data->buffer; -    } -    if (size == 0) { -        size = 1024; -    } -    data->buffer = new unsigned char[size * 16]; -    data->maxSize = size * 16; -#ifdef _WIN32 -    ReleaseSemaphore(data->semBuffer, 1, NULL); -#else -    sem_post(&data->semBuffer); -#endif - -    return 0; -} - - -int dabInputFifoRead(void* args, void* buffer, int size) -{ -    //fprintf(stderr, "INFO: read %i bytes\n", size); -    dabInputFifoData* data = (dabInputFifoData*)args; -    dabInputFifoStats* stats = &data->stats; -    int head; -    int tail; -    int curSize; -    int maxSize; -#ifdef _WIN32 -    WaitForSingleObject(data->semInfo, INFINITE); -#else -    sem_wait(&data->semInfo); -#endif -    head = data->head; -    tail = data->tail; -    curSize = data->curSize; -    maxSize = data->maxSize; -#ifdef _WIN32 -    ReleaseSemaphore(data->semInfo, 1, NULL); -#else -    sem_post(&data->semInfo); -#endif -    //fprintf(stderr, "head: %i, tail: %i, curSize: %i\n", head, tail, curSize); -    if (size > curSize) { -        if (curSize == 0) { -            stats->empty = true; -        } else { -            etiLog.log(warn, "Not enough data in FIFO buffer: (%i) %i/%i\n", -                    data->stats.id, curSize, size); -        } -        return 0; -    } -    if (head > tail) { -        memcpy(buffer, data->buffer + tail, size); -#ifdef _WIN32 -        WaitForSingleObject(data->semInfo, INFINITE); -#else -        sem_wait(&data->semInfo); -#endif -        data->tail += size; -        data->curSize -= size; -#ifdef _WIN32 -        ReleaseSemaphore(data->semInfo, 1, NULL); -#else -        sem_post(&data->semInfo); -#endif -        return size; -    } else { -        if (maxSize - tail >= size) { -            memcpy(buffer, data->buffer + tail, size); -#ifdef _WIN32 -            WaitForSingleObject(data->semInfo, INFINITE); -#else -            sem_wait(&data->semInfo); -#endif -            data->tail += size; -            data->curSize -= size; -#ifdef _WIN32 -            ReleaseSemaphore(data->semInfo, 1, NULL); -#else -            sem_post(&data->semInfo); -#endif -            return size; -        } else { -            memcpy(buffer, data->buffer + tail, maxSize - tail); -#ifdef _WIN32 -            WaitForSingleObject(data->semInfo, INFINITE); -#else -            sem_wait(&data->semInfo); -#endif -            data->tail = 0; -            data->curSize -= maxSize - tail; -#ifdef _WIN32 -            ReleaseSemaphore(data->semInfo, 1, NULL); -#else -            sem_post(&data->semInfo); -#endif -            return maxSize - tail + dabInputFifoRead(data, (char*)buffer + maxSize - tail, size - (maxSize - tail)); -        } -    } -    return -1; -} - - -int dabInputFifoLock(void* args) { -    dabInputFifoData* data = (dabInputFifoData*)args; -    dabInputFifoStats* stats = &data->stats; - -    int maxSize; -    int curSize; -#ifdef _WIN32 -    WaitForSingleObject(data->semInfo, INFINITE); -#else -    sem_wait(&data->semInfo); -#endif -    maxSize = data->maxSize; -    curSize = data->curSize; -#ifdef _WIN32 -    ReleaseSemaphore(data->semInfo, 1, NULL); -#else -    sem_post(&data->semInfo); -#endif - -    stats->bufferRecords[stats->bufferCount].curSize = curSize; -    stats->bufferRecords[stats->bufferCount].maxSize = maxSize; - -    if (++stats->bufferCount == NB_RECORDS) { -        etiLog.log(info, "FIFO buffer state: (%i)", stats->id); -        for (int i = 0; i < stats->bufferCount; ++i) { -            etiLog.log(info, " %i/%i", -                    stats->bufferRecords[i].curSize, -                    stats->bufferRecords[i].maxSize); -        } -        etiLog.log(info, "\n"); - -        if (stats->full) { -            etiLog.log(warn, "FIFO buffer full: (%i)\n", -                    data->stats.id); -            stats->full = false; -        } -        if (stats->empty) { -            etiLog.log(warn, "FIFO buffer empty: (%i)\n", -                    data->stats.id); -            stats->empty = false; -        } -        if (stats->error) { -            etiLog.log(error, "FIFO input read error: (%i)\n", -                    data->stats.id); -            stats->error = false; -        } -        if (stats->input) { -            etiLog.log(error, "FIFO input not connected: (%i)\n", -                    data->stats.id); -            stats->input = false; -        } - -        stats->bufferCount = 0; -    } -    return 0; -} - - -int dabInputFifoUnlock(void* args) { -    dabInputFifoData* data = (dabInputFifoData*)args; -    if (data->full) { -#ifdef _WIN32 -        ReleaseSemaphore(data->semFull, 1, NULL); -#else -        sem_post(&data->semFull); -#endif -    } -    return 0; -} - - -int dabInputFifoClose(void* args) -{ -    dabInputFifoData* data = (dabInputFifoData*)args; -    close(data->file); -    return 0; -} - - -int dabInputFifoClean(void** args) -{ -    dabInputFifoData* data = (dabInputFifoData*)*args; -    data->running = false; -    etiLog.log(debug, "Wait FIFO child...\n"); -#ifdef WIN32 -    DWORD status; -    for (int i = 0; i < 5; ++i) { -        if (GetExitCodeThread(data->thread, &status)) { -            break; -        } -        Sleep(100); -    } -    TerminateThread(data->thread, 1); -    if (CloseHandle(data->thread) == 0) { -        etiLog.log(debug, "ERROR: Failed to close FIFO child thread\n"); -    } -#else -    if (data->thread != (pthread_t)NULL) { -        if (pthread_join(data->thread, nullptr)) { -            etiLog.log(debug, "ERROR: FIFO child thread had not exit normally\n"); -        } -    } -#endif -    etiLog.log(debug, "Done\n"); -#ifdef _WIN32 -    CloseHandle(data->semInfo); -    CloseHandle(data->semFull); -    CloseHandle(data->semBuffer); -#else -    sem_destroy(&data->semInfo); -    sem_destroy(&data->semFull); -    sem_destroy(&data->semBuffer); -#endif -    if (data->packetData != nullptr) { -        delete[] data->packetData; -    } -    if (data->enhancedPacketData != nullptr) { -        for (int i = 0; i < 12; ++i) { -            if (data->enhancedPacketData[i] != nullptr) { -                delete[] data->enhancedPacketData[i]; -            } -        } -        delete[] data->enhancedPacketData; -    } -    delete data->buffer; -    delete data; -    return 0; -} - - -int dabInputFifoRewind(void* args) -{ -    return -1; -} - - -void* dabInputFifoThread(void* args) -{ -    dabInputFifoData* data = (dabInputFifoData*)args; -    int head; -    int tail; -    int curSize; -    int maxSize; -    int ret; -    while (data->running) { -#ifdef _WIN32 -        WaitForSingleObject(data->semBuffer, INFINITE); -        WaitForSingleObject(data->semInfo, INFINITE); -#else -        sem_wait(&data->semBuffer); -        sem_wait(&data->semInfo); -#endif -        head = data->head; -        tail = data->tail; -        curSize = data->curSize; -        maxSize = data->maxSize; -#ifdef _WIN32 -        ReleaseSemaphore(data->semInfo, 1, NULL); -#else -        sem_post(&data->semInfo); -#endif -        //fprintf(stderr, "thread, head: %i, tail: %i, curSize: %i\n", head, tail, curSize); - -        if (curSize == maxSize) { -            data->stats.full = true; -            data->full = true; -#ifdef _WIN32 -            WaitForSingleObject(data->semFull, INFINITE); -#else -            sem_wait(&data->semFull); -#endif -        } else if (head >= tail) {          // 2 blocks -            ret = read(data->file, data->buffer + head, maxSize - head); -            if (ret == 0) { -                data->stats.input = true; -                data->full = true; -#ifdef _WIN32 -                WaitForSingleObject(data->semFull, INFINITE); -#else -                sem_wait(&data->semFull); -#endif -            } else if (ret == -1) { -                data->stats.error = true; -            } else { -#ifdef _WIN32 -                WaitForSingleObject(data->semInfo, INFINITE); -#else -                sem_wait(&data->semInfo); -#endif -                data->head += ret; -                data->curSize += ret; -                if (data->head == maxSize) { -                    data->head = 0; -                } -#ifdef _WIN32 -                ReleaseSemaphore(data->semInfo, 1, NULL); -#else -                sem_post(&data->semInfo); -#endif -            } -        } else {   // 1 block -            ret = read(data->file, data->buffer + head, tail - head); -            if (ret == 0) { -                data->stats.input = true; -                data->full = true; -#ifdef _WIN32 -                WaitForSingleObject(data->semFull, INFINITE); -#else -                sem_wait(&data->semFull); -#endif -            } else if (ret == -1) { -                data->stats.error = true; -            } else { -#ifdef _WIN32 -                WaitForSingleObject(data->semInfo, INFINITE); -#else -                sem_wait(&data->semInfo); -#endif -                data->head += ret; -                data->curSize += ret; -                if (data->head == maxSize) { -                    data->head = 0; -                } -#ifdef _WIN32 -                ReleaseSemaphore(data->semInfo, 1, NULL); -#else -                sem_post(&data->semInfo); -#endif -            } -        } -#ifdef _WIN32 -        ReleaseSemaphore(data->semBuffer, 1, NULL); -#else -        sem_post(&data->semBuffer); -#endif -    } -    return nullptr; -} - - -#   endif -#endif diff --git a/src/dabInputFifo.h b/src/dabInputFifo.h deleted file mode 100644 index 99edac6..0000000 --- a/src/dabInputFifo.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) - -   Copyright (C) 2016 -   Matthias P. Braendli, matthias.braendli@mpb.li - -    http://www.opendigitalradio.org -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#pragma once - -#ifdef HAVE_CONFIG_H -#  include "config.h" -#endif - -#include "dabInputFile.h" -#include "Log.h" - - -#ifdef _WIN32 -#   include <io.h> -#   define sem_t HANDLE -#   define O_NONBLOCK 0 -#else -#   include <semaphore.h> -#   define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_PACKET -#   ifdef HAVE_INPUT_FIFO -extern struct dabInputOperations dabInputFifoOperations; - - -struct dabInputFifoStatRecord { -    int curSize; -    int maxSize; -}; - - -#define NB_RECORDS      10 -struct dabInputFifoStats { -    int id; -    bool full; -    bool empty; -    bool error; -    bool input; -    int bufferCount; -    dabInputFifoStatRecord bufferRecords[NB_RECORDS]; -    int frameCount; -    dabInputFifoStatRecord frameRecords[NB_RECORDS]; -}; - - -struct dabInputFifoData : dabInputFileData { -    static int nb; -    int maxSize; -    int curSize; -    int head; -    int tail; -    dabInputFifoStats stats; -    unsigned char* buffer; -    pthread_t thread; -    sem_t semInfo; -    sem_t semBuffer; -    sem_t semFull; -    bool full; -    bool running; -}; - - -int dabInputFifoInit(void** args); -int dabInputFifoOpen(void* args, const char* filename); -int dabInputFifoSetbuf(void* args, int size); -int dabInputFifoRead(void* args, void* buffer, int size); -int dabInputFifoLock(void* args); -int dabInputFifoUnlock(void* args); -int dabInputFifoClose(void* args); -int dabInputFifoClean(void** args); -int dabInputFifoRewind(void* args); -void* dabInputFifoThread(void* args); - - -#   endif -#endif - diff --git a/src/dabInputFile.cpp b/src/dabInputFile.cpp deleted file mode 100644 index 2847caa..0000000 --- a/src/dabInputFile.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* -   Copyright (C) 2009,2011 Her Majesty the Queen in Right of Canada -   (Communications Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputFile.h" - -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> - -#ifndef _WIN32 -#   define O_BINARY 0 -#endif - - -int dabInputFileInit(void** args) -{ -    dabInputFileData* data = new dabInputFileData; -    data->file = -1; -    data->parity = false; -    data->packetLength = 0; -    data->packetData = new unsigned char[96]; -    data->enhancedPacketData = nullptr; -    data->enhancedPacketLength = 0; -    data->enhancedPacketWaiting = 0; - -    *args = data; -    return 0; -} - - -int dabInputFileOpen(void* args, const char* filename) -{ -    dabInputFileData* data = (dabInputFileData*)args; -    data->file = open(filename, O_RDONLY | O_BINARY); -    if (data->file == -1) { -        perror(filename); -        return -1; -    } -    return 0; -} - - -int dabInputFileRead(void* args, void* buffer, int size) -{ -    dabInputFileData* data = (dabInputFileData*)args; -    return read(data->file, buffer, size); -} - - -int dabInputFileClose(void* args) -{ -    dabInputFileData* data = (dabInputFileData*)args; -    if (data->file != -1) { -        close(data->file); -    } -    return 0; -} - - -int dabInputFileClean(void** args) -{ -    dabInputFileData* data = (dabInputFileData*)*args; -    if (data->packetData != nullptr) { -        delete[] data->packetData; -    } -    if (data->enhancedPacketData != nullptr) { -        for (int i = 0; i < 12; ++i) { -            if (data->enhancedPacketData[i] != nullptr) { -                delete[] data->enhancedPacketData[i]; -            } -        } -        delete[] data->enhancedPacketData; -    } -    delete data; -    return 0; -} - - -int dabInputFileRewind(void* args) -{ -    dabInputFileData* data = (dabInputFileData*)args; -    return lseek(data->file, 0, SEEK_SET); -} - - diff --git a/src/dabInputFile.h b/src/dabInputFile.h deleted file mode 100644 index e3eaa48..0000000 --- a/src/dabInputFile.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_FILE_H -#define DAB_INPUT_FILE_H - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif - - -struct dabInputFileData { -    int file; -    bool parity; -    unsigned packetLength; -    unsigned char* packetData; -    unsigned char** enhancedPacketData; -    unsigned enhancedPacketLength; -    unsigned enhancedPacketWaiting; -}; - - -int dabInputFileInit(void** args); -int dabInputFileOpen(void* args, const char* filename); -int dabInputFileRead(void* args, void* buffer, int size); -int dabInputFileClose(void* args); -int dabInputFileClean(void** args); -int dabInputFileRewind(void* args); - - -#endif // DAB_INPUT_FILE_H diff --git a/src/dabInputMpegFifo.cpp b/src/dabInputMpegFifo.cpp deleted file mode 100644 index 0f1d3b0..0000000 --- a/src/dabInputMpegFifo.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputMpegFifo.h" -#include "dabInputFifo.h" -#include "dabInputMpegFile.h" - - -#ifdef HAVE_FORMAT_MPEG -#   ifdef HAVE_INPUT_FIFO - - -struct dabInputOperations dabInputMpegFifoOperations = { -    dabInputFifoInit, -    dabInputFifoOpen, -    dabInputFifoSetbuf, -    dabInputFifoRead, -    dabInputFifoLock, -    dabInputFifoUnlock, -    dabInputMpegFileRead, -    dabInputSetbitrate, -    dabInputFifoClose, -    dabInputFifoClean, -    dabInputFifoRewind -}; - - -#   endif -#endif diff --git a/src/dabInputMpegFifo.h b/src/dabInputMpegFifo.h deleted file mode 100644 index a14ccbd..0000000 --- a/src/dabInputMpegFifo.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_MPEG_FIFO_H -#define DAB_INPUT_MPEG_FIFO_H - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif - - -#ifdef HAVE_FORMAT_MPEG -#   ifdef HAVE_INPUT_FIFO -extern struct dabInputOperations dabInputMpegFifoOperations; -#   endif -#endif - - -#endif // DAB_INPUT_MPEG_FIFO_H diff --git a/src/dabInputMpegFile.cpp b/src/dabInputMpegFile.cpp deleted file mode 100644 index 804ea29..0000000 --- a/src/dabInputMpegFile.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputMpegFile.h" -#include "dabInputFile.h" -#include "mpeg.h" - -#include <stdio.h> -#include <errno.h> -#include <string.h> - - -#ifdef HAVE_FORMAT_MPEG -#   ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputMpegFileOperations = { -    dabInputFileInit, -    dabInputFileOpen, -    dabInputSetbuf, -    dabInputFileRead, -    nullptr, -    nullptr, -    dabInputMpegFileRead, -    dabInputMpegSetbitrate, -    dabInputFileClose, -    dabInputFileClean, -    dabInputFileRewind -}; - - -#define MPEG_FREQUENCY      -2 -#define MPEG_PADDING        -3 -#define MPEG_COPYRIGHT      -4 -#define MPEG_ORIGINAL       -5 -#define MPEG_EMPHASIS       -6 -int checkDabMpegFrame(void* data) { -    mpegHeader* header = (mpegHeader*)data; -    unsigned long* headerData = (unsigned long*)data; -    if ((*headerData & 0x0f0ffcff) == 0x0004fcff) return 0; -    if ((*headerData & 0x0f0ffcff) == 0x0004f4ff) return 0; -    if (getMpegFrequency(header) != 48000) { -        if (getMpegFrequency(header) != 24000) { -            return MPEG_FREQUENCY; -        } -    } -    if (header->padding != 0) { -        return MPEG_PADDING; -    } -    if (header->copyright != 0) { -        return MPEG_COPYRIGHT; -    } -    if (header->original != 0) { -        return MPEG_ORIGINAL; -    } -    if (header->emphasis != 0) { -        return MPEG_EMPHASIS; -    } -    return -1; -} - - -int dabInputMpegFileRead(dabInputOperations* ops, void* args, void* buffer, int size) -{ -    dabInputFileData* data = (dabInputFileData*)args; -    int result; -    bool rewind = false; -READ_SUBCHANNEL: -    if (data->parity) { -        result = readData(data->file, buffer, size, 2); -        data->parity = false; -        return 0; -    } else { -        result = readMpegHeader(data->file, buffer, size); -        if (result > 0) { -            result = readMpegFrame(data->file, buffer, size); -            if (result < 0 && getMpegFrequency(buffer) == 24000) { -                data->parity = true; -                result = size; -            } -        } -    } -    switch (result) { -    case MPEG_BUFFER_UNDERFLOW: -        etiLog.log(warn, "data underflow -> frame muted\n"); -        goto MUTE_SUBCHANNEL; -    case MPEG_BUFFER_OVERFLOW: -        etiLog.log(warn, "bitrate too high -> frame muted\n"); -        goto MUTE_SUBCHANNEL; -    case MPEG_FILE_EMPTY: -        if (rewind) { -            etiLog.log(error, "file rewinded and still empty " -                    "-> frame muted\n"); -            goto MUTE_SUBCHANNEL; -        } else { -            rewind = true; -            etiLog.log(info, "reach end of file -> rewinding\n"); -            lseek(data->file, 0, SEEK_SET); -            goto READ_SUBCHANNEL; -        } -    case MPEG_FILE_ERROR: -        etiLog.log(alert, "can't read file (%i) -> frame muted\n", errno); -        perror(""); -        goto MUTE_SUBCHANNEL; -    case MPEG_SYNC_NOT_FOUND: -        etiLog.log(alert, "mpeg sync not found, maybe is not a valid file " -                "-> frame muted\n"); -        goto MUTE_SUBCHANNEL; -    case MPEG_INVALID_FRAME: -        etiLog.log(alert, "file is not a valid mpeg file " -                "-> frame muted\n"); -        goto MUTE_SUBCHANNEL; -    default: -        if (result < 0) { -            etiLog.log(alert, -                    "unknown error (code = %i) -> frame muted\n", -                    result); -MUTE_SUBCHANNEL: -            memset(buffer, 0, size); -        } else { -            if (result < size) { -                etiLog.log(warn, "bitrate too low from file " -                        "-> frame padded\n"); -                memset((char*)buffer + result, 0, size - result); -            } -            result = checkDabMpegFrame(buffer); -            switch (result) { -            case MPEG_FREQUENCY: -                etiLog.log(error, "file has a frame with an invalid " -                        "frequency: %i, should be 48000 or 24000\n", -                        getMpegFrequency(buffer)); -                break; -            case MPEG_PADDING: -                etiLog.log(warn, -                        "file has a frame with padding bit set\n"); -                break; -            case MPEG_COPYRIGHT: -                etiLog.log(warn, -                        "file has a frame with copyright bit set\n"); -                break; -            case MPEG_ORIGINAL: -                etiLog.log(warn, -                        "file has a frame with original bit set\n"); -                break; -            case MPEG_EMPHASIS: -                etiLog.log(warn, -                        "file has a frame with emphasis bits set\n"); -                break; -            default: -                if (result < 0) { -                    etiLog.log(alert, "mpeg file has an invalid DAB " -                            "mpeg frame (unknown reason: %i)\n", result); -                } -                break; -            } -        } -    } -    return result; -} - - -int dabInputMpegSetbitrate(dabInputOperations* ops, void* args, int bitrate) -{ -    //dabInputFileData* data = (dabInputFileData*)args; -    if (bitrate == 0) { -        char buffer[4]; - -        if (ops->readFrame(ops, args, buffer, 4) == 0) { -            bitrate = getMpegBitrate(buffer); -        } else { -            bitrate = -1; -        } -        ops->rewind(args); -    } -    if (ops->setbuf(args, bitrate * 3) != 0) { -        bitrate = -1; -    } -    return bitrate; -} - - -#   endif -#endif diff --git a/src/dabInputMpegFile.h b/src/dabInputMpegFile.h deleted file mode 100644 index a7dcb76..0000000 --- a/src/dabInputMpegFile.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_MPEG_FILE_H -#define DAB_INPUT_MPEG_FILE_H - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_MPEG -#   ifdef HAVE_INPUT_FILE -extern struct dabInputOperations dabInputMpegFileOperations; - -int dabInputMpegFileRead(dabInputOperations* ops, void* args, void* buffer, int size); -int dabInputMpegSetbitrate(dabInputOperations* ops, void* args, int bitrate); -int checkDabMpegFrame(void* data); -#   endif -#endif - - -#endif  // DAB_INPUT_MPEG_FILE_H diff --git a/src/dabInputPacketFile.cpp b/src/dabInputPacketFile.cpp deleted file mode 100644 index 867d9fc..0000000 --- a/src/dabInputPacketFile.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -   Copyright (C) 2009, 2011 Her Majesty the Queen in Right of Canada -   (Communications Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputPacketFile.h" -#include "dabInputFile.h" -#include "dabInputFifo.h" -#include "ReedSolomon.h" - -#ifdef HAVE_FORMAT_PACKET -#   ifdef HAVE_INPUT_FILE - - -#include <string.h> -#include <stdio.h> -#include <errno.h> - - -#ifdef _WIN32 -#   pragma pack(push, 1) -#endif -struct packetHeader { -    unsigned char addressHigh:2; -    unsigned char last:1; -    unsigned char first:1; -    unsigned char continuityIndex:2; -    unsigned char packetLength:2; -    unsigned char addressLow; -    unsigned char dataLength:7; -    unsigned char command; -} -#ifdef _WIN32 -#   pragma pack(pop) -#else -__attribute((packed)) -#endif -; - - -struct dabInputOperations dabInputPacketFileOperations = { -    dabInputFileInit, -    dabInputFileOpen, -    dabInputSetbuf, -    dabInputFileRead, -    nullptr, -    nullptr, -    dabInputPacketFileRead, -    dabInputSetbitrate, -    dabInputFileClose, -    dabInputFileClean, -    dabInputFileRewind -}; - - -int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, -        int size) -{ -    dabInputFileData* data = (dabInputFileData*)args; -    unsigned char* dataBuffer = (unsigned char*)buffer; -    int written = 0; -    int length; -    packetHeader* header; -    int indexRow; -    int indexCol; - -    while (written < size) { -        if (data->enhancedPacketWaiting > 0) { -            *dataBuffer = 192 - data->enhancedPacketWaiting; -            *dataBuffer /= 22; -            *dataBuffer <<= 2; -            *(dataBuffer++) |= 0x03; -            *(dataBuffer++) = 0xfe; -            indexCol = 188; -            indexCol += (192 - data->enhancedPacketWaiting) / 12; -            indexRow = 0; -            indexRow += (192 - data->enhancedPacketWaiting) % 12; -            for (int j = 0; j < 22; ++j) { -                if (data->enhancedPacketWaiting == 0) { -                    *(dataBuffer++) = 0; -                } else { -                    *(dataBuffer++) = data->enhancedPacketData[indexRow][indexCol]; -                    if (++indexRow == 12) { -                        indexRow = 0; -                        ++indexCol; -                    } -                    --data->enhancedPacketWaiting; -                } -            } -            written += 24; -            if (data->enhancedPacketWaiting == 0) { -                data->enhancedPacketLength = 0; -            } -        } else if (data->packetLength != 0) { -            header = (packetHeader*)data->packetData; -            if (written + data->packetLength > (unsigned)size) { -                memset(dataBuffer, 0, 22); -                dataBuffer[22] = 0x60; -                dataBuffer[23] = 0x4b; -                length = 24; -            } else if (data->enhancedPacketData != nullptr) { -                if (data->enhancedPacketLength + data->packetLength -                        > (12 * 188)) { -                    memset(dataBuffer, 0, 22); -                    dataBuffer[22] = 0x60; -                    dataBuffer[23] = 0x4b; -                    length = 24; -                } else { -                    memcpy(dataBuffer, data->packetData, data->packetLength); -                    length = data->packetLength; -                    data->packetLength = 0; -                } -            } else { -                memcpy(dataBuffer, data->packetData, data->packetLength); -                length = data->packetLength; -                data->packetLength = 0; -            } -            if (data->enhancedPacketData != nullptr) { -                indexCol = data->enhancedPacketLength / 12; -                indexRow = data->enhancedPacketLength % 12;     // TODO Check if always 0 -                for (int j = 0; j < length; ++j) { -                    data->enhancedPacketData[indexRow][indexCol] = dataBuffer[j]; -                    if (++indexRow == 12) { -                        indexRow = 0; -                        ++indexCol; -                    } -                } -                data->enhancedPacketLength += length; -                if (data->enhancedPacketLength >= (12 * 188)) { -                    data->enhancedPacketLength = (12 * 188); -                    ReedSolomon encoder(204, 188); -                    for (int j = 0; j < 12; ++j) { -                        encoder.encode(data->enhancedPacketData[j], 188); -                    } -                    data->enhancedPacketWaiting = 192; -                } -            } -            written += length; -            dataBuffer += length; -        } else { -            int nbBytes = ops->read(args, dataBuffer, 3); -            header = (packetHeader*)dataBuffer; -            if (nbBytes == -1) { -                if (errno == EAGAIN) goto END_PACKET; -                perror("Packet file"); -                return -1; -            } else if (nbBytes == 0) { -                if (ops->rewind(args) == -1) { -                    goto END_PACKET; -                } -                continue; -            } else if (nbBytes < 3) { -                etiLog.log(error, -                        "Error while reading file for packet header; " -                        "read %i out of 3 bytes\n", nbBytes); -                break; -            } - -            length = header->packetLength * 24 + 24; -            if (written + length > size) { -                memcpy(data->packetData, header, 3); -                ops->read(args, &data->packetData[3], length - 3); -                data->packetLength = length; -                continue; -            } -            if (data->enhancedPacketData != nullptr) { -                if (data->enhancedPacketLength + length > (12 * 188)) { -                    memcpy(data->packetData, header, 3); -                    ops->read(args, &data->packetData[3], length - 3); -                    data->packetLength = length; -                    continue; -                } -            } -            nbBytes = ops->read(args, dataBuffer + 3, length - 3); -            if (nbBytes == -1) { -                perror("Packet file"); -                return -1; -            } else if (nbBytes == 0) { -                etiLog.log(info, -                        "Packet header read, but no data!\n"); -                if (ops->rewind(args) == -1) { -                    goto END_PACKET; -                } -                continue; -            } else if (nbBytes < length - 3) { -                etiLog.log(error, "Error while reading packet file; " -                        "read %i out of %i bytes\n", nbBytes, length - 3); -                break; -            } -            if (data->enhancedPacketData != nullptr) { -                indexCol = data->enhancedPacketLength / 12; -                indexRow = data->enhancedPacketLength % 12;     // TODO Check if always 0 -                for (int j = 0; j < length; ++j) { -                    data->enhancedPacketData[indexRow][indexCol] = dataBuffer[j]; -                    if (++indexRow == 12) { -                        indexRow = 0; -                        ++indexCol; -                    } -                } -                data->enhancedPacketLength += length; -                if (data->enhancedPacketLength >= (12 * 188)) { -                    if (data->enhancedPacketLength > (12 * 188)) { -                        etiLog.log(error, -                                "Error, too much enhanced packet data!\n"); -                    } -                    ReedSolomon encoder(204, 188); -                    for (int j = 0; j < 12; ++j) { -                        encoder.encode(data->enhancedPacketData[j], 188); -                    } -                    data->enhancedPacketWaiting = 192; -                } -            } -            written += length; -            dataBuffer += length; -        } -    } -END_PACKET: -    if (ops->read == dabInputFifoRead) { -        dabInputFifoData* fifoData = (dabInputFifoData*)args; -        dabInputFifoStats* fifoStats = (dabInputFifoStats*)&fifoData->stats; -        fifoStats->frameRecords[fifoStats->frameCount].curSize = written; -        fifoStats->frameRecords[fifoStats->frameCount].maxSize = size; -        if (++fifoStats->frameCount == NB_RECORDS) { -            etiLog.log(info, "Packet subchannel usage: (%i)", -                    fifoStats->id); -            for (int i = 0; i < fifoStats->frameCount; ++i) { -            etiLog.log(info, " %i/%i", -                    fifoStats->frameRecords[i].curSize, -                    fifoStats->frameRecords[i].maxSize); -            } -            etiLog.log(info, "\n"); -            fifoStats->frameCount = 0; -        } -    } -    while (written < size) { -        memset(dataBuffer, 0, 22); -        dataBuffer[22] = 0x60; -        dataBuffer[23] = 0x4b; -        dataBuffer += 24; -        written += 24; -    } -    return written; -} - - -#   endif -#endif diff --git a/src/dabInputPacketFile.h b/src/dabInputPacketFile.h deleted file mode 100644 index 77f33a6..0000000 --- a/src/dabInputPacketFile.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_PACKET_FILE_H -#define DAB_INPUT_PACKET_FILE_H - - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_PACKET -#   ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputPacketFileOperations; - -int dabInputPacketFileRead(dabInputOperations* ops, void* args, void* buffer, -        int size); - - -#   endif -#endif - - -#endif // DAB_INPUT_PACKET_FILE_H diff --git a/src/dabInputRawFifo.cpp b/src/dabInputRawFifo.cpp deleted file mode 100644 index cc6268b..0000000 --- a/src/dabInputRawFifo.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputRawFifo.h" - -#include <unistd.h> -#include <stdio.h> -#include <fcntl.h> -#include <string.h> - -#ifndef _WIN32 -#   define O_BINARY 0 -#endif - - -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputRawFifoOperations = { -    dabInputRawFifoInit, -    dabInputRawFifoOpen, -    dabInputRawFifoSetbuf, -    dabInputRawFifoRead, -    nullptr, -    nullptr, -    dabInputRawFifoReadFrame, -    dabInputSetbitrate, -    dabInputRawFifoClose, -    dabInputRawFifoClean, -    dabInputRawFifoRewind -}; - - -int dabInputRawFifoInit(void** args) -{ -    dabInputRawFifoData* data = new dabInputRawFifoData; -    data->file = -1; -    data->buffer = nullptr; -    data->bufferSize = 0; -    data->bufferOffset = 0; - -    *args = data; -    return 0; -} - - -int dabInputRawFifoOpen(void* args, const char* filename) -{ -    dabInputRawFifoData* data = (dabInputRawFifoData*)args; -    data->file = open(filename, O_RDONLY | O_BINARY | O_NONBLOCK); -    if (data->file == -1) { -        perror(filename); -        return -1; -    } -#ifdef _WIN32 -#else -    int flags = fcntl(data->file, F_GETFL); -    if (flags == -1) { -        perror(filename); -        return -1; -    } -    if (fcntl(data->file, F_SETFL, flags & ~O_NONBLOCK) == -1) { -        perror(filename); -        return -1; -    } -#endif - -    return 0; -} - - -int dabInputRawFifoSetbuf(void* args, int size) -{ -    dabInputRawFifoData* data = (dabInputRawFifoData*)args; - -    if (size <= 0) { -        return size; -    } - -    if (data->bufferSize != (size_t)size) { -        if (data->buffer != nullptr) { -            delete[] data->buffer; -        } -        data->buffer = new uint8_t[size]; -        data->bufferSize = size; -        data->bufferOffset = 0; -    } - -    return 0; -} - - -int dabInputRawFifoRead(void* args, void* buffer, int size) -{ -    dabInputRawFifoData* data = (dabInputRawFifoData*)args; - -    return read(data->file, buffer, size); -} - - -int dabInputRawFifoReadFrame(dabInputOperations* ops, void* args, -        void* buffer, int size) -{ -    dabInputRawFifoData* data = (dabInputRawFifoData*)args; -    int result; - -    result = ops->read(args, data->buffer + data->bufferOffset, size - data->bufferOffset); -    if (result == -1) { -        etiLog.log(alert, "ERROR: Can't read fifo\n"); -        perror(""); -        return -1; -    } - -    if (result + data->bufferOffset < (size_t)size) { -        data->bufferOffset += result; - -        etiLog.log(info, "reach end of fifo -> rewinding\n"); -        if (ops->rewind(args) == -1) { -            etiLog.log(alert, "ERROR: Can't rewind fifo\n"); -            return -1; -        } - -        result = ops->read(args, data->buffer + data->bufferOffset, size - data->bufferOffset); -        if (result == -1) { -            etiLog.log(alert, "ERROR: Can't read fifo\n"); -            perror(""); -            return -1; -        } - -        if (result < size) { -            etiLog.log(alert, "ERROR: Not enought data in fifo\n"); -            return 0; -        } -    } - -    memcpy(buffer, data->buffer, size); -    data->bufferOffset = 0; - -    return size; -} - - -int dabInputRawFifoClose(void* args) -{ -    dabInputRawFifoData* data = (dabInputRawFifoData*)args; -     -    if (data->file != -1) { -        close(data->file); -        data->file = -1; -    } -    return 0; -} - - -int dabInputRawFifoClean(void** args) -{ -    dabInputRawFifoData* data = (dabInputRawFifoData*)*args; -    if (data->buffer != nullptr) { -        delete[] data->buffer; -    } -    delete data; -    return 0; -} - - -int dabInputRawFifoRewind(void* args) -{ -    dabInputRawFifoData* data = (dabInputRawFifoData*)args; -    return lseek(data->file, 0, SEEK_SET); -} - - -#   endif -#endif diff --git a/src/dabInputRawFifo.h b/src/dabInputRawFifo.h deleted file mode 100644 index 7d2a3a0..0000000 --- a/src/dabInputRawFifo.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_RAW_FIFO_H -#define DAB_INPUT_RAW_FIFO_H - - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif - -#include "dabInput.h" - -#include <stdint.h> - - -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputRawFifoOperations; - -int dabInputRawFifoInit(void** args); -int dabInputRawFifoOpen(void* args, const char* filename); -int dabInputRawFifoSetbuf(void* args, int size); -int dabInputRawFifoRead(void* args, void* buffer, int size); -int dabInputRawFifoReadFrame(dabInputOperations* ops, void* args, -        void* buffer, int size); -int dabInputRawFifoClose(void* args); -int dabInputRawFifoClean(void** args); -int dabInputRawFifoRewind(void* args); - - -struct dabInputRawFifoData { -    int file; -    uint8_t* buffer; -    size_t bufferSize; -    size_t bufferOffset; -}; - - -#   endif -#endif - -#endif // DAB_INPUT_RAW_FIFO_H diff --git a/src/dabInputRawFile.cpp b/src/dabInputRawFile.cpp deleted file mode 100644 index be33a45..0000000 --- a/src/dabInputRawFile.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputRawFile.h" -#include "dabInputFile.h" - - -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_FILE - - -struct dabInputOperations dabInputRawFileOperations = { -    dabInputFileInit, -    dabInputFileOpen, -    dabInputSetbuf, -    dabInputFileRead, -    nullptr, -    nullptr, -    dabInputRawFileRead, -    dabInputSetbitrate, -    dabInputFileClose, -    dabInputFileClean, -    dabInputFileRewind -}; - - -int dabInputRawFileRead(dabInputOperations* ops, void* args, void* buffer, -        int size) -{ -    int ret = ops->read(args, buffer, size); -    if (ret == 0) { -        etiLog.log(info, "reach end of raw file -> rewinding\n"); -        ops->rewind(args); -        ret = ops->read(args, buffer, size); -    } -    return ret; -} - - -#   endif -#endif diff --git a/src/dabInputRawFile.h b/src/dabInputRawFile.h deleted file mode 100644 index 9a4a607..0000000 --- a/src/dabInputRawFile.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_RAW_FILE_H -#define DAB_INPUT_RAW_FILE_H - - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_FILE - - -extern struct dabInputOperations dabInputRawFileOperations; - -int dabInputRawFileRead(dabInputOperations* ops, void* args, void* buffer, -        int size); - - -#   endif -#endif - -#endif // DAB_INPUT_RAW_FILE_H diff --git a/src/dabInputTest.cpp b/src/dabInputTest.cpp deleted file mode 100644 index fd4fc59..0000000 --- a/src/dabInputTest.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputTest.h" - -#include <string.h> -#ifdef _WIN32 -#else -#   include <arpa/inet.h> -#endif - - -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_TEST - - -struct dabInputTestData { -    unsigned long counter; -}; - - -struct dabInputOperations dabInputTestOperations = { -    dabInputTestInit, -    dabInputTestOpen, -    NULL, -    NULL, -    NULL, -    NULL, -    dabInputTestRead, -    dabInputTestSetbitrate, -    dabInputTestClose, -    dabInputTestClean, -    NULL -}; - - -int dabInputTestInit(void** args) -{ -    dabInputTestData* input = new dabInputTestData; -    memset(input, 0, sizeof(*input)); -    input->counter = 0; -    *args = input; -    return 0; -} - - -int dabInputTestOpen(void* args, const char* inputName) -{ -    return 0; -} - - -int dabInputTestRead(dabInputOperations* ops, void* args, void* buffer, int size) -{ -    dabInputTestData* input = (dabInputTestData*)args; -    char* data = (char*)buffer; - -    *((long*)buffer) = htonl(input->counter++); -    for (int i = sizeof(input->counter); i < size; ++i) { -        data[i] = i; -    } -    return size; -} - - -int dabInputTestSetbitrate(dabInputOperations* ops, void* args, int bitrate) -{ -    return bitrate; -} - - -int dabInputTestClose(void* args) -{ -    return 0; -} - - -int dabInputTestClean(void** args) -{ -    dabInputTestData* input = (dabInputTestData*)(*args); -    delete input; -    return 0; -} - - -#   endif -#endif diff --git a/src/dabInputTest.h b/src/dabInputTest.h deleted file mode 100644 index 34ebc05..0000000 --- a/src/dabInputTest.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#ifndef DAB_INPUT_TEST_H -#define DAB_INPUT_TEST_H - - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" - - -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_TEST - - -extern struct dabInputOperations dabInputTestOperations; - -int dabInputTestInit(void** args); -int dabInputTestOpen(void* args, const char* inputName); -int dabInputTestRead(dabInputOperations* ops, void* args, void* buffer, int size); -int dabInputTestSetbitrate(dabInputOperations* ops, void* args, int bitrate); -int dabInputTestClose(void* args); -int dabInputTestClean(void** args); - - -#   endif -#endif - - -#endif // DAB_INPUT_TEST_H diff --git a/src/dabInputUdp.cpp b/src/dabInputUdp.cpp deleted file mode 100644 index 0765599..0000000 --- a/src/dabInputUdp.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* -   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications -   Research Center Canada) -   */ -/* -   This file is part of ODR-DabMux. - -   ODR-DabMux 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 3 of the -   License, or (at your option) any later version. - -   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. -   */ - -#include "dabInputUdp.h" - -#include <string.h> -#include <limits.h> - - -#ifdef __MINGW32__ -#   define bzero(s, n) memset(s, 0, n) -#endif - -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_UDP - - -struct dabInputOperations dabInputUdpOperations = { -    dabInputUdpInit, -    dabInputUdpOpen, -    dabInputSetbuf, -    NULL, -    NULL, -    NULL, -    dabInputUdpRead, -    dabInputSetbitrate, -    dabInputUdpClose, -    dabInputUdpClean, -    NULL -}; - - -int dabInputUdpInit(void** args) -{ -    dabInputUdpData* input = new dabInputUdpData; -    memset(&input->stats, 0, sizeof(input->stats)); -    input->stats.id = dabInputFifoData::nb++; -    input->socket = new UdpSocket(); -    input->packet = new UdpPacket(2048); -    *args = input; - -    UdpSocket::init(); -    return 0; -} - - -int dabInputUdpOpen(void* args, const char* inputName) -{ -    int returnCode = 0; -    char* address; -    char* ptr; -    long port; -    dabInputUdpData* input = (dabInputUdpData*)args; - -    // Skip the udp:// part if it is present -    if (strncmp(inputName, "udp://", 6) == 0) { -        address = strdup(inputName + 6); -    } -    else { -        address = strdup(inputName); -    } - -    ptr = strchr(address, ':'); -    if (ptr == NULL) { -        etiLog.log(error, -                "\"%s\" is an invalid format for udp address: " -                "should be [udp://][address]:port - > aborting\n", address); -        returnCode = -1; -        goto udpopen_ptr_null_out; -    } -    *(ptr++) = 0; -    port = strtol(ptr, (char **)NULL, 10); -    if ((port == LONG_MIN) || (port == LONG_MAX)) { -        etiLog.log(error, -                "can't convert port number in udp address %s\n", -                address); -        returnCode = -1; -    } -    if (port == 0) { -        etiLog.log(error, "can't use port number 0 in udp address\n"); -        returnCode = -1; -    } -    if (input->socket->create(port) == -1) { -        etiLog.log(error, "can't set port %i on Udp input (%s: %s)\n", -                port, inetErrDesc, inetErrMsg); -        returnCode = -1; -    } - -    if (*address != 0) { -        if (input->socket->joinGroup(address) == -1) { -            etiLog.log(error, -                    "can't join multicast group %s (%s: %s)\n", -                    address, inetErrDesc, inetErrMsg); -            returnCode = -1; -        } -    } - -    if (input->socket->setBlocking(false) == -1) { -        etiLog.log(error, "can't set Udp input socket in blocking mode " -                "(%s: %s)\n", inetErrDesc, inetErrMsg); -        returnCode = -1; -    } - -udpopen_ptr_null_out: -    free(address); -    etiLog.log(debug, "check return code of create\n"); -    return returnCode; -} - - -int dabInputUdpRead(dabInputOperations* ops, void* args, void* buffer, int size) -{ -    int nbBytes = 0; -    uint8_t* data = reinterpret_cast<uint8_t*>(buffer); - -    dabInputUdpData* input = (dabInputUdpData*)args; -    dabInputFifoStats* stats = (dabInputFifoStats*)&input->stats; - -    input->stats.frameRecords[input->stats.frameCount].curSize = 0; -    input->stats.frameRecords[input->stats.frameCount].maxSize = size; - -    if (input->packet->getLength() == 0) { -        input->socket->receive(*input->packet); -    } - -    while (nbBytes < size) { -        unsigned freeSize = size - nbBytes; -        if (input->packet->getLength() > freeSize) { -            // Not enought place in output -            memcpy(&data[nbBytes], input->packet->getData(), freeSize); -            nbBytes = size; -            input->packet->setOffset(input->packet->getOffset() + freeSize); -        } else { -            unsigned length = input->packet->getLength(); -            memcpy(&data[nbBytes], input->packet->getData(), length); -            nbBytes += length; -            input->packet->setOffset(0); -            input->socket->receive(*input->packet); -            if (input->packet->getLength() == 0) { -                break; -            } -        }  -    } -    input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes; -    bzero(&data[nbBytes], size - nbBytes); -     -    input->stats.frameRecords[input->stats.frameCount].curSize = nbBytes; -    if (++stats->frameCount == NB_RECORDS) { -        etiLog.log(info, "Data subchannel usage: (%i)", -                stats->id); -        for (int i = 0; i < stats->frameCount; ++i) { -            etiLog.log(info, " %i/%i", -                    stats->frameRecords[i].curSize, -                    stats->frameRecords[i].maxSize); -        } -        etiLog.log(info, "\n"); -        stats->frameCount = 0; -    } - -    return size; -} - - -int dabInputUdpClose(void* args) -{ -    return 0; -} - - -int dabInputUdpClean(void** args) -{ -    dabInputUdpData* input = (dabInputUdpData*)(*args); -    delete input->socket; -    delete input->packet; -    delete input; -    return 0; -} - - -#   endif -#endif diff --git a/src/dabOutput/dabOutput.h b/src/dabOutput/dabOutput.h index eaa623f..c10d358 100644 --- a/src/dabOutput/dabOutput.h +++ b/src/dabOutput/dabOutput.h @@ -222,11 +222,6 @@ class TCPDataDispatcher;  class DabOutputTcp : public DabOutput  {      public: -        DabOutputTcp() {} -        DabOutputTcp(const DabOutputTcp& other) = delete; -        const DabOutputTcp& operator=(const DabOutputTcp& other) = delete; -        ~DabOutputTcp(); -          int Open(const char* name);          int Write(void* buffer, int size);          int Close(); @@ -238,7 +233,7 @@ class DabOutputTcp : public DabOutput      private:          std::string uri_; -        TCPDataDispatcher* dispatcher_; +        std::shared_ptr<TCPDataDispatcher> dispatcher_;  };  // -------------- Simul ------------------ diff --git a/src/dabOutput/dabOutputTcp.cpp b/src/dabOutput/dabOutputTcp.cpp index 8696bec..2aab48a 100644 --- a/src/dabOutput/dabOutputTcp.cpp +++ b/src/dabOutput/dabOutputTcp.cpp @@ -95,6 +95,10 @@ class TCPConnection                      m_running = false;                  }              } + +            auto addr = m_sock.getRemoteAddress(); +            etiLog.level(debug) << "Dropping TCP Connection from " << +                addr.getHostAddress() << ":" << addr.getPort();          }  }; @@ -121,22 +125,28 @@ class TCPDataDispatcher                  connection.queue.push(data);              } -            m_connections.remove_if([](TCPConnection& conn){ return conn.is_overloaded(); }); +            m_connections.remove_if([](const TCPConnection& conn){ return conn.is_overloaded(); });          }      private:          void process(long) { -            m_listener_socket.listen(); +            try { +                m_listener_socket.listen(); -            const int timeout_ms = 1000; +                const int timeout_ms = 1000; -            while (m_running) { -                // Add a new TCPConnection to the list, constructing it from the client socket -                auto optional_sock = m_listener_socket.accept(timeout_ms); -                if (optional_sock) { -                    m_connections.emplace(m_connections.begin(), std::move(*optional_sock)); +                while (m_running) { +                    // Add a new TCPConnection to the list, constructing it from the client socket +                    auto sock = m_listener_socket.accept(timeout_ms); +                    if (sock.isValid()) { +                        m_connections.emplace(m_connections.begin(), move(sock)); +                    }                  }              } +            catch (std::runtime_error& e) { +                etiLog.level(error) << "TCPDataDispatcher caught runtime error: " << e.what(); +                m_running = false; +            }          }          atomic<bool> m_running; @@ -145,14 +155,6 @@ class TCPDataDispatcher          std::list<TCPConnection> m_connections;  }; -DabOutputTcp::~DabOutputTcp() -{ -    if (dispatcher_) { -        delete dispatcher_; -        dispatcher_ = nullptr; -    } -} -  static bool parse_uri(const char *uri, long *port, string& addr)  {      char* const hostport = strdup(uri); // the uri is actually an tuple host:port @@ -199,7 +201,7 @@ int DabOutputTcp::Open(const char* name)      uri_ = name;      if (success) { -        dispatcher_ = new TCPDataDispatcher(); +        dispatcher_ = make_shared<TCPDataDispatcher>();          try {              dispatcher_->start(port, address);          } diff --git a/src/input/File.cpp b/src/input/File.cpp new file mode 100644 index 0000000..5c61fd4 --- /dev/null +++ b/src/input/File.cpp @@ -0,0 +1,443 @@ +/* +   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications +   Research Center Canada) + +   Copyright (C) 2016 Matthias P. Braendli +    http://www.opendigitalradio.org + +   */ +/* +   This file is part of ODR-DabMux. + +   ODR-DabMux 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 3 of the +   License, or (at your option) any later version. + +   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. +   */ + +#include <sstream> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#ifndef _WIN32 +#   define O_BINARY 0 +#endif + +#include "input/File.h" +#include "mpeg.h" +#include "ReedSolomon.h" + +namespace Inputs { + +#ifdef _WIN32 +#   pragma pack(push, 1) +#endif +struct packetHeader { +    unsigned char addressHigh:2; +    unsigned char last:1; +    unsigned char first:1; +    unsigned char continuityIndex:2; +    unsigned char packetLength:2; +    unsigned char addressLow; +    unsigned char dataLength:7; +    unsigned char command; +} +#ifdef _WIN32 +#   pragma pack(pop) +#else +__attribute((packed)) +#endif +; + + +int FileBase::open(const std::string& name) +{ +    m_fd = ::open(name.c_str(), O_RDONLY | O_BINARY); +    if (m_fd == -1) { +        std::stringstream ss; +        ss << "Could not open input file " << name << ": " << +            strerror(errno); +        throw std::runtime_error(ss.str()); +    } +    return 0; +} + +int FileBase::setBitrate(int bitrate) +{ +    if (bitrate <= 0) { +        etiLog.log(error, "Invalid bitrate (%i)\n", bitrate); +        return -1; +    } + +    return bitrate; +} + + +int FileBase::close() +{ +    if (m_fd != -1) { +        ::close(m_fd); +        m_fd = -1; +    } +    return 0; +} + +int FileBase::rewind() +{ +    return ::lseek(m_fd, 0, SEEK_SET); +} + +ssize_t FileBase::readFromFile(uint8_t* buffer, size_t size) +{ +    ssize_t ret = read(m_fd, buffer, size); + +    if (ret == -1) { +        etiLog.log(alert, "ERROR: Can't read file\n"); +        perror(""); +        return -1; +    } + +    if (ret < (ssize_t)size) { +        ssize_t sizeOut = ret; +        etiLog.log(info, "reach end of file -> rewinding\n"); +        if (rewind() == -1) { +            etiLog.log(alert, "ERROR: Can't rewind file\n"); +            return -1; +        } + +        ret = read(m_fd, buffer + sizeOut, size - sizeOut); +        if (ret == -1) { +            etiLog.log(alert, "ERROR: Can't read file\n"); +            perror(""); +            return -1; +        } + +        if (ret < (ssize_t)size) { +            etiLog.log(alert, "ERROR: Not enough data in file\n"); +            return -1; +        } +    } + +    return size; +} + +int MPEGFile::readFrame(uint8_t* buffer, size_t size) +{ +    int result; +    bool do_rewind = false; +READ_SUBCHANNEL: +    if (m_parity) { +        result = readData(m_fd, buffer, size, 2); +        m_parity = false; +        return 0; +    } else { +        result = readMpegHeader(m_fd, buffer, size); +        if (result > 0) { +            result = readMpegFrame(m_fd, buffer, size); +            if (result < 0 && getMpegFrequency(buffer) == 24000) { +                m_parity = true; +                result = size; +            } +        } +    } +    switch (result) { +    case MPEG_BUFFER_UNDERFLOW: +        etiLog.log(warn, "data underflow -> frame muted\n"); +        goto MUTE_SUBCHANNEL; +    case MPEG_BUFFER_OVERFLOW: +        etiLog.log(warn, "bitrate too high -> frame muted\n"); +        goto MUTE_SUBCHANNEL; +    case MPEG_FILE_EMPTY: +        if (do_rewind) { +            etiLog.log(error, "file rewinded and still empty " +                    "-> frame muted\n"); +            goto MUTE_SUBCHANNEL; +        } +        else { +            etiLog.log(info, "reach end of file -> rewinding\n"); +            rewind(); +            goto READ_SUBCHANNEL; +        } +    case MPEG_FILE_ERROR: +        etiLog.log(alert, "can't read file (%i) -> frame muted\n", errno); +        perror(""); +        goto MUTE_SUBCHANNEL; +    case MPEG_SYNC_NOT_FOUND: +        etiLog.log(alert, "mpeg sync not found, maybe is not a valid file " +                "-> frame muted\n"); +        goto MUTE_SUBCHANNEL; +    case MPEG_INVALID_FRAME: +        etiLog.log(alert, "file is not a valid mpeg file " +                "-> frame muted\n"); +        goto MUTE_SUBCHANNEL; +    default: +        if (result < 0) { +            etiLog.log(alert, +                    "unknown error (code = %i) -> frame muted\n", +                    result); +MUTE_SUBCHANNEL: +            memset(buffer, 0, size); +        } +        else { +            if (result < (ssize_t)size) { +                etiLog.log(warn, "bitrate too low from file " +                        "-> frame padded\n"); +                memset((char*)buffer + result, 0, size - result); +            } + +            result = checkDabMpegFrame(buffer); +            switch (result) { +            case MPEG_FREQUENCY: +                etiLog.log(error, "file has a frame with an invalid " +                        "frequency: %i, should be 48000 or 24000\n", +                        getMpegFrequency(buffer)); +                break; +            case MPEG_PADDING: +                etiLog.log(warn, +                        "file has a frame with padding bit set\n"); +                break; +            case MPEG_COPYRIGHT: +                result = 0; +                break; +            case MPEG_ORIGINAL: +                result = 0; +                break; +            case MPEG_EMPHASIS: +                etiLog.log(warn, +                        "file has a frame with emphasis bits set\n"); +                break; +            default: +                if (result < 0) { +                    etiLog.log(alert, "mpeg file has an invalid DAB " +                            "mpeg frame (unknown reason: %i)\n", result); +                } +                break; +            } +        } +    } +    return result; +} + +int MPEGFile::setBitrate(int bitrate) +{ +    if (bitrate == 0) { +        uint8_t buffer[4]; + +        if (readFrame(buffer, 4) == 0) { +            bitrate = getMpegBitrate(buffer); +        } +        else { +            bitrate = -1; +        } +        rewind(); +    } +    return bitrate; +} + +int RawFile::readFrame(uint8_t* buffer, size_t size) +{ +    return readFromFile(buffer, size); +} + +PacketFile::PacketFile(bool enhancedPacketMode) +{ +    m_enhancedPacketEnabled = enhancedPacketMode; +} + +int PacketFile::readFrame(uint8_t* buffer, size_t size) +{ +    size_t written = 0; +    int length; +    packetHeader* header; +    int indexRow; +    int indexCol; + +    while (written < size) { +        if (m_enhancedPacketWaiting > 0) { +            *buffer = 192 - m_enhancedPacketWaiting; +            *buffer /= 22; +            *buffer <<= 2; +            *(buffer++) |= 0x03; +            *(buffer++) = 0xfe; +            indexCol = 188; +            indexCol += (192 - m_enhancedPacketWaiting) / 12; +            indexRow = 0; +            indexRow += (192 - m_enhancedPacketWaiting) % 12; +            for (int j = 0; j < 22; ++j) { +                if (m_enhancedPacketWaiting == 0) { +                    *(buffer++) = 0; +                } +                else { +                    *(buffer++) = m_enhancedPacketData[indexRow][indexCol]; +                    if (++indexRow == 12) { +                        indexRow = 0; +                        ++indexCol; +                    } +                    --m_enhancedPacketWaiting; +                } +            } +            written += 24; +            if (m_enhancedPacketWaiting == 0) { +                m_enhancedPacketLength = 0; +            } +        } +        else if (m_packetLength != 0) { +            header = (packetHeader*)(&m_packetData[0]); +            if (written + m_packetLength > (unsigned)size) { +                memset(buffer, 0, 22); +                buffer[22] = 0x60; +                buffer[23] = 0x4b; +                length = 24; +            } +            else if (m_enhancedPacketEnabled) { +                if (m_enhancedPacketLength + m_packetLength > (12 * 188)) { +                    memset(buffer, 0, 22); +                    buffer[22] = 0x60; +                    buffer[23] = 0x4b; +                    length = 24; +                } +                else { +                    std::copy(m_packetData.begin(), +                            m_packetData.begin() + m_packetLength, +                            buffer); +                    length = m_packetLength; +                    m_packetLength = 0; +                } +            } +            else { +                std::copy(m_packetData.begin(), +                        m_packetData.begin() + m_packetLength, +                        buffer); +                length = m_packetLength; +                m_packetLength = 0; +            } + +            if (m_enhancedPacketEnabled) { +                indexCol = m_enhancedPacketLength / 12; +                indexRow = m_enhancedPacketLength % 12;     // TODO Check if always 0 +                for (int j = 0; j < length; ++j) { +                    m_enhancedPacketData[indexRow][indexCol] = buffer[j]; +                    if (++indexRow == 12) { +                        indexRow = 0; +                        ++indexCol; +                    } +                } +                m_enhancedPacketLength += length; +                if (m_enhancedPacketLength >= (12 * 188)) { +                    m_enhancedPacketLength = (12 * 188); +                    ReedSolomon encoder(204, 188); +                    for (int j = 0; j < 12; ++j) { +                        encoder.encode(&m_enhancedPacketData[j][0], 188); +                    } +                    m_enhancedPacketWaiting = 192; +                } +            } +            written += length; +            buffer += length; +        } +        else { +            int nbBytes = readFromFile(buffer, 3); +            header = (packetHeader*)buffer; +            if (nbBytes == -1) { +                if (errno == EAGAIN) goto END_PACKET; +                perror("Packet file"); +                return -1; +            } +            else if (nbBytes == 0) { +                if (rewind() == -1) { +                    goto END_PACKET; +                } +                continue; +            } +            else if (nbBytes < 3) { +                etiLog.log(error, +                        "Error while reading file for packet header; " +                        "read %i out of 3 bytes\n", nbBytes); +                break; +            } + +            length = header->packetLength * 24 + 24; +            if (written + length > size) { +                memcpy(&m_packetData[0], header, 3); +                readFromFile(&m_packetData[3], length - 3); +                m_packetLength = length; +                continue; +            } + +            if (m_enhancedPacketEnabled) { +                if (m_enhancedPacketLength + length > (12 * 188)) { +                    memcpy(&m_packetData[0], header, 3); +                    readFromFile(&m_packetData[3], length - 3); +                    m_packetLength = length; +                    continue; +                } +            } + +            nbBytes = readFromFile(buffer + 3, length - 3); +            if (nbBytes == -1) { +                perror("Packet file"); +                return -1; +            } +            else if (nbBytes == 0) { +                etiLog.log(info, +                        "Packet header read, but no data!\n"); +                if (rewind() == -1) { +                    goto END_PACKET; +                } +                continue; +            } +            else if (nbBytes < length - 3) { +                etiLog.log(error, "Error while reading packet file; " +                        "read %i out of %i bytes\n", nbBytes, length - 3); +                break; +            } + +            if (m_enhancedPacketEnabled) { +                indexCol = m_enhancedPacketLength / 12; +                indexRow = m_enhancedPacketLength % 12;     // TODO Check if always 0 +                for (int j = 0; j < length; ++j) { +                    m_enhancedPacketData[indexRow][indexCol] = buffer[j]; +                    if (++indexRow == 12) { +                        indexRow = 0; +                        ++indexCol; +                    } +                } +                m_enhancedPacketLength += length; +                if (m_enhancedPacketLength >= (12 * 188)) { +                    if (m_enhancedPacketLength > (12 * 188)) { +                        etiLog.log(error, +                                "Error, too much enhanced packet data!\n"); +                    } +                    ReedSolomon encoder(204, 188); +                    for (int j = 0; j < 12; ++j) { +                        encoder.encode(&m_enhancedPacketData[j][0], 188); +                    } +                    m_enhancedPacketWaiting = 192; +                } +            } +            written += length; +            buffer += length; +        } +    } +END_PACKET: +    while (written < size) { +        memset(buffer, 0, 22); +        buffer[22] = 0x60; +        buffer[23] = 0x4b; +        buffer += 24; +        written += 24; +    } +    return written; +} + +}; diff --git a/src/input/File.h b/src/input/File.h new file mode 100644 index 0000000..080d6b5 --- /dev/null +++ b/src/input/File.h @@ -0,0 +1,91 @@ +/* +   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications +   Research Center Canada) + +   Copyright (C) 2016 Matthias P. Braendli +    http://www.opendigitalradio.org + +   */ +/* +   This file is part of ODR-DabMux. + +   ODR-DabMux 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 3 of the +   License, or (at your option) any later version. + +   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. +   */ + +#pragma once + +#include <vector> +#include <array> +#include <string> +#include <stdint.h> +#include "input/inputs.h" +#include "ManagementServer.h" + +namespace Inputs { + +class FileBase : public InputBase { +    public: +        virtual int open(const std::string& name); +        virtual int readFrame(uint8_t* buffer, size_t size) = 0; +        virtual int setBitrate(int bitrate); +        virtual int close(); + +        /* Rewind the file +         * Returns -1 on failure, 0 on success +         */ +        virtual int rewind(); +    protected: +        /* Read len bytes from the file into buf, and return +         * the number of bytes read, or -1 in case of error. +         */ +        virtual ssize_t readFromFile(uint8_t* buf, size_t len); + +        // We use unix open() instead of fopen() because +        // we might want to do non-blocking I/O in the future +        int m_fd = -1; +}; + +class MPEGFile : public FileBase { +    public: +        virtual int readFrame(uint8_t* buffer, size_t size); +        virtual int setBitrate(int bitrate); + +    private: +        bool m_parity = false; +}; + +class RawFile : public FileBase { +    public: +        virtual int readFrame(uint8_t* buffer, size_t size); +}; + +class PacketFile : public FileBase { +    public: +        PacketFile(bool enhancedPacketMode); +        virtual int readFrame(uint8_t* buffer, size_t size); + +    protected: +        std::array<uint8_t,96> m_packetData; +        size_t m_packetLength; + +        /* Enhanced packet mode enables FEC for MSC packet mode +         * as described in EN 300 401 Clause 5.3.5 +         */ +        bool m_enhancedPacketEnabled = false; +        std::array<std::array<uint8_t, 204>,12> m_enhancedPacketData; +        size_t m_enhancedPacketWaiting; +        size_t m_enhancedPacketLength; +}; + +}; diff --git a/src/dabInputPrbs.cpp b/src/input/Prbs.cpp index f34c427..7856a46 100644 --- a/src/dabInputPrbs.cpp +++ b/src/input/Prbs.cpp @@ -26,7 +26,7 @@     along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>.     */ -#include "dabInputPrbs.h" +#include "input/Prbs.h"  #include <stdexcept>  #include <sstream> @@ -34,59 +34,72 @@  #include <limits.h>  #include <stdlib.h>  #include <errno.h> +#include "utils.h"  using namespace std; -int DabInputPrbs::open(const string name) +namespace Inputs { + +// ETS 300 799 Clause G.2.1 +// Preferred polynomial is G(x) = x^20 + x^17 + 1 +const uint32_t PRBS_DEFAULT_POLY = (1 << 20) | (1 << 17) | (1 << 0); + +int Prbs::open(const string& name)  { -    if (name[0] != ':') { -        throw invalid_argument( -                "Invalid PRBS address format. Must be prbs://:polynomial."); +    if (name.substr(0, 7) != "prbs://") { +        throw logic_error("Invalid PRBS name");      } -    const string poly_str = name.substr(1); +    const string& url_polynomial = name.substr(7); -    long polynomial = strtol(poly_str.c_str(), (char **)NULL, 10); -    if ((polynomial == LONG_MIN) || (polynomial == LONG_MAX)) { -        stringstream ss; -        ss <<  "Can't convert polynomial number " << poly_str; -        throw invalid_argument(ss.str()); +    if (url_polynomial.empty()) { +        m_prbs.setup(PRBS_DEFAULT_POLY);      } +    else { +        if (url_polynomial[0] != ':') { +            throw invalid_argument( +                    "Invalid PRBS address format. " +                    "Must be prbs://:polynomial."); +        } -    if (polynomial == 0) { -        throw invalid_argument("No polynomial given for PRBS input"); -    } +        const string poly_str = url_polynomial.substr(1); + +        long polynomial = hexparse(poly_str); -    m_prbs.setup(polynomial); +        if (polynomial == 0) { +            throw invalid_argument("No polynomial given for PRBS input"); +        } + +        m_prbs.setup(polynomial); +    }      rewind();      return 0;  } -int DabInputPrbs::readFrame(void* buffer, int size) +int Prbs::readFrame(uint8_t* buffer, size_t size)  { -    unsigned char* cbuffer = reinterpret_cast<unsigned char*>(buffer); - -    for (int i = 0; i < size; ++i) { -        cbuffer[i] = m_prbs.step(); +    for (size_t i = 0; i < size; ++i) { +        buffer[i] = m_prbs.step();      }      return size;  } -int DabInputPrbs::setBitrate(int bitrate) +int Prbs::setBitrate(int bitrate)  {      return bitrate;  } -int DabInputPrbs::close() +int Prbs::close()  {      return 0;  } -int DabInputPrbs::rewind() +int Prbs::rewind()  {      m_prbs.rewind();      return 0;  } +}; diff --git a/src/dabInputPrbs.h b/src/input/Prbs.h index 9cde7e2..3b2b7d4 100644 --- a/src/dabInputPrbs.h +++ b/src/input/Prbs.h @@ -28,19 +28,17 @@  #pragma once -#ifdef HAVE_CONFIG_H -#  include "config.h" -#endif -  #include <string> -#include "dabInput.h" +#include "input/inputs.h"  #include "prbs.h" -class DabInputPrbs : public DabInputBase { +namespace Inputs { + +class Prbs : public InputBase {      public: -        virtual int open(const std::string name); -        virtual int readFrame(void* buffer, int size); +        virtual int open(const std::string& name); +        virtual int readFrame(uint8_t* buffer, size_t size);          virtual int setBitrate(int bitrate);          virtual int close(); @@ -50,3 +48,5 @@ class DabInputPrbs : public DabInputBase {          PrbsGenerator m_prbs;  }; +}; + diff --git a/src/input/Udp.cpp b/src/input/Udp.cpp new file mode 100644 index 0000000..a238d9b --- /dev/null +++ b/src/input/Udp.cpp @@ -0,0 +1,134 @@ +/* +   Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications +   Research Center Canada) + +   Copyright (C) 2016 +   Matthias P. Braendli, matthias.braendli@mpb.li + +    http://www.opendigitalradio.org +   */ +/* +   This file is part of ODR-DabMux. + +   ODR-DabMux 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 3 of the +   License, or (at your option) any later version. + +   ODR-DabMux 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 ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>. +   */ + +#include "input/Udp.h" + +#include <stdexcept> +#include <sstream> +#include <string.h> +#include <limits.h> +#include <stdlib.h> +#include <errno.h> +#include "utils.h" + +using namespace std; + +namespace Inputs { + +int Udp::open(const std::string& name) +{ +    // Skip the udp:// part if it is present +    const string endpoint = (name.substr(0, 6) == "udp://") ? +        name.substr(6) : name; + +    // The endpoint should be address:port +    const auto colon_pos = endpoint.find_first_of(":"); +    if (colon_pos == string::npos) { +        stringstream ss; +        ss << "'" << name << +                " is an invalid format for udp address: " +                "expected [udp://]address:port"; +        throw invalid_argument(ss.str()); +    } + +    const auto address = endpoint.substr(0, colon_pos); +    const auto port_str = endpoint.substr(colon_pos + 1); + +    const long port = strtol(port_str.c_str(), nullptr, 10); + +    if ((port == LONG_MIN or port == LONG_MAX) and errno == ERANGE) { +        throw out_of_range("udp input: port out of range"); +    } +    else if (port == 0 and errno != 0) { +        stringstream ss; +        ss << "udp input port parse error: " << strerror(errno); +        throw invalid_argument(ss.str()); +    } + +    if (port == 0) { +        throw out_of_range("can't use port number 0 in udp address"); +    } + +    if (m_sock.reinit(port, address) == -1) { +        stringstream ss; +        ss << "Could not init UDP socket: " << inetErrMsg; +        throw runtime_error(ss.str()); +    } + +    if (m_sock.setBlocking(false) == -1) { +        stringstream ss; +        ss << "Could not set non-blocking UDP socket: " << inetErrMsg; +        throw runtime_error(ss.str()); +    } + +    return 0; +} + +int Udp::readFrame(uint8_t* buffer, size_t size) +{ +    uint8_t* data = reinterpret_cast<uint8_t*>(buffer); + +    // Regardless of buffer contents, try receiving data. +    UdpPacket packet; +    int ret = m_sock.receive(packet); + +    if (ret == -1) { +        stringstream ss; +        ss << "Could not read from UDP socket: " << inetErrMsg; +        throw runtime_error(ss.str()); +    } + +    std::copy(packet.getData(), packet.getData() + packet.getSize(), +            back_inserter(m_buffer)); + +    // Take data from the buffer if it contains enough data, +    // in any case write the buffer +    if (m_buffer.size() >= (size_t)size) { +        std::copy(m_buffer.begin(), m_buffer.begin() + size, data); +    } +    else { +        memset(data, 0x0, size); +    } + +    return size; +} + +int Udp::setBitrate(int bitrate) +{ +    if (bitrate <= 0) { +        etiLog.log(error, "Invalid bitrate (%i)\n", bitrate); +        return -1; +    } + +    return bitrate; +} + +int Udp::close() +{ +    return m_sock.close(); +} + +}; diff --git a/src/dabInputUdp.h b/src/input/Udp.h index ac9ddb0..379dbf3 100644 --- a/src/dabInputUdp.h +++ b/src/input/Udp.h @@ -1,6 +1,11 @@  /*     Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications     Research Center Canada) + +   Copyright (C) 2016 +   Matthias P. Braendli, matthias.braendli@mpb.li + +    http://www.opendigitalradio.org     */  /*     This file is part of ODR-DabMux. @@ -19,41 +24,29 @@     along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>.     */ -#ifndef DAB_INPUT_UDP_H -#define DAB_INPUT_UDP_H - +#pragma once -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif -#include "dabInput.h" -#include "dabInputFifo.h" +#include <string> +#include <vector> +#include "input/inputs.h"  #include "UdpSocket.h" +namespace Inputs { -#ifdef HAVE_FORMAT_RAW -#   ifdef HAVE_INPUT_UDP - - -extern struct dabInputOperations dabInputUdpOperations; +class Udp : public InputBase { +    public: +        virtual int open(const std::string& name); +        virtual int readFrame(uint8_t* buffer, size_t size); +        virtual int setBitrate(int bitrate); +        virtual int close(); +    private: +        UdpSocket m_sock; -struct dabInputUdpData { -    UdpSocket* socket; -    UdpPacket* packet; -    dabInputFifoStats stats; +        // The content of the UDP packets gets written into the +        // buffer, and the UDP packet boundaries disappear there. +        std::vector<uint8_t> m_buffer;  }; +}; -int dabInputUdpInit(void** args); -int dabInputUdpOpen(void* args, const char* inputName); -int dabInputUdpRead(dabInputOperations* ops, void* args, void* buffer, int size); -int dabInputUdpClose(void* args); -int dabInputUdpClean(void** args); - - -#   endif -#endif - - -#endif // DAB_INPUT_UDP_H diff --git a/src/dabInputZmq.cpp b/src/input/Zmq.cpp index 790a961..a5601fa 100644 --- a/src/dabInputZmq.cpp +++ b/src/input/Zmq.cpp @@ -2,7 +2,7 @@     Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications     Research Center Canada) -   Copyright (C) 2013, 2014 Matthias P. Braendli +   Copyright (C) 2016 Matthias P. Braendli      http://www.opendigitalradio.org     ZeroMQ input. see www.zeromq.org for more info @@ -39,17 +39,8 @@     along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>.     */ -#include "dabInput.h" -#include "dabInputZmq.h" -#include "PcDebug.h" - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif +#include "input/Zmq.h" -#ifdef HAVE_INPUT_ZEROMQ - -#include "zmq.hpp"  #include <cstdio>  #include <cstdlib>  #include <list> @@ -58,22 +49,28 @@  #include <string>  #include <sstream>  #include <limits.h> +#include "PcDebug.h" +#include "Log.h"  #ifdef __MINGW32__  #   define bzero(s, n) memset(s, 0, n)  #endif +namespace Inputs { +  using namespace std;  int readkey(string& keyfile, char* key)  { -    int fd = open(keyfile.c_str(), O_RDONLY); -    if (fd < 0) -        return fd; -    int ret = read(fd, key, CURVE_KEYLEN); -    close(fd); -    if (ret < 0) { -        return ret; +    FILE* fd = fopen(keyfile.c_str(), "r"); +    if (fd == nullptr) { +        return -1; +    } + +    int ret = fread(key, CURVE_KEYLEN, 1, fd); +    fclose(fd); +    if (ret == 0) { +        return -1;      }      /* It needs to be zero-terminated */ @@ -89,7 +86,7 @@ int readkey(string& keyfile, char* key)   * keys to the socket, and finally bind the socket   * to the new address   */ -void DabInputZmqBase::rebind() +void ZmqBase::rebind()  {      if (! m_zmq_sock_bound_to.empty()) {          try { @@ -223,7 +220,7 @@ void DabInputZmqBase::rebind()      }  } -int DabInputZmqBase::open(const std::string inputUri) +int ZmqBase::open(const std::string& inputUri)  {      m_inputUri = inputUri; @@ -236,20 +233,20 @@ int DabInputZmqBase::open(const std::string inputUri)      return 0;  } -int DabInputZmqBase::close() +int ZmqBase::close()  {      m_zmq_sock.close();      return 0;  } -int DabInputZmqBase::setBitrate(int bitrate) +int ZmqBase::setBitrate(int bitrate)  {      m_bitrate = bitrate;      return bitrate; // TODO do a nice check here  }  // size corresponds to a frame size. It is constant for a given bitrate -int DabInputZmqBase::readFrame(void* buffer, int size) +int ZmqBase::readFrame(uint8_t* buffer, size_t size)  {      int rc; @@ -340,7 +337,7 @@ int DabInputZmqBase::readFrame(void* buffer, int size)  /******** MPEG input *******/  // Read a MPEG frame from the socket, and push to list -int DabInputZmqMPEG::readFromSocket(size_t framesize) +int ZmqMPEG::readFromSocket(size_t framesize)  {      bool messageReceived = false;      zmq::message_t msg; @@ -410,7 +407,7 @@ int DabInputZmqMPEG::readFromSocket(size_t framesize)  // Read a AAC+ superframe from the socket, cut it into five frames,  // and push to list -int DabInputZmqAAC::readFromSocket(size_t framesize) +int ZmqAAC::readFromSocket(size_t framesize)  {      bool messageReceived;      zmq::message_t msg; @@ -496,7 +493,7 @@ int DabInputZmqAAC::readFromSocket(size_t framesize)  /********* REMOTE CONTROL ***********/ -void DabInputZmqBase::set_parameter(const string& parameter, +void ZmqBase::set_parameter(const string& parameter,          const string& value)  {      if (parameter == "buffer") { @@ -576,7 +573,7 @@ void DabInputZmqBase::set_parameter(const string& parameter,      }  } -const string DabInputZmqBase::get_parameter(const string& parameter) const +const string ZmqBase::get_parameter(const string& parameter) const  {      stringstream ss;      if (parameter == "buffer") { @@ -615,5 +612,5 @@ const string DabInputZmqBase::get_parameter(const string& parameter) const  } -#endif +}; diff --git a/src/dabInputZmq.h b/src/input/Zmq.h index fdd0f1b..8d729e0 100644 --- a/src/dabInputZmq.h +++ b/src/input/Zmq.h @@ -2,7 +2,7 @@     Copyright (C) 2009 Her Majesty the Queen in Right of Canada (Communications     Research Center Canada) -   Copyright (C) 2013, 2014 Matthias P. Braendli +   Copyright (C) 2016 Matthias P. Braendli      http://www.opendigitalradio.org     ZeroMQ input. see www.zeromq.org for more info @@ -41,48 +41,37 @@     along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>.     */ -#ifndef DAB_INPUT_ZMQ_H -#define DAB_INPUT_ZMQ_H - -#ifdef HAVE_CONFIG_H -#   include "config.h" -#endif - -#ifdef HAVE_INPUT_ZEROMQ +#pragma once  #include <list>  #include <string>  #include <stdint.h>  #include "zmq.hpp" -#include "dabInput.h" +#include "input/inputs.h"  #include "ManagementServer.h" +namespace Inputs { +  /* The frame_buffer contains DAB logical frames as defined in   * TS 102 563, section 6.   * Five elements of this buffer make one AAC superframe (120ms audio)   */ -// Number of elements to prebuffer before starting the pipeline -#define INPUT_ZMQ_DEF_PREBUFFERING (5*4) // 480ms - -// Default frame_buffer size in number of elements -#define INPUT_ZMQ_DEF_BUFFER_SIZE (5*8) // 960ms -  // Minimum frame_buffer size in number of elements  // This is one AAC superframe, but you probably don't want to  // go that low anyway. -#define INPUT_ZMQ_MIN_BUFFER_SIZE (5*1) // 120ms +const size_t INPUT_ZMQ_MIN_BUFFER_SIZE = 5*1; // 120ms  // Maximum frame_buffer size in number of elements  // One minute is clearly way over what everybody would  // want. -#define INPUT_ZMQ_MAX_BUFFER_SIZE (5*500) // 60s +const size_t INPUT_ZMQ_MAX_BUFFER_SIZE = 5*500; // 60s  /* The ZeroMQ Curve key is 40 bytes long in Z85 representation   *   * But we need to store it as zero-terminated string.   */ -#define CURVE_KEYLEN 40 +const size_t CURVE_KEYLEN = 40;  /* helper to invalidate a key */  #define INVALIDATE_KEY(k) memset(k, 0, CURVE_KEYLEN+1) @@ -156,9 +145,9 @@ struct zmq_frame_header_t  #define ZMQ_FRAME_DATA(f) ( ((uint8_t*)f)+sizeof(zmq_frame_header_t) ) -class DabInputZmqBase : public DabInputBase, public RemoteControllable { +class ZmqBase : public InputBase, public RemoteControllable {      public: -        DabInputZmqBase(const std::string name, +        ZmqBase(const std::string name,                  dab_input_zmq_config_t config)              : RemoteControllable(name),              m_zmq_context(1), @@ -191,8 +180,8 @@ class DabInputZmqBase : public DabInputBase, public RemoteControllable {                  INVALIDATE_KEY(m_curve_encoder_key);              } -        virtual int open(const std::string inputUri); -        virtual int readFrame(void* buffer, int size); +        virtual int open(const std::string& inputUri); +        virtual int readFrame(uint8_t* buffer, size_t size);          virtual int setBitrate(int bitrate);          virtual int close(); @@ -238,11 +227,11 @@ class DabInputZmqBase : public DabInputBase, public RemoteControllable {          size_t m_prebuf_current;  }; -class DabInputZmqMPEG : public DabInputZmqBase { +class ZmqMPEG : public ZmqBase {      public: -        DabInputZmqMPEG(const std::string name, +        ZmqMPEG(const std::string name,                  dab_input_zmq_config_t config) -            : DabInputZmqBase(name, config) { +            : ZmqBase(name, config) {                  RC_ADD_PARAMETER(buffer,                          "Size of the input buffer [mpeg frames]"); @@ -254,11 +243,11 @@ class DabInputZmqMPEG : public DabInputZmqBase {          virtual int readFromSocket(size_t framesize);  }; -class DabInputZmqAAC : public DabInputZmqBase { +class ZmqAAC : public ZmqBase {      public: -        DabInputZmqAAC(const std::string name, +        ZmqAAC(const std::string name,                  dab_input_zmq_config_t config) -            : DabInputZmqBase(name, config) { +            : ZmqBase(name, config) {                  RC_ADD_PARAMETER(buffer,                          "Size of the input buffer [aac superframes]"); @@ -270,7 +259,6 @@ class DabInputZmqAAC : public DabInputZmqBase {          virtual int readFromSocket(size_t framesize);  }; -#endif // HAVE_INPUT_ZMQ +}; -#endif // DAB_INPUT_ZMQ_H diff --git a/src/dabInput.cpp b/src/input/inputs.h index 942e58d..bfb1fb6 100644 --- a/src/dabInput.cpp +++ b/src/input/inputs.h @@ -1,6 +1,11 @@  /*     Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the Queen in     Right of Canada (Communications Research Center Canada) + +   Copyright (C) 2016 +   Matthias P. Braendli, matthias.braendli@mpb.li + +    http://www.opendigitalradio.org     */  /*     This file is part of ODR-DabMux. @@ -19,31 +24,29 @@     along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>.     */ -#include "dabInput.h" -#include "Log.h" +#pragma once -#include <string.h> +#ifdef HAVE_CONFIG_H +#   include "config.h" +#endif +#include "Log.h" +#include "RemoteControl.h" +#include <string> -bool dabInputOperations::operator==(const dabInputOperations& ops) -{ -    return memcmp(this, &ops, sizeof(*this)) == 0; -} +namespace Inputs { +/* New input object base */ +class InputBase { +    public: +        virtual int open(const std::string& name) = 0; +        virtual int readFrame(uint8_t* buffer, size_t size) = 0; +        virtual int setBitrate(int bitrate) = 0; +        virtual int close() = 0; -int dabInputSetbuf(void* args, int size) -{ -    return 0; -} +        virtual ~InputBase() {} +    protected: +        InputBase() {} +}; +}; -int dabInputSetbitrate(dabInputOperations* ops, void* args, int bitrate) -{ -    if (bitrate <= 0) { -        etiLog.log(error, "Invalid bitrate (%i)\n", bitrate); -        return -1; -    } -    if (ops->setbuf(args, bitrate * 3) == 0) { -        return bitrate; -    } -    return -1; -} @@ -219,3 +219,29 @@ int readMpegFrame(int file, void* data, int size)      }      return framelength;  } + +int checkDabMpegFrame(void* data) { +    mpegHeader* header = (mpegHeader*)data; +    unsigned long* headerData = (unsigned long*)data; +    if ((*headerData & 0x0f0ffcff) == 0x0004fcff) return 0; +    if ((*headerData & 0x0f0ffcff) == 0x0004f4ff) return 0; +    if (getMpegFrequency(header) != 48000) { +        if (getMpegFrequency(header) != 24000) { +            return MPEG_FREQUENCY; +        } +    } +    if (header->padding != 0) { +        return MPEG_PADDING; +    } +    if (header->emphasis != 0) { +        return MPEG_EMPHASIS; +    } +    if (header->copyright != 0) { +        return MPEG_COPYRIGHT; +    } +    if (header->original != 0) { +        return MPEG_ORIGINAL; +    } +    return -1; +} + @@ -75,6 +75,13 @@ ssize_t readData(int file, void* data, size_t size, unsigned int tries);  int readMpegHeader(int file, void* data, int size);  int readMpegFrame(int file, void* data, int size); +#define MPEG_FREQUENCY      -2 +#define MPEG_PADDING        -3 +#define MPEG_COPYRIGHT      -4 +#define MPEG_ORIGINAL       -5 +#define MPEG_EMPHASIS       -6 +int checkDabMpegFrame(void* data); +  #ifdef __cplusplus  }  #endif diff --git a/src/prbs.cpp b/src/prbs.cpp index 0ac3187..b0e3d6d 100644 --- a/src/prbs.cpp +++ b/src/prbs.cpp @@ -28,18 +28,18 @@  /*   * Generate a parity check for a 32-bit word.   */ -static unsigned long parity_check(unsigned long prbs_accum) +static uint32_t parity_check(uint32_t prbs_accum)  { -    unsigned long mask=1UL, parity=0UL; -    int i; -    for (i = 0;  i < 32;  ++i) { -        parity ^= ((prbs_accum & mask) != 0UL); +    uint32_t mask = 1; +    uint32_t parity = 0; +    for (int i = 0; i < 32; ++i) { +        parity ^= ((prbs_accum & mask) != 0);          mask <<= 1;      }      return parity;  } -void PrbsGenerator::setup(long polynomial) +void PrbsGenerator::setup(uint32_t polynomial)  {      this->polynomial = polynomial;      this->accum = 0; @@ -65,7 +65,7 @@ void PrbsGenerator::gen_prbs_table()  {      for (int i = 0; i < 4; ++i) {          for (int j = 0; j < 256; ++j) { -            unsigned long prbs_accum = ((unsigned long)j << (i * 8)); +            uint32_t prbs_accum = ((uint32_t)j << (i * 8));              for (int k = 0; k < 8; ++k) {                  prbs_accum = (prbs_accum << 1)                      ^ parity_check(prbs_accum & polynomial); @@ -76,24 +76,23 @@ void PrbsGenerator::gen_prbs_table()      }  } -unsigned long PrbsGenerator::update_prbs() +uint32_t PrbsGenerator::update_prbs()  { -    unsigned char acc_lsb = 0; -    int i; -    for (i = 0;  i < 4;  ++i ) { +    uint8_t acc_lsb = 0; +    for (int i = 0; i < 4; ++i ) {          acc_lsb ^= prbs_table [i] [ (accum >> (i * 8) ) & 0xff ];      } -    return (accum << 8) ^ ((unsigned long)acc_lsb); +    return (accum << 8) ^ ((uint32_t)acc_lsb);  }  void PrbsGenerator::gen_weight_table()  {      for (int i = 0; i < 256; ++i) { -        unsigned char mask = 1U; -        unsigned char ones_count = 0U; +        uint8_t mask = 1; +        uint8_t ones_count = 0;          for (int j = 0; j < 8; ++j) { -            ones_count += ((i & mask) != 0U); +            ones_count += ((i & mask) != 0);              mask = mask << 1;          }          weight[i] = ones_count; @@ -101,23 +100,23 @@ void PrbsGenerator::gen_weight_table()  }  size_t PrbsGenerator::error_count( -        unsigned char *rx_data, -        int rx_data_length) +        uint8_t *rx_data, +        size_t rx_data_length)  { -    unsigned long error_count = 0U; -    unsigned long prbs_accum = 0U; +    uint32_t error_count = 0; +    uint32_t prbs_accum = 0;      /* seed the PRBS accumulator */ -    for (int i = 0;  i < 4;  ++i) { +    for (int i = 0; i < 4; ++i) {          prbs_accum = (prbs_accum << 8) ^ (rx_data[i] ^ polarity_mask);      }      /* check the received data */ -    for (int i = 0;  i < rx_data_length;  ++i) { -        unsigned char error_pattern = (unsigned char) -                          ((prbs_accum >> 24) -                          ^ (rx_data[i] ^ polarity_mask)); -        if (error_pattern != 0U) { +    for (size_t i = 0; i < rx_data_length; ++i) { +        uint8_t error_pattern = +            (prbs_accum >> 24) ^ (rx_data[i] ^ polarity_mask); + +        if (error_pattern != 0) {              error_count += weight[error_pattern];          }          prbs_accum = update_prbs(); @@ -126,19 +125,19 @@ size_t PrbsGenerator::error_count(  }  void PrbsGenerator::gen_sequence( -        unsigned char *tx_data, -        int tx_data_length, -        unsigned long polynomial) +        uint8_t *tx_data, +        size_t tx_data_length, +        uint32_t polynomial)  { -    unsigned long prbs_accum = 0U; +    uint32_t prbs_accum = 0;      while (prbs_accum < polynomial) {          prbs_accum <<= 1;          prbs_accum |= 1;      } -    while (tx_data_length-- > 0) { +    for (size_t i = 0; i < tx_data_length; i++) {          prbs_accum = update_prbs(); -        *(tx_data++) = (unsigned char)(prbs_accum & 0xff); +        tx_data[i] = (uint8_t)(prbs_accum & 0xff);      }  } @@ -30,7 +30,7 @@  class PrbsGenerator {      public: -        void setup(long polynomial); +        void setup(uint32_t polynomial);          uint8_t step(void); @@ -42,30 +42,30 @@ class PrbsGenerator {          void gen_prbs_table(void);          /* Update a 32-bit PRBS generator eight bits at a time. */ -        unsigned long update_prbs(void); +        uint32_t update_prbs(void);          /* Generate the weight table. */          void gen_weight_table(void);          /* Count the number of errors in a block of received data. */          size_t error_count( -                unsigned char *rx_data, -                int rx_data_length); +                uint8_t *rx_data, +                size_t rx_data_length);          void gen_sequence( -                unsigned char *tx_data, -                int tx_data_length, -                unsigned long polynomial); +                uint8_t *tx_data, +                size_t tx_data_length, +                uint32_t polynomial);          // table of matrix products used to update a 32-bit PRBS generator -        unsigned long prbs_table [4] [256]; +        uint32_t prbs_table [4] [256];          // table of weights for 8-bit bytes -        unsigned char weight[256]; +        uint8_t weight[256];          // PRBS polynomial generator -        unsigned long polynomial; +        uint32_t polynomial;          // PRBS generator polarity mask -        unsigned char polarity_mask; +        uint8_t polarity_mask;          // PRBS accumulator -        unsigned long accum; +        uint32_t accum;  }; diff --git a/src/utils.cpp b/src/utils.cpp index 0399467..4431407 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -103,42 +103,16 @@ void header_message()      std::cerr << "Input URLs supported:" << std::endl <<      " prbs" << -#if defined(HAVE_INPUT_TEST) -    " test" << -#endif -#if defined(HAVE_INPUT_UDP)      " udp" << -#endif -#if defined(HAVE_INPUT_FIFO) -    " fifo" << -#endif -#if defined(HAVE_INPUT_FILE)      " file" << -#endif -#if defined(HAVE_INPUT_ZEROMQ)      " zmq" << -#endif      std::endl;      std::cerr << "Inputs format supported:" << std::endl << -#if defined(HAVE_FORMAT_RAW)      " raw" << -#endif -#if defined(HAVE_FORMAT_BRIDGE) -    " bridge" << -#endif -#if defined(HAVE_FORMAT_MPEG)      " mpeg" << -#endif -#if defined(HAVE_FORMAT_PACKET)      " packet" << -#endif -#if defined(HAVE_FORMAT_DMB) -    " dmb" << -#endif -#if defined(HAVE_FORMAT_EPM)      " epm" << -#endif      std::endl;      std::cerr << "Output URLs supported:" << std::endl << @@ -465,3 +439,29 @@ void printEnsemble(const shared_ptr<dabEnsemble> ensemble)      printLinking(ensemble);  } +long hexparse(const std::string& input) +{ +    long value = 0; +    errno = 0; + +    // Do not use strtol's base=0 because +    // we do not want to accept octal. +    if (input.find("0x") == 0) { +        value = strtol(input.c_str() + 2, nullptr, 16); +    } +    else { +        value = strtol(input.c_str(), nullptr, 10); +    } + +    if ((value == LONG_MIN or value == LONG_MAX) and errno == ERANGE) { +        throw out_of_range("hexparse: value out of range"); +    } +    else if (value == 0 and errno != 0) { +        stringstream ss; +        ss << "hexparse: " << strerror(errno); +        throw invalid_argument(ss.str()); +    } + +    return value; +} + diff --git a/src/utils.h b/src/utils.h index f65bba8..94712cd 100644 --- a/src/utils.h +++ b/src/utils.h @@ -26,9 +26,10 @@     You should have received a copy of the GNU General Public License     along with ODR-DabMux.  If not, see <http://www.gnu.org/licenses/>.  */ -#ifndef _UTILS_H -#define _UTILS_H +#pragma once +#include <string> +#include <vector>  #include <cstdio>  #include <memory>  #include "MuxElements.h" @@ -78,5 +79,6 @@ void printEnsemble(const std::shared_ptr<dabEnsemble> ensemble);  /* Print detailed component information */  void printComponent(DabComponent* component); -#endif + +long hexparse(const std::string& input); diff --git a/src/zmqinput-keygen.c b/src/zmqinput-keygen.c index 8bf61ac..ee0042e 100644 --- a/src/zmqinput-keygen.c +++ b/src/zmqinput-keygen.c @@ -25,6 +25,7 @@  #include <stdint.h>  #include <stdlib.h>  #include <zmq_utils.h> +#include <zmq.h>  #include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h>  | 
