summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-03-21 04:51:48 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-03-21 04:51:48 +0100
commita78a01eaccf4fcbdf34aa994254d7e536040f906 (patch)
treec9ad194010fef26dd530e025db254001eb54a40a
parentaaddd2e7cde6d23c26573d7da0ab10398037a954 (diff)
downloadgmrf-a78a01eaccf4fcbdf34aa994254d7e536040f906.tar
gmrf-a78a01eaccf4fcbdf34aa994254d7e536040f906.zip
Add monitors
Monitors are used to log events from the simulated nodes. So far there are a log monitor which just logs the nodes' log messages and a SQLite monitor which does nothing at the moment.
-rw-r--r--mmss/CMakeLists.txt2
-rw-r--r--mmss/context.cpp23
-rw-r--r--mmss/context.hpp37
-rw-r--r--mmss/gmrf.cpp30
-rw-r--r--mmss/monitor.hpp51
-rw-r--r--mmss/monitor_log.cpp53
-rw-r--r--mmss/monitor_log.hpp46
-rw-r--r--mmss/monitor_sqlite.cpp49
-rw-r--r--mmss/monitor_sqlite.hpp46
-rw-r--r--mmss/types.hpp1
10 files changed, 319 insertions, 19 deletions
diff --git a/mmss/CMakeLists.txt b/mmss/CMakeLists.txt
index 694a49d..4823bce 100644
--- a/mmss/CMakeLists.txt
+++ b/mmss/CMakeLists.txt
@@ -11,6 +11,8 @@ add_executable(mmss
iface.cpp
lex.cpp
mmss.cpp
+ monitor_log.cpp
+ monitor_sqlite.cpp
network.cpp
protocol.cpp
${BISON_mmss_config_parse_OUTPUTS}
diff --git a/mmss/context.cpp b/mmss/context.cpp
index dd24ae8..4cf5011 100644
--- a/mmss/context.cpp
+++ b/mmss/context.cpp
@@ -29,6 +29,9 @@
#include "network.hpp"
#include "node.hpp"
+#include "monitor_log.hpp"
+#include "monitor_sqlite.hpp"
+
#include <algorithm>
#include <cassert>
#include <cstdio>
@@ -65,25 +68,18 @@ static inline const char* get_log_prefix(int log_level) {
}
-void context_t::vlogf_orig(const node_t *orig, int priority, const char *format, std::va_list ap) {
+void context_t::logf(int priority, const char *format, ...) {
char buf[1024];
size_t pos;
- if (orig)
- pos = snprintf_safe(buf, sizeof(buf), "[% 6u.%03u] %s: %s", now()/1000, now()%1000, orig->get_name().c_str(), get_log_prefix(priority));
- else
- pos = snprintf_safe(buf, sizeof(buf), "[% 6u.%03u] %s", now()/1000, now()%1000, get_log_prefix(priority));
-
- std::vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
-
- std::fprintf(stderr, "%s\n", buf);
-}
+ pos = snprintf_safe(buf, sizeof(buf), "[% 6u.%03u] %s", now()/1000, now()%1000, get_log_prefix(priority));
-void context_t::logf(int priority, const char *format, ...) {
std::va_list ap;
va_start(ap, format);
- vlogf_orig(nullptr, priority, format, ap);
+ std::vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
va_end(ap);
+
+ std::fprintf(stderr, "%s\n", buf);
}
void context_t::run(int argc, char *argv[]) {
@@ -93,6 +89,9 @@ void context_t::run(int argc, char *argv[]) {
}
+ attach_monitor(std::make_shared<monitor_log_t>());
+ attach_monitor(std::make_shared<monitor_sqlite_t>());
+
std::shared_ptr<const config_t> conf = config_t::read(this, argv[1]);
if (!conf)
diff --git a/mmss/context.hpp b/mmss/context.hpp
index db0c283..60fa4c3 100644
--- a/mmss/context.hpp
+++ b/mmss/context.hpp
@@ -27,6 +27,7 @@
#pragma once
#include "event.hpp"
+#include "monitor.hpp"
#include "queue.hpp"
#include <cstdarg>
@@ -39,6 +40,7 @@ namespace MMSS {
class context_t : public now_t, public nocopy_t {
private:
timeout_queue_t<event_t> event_queue;
+ std::list<std::shared_ptr<monitor_t>> monitors;
public:
context_t() : event_queue(this) {}
@@ -47,7 +49,40 @@ public:
event_queue.put(std::move(data), timeout);
}
- void vlogf_orig(const node_t *orig, int priority, const char *format, std::va_list ap);
+ void attach_monitor(std::shared_ptr<monitor_t> &&monitor) {
+ monitors.emplace_back(std::move(monitor));
+ }
+
+ void node_log(node_t *node, int priority, const std::string &message) {
+ for (auto monitor : monitors)
+ monitor->handle_log(node, priority, message);
+ }
+
+ void node_init(node_t *node, const uint8_t *node_id, size_t len) {
+ for (auto monitor : monitors)
+ monitor->handle_init(node, node_id, len);
+ }
+
+ void node_neigh(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr, float rxcost, float txcost) {
+ for (auto monitor : monitors)
+ monitor->handle_neigh(node, iface, addr, rxcost, txcost);
+ }
+
+ void node_neigh_lost(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr) {
+ for (auto monitor : monitors)
+ monitor->handle_neigh_lost(node, iface, addr);
+ }
+
+ void node_route(node_t *node, const uint8_t *node_id, size_t len, gmrf_iface_t *iface, const gmrf_addr_t *addr, int metric) {
+ for (auto monitor : monitors)
+ monitor->handle_route(node, node_id, len, iface, addr, metric);
+ }
+
+ void node_route_lost(node_t *node, const uint8_t *node_id, size_t len) {
+ for (auto monitor : monitors)
+ monitor->handle_route_lost(node, node_id, len);
+ }
+
void logf(int priority, const char *format, ...);
void run(int argc, char *argv[]);
diff --git a/mmss/gmrf.cpp b/mmss/gmrf.cpp
index 1b05b7d..a2a60a8 100644
--- a/mmss/gmrf.cpp
+++ b/mmss/gmrf.cpp
@@ -29,6 +29,8 @@
#include "iface.hpp"
#include "node.hpp"
+#include <cstdlib>
+
using namespace MMSS;
@@ -82,23 +84,39 @@ void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
va_list ap;
va_start(ap, format);
- node->get_context()->vlogf_orig(node, priority, format, ap);
+
+ char *message;
+ if (vasprintf(&message, format, ap) >= 0) {
+ node->get_context()->node_log(node, priority, std::string(message));
+ std::free(message);
+ }
+
va_end(ap);
}
-void gmrf_debug_init(gmrf_t *gmrf UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED) {
+void gmrf_debug_init(gmrf_t *gmrf, const uint8_t *node_id, size_t len) {
+ node_t *node = static_cast<node_t*>(gmrf);
+ node->get_context()->node_init(node, node_id, len);
}
-void gmrf_debug_neigh(gmrf_t *gmrf UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED, float rxcost UNUSED, float txcost UNUSED) {
+void gmrf_debug_neigh(gmrf_t *gmrf, gmrf_iface_t *iface, const gmrf_addr_t *addr, float rxcost, float txcost) {
+ node_t *node = static_cast<node_t*>(gmrf);
+ node->get_context()->node_neigh(node, iface, addr, rxcost, txcost);
}
-void gmrf_debug_neigh_lost(gmrf_t *gmrf UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED) {
+void gmrf_debug_neigh_lost(gmrf_t *gmrf, gmrf_iface_t *iface, const gmrf_addr_t *addr) {
+ node_t *node = static_cast<node_t*>(gmrf);
+ node->get_context()->node_neigh_lost(node, iface, addr);
}
-void gmrf_debug_route(gmrf_t *gmrf UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED, int metric UNUSED) {
+void gmrf_debug_route(gmrf_t *gmrf, const uint8_t *node_id, size_t len, gmrf_iface_t *iface, const gmrf_addr_t *addr, int metric) {
+ node_t *node = static_cast<node_t*>(gmrf);
+ node->get_context()->node_route(node, node_id, len, iface, addr, metric);
}
-void gmrf_debug_route_lost(gmrf_t *gmrf UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED) {
+void gmrf_debug_route_lost(gmrf_t *gmrf, const uint8_t *node_id, size_t len) {
+ node_t *node = static_cast<node_t*>(gmrf);
+ node->get_context()->node_route_lost(node, node_id, len);
}
}
diff --git a/mmss/monitor.hpp b/mmss/monitor.hpp
new file mode 100644
index 0000000..7ce3816
--- /dev/null
+++ b/mmss/monitor.hpp
@@ -0,0 +1,51 @@
+/*
+ Copyright (c) 2013-2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#pragma once
+
+#include "types.hpp"
+
+#include <string>
+
+
+namespace MMSS {
+
+class monitor_t : public nocopy_t {
+public:
+ virtual ~monitor_t() {}
+
+ virtual void handle_log(node_t *node, int priority, const std::string &message) = 0;
+
+ virtual void handle_init(node_t *node, const uint8_t *node_id, size_t len) = 0;
+
+ virtual void handle_neigh(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr, float rxcost, float txcost) = 0;
+ virtual void handle_neigh_lost(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr) = 0;
+
+ virtual void handle_route(node_t *node, const uint8_t *node_id, size_t len, gmrf_iface_t *iface, const gmrf_addr_t *addr, int metric) = 0;
+ virtual void handle_route_lost(node_t *node, const uint8_t *node_id, size_t len) = 0;
+};
+
+}
diff --git a/mmss/monitor_log.cpp b/mmss/monitor_log.cpp
new file mode 100644
index 0000000..4356e24
--- /dev/null
+++ b/mmss/monitor_log.cpp
@@ -0,0 +1,53 @@
+/*
+ Copyright (c) 2013-2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include "monitor_log.hpp"
+#include "context.hpp"
+#include "node.hpp"
+
+
+namespace MMSS {
+
+void monitor_log_t::handle_log(node_t *node, int priority, const std::string &message) {
+ node->get_context()->logf(priority, "%s: %s", node->get_name().c_str(), message.c_str());
+}
+
+void monitor_log_t::handle_init(node_t *node UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED) {
+}
+
+void monitor_log_t::handle_neigh(node_t *node UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED, float rxcost UNUSED, float txcost UNUSED) {
+}
+
+void monitor_log_t::handle_neigh_lost(node_t *node UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED) {
+}
+
+void monitor_log_t::handle_route(node_t *node UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED, int metric UNUSED) {
+}
+
+void monitor_log_t::handle_route_lost(node_t *node UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED) {
+}
+
+}
diff --git a/mmss/monitor_log.hpp b/mmss/monitor_log.hpp
new file mode 100644
index 0000000..960eacb
--- /dev/null
+++ b/mmss/monitor_log.hpp
@@ -0,0 +1,46 @@
+/*
+ Copyright (c) 2013-2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#pragma once
+
+#include "monitor.hpp"
+
+namespace MMSS {
+
+class monitor_log_t : public monitor_t {
+public:
+ virtual void handle_log(node_t *node, int priority, const std::string &message);
+
+ virtual void handle_init(node_t *node, const uint8_t *node_id, size_t len);
+
+ virtual void handle_neigh(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr, float rxcost, float txcost);
+ virtual void handle_neigh_lost(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr);
+
+ virtual void handle_route(node_t *node, const uint8_t *node_id, size_t len, gmrf_iface_t *iface, const gmrf_addr_t *addr, int metric);
+ virtual void handle_route_lost(node_t *node, const uint8_t *node_id, size_t len);
+};
+
+}
diff --git a/mmss/monitor_sqlite.cpp b/mmss/monitor_sqlite.cpp
new file mode 100644
index 0000000..34b1da4
--- /dev/null
+++ b/mmss/monitor_sqlite.cpp
@@ -0,0 +1,49 @@
+/*
+ Copyright (c) 2013-2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include "monitor_sqlite.hpp"
+
+namespace MMSS {
+
+void monitor_sqlite_t::handle_log(node_t *node UNUSED, int priority UNUSED, const std::string &message UNUSED) {
+}
+
+void monitor_sqlite_t::handle_init(node_t *node UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED) {
+}
+
+void monitor_sqlite_t::handle_neigh(node_t *node UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED, float rxcost UNUSED, float txcost UNUSED) {
+}
+
+void monitor_sqlite_t::handle_neigh_lost(node_t *node UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED) {
+}
+
+void monitor_sqlite_t::handle_route(node_t *node UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED, gmrf_iface_t *iface UNUSED, const gmrf_addr_t *addr UNUSED, int metric UNUSED) {
+}
+
+void monitor_sqlite_t::handle_route_lost(node_t *node UNUSED, const uint8_t *node_id UNUSED, size_t len UNUSED) {
+}
+
+}
diff --git a/mmss/monitor_sqlite.hpp b/mmss/monitor_sqlite.hpp
new file mode 100644
index 0000000..afb6e2f
--- /dev/null
+++ b/mmss/monitor_sqlite.hpp
@@ -0,0 +1,46 @@
+/*
+ Copyright (c) 2013-2014, Matthias Schiffer <mschiffer@universe-factory.net>
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#pragma once
+
+#include "monitor.hpp"
+
+namespace MMSS {
+
+class monitor_sqlite_t : public monitor_t {
+public:
+ virtual void handle_log(node_t *node, int priority, const std::string &message);
+
+ virtual void handle_init(node_t *node, const uint8_t *node_id, size_t len);
+
+ virtual void handle_neigh(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr, float rxcost, float txcost);
+ virtual void handle_neigh_lost(node_t *node, gmrf_iface_t *iface, const gmrf_addr_t *addr);
+
+ virtual void handle_route(node_t *node, const uint8_t *node_id, size_t len, gmrf_iface_t *iface, const gmrf_addr_t *addr, int metric);
+ virtual void handle_route_lost(node_t *node, const uint8_t *node_id, size_t len);
+};
+
+}
diff --git a/mmss/types.hpp b/mmss/types.hpp
index 54a8474..b649849 100644
--- a/mmss/types.hpp
+++ b/mmss/types.hpp
@@ -56,6 +56,7 @@ private:
class context_t;
class config_t;
class iface_t;
+class monitor_t;
class network_t;
class node_t;
class now_t;