25 #include <libconfig.h++>
26 #include <boost/asio.hpp>
28 #include "spdlog/async.h"
29 #include "spdlog/spdlog.h"
30 #include "spdlog/sinks/syslog_sink.h"
37 using libconfig::Config;
38 using libconfig::FileIOException;
39 using libconfig::ParseException;
41 static void print_version(FILE *stream,
struct argp_state *state);
44 static char doc[] =
"FLUTE/ALC receiver demo";
46 static struct argp_option
options[] = {
47 {
"interface",
'i',
"IF", 0,
"IP address of the interface to bind flute receivers to (default: 0.0.0.0)", 0},
48 {
"target",
'm',
"IP", 0,
"Multicast address to receive on (default: 238.1.1.95)", 0},
49 {
"port",
'p',
"PORT", 0,
"Multicast port (default: 40085)", 0},
50 {
"ipsec-key",
'k',
"KEY", 0,
"To enable IPSec/ESP decryption of packets, provide a hex-encoded AES key here", 0},
51 {
"log-level",
'l',
"LEVEL", 0,
52 "Log verbosity: 0 = trace, 1 = debug, 2 = info, 3 = warn, 4 = error, 5 = "
53 "critical, 6 = none. Default: 2.",
55 {
"tsi",
'T',
"ID", 0,
"The TSI to use for the FLUTE session (default: 16)", 0},
56 {
"output-path",
'o',
"PATH", 0,
"Directory to save received files", 0},
57 {
nullptr, 0,
nullptr, 0,
nullptr, 0}};
77 static auto parse_opt(
int key,
char *arg,
struct argp_state *state) -> error_t {
78 auto arguments =
static_cast<struct
ft_arguments *
>(state->input);
84 arguments->flute_interface = arg;
87 arguments->aes_key = arg;
88 arguments->enable_ipsec =
true;
91 arguments->mcast_port =
static_cast<unsigned short>(strtoul(arg,
nullptr, 10));
94 arguments->log_level =
static_cast<unsigned>(strtoul(arg,
nullptr, 10));
97 arguments->tsi =
static_cast<uint64_t
>(strtoul(arg,
nullptr, 10));
100 arguments->output_path = arg;
103 return ARGP_ERR_UNKNOWN;
109 nullptr,
nullptr,
nullptr};
115 fprintf(stream,
"%s.%s.%s\n", std::to_string(VERSION_MAJOR).c_str(),
116 std::to_string(VERSION_MINOR).c_str(),
117 std::to_string(VERSION_PATCH).c_str());
129 auto main(
int argc,
char **argv) ->
int {
136 argp_parse(&
argp, argc, argv, 0,
nullptr, &arguments);
139 std::string ident =
"flute-receiver";
140 auto syslog_logger = spdlog::syslog_logger_mt(
"syslog", ident, LOG_PID | LOG_PERROR | LOG_CONS );
143 static_cast<spdlog::level::level_enum
>(arguments.
log_level));
144 spdlog::set_pattern(
"[%H:%M:%S.%f %z] [%^%l%$] [thr %t] %v");
146 spdlog::set_default_logger(syslog_logger);
147 spdlog::info(
"FLUTE receiver demo starting up");
151 boost::asio::io_context io;
169 std::string out_file = file->meta().content_location;
170 if (output_path && std::strlen(output_path) > 0) {
171 out_file = (std::filesystem::path(output_path) / std::filesystem::path(out_file).filename()).string();
174 spdlog::info(
"{} (TOI {}) has been received",
175 out_file, file->meta().toi);
176 FILE *fd = fopen(out_file.c_str(),
"wb");
177 fwrite(file->buffer(), 1, file->length(), fd);
183 }
catch (std::exception ex ) {
184 spdlog::error(
"Exiting on unhandled exception: %s", ex.what());
void register_completion_callback(completion_callback_t cb)
Register a callback for file reception notifications.
void enable_ipsec(uint32_t spi, const std::string &aes_key)
Enable IPSEC ESP decryption of FLUTE payloads.
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_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.
Holds all options passed on the command line.
unsigned log_level
log level
const char * mcast_target
unsigned short mcast_port
const char * flute_interface
file path of the config file.