55 const config::parse_tree::node &root)
57 std::map<std::string, std::shared_ptr<Chain>> chains;
60 for (
auto &node : root.children)
62 if (node->name() ==
"config::chain")
64 if (node->has_content() && node->content() !=
"default")
66 chains[node->content()]
67 = std::make_shared<Chain>(node->content());
93 const config::parse_tree::node &root,
94 std::optional<int> priority,
95 std::optional<If> condition,
96 const std::map<std::string, std::shared_ptr<Chain>> &chains)
99 if (root.name() ==
"config::accept")
103 return std::make_unique<Accept>(
104 priority.value(), std::move(condition));
108 return std::make_unique<Accept>(std::move(condition));
112 else if (root.name() ==
"config::reject")
114 return std::make_unique<Reject>(std::move(condition));
117 else if (root.name() ==
"config::call")
119 if (root.content() ==
"default")
121 throw std::invalid_argument(
"cannot 'call' the default chain");
126 return std::make_unique<Call>(
127 chains.at(root.content()),
129 std::move(condition));
133 return std::make_unique<Call>(
134 chains.at(root.content()),
135 std::move(condition));
139 else if (root.name() ==
"config::goto_")
141 if (root.content() ==
"default")
143 throw std::invalid_argument(
"cannot 'goto' the default chain");
148 return std::make_unique<GoTo>(
149 chains.at(root.content()),
151 std::move(condition));
155 return std::make_unique<GoTo>(
156 chains.at(root.content()),
157 std::move(condition));
164 throw std::runtime_error(
"unknown action " + root.name());
178 const config::parse_tree::node &root,
179 const std::map<std::string, std::shared_ptr<Chain>> &chains)
182 for (
auto &node : root.children)
184 std::optional<int> priority;
185 std::optional<If> condition;
188 for (
auto &child : node->children)
191 if (child->name() ==
"config::priority")
193 priority = std::stoi(child->content());
196 else if (child->name() ==
"config::condition")
205 *node, std::move(priority), std::move(condition), chains));
221 for (
auto &child : root.children)
224 if (child->name() ==
"config::packet_type")
226 condition.
type(child->content());
229 else if (child->name() ==
"config::source")
231 condition.
from(child->content());
234 else if (child->name() ==
"config::dest")
236 condition.
to(child->content());
250 std::unique_ptr<Filter>
parse_filter(
const config::parse_tree::node &root)
252 Chain default_chain(
"default");
253 bool default_action =
false;
254 std::map<std::string, std::shared_ptr<Chain>> chains =
init_chains(root);
257 for (
auto &node : root.children)
260 if (node->name() ==
"config::chain")
263 if (node->content() ==
"default")
270 parse_chain(*chains.at(node->content()), *node, chains);
274 else if (node->name() ==
"config::default_action")
276 default_action = node->children[0]->name() ==
"config::accept";
281 return std::make_unique<Filter>(std::move(default_chain), default_action);
293 const config::parse_tree::node &root, std::unique_ptr<Filter> filter)
295 std::shared_ptr<Filter> shared_filter = std::move(filter);
296 std::vector<std::unique_ptr<Interface>> interfaces;
297 auto connection_pool = std::make_shared<ConnectionPool>();
300 for (
auto &node : root.children)
303 if (node->name() ==
"config::udp")
305 interfaces.push_back(
306 parse_udp(*node, shared_filter, connection_pool));
309 else if (node->name() ==
"config::serial")
311 interfaces.push_back(
331 const config::parse_tree::node &root,
332 std::shared_ptr<Filter> filter,
333 std::shared_ptr<ConnectionPool> pool)
336 std::optional<std::string> device;
337 unsigned long baud_rate = 9600;
339 std::vector<MAVAddress> preload;
342 for (
auto &node : root.children)
345 if (node->name() ==
"config::device")
347 device = node->content();
350 else if (node->name() ==
"config::baudrate")
352 baud_rate =
static_cast<unsigned long>(std::stol(node->content()));
355 else if (node->name() ==
"config::flow_control")
357 if (
to_lower(node->content()) ==
"yes")
363 else if (node->name() ==
"config::preload")
365 preload.push_back(
MAVAddress(node->content()));
370 if (!device.has_value())
372 throw std::invalid_argument(
"missing device string");
376 auto port = std::make_unique<UnixSerialPort>(
377 device.value(), baud_rate, features);
378 auto connection = std::make_unique<Connection>(
379 device.value(), filter,
false);
381 for (
const auto &addr : preload)
383 connection->add_address(addr);
386 return std::make_unique<SerialInterface>(
387 std::move(port), pool, std::move(connection));
401 const config::parse_tree::node &root,
402 std::shared_ptr<Filter> filter,
403 std::shared_ptr<ConnectionPool> pool)
405 unsigned int port = 14500;
406 std::optional<IPAddress> address;
407 unsigned long max_bitrate = 0;
410 for (
auto &node : root.children)
413 if (node->name() ==
"config::port")
415 port =
static_cast<unsigned int>(std::stol(node->content()));
418 else if (node->name() ==
"config::address")
423 else if (node->name() ==
"config::max_bitrate")
425 max_bitrate =
static_cast<unsigned long>(
426 std::stoll(node->content()));
431 auto socket = std::make_unique<UnixUDPSocket>(port, address, max_bitrate);
432 auto factory = std::make_unique<ConnectionFactory<>>(filter,
false);
433 return std::make_unique<UDPInterface>(
434 std::move(socket), pool, std::move(factory));
448 if (
root_ ==
nullptr)
453 throw std::runtime_error(
454 "Unexpected error while parsing configuration file.");
468 return std::make_unique<App>(std::move(interfaces));
514 os << *config_parser.
root_;
If & from(MAVSubnet subnet)
If & type(unsigned long id)
tao::pegtl::read_input in_
std::unique_ptr< config::parse_tree::node > parse(Input &in)
If parse_condition(const config::parse_tree::node &root)
std::unique_ptr< App > make_app()
std::unique_ptr< Filter > parse_filter(const config::parse_tree::node &root)
If & to(MAVSubnet subnet)
std::string to_lower(std::string string)
std::unique_ptr< UDPInterface > parse_udp(const config::parse_tree::node &root, std::shared_ptr< Filter > filter, std::shared_ptr< ConnectionPool > pool)
std::unique_ptr< SerialInterface > parse_serial(const config::parse_tree::node &root, std::shared_ptr< Filter > filter, std::shared_ptr< ConnectionPool > pool)
std::ostream & operator<<(std::ostream &os, const Action &action)
std::unique_ptr< config::parse_tree::node > root_
ConfigParser(std::string filename)
std::vector< std::unique_ptr< Interface > > parse_interfaces(const config::parse_tree::node &root, std::unique_ptr< Filter > filter)
void append(std::unique_ptr< Rule > rule)
void parse_chain(Chain &chain, const config::parse_tree::node &root, const std::map< std::string, std::shared_ptr< Chain >> &chains)
std::map< std::string, std::shared_ptr< Chain > > init_chains(const config::parse_tree::node &root)
std::unique_ptr< Rule > parse_action(const config::parse_tree::node &root, std::optional< int > priority, std::optional< If > condition, const std::map< std::string, std::shared_ptr< Chain >> &chains)