summaryrefslogtreecommitdiffstats
path: root/mmss/gmrf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mmss/gmrf.cpp')
-rw-r--r--mmss/gmrf.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/mmss/gmrf.cpp b/mmss/gmrf.cpp
new file mode 100644
index 0000000..d6eecbc
--- /dev/null
+++ b/mmss/gmrf.cpp
@@ -0,0 +1,143 @@
+/*
+ Copyright (c) 2013, 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 "mmss.hpp"
+#include "util.hpp"
+
+#include <cassert>
+
+
+extern "C" {
+
+gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) {
+ return iface->address;
+}
+
+const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) {
+ return iface->name.c_str();
+}
+
+size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) {
+ auto net = iface->net.lock();
+ if (!net)
+ return 0;
+
+ return net->mtu;
+}
+
+bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) {
+ auto src_iface = iface->iface.lock();
+ assert(src_iface);
+
+ auto net = src_iface->net.lock();
+ if (!net)
+ return false;
+
+ for (auto dest_iface : net->interfaces) {
+ if (gmrf_addr_equal(&dest_iface->address, dest)) {
+ MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len);
+ break;
+ }
+ }
+
+ return true;
+}
+
+bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) {
+ auto src_iface = iface->iface.lock();
+ assert(src_iface);
+
+ auto net = src_iface->net.lock();
+ if (!net)
+ return false;
+
+ for (auto dest_iface : net->interfaces) {
+ if (dest_iface != src_iface)
+ MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len);
+ }
+
+ return true;
+}
+
+void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
+ auto node = gmrf->node.lock();
+ assert(node);
+
+ std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
+
+ scheduled->node = node;
+ scheduled->f = f;
+ scheduled->arg = arg;
+
+ gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay);
+}
+
+gmrf_time_t gmrf_now(gmrf_t *gmrf) {
+ return gmrf->mmss->now;
+}
+
+void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) {
+ uint8_t *data = reinterpret_cast<uint8_t*>(buffer);
+
+ size_t i;
+ for (i = 0; i < len; i++)
+ data[i] = rand_r(&gmrf->rand_seed);
+}
+
+static inline const char* get_log_prefix(int log_level) {
+ switch(log_level) {
+ case LOG_CRIT:
+ return "Fatal: ";
+ case LOG_ERR:
+ return "Error: ";
+ case LOG_WARNING:
+ return "Warning: ";
+ case LOG_NOTICE:
+ return "Info: ";
+ case LOG_INFO:
+ return "Verbose: ";
+ case LOG_DEBUG:
+ return "DEBUG: ";
+ default:
+ return "";
+ }
+}
+
+void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
+ char buf[1024];
+ size_t pos = 0;
+
+ pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name.c_str(), get_log_prefix(priority));
+
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
+ va_end(ap);
+
+ MMSS::logf(gmrf->mmss, priority, "%s", buf);
+}
+
+}