diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/zmq2edi/zmq2edi.cpp | 104 | 
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);  | 
