diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ConfigParser.cpp | 4 | ||||
| -rw-r--r-- | src/DabMultiplexer.cpp | 38 | ||||
| -rw-r--r-- | src/DabMultiplexer.h | 12 | ||||
| -rw-r--r-- | src/DabMux.cpp | 13 | ||||
| -rw-r--r-- | src/MuxElements.cpp | 16 | ||||
| -rw-r--r-- | src/MuxElements.h | 1 | ||||
| -rw-r--r-- | src/UdpSocket.cpp | 34 | ||||
| -rw-r--r-- | src/UdpSocket.h | 9 | ||||
| -rw-r--r-- | src/dabOutput/dabOutput.h | 4 | ||||
| -rw-r--r-- | src/fig/FIG0.h | 3 | 
10 files changed, 117 insertions, 17 deletions
| diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp index 7803ad5..db01769 100644 --- a/src/ConfigParser.cpp +++ b/src/ConfigParser.cpp @@ -778,7 +778,7 @@ void setup_subchannel_from_ptree(dabSubchannel* subchan,          subchan->bitrate = DEFAULT_DATA_BITRATE;  #if defined(HAVE_INPUT_TEST) && defined(HAVE_FORMAT_RAW)      } else if (type == "test") { -        subchan->type = DataDmb; +        subchan->type = subchannel_type_t::DataDmb;          subchan->bitrate = DEFAULT_DATA_BITRATE;          operations = dabInputTestOperations;  #endif // defined(HAVE_INPUT_TEST)) && defined(HAVE_FORMAT_RAW) @@ -794,7 +794,7 @@ void setup_subchannel_from_ptree(dabSubchannel* subchan,  #   pragma error("Must define at least one packet input")  #endif // defined(HAVE_INPUT_FILE)  #ifdef HAVE_FORMAT_EPM -    } else if (type == "enhancedpacked") { +    } else if (type == "enhancedpacket") {          subchan->type = subchannel_type_t::Packet;          subchan->bitrate = DEFAULT_PACKET_BITRATE;          operations = dabInputEnhancedPacketFileOperations; diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 5defce7..399084a 100644 --- a/src/DabMultiplexer.cpp +++ b/src/DabMultiplexer.cpp @@ -151,7 +151,25 @@ void DabMultiplexer::set_edi_config(const edi_configuration_t& new_edi_conf)      }      if (edi_conf.enabled) { -        edi_output.create(edi_conf.source_port); +        int err = edi_output.create(edi_conf.source_port); + +        if (err) { +            etiLog.level(error) << "EDI socket creation failed!"; +            throw MuxInitException(); +        } + +        if (not edi_conf.source_addr.empty()) { +            err = edi_output.setMulticastSource(edi_conf.source_addr.c_str()); +            if (err) { +                etiLog.level(error) << "EDI socket set source failed!"; +                throw MuxInitException(); +            } +            err = edi_output.setMulticastTTL(edi_conf.ttl); +            if (err) { +                etiLog.level(error) << "EDI socket set TTL failed!"; +                throw MuxInitException(); +            } +        }      }      if (edi_conf.verbose) { @@ -1734,10 +1752,22 @@ void DabMultiplexer::mux_frame(std::vector<boost::shared_ptr<DabOutput> >& outpu      edi_tagDETI.tsta = tist->TIST; -    timestamp += 3 << 17; -    if (timestamp > 0xf9ffff) +    /* Coding of the TIST, according to ETS 300 799 Annex C + +    Bit number      b0(MSb)..b6     b7..b9   b10..b17   b18..b20   b21..b23(LSb) +    Bit number      b23(MSb)..b17   b16..b14 b13..b6    b5..b3     b2..b0(LSb) +    as uint32_t +    Width           7               3        8          3          3 +    Timestamp level 1               2        3          4          5 +    Valid range     [0..124], 127   [0..7]   [0..255]   [0..7]     [0..7] +    Approximate     8 ms            1 ms     3,91 us    488 ns     61 ns +    time resolution +    */ + +    timestamp += 24 << 13; // Shift 24ms by 13 to Timestamp level 2 +    if (timestamp > 0xf9FFff)      { -        timestamp -= 0xfa0000; +        timestamp -= 0xfa0000; // Substract 16384000, corresponding to one second          // Also update MNSC time for next frame          MNSC_increment_time = true; diff --git a/src/DabMultiplexer.h b/src/DabMultiplexer.h index f454d20..bafefff 100644 --- a/src/DabMultiplexer.h +++ b/src/DabMultiplexer.h @@ -381,10 +381,14 @@ struct FIGtype0_17_programme {      uint16_t SId;      uint8_t NFC:2;      uint8_t Rfa:2; -    uint8_t CC:1; -    uint8_t L:1; -    uint8_t PS:1; -    uint8_t SD:1; +    uint8_t CC:1; // Complimentary code +    uint8_t L:1; // Signals presence of language field +    uint8_t PS:1; // Primary/Secondary +    // PS==0: language refers to primary service component +    // PS==1: language refers to secondary service component +    uint8_t SD:1; // Static/Dynamic +    // SD==0: PTy and language may not represent the current programme contents +    // SD==1: PTy and language represent the current programme contents  } PACKED;  struct FIGtype0_18 { diff --git a/src/DabMux.cpp b/src/DabMux.cpp index 04aed2b..f3f0c95 100644 --- a/src/DabMux.cpp +++ b/src/DabMux.cpp @@ -325,7 +325,9 @@ int main(int argc, char *argv[])                  edi_conf.dest_addr           = pt_edi.get<string>("destination");                  edi_conf.dest_port           = pt_edi.get<unsigned int>("port"); +                edi_conf.source_addr         = pt_edi.get<string>("source", "");                  edi_conf.source_port         = pt_edi.get<unsigned int>("sourceport"); +                edi_conf.ttl                 = pt_edi.get<unsigned int>("ttl", 1);                  edi_conf.dump                = pt_edi.get<bool>("dump");                  edi_conf.enable_pft          = pt_edi.get<bool>("enable_pft"); @@ -430,10 +432,13 @@ int main(int argc, char *argv[])  #if HAVE_OUTPUT_EDI          if (edi_conf.enabled) { -            etiLog.level(warn) << "EXPERIMENTAL EDI OUTPUT ENABLED!"; -            etiLog.level(info) << "edi to " << edi_conf.dest_addr << ":" << edi_conf.dest_port; -            etiLog.level(info) << "source port " << edi_conf.source_port; -            etiLog.level(info) << "verbose     " << edi_conf.verbose; +            etiLog.level(info) << "EDI to " << edi_conf.dest_addr << ":" << edi_conf.dest_port; +            if (not edi_conf.source_addr.empty()) { +                etiLog.level(info) << " source      " << edi_conf.source_addr; +                etiLog.level(info) << " ttl         " << edi_conf.ttl; +            } +            etiLog.level(info) << " source port " << edi_conf.source_port; +            etiLog.level(info) << " verbose     " << edi_conf.verbose;          }  #endif diff --git a/src/MuxElements.cpp b/src/MuxElements.cpp index be0906e..adc6a60 100644 --- a/src/MuxElements.cpp +++ b/src/MuxElements.cpp @@ -404,6 +404,19 @@ void DabService::set_parameter(const string& parameter,                  throw ParameterError(ss.str());          }      } +    else if (parameter == "pty") { +        int newpty = std::stoi(value); // International code, 5 bits + +        if (newpty >= 0 and newpty < (1<<5)) { +            pty = newpty; +        } +        else { +            stringstream ss; +            ss << m_name << " pty is out of bounds"; +            etiLog.level(warn) << ss.str(); +            throw ParameterError(ss.str()); +        } +    }      else {          stringstream ss;          ss << "Parameter '" << parameter << @@ -418,6 +431,9 @@ const string DabService::get_parameter(const string& parameter) const      if (parameter == "label") {          ss << label.long_label() << "," << label.short_label();      } +    else if (parameter == "pty") { +        ss << (int)pty; +    }      else {          ss << "Parameter '" << parameter <<              "' is not exported by controllable " << get_rc_name(); diff --git a/src/MuxElements.h b/src/MuxElements.h index 9fe2aeb..dc84ccb 100644 --- a/src/MuxElements.h +++ b/src/MuxElements.h @@ -338,6 +338,7 @@ class DabService : public RemoteControllable              uid(uid)          {              RC_ADD_PARAMETER(label, "Label and shortlabel [label,short]"); +            RC_ADD_PARAMETER(pty, "Programme Type");          }          std::string uid; diff --git a/src/UdpSocket.cpp b/src/UdpSocket.cpp index a1a7935..af26430 100644 --- a/src/UdpSocket.cpp +++ b/src/UdpSocket.cpp @@ -1,6 +1,9 @@  /*     Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the     Queen in Right of Canada (Communications Research Center Canada) + +   Copyright (C) 2015 Matthias P. Braendli +    http://www.opendigitalradio.org     */  /*     This file is part of ODR-DabMux. @@ -155,6 +158,7 @@ int UdpSocket::create(int port, char *name)      setInetError("Can't reuse address");      return -1;    } +    if (bind(listenSocket, address.getAddress(), sizeof(sockaddr_in)) == SOCKET_ERROR) {      setInetError("Can't bind socket");      closesocket(listenSocket); @@ -291,7 +295,35 @@ int UdpSocket::joinGroup(char* groupname)    return 0;  } -   +int UdpSocket::setMulticastTTL(int ttl) +{ +    if (setsockopt(listenSocket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) +            == SOCKET_ERROR) { +        setInetError("Can't set ttl"); +        return -1; +    } + +    return 0; +} + +int UdpSocket::setMulticastSource(const char* source_addr) +{ +    struct in_addr addr; +    if (inet_aton(source_addr, &addr) == 0) { +        setInetError("Can't parse source address"); +        return -1; +    } + +    if (setsockopt(listenSocket, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)) +            == SOCKET_ERROR) { +        setInetError("Can't set source address"); +        return -1; +    } + +    return 0; +} + +  /**   *  Constructs an UDP packet.   *  @param initSize The initial size of the data buffer diff --git a/src/UdpSocket.h b/src/UdpSocket.h index e23401c..07e9f0e 100644 --- a/src/UdpSocket.h +++ b/src/UdpSocket.h @@ -1,6 +1,9 @@  /*     Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Her Majesty the     Queen in Right of Canada (Communications Research Center Canada) + +   Copyright (C) 2015 Matthias P. Braendli +    http://www.opendigitalradio.org     */  /*     This file is part of ODR-DabMux. @@ -58,7 +61,7 @@ class UdpPacket;   *  A UDP socket is the sending or receiving point for a packet delivery service.   *  Each packet sent or received on a datagram socket is individually   *  addressed and routed. Multiple packets sent from one machine to another may - *  be routed differently, and may arrive in any order.  + *  be routed differently, and may arrive in any order.   *  @author Pascal Charest pascal.charest@crc.ca   */  class UdpSocket { @@ -66,6 +69,8 @@ class UdpSocket {    UdpSocket();    UdpSocket(int port, char *name = NULL);    ~UdpSocket(); +  UdpSocket(const UdpSocket& other) = delete; +  const UdpSocket& operator=(const UdpSocket& other) = delete;    static int init();    static int clean(); @@ -77,6 +82,8 @@ class UdpSocket {    int send(std::vector<uint8_t> data, InetAddress destination);    int receive(UdpPacket &packet);    int joinGroup(char* groupname); +  int setMulticastSource(const char* source_addr); +  int setMulticastTTL(int ttl);    /**     *  Connects the socket on a specific address. Only data from this address     *  will be received. diff --git a/src/dabOutput/dabOutput.h b/src/dabOutput/dabOutput.h index 0ced9d3..b2100ab 100644 --- a/src/dabOutput/dabOutput.h +++ b/src/dabOutput/dabOutput.h @@ -61,12 +61,14 @@ struct edi_configuration_t {      unsigned chunk_len; // RSk, data length of each chunk      unsigned fec;       // number of fragments that can be recovered      bool enabled; -    unsigned int source_port;      bool dump;      bool verbose;      bool enable_pft;      std::string dest_addr; +    std::string source_addr; +    unsigned int source_port;      unsigned int dest_port; +    unsigned int ttl;      unsigned int tagpacket_alignment;  }; diff --git a/src/fig/FIG0.h b/src/fig/FIG0.h index 9811eaf..2dc6483 100644 --- a/src/fig/FIG0.h +++ b/src/fig/FIG0.h @@ -27,6 +27,8 @@  #define __FIG0_H_  #include <cstdint> +#include <map> +#include <set>  #include "fig/FIG.h" @@ -181,6 +183,7 @@ class FIG0_13 : public IFIG  };  // FIG type 0/17 +// Programme Type (PTy)  class FIG0_17 : public IFIG  {      public: | 
