5G-MAG Reference Tools - MBMS Middleware
main.cpp
Go to the documentation of this file.
1 // 5G-MAG Reference Tools
2 // MBMS Middleware Process
3 //
4 // Copyright (C) 2021 Klaus Kühnhammer (Österreichische Rundfunksender GmbH & Co KG)
5 //
6 // Licensed under the License terms and conditions for use, reproduction, and
7 // distribution of 5G-MAG software (the “License”). You may not use this file
8 // except in compliance with the License. You may obtain a copy of the License at
9 // https://www.5g-mag.com/reference-tools. Unless required by applicable law or
10 // agreed to in writing, software distributed under the License is distributed on
11 // an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 // or implied.
13 //
14 // See the License for the specific language governing permissions and limitations
15 // under the License.
16 //
17 
29 #include <argp.h>
30 
31 #include <cstdlib>
32 #include <string>
33 #include <filesystem>
34 #include <libconfig.h++>
35 #include <boost/asio.hpp>
36 
37 #include "Version.h"
38 
39 #include "spdlog/async.h"
40 #include "spdlog/spdlog.h"
41 #include "spdlog/sinks/syslog_sink.h"
42 
43 #include "Middleware.h"
44 
45 using libconfig::Config;
46 using libconfig::FileIOException;
47 using libconfig::ParseException;
48 
49 using std::placeholders::_1;
50 using std::placeholders::_2;
51 using std::placeholders::_3;
52 
53 static void print_version(FILE *stream, struct argp_state *state);
54 void (*argp_program_version_hook)(FILE *, struct argp_state *) = print_version;
55 const char *argp_program_bug_address = "5G-MAG Reference Tools <reference-tools@5g-mag.com>";
56 static char doc[] = "5G-MAG-RT MBMS Middleware Process"; // NOLINT
57 
58 static struct argp_option options[] = { // NOLINT
59  {"config", 'c', "FILE", 0, "Configuration file (default: /etc/5gmag-rt.conf)", 0},
60  {"interface", 'i', "IF", 0, "IP address of the interface to bind flute receivers to (default: 192.168.180.10)", 0},
61  {"log-level", 'l', "LEVEL", 0,
62  "Log verbosity: 0 = trace, 1 = debug, 2 = info, 3 = warn, 4 = error, 5 = "
63  "critical, 6 = none. Default: 2.",
64  0},
65  {nullptr, 0, nullptr, 0, nullptr, 0}};
66 
70 struct mw_arguments {
71  const char *config_file = {};
72  const char *flute_interface = {};
73  unsigned log_level = 2;
74 };
75 
79 static auto parse_opt(int key, char *arg, struct argp_state *state) -> error_t {
80  auto arguments = static_cast<struct mw_arguments *>(state->input);
81  switch (key) {
82  case 'c':
83  arguments->config_file = arg;
84  break;
85  case 'i':
86  arguments->flute_interface = arg;
87  break;
88  case 'l':
89  arguments->log_level = static_cast<unsigned>(strtoul(arg, nullptr, 10));
90  break;
91  default:
92  return ARGP_ERR_UNKNOWN;
93  }
94  return 0;
95 }
96 
97 static struct argp argp = {options, parse_opt, nullptr, doc,
98  nullptr, nullptr, nullptr};
99 
103 void print_version(FILE *stream, struct argp_state * /*state*/) {
104  fprintf(stream, "%s.%s.%s\n", std::to_string(VERSION_MAJOR).c_str(),
105  std::to_string(VERSION_MINOR).c_str(),
106  std::to_string(VERSION_PATCH).c_str());
107 }
108 
109 
110 
111 static Config cfg;
120 auto main(int argc, char **argv) -> int {
121  struct mw_arguments arguments;
122  /* Default values */
123  arguments.config_file = "/etc/5gmag-rt.conf";
124  arguments.flute_interface= "0.0.0.0";
125 
126  argp_parse(&argp, argc, argv, 0, nullptr, &arguments);
127 
128  // Read and parse the configuration file
129  try {
130  cfg.readFile(arguments.config_file);
131  } catch(const FileIOException &fioex) {
132  spdlog::error("I/O error while reading config file at {}. Exiting.", arguments.config_file);
133  exit(1);
134  } catch(const ParseException &pex) {
135  spdlog::error("Config parse error at {}:{} - {}. Exiting.",
136  pex.getFile(), pex.getLine(), pex.getError());
137  exit(1);
138  }
139 
140  // Set up logging
141  std::string ident = "mw";
142  auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID | LOG_PERROR | LOG_CONS );
143 
144  spdlog::set_level(
145  static_cast<spdlog::level::level_enum>(arguments.log_level));
146  spdlog::set_pattern("[%H:%M:%S.%f %z] [%^%l%$] [thr %t] %v");
147 
148  spdlog::set_default_logger(syslog_logger);
149  spdlog::info("5g-mag-rt mw v{}.{}.{} starting up", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
150 
151  std::string uri = "http://0.0.0.0:3020/";
152  cfg.lookupValue("mw.http_server.uri", uri);
153 
154  try {
155  boost::asio::io_service io;
156  MBMS_RT::Middleware mw(io, cfg, uri, arguments.flute_interface);
157  io.run();
158  } catch (const std::exception& ex) {
159  spdlog::error("BUG ALERT: Unhandled exception in main: {}", ex.what());
160  }
161 
162 exit:
163  return 0;
164 }
static Config cfg
Global configuration object.
Definition: main.cpp:111
static void print_version(FILE *stream, struct argp_state *state)
Print the program version in MAJOR.MINOR.PATCH format.
Definition: main.cpp:103
auto main(int argc, char **argv) -> int
Main entry point for the program.
Definition: main.cpp:120
const char * argp_program_bug_address
Definition: main.cpp:55
static struct argp argp
Definition: main.cpp:97
static struct argp_option options[]
Definition: main.cpp:58
void(* argp_program_version_hook)(FILE *, struct argp_state *)
Definition: main.cpp:54
static auto parse_opt(int key, char *arg, struct argp_state *state) -> error_t
Parses the command line options into the arguments struct.
Definition: main.cpp:79
static char doc[]
Definition: main.cpp:56
Holds all options passed on the command line.
Definition: main.cpp:70
unsigned log_level
log level
Definition: main.cpp:73
const char * config_file
file path of the config file.
Definition: main.cpp:71
const char * flute_interface
file path of the config file.
Definition: main.cpp:72