From 79a788b6139f121e30816c046f7ff2c4320d5a0b Mon Sep 17 00:00:00 2001 From: "Matthias P. Braendli" Date: Fri, 27 Nov 2015 16:27:08 +0100 Subject: Add source and ttl settings for EDI --- doc/example.mux | 23 +++++++++++++++++------ src/DabMultiplexer.cpp | 20 +++++++++++++++++++- src/DabMux.cpp | 13 +++++++++---- src/UdpSocket.cpp | 34 +++++++++++++++++++++++++++++++++- src/UdpSocket.h | 7 ++++++- src/dabOutput/dabOutput.h | 4 +++- 6 files changed, 87 insertions(+), 14 deletions(-) diff --git a/doc/example.mux b/doc/example.mux index 9211631..456e046 100644 --- a/doc/example.mux +++ b/doc/example.mux @@ -321,17 +321,28 @@ outputs { ; The edi output has a different syntax edi { - destination "192.168.23.23" - port 12000 - sourceport 13000 + ; example for unicast EDI + ;destination "192.168.23.23" + ; for unicast EDI, do not set source + + ; example for multicast EDI, the source IP is required + ; so that the data is sent on the correct ethernet interface + destination "232.20.10.1" + source "192.168.0.50" + ; The multicast TTL has to be adapted according to your network + ttl 1 + + ; The settings below apply to both unicast and multicast ; EDI uses the UDP protocol + port 12000 + sourceport 13000 ; Enable the PFT subsystem. If false, AFPackets are sent. - enable_pft false + enable_pft true ; How many lost fragments can be recovered by Reed-Solomon - fec 3 + fec 2 ; Length of a RS chunk, can be overriden ;default=207 @@ -341,7 +352,7 @@ outputs { dump false ; show more debugging info - verbose true + verbose false ; (optional) set the kind of alignment to use in TAG Packets ; 0: no padding diff --git a/src/DabMultiplexer.cpp b/src/DabMultiplexer.cpp index 5defce7..2b2acd9 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) { 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("destination"); edi_conf.dest_port = pt_edi.get("port"); + edi_conf.source_addr = pt_edi.get("source", ""); edi_conf.source_port = pt_edi.get("sourceport"); + edi_conf.ttl = pt_edi.get("ttl", 1); edi_conf.dump = pt_edi.get("dump"); edi_conf.enable_pft = pt_edi.get("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/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..849bed4 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 { @@ -77,6 +80,8 @@ class UdpSocket { int send(std::vector 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; }; -- cgit v1.2.3