libflute
flute-receiver.cpp
Go to the documentation of this file.
1 
2 #include <cstdio>
3 #include <iostream>
4 #include <argp.h>
5 
6 #include <cstdlib>
7 
8 #include <fstream>
9 #include <string>
10 #include <filesystem>
11 #include <libconfig.h++>
12 #include <boost/asio.hpp>
13 
14 #include "spdlog/async.h"
15 #include "spdlog/spdlog.h"
16 #include "spdlog/sinks/syslog_sink.h"
17 
18 #include "Receiver.h"
19 #include "File.h"
20 
21 
22 using libconfig::Config;
23 using libconfig::FileIOException;
24 using libconfig::ParseException;
25 
26 using std::placeholders::_1;
27 using std::placeholders::_2;
28 using std::placeholders::_3;
29 
30 static void print_version(FILE *stream, struct argp_state *state);
31 void (*argp_program_version_hook)(FILE *, struct argp_state *) = print_version;
32 const char *argp_program_bug_address = "Austrian Broadcasting Services <obeca@ors.at>";
33 static char doc[] = "FLUTE/ALC receiver demo"; // NOLINT
34 
35 static struct argp_option options[] = { // NOLINT
36  {"interface", 'i', "IF", 0, "IP address of the interface to bind flute receivers to (default: 0.0.0.0)", 0},
37  {"target", 'm', "IP", 0, "Multicast address to receive on (default: 238.1.1.95)", 0},
38  {"port", 'p', "PORT", 0, "Multicast port (default: 40085)", 0},
39  {"ipsec-key", 'k', "KEY", 0, "To enable IPSec/ESP decryption of packets, provide a hex-encoded AES key here", 0},
40  {"log-level", 'l', "LEVEL", 0,
41  "Log verbosity: 0 = trace, 1 = debug, 2 = info, 3 = warn, 4 = error, 5 = "
42  "critical, 6 = none. Default: 2.",
43  0},
44  {nullptr, 0, nullptr, 0, nullptr, 0}};
45 
49 struct ft_arguments {
50  const char *flute_interface = {};
51  const char *mcast_target = {};
52  bool enable_ipsec = false;
53  const char *aes_key = {};
54  unsigned short mcast_port = 40085;
55  unsigned log_level = 2;
56  char **files;
57 };
58 
62 static auto parse_opt(int key, char *arg, struct argp_state *state) -> error_t {
63  auto arguments = static_cast<struct ft_arguments *>(state->input);
64  switch (key) {
65  case 'm':
66  arguments->mcast_target = arg;
67  break;
68  case 'i':
69  arguments->flute_interface = arg;
70  break;
71  case 'k':
72  arguments->aes_key = arg;
73  arguments->enable_ipsec = true;
74  break;
75  case 'p':
76  arguments->mcast_port = static_cast<unsigned short>(strtoul(arg, nullptr, 10));
77  break;
78  case 'l':
79  arguments->log_level = static_cast<unsigned>(strtoul(arg, nullptr, 10));
80  break;
81  default:
82  return ARGP_ERR_UNKNOWN;
83  }
84  return 0;
85 }
86 
87 static struct argp argp = {options, parse_opt, nullptr, doc,
88  nullptr, nullptr, nullptr};
89 
93 void print_version(FILE *stream, struct argp_state * /*state*/) {
94  fprintf(stream, "1.0.0\n");
95 }
96 
97 
98 
106 auto main(int argc, char **argv) -> int {
107  struct ft_arguments arguments;
108  /* Default values */
109  arguments.mcast_target = "238.1.1.95";
110  arguments.flute_interface= "0.0.0.0";
111 
112  // Parse the arguments
113  argp_parse(&argp, argc, argv, 0, nullptr, &arguments);
114 
115  // Set up logging
116  std::string ident = "flute-receiver";
117  auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID | LOG_PERROR | LOG_CONS );
118 
119  spdlog::set_level(
120  static_cast<spdlog::level::level_enum>(arguments.log_level));
121  spdlog::set_pattern("[%H:%M:%S.%f %z] [%^%l%$] [thr %t] %v");
122 
123  spdlog::set_default_logger(syslog_logger);
124  spdlog::info("FLUTE receiver demo starting up");
125 
126  // Create a Boost io_service
127  boost::asio::io_service io;
128 
129  // Create the receiver
130  LibFlute::Receiver receiver(
131  arguments.flute_interface,
132  arguments.mcast_target,
133  arguments.mcast_port,
134  0,
135  io);
136 
137  // Configure IPSEC, if enabled
138  if (arguments.enable_ipsec)
139  {
140  receiver.enable_ipsec(1, arguments.aes_key);
141  }
142 
144  [](std::shared_ptr<LibFlute::File> file) {
145  spdlog::info("{} (TOI {}) has been received",
146  file->meta().content_location, file->meta().toi);
147  FILE* fd = fopen(file->meta().content_location.c_str(), "wb");
148  fwrite(file->buffer(), 1, file->length(), fd);
149  fclose(fd);
150  });
151 
152  // Start the IO service
153  io.run();
154 
155 exit:
156  return 0;
157 }
FLUTE receiver class.
Definition: Receiver.h:32
void register_completion_callback(completion_callback_t cb)
Register a callback for file reception notifications.
Definition: Receiver.h:84
void enable_ipsec(uint32_t spi, const std::string &aes_key)
Enable IPSEC ESP decryption of FLUTE payloads.
Definition: Receiver.cpp:60
static void print_version(FILE *stream, struct argp_state *state)
Print the program version in MAJOR.MINOR.PATCH format.
auto main(int argc, char **argv) -> int
Main entry point for the program.
const char * argp_program_bug_address
static struct argp argp
static struct argp_option options[]
void(* argp_program_version_hook)(FILE *, struct argp_state *)
static auto parse_opt(int key, char *arg, struct argp_state *state) -> error_t
Parses the command line options into the arguments struct.
static char doc[]
Holds all options passed on the command line.
unsigned log_level
log level
const char * mcast_target
unsigned short mcast_port
const char * aes_key
const char * flute_interface
file path of the config file.