summaryrefslogtreecommitdiffstats
path: root/mmss/mmss.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mmss/mmss.cpp')
-rw-r--r--mmss/mmss.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/mmss/mmss.cpp b/mmss/mmss.cpp
new file mode 100644
index 0000000..8447e5e
--- /dev/null
+++ b/mmss/mmss.cpp
@@ -0,0 +1,137 @@
+/*
+ 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 <cassert>
+#include <cstdio>
+#include <cstdlib>
+
+
+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 void init_nodes(gmrf_t *nodes) {
+ gmrf_t *node;
+ for (node = nodes; node; node = node->next) {
+ node->ctx = node->proto->init(node);
+ }
+}
+
+
+static inline int timeout_min(int a, int b) {
+ if (a < 0)
+ return b;
+ else if (b < 0)
+ return a;
+ else
+ return min(a, b);
+}
+
+
+static int get_queue_timeout(const mmss_t *mmss) {
+ return timeout_min(mmss_queue_timeout(mmss, &mmss->packet_queue), mmss_queue_timeout(mmss, &mmss->scheduled_queue));
+}
+
+
+int main(int argc, char *argv[]) {
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s protocol_module\n", argv[0]);
+ return 1;
+ }
+
+ const mmss_protocol_t *proto = mmss_load_protocol(argv[1]);
+ if (!proto)
+ return 1;
+
+ mmss_t mmss = { .now = 0 };
+ mmss_config_t conf = {};
+
+ mmss_read_config(&mmss, &conf, "babel_test.mmss");
+
+ mmss_network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 };
+ gmrf_t node1 = { .name = strdup("node1"), .mmss = &mmss, .rand_seed = 1, .proto = proto };
+ gmrf_t node2 = { .name = strdup("node2"), .mmss = &mmss, .rand_seed = 2, .proto = proto };
+ gmrf_t node3 = { .name = strdup("node3"), .mmss = &mmss, .rand_seed = 3, .proto = proto };
+
+ node2.next = &node1;
+ node3.next = &node2;
+ gmrf_t *nodes = &node3;
+
+ init_nodes(nodes);
+
+ gmrf_addr_t addr1 = {{1}}, addr2 = {{2}}, addr3 = {{3}}, addr4 = {{4}};
+ mmss_add_iface(&node1, &net0, "mmss0", &addr1);
+ mmss_add_iface(&node2, &net0, "mmss0", &addr2);
+ mmss_add_iface(&node2, &net1, "mmss1", &addr3);
+ mmss_add_iface(&node3, &net1, "mmss1", &addr4);
+
+ while (true) {
+ int timeout = get_queue_timeout(&mmss);
+
+ if (timeout < 0) {
+ fprintf(stderr, "nothing queued, deadlock occured.\n");
+ break;
+ }
+
+ if (timeout > 0) {
+ assert(!mmss_queue_get(&mmss, &mmss.packet_queue));
+ assert(!mmss_queue_get(&mmss, &mmss.scheduled_queue));
+
+ mmss.now += timeout;
+ timeout = get_queue_timeout(&mmss);
+ }
+
+ assert(timeout == 0);
+
+ while (timeout == 0) {
+ mmss_packet_t *packet = reinterpret_cast<mmss_packet_t*>(mmss_queue_get(&mmss, &mmss.packet_queue));
+ mmss_scheduled_t *scheduled = reinterpret_cast<mmss_scheduled_t*>(mmss_queue_get(&mmss, &mmss.scheduled_queue));
+
+ assert(packet || scheduled);
+
+ if (packet)
+ mmss_dispatch(packet);
+
+ if (scheduled)
+ mmss_run_scheduled(scheduled);
+
+ timeout = get_queue_timeout(&mmss);
+ }
+ }
+
+ return 0;
+}