summaryrefslogtreecommitdiffstats
path: root/src/zmq2edi/zmq2edi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/zmq2edi/zmq2edi.cpp')
-rw-r--r--src/zmq2edi/zmq2edi.cpp104
1 files changed, 83 insertions, 21 deletions
diff --git a/src/zmq2edi/zmq2edi.cpp b/src/zmq2edi/zmq2edi.cpp
index 2216c85..fadd163 100644
--- a/src/zmq2edi/zmq2edi.cpp
+++ b/src/zmq2edi/zmq2edi.cpp
@@ -48,20 +48,23 @@ void usage(void)
cerr << "Usage:" << endl;
cerr << "odr-zmq2edi [options] <source>" << endl << endl;
- cerr << "Where the options are:" << endl;
+ cerr << "Options:" << endl;
+ cerr << "The following options can be given only once:" << endl;
cerr << " <source> is a ZMQ URL that points to a ODR-DabMux ZMQ output." << endl;
cerr << " -w <delay> Keep every ETI frame until TIST is <delay> milliseconds after current system time." << endl;
- cerr << " -d <destination ip> sets the destination ip." << endl;
cerr << " -p <destination port> sets the destination port." << endl;
- cerr << " -s <source port> sets the source port." << endl;
- cerr << " -S <source ip> select the source IP in case we want to use multicast." << endl;
- cerr << " -t <ttl> set the packet's TTL." << endl;
cerr << " -P Disable PFT and send AFPackets." << endl;
cerr << " -f <fec> sets the FEC." << endl;
cerr << " -i <interleave> enables the interleaved with this latency." << endl;
cerr << " -D dumps the EDI to edi.debug file." << endl;
cerr << " -v Enables verbose mode." << endl;
- cerr << " -a <tagpacket alignement> sets the alignment of the TAG Packet (default 8)." << endl;
+ cerr << " -a <tagpacket alignement> sets the alignment of the TAG Packet (default 8)." << endl << endl;
+
+ cerr << "The following options can be given several times, when more than once destination is addressed:" << endl;
+ cerr << " -d <destination ip> sets the destination ip." << endl;
+ cerr << " -s <source port> sets the source port." << endl;
+ cerr << " -S <source ip> select the source IP in case we want to use multicast." << endl;
+ cerr << " -t <ttl> set the packet's TTL." << endl;
}
static metadata_t get_md_one_frame(uint8_t *buf, size_t size, size_t *consumed_bytes)
@@ -141,10 +144,70 @@ static metadata_t get_md_one_frame(uint8_t *buf, size_t size, size_t *consumed_b
throw std::runtime_error("Insufficient data");
}
-int start(int argc, char **argv)
+/* There is some state inside the parsing of destination arguments,
+ * because several destinations can be given. */
+
+static edi_destination_t edi_destination;
+static bool source_port_set = false;
+static bool source_addr_set = false;
+static bool ttl_set = false;
+static bool dest_addr_set = false;
+
+static void add_edi_destination(void)
+{
+ if (not dest_addr_set) {
+ throw std::runtime_error("Destination address not specified for destination number " +
+ std::to_string(edi_conf.destinations.size() + 1));
+ }
+
+ edi_conf.destinations.push_back(edi_destination);
+ edi_destination_t newdest;
+ edi_destination = newdest;
+
+ source_port_set = false;
+ source_addr_set = false;
+ ttl_set = false;
+ dest_addr_set = false;
+}
+
+static void parse_destination_args(char option)
{
- edi_destination_t edi_destination;
+ switch (option) {
+ case 's':
+ if (source_port_set) {
+ add_edi_destination();
+ }
+ edi_destination.source_port = std::stoi(optarg);
+ source_port_set = true;
+ break;
+ case 'S':
+ if (source_addr_set) {
+ add_edi_destination();
+ }
+ edi_destination.source_addr = optarg;
+ source_addr_set = true;
+ break;
+ case 't':
+ if (ttl_set) {
+ add_edi_destination();
+ }
+ edi_destination.ttl = std::stoi(optarg);
+ ttl_set = true;
+ break;
+ case 'd':
+ if (dest_addr_set) {
+ add_edi_destination();
+ }
+ edi_destination.dest_addr = optarg;
+ dest_addr_set = true;
+ break;
+ default:
+ throw std::logic_error("parse_destination_args invalid");
+ }
+}
+int start(int argc, char **argv)
+{
edi_conf.enable_pft = true;
if (argc == 0) {
@@ -161,19 +224,13 @@ int start(int argc, char **argv)
case -1:
break;
case 'd':
- edi_destination.dest_addr = optarg;
- break;
- case 'p':
- edi_conf.dest_port = std::stoi(optarg);
- break;
case 's':
- edi_destination.source_port = std::stoi(optarg);
- break;
case 'S':
- edi_destination.source_addr = optarg;
- break;
case 't':
- edi_destination.ttl = std::stoi(optarg);
+ parse_destination_args(ch);
+ break;
+ case 'p':
+ edi_conf.dest_port = std::stoi(optarg);
break;
case 'P':
edi_conf.enable_pft = false;
@@ -217,17 +274,22 @@ int start(int argc, char **argv)
}
}
+ add_edi_destination();
+
if (optind >= argc) {
etiLog.level(error) << "source option is missing";
return 1;
}
- if (edi_destination.dest_addr.empty() or edi_conf.dest_port == 0) {
- etiLog.level(error) << "No EDI output defined";
+ if (edi_conf.dest_port == 0) {
+ etiLog.level(error) << "No EDI destination port defined";
return 1;
}
- edi_conf.destinations.push_back(edi_destination);
+ if (edi_conf.destinations.empty()) {
+ etiLog.level(error) << "No EDI destinations set";
+ return 1;
+ }
etiLog.level(info) << "Setting up EDI Sender with delay " << delay_ms << " ms";
edisender.start(edi_conf, delay_ms);