summaryrefslogtreecommitdiffstats
path: root/mmss/iface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mmss/iface.cpp')
-rw-r--r--mmss/iface.cpp100
1 files changed, 100 insertions, 0 deletions
diff --git a/mmss/iface.cpp b/mmss/iface.cpp
new file mode 100644
index 0000000..441da4a
--- /dev/null
+++ b/mmss/iface.cpp
@@ -0,0 +1,100 @@
+/*
+ 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 <cstdlib>
+
+
+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;
+}
+
+size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) {
+ return iface->net->mtu;
+}
+
+static void enqueue(mmss_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, const void *data, size_t len) {
+ mmss_packet_t *packet = reinterpret_cast<mmss_packet_t*>(calloc(1, sizeof(mmss_packet_t) + len));
+
+ packet->sent = mmss->now;
+ packet->source = source;
+ packet->dest = dest;
+ packet->len = len;
+ memcpy(packet->data, data, len);
+
+ mmss_queue_put(mmss, &mmss->packet_queue, packet, mmss->now+1);
+}
+
+bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len, const gmrf_addr_t *dest) {
+ gmrf_iface_t *dest_iface;
+ for (dest_iface = iface->net->interfaces; dest_iface; dest_iface = dest_iface->network_next) {
+ if (gmrf_addr_equal(&dest_iface->address, dest)) {
+ enqueue(gmrf->mmss, 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) {
+ gmrf_iface_t *dest_iface;
+ for (dest_iface = iface->net->interfaces; dest_iface; dest_iface = dest_iface->network_next) {
+ if (dest_iface != iface)
+ enqueue(gmrf->mmss, iface, dest_iface, data, len);
+ }
+
+ return true;
+}
+
+void mmss_dispatch(mmss_packet_t *packet) {
+ packet->dest->node->proto->handle_packet(packet->dest->node, packet->dest->node->ctx, packet->dest,
+ &packet->source->address, packet->data, packet->len);
+ free(packet);
+}
+
+void mmss_add_iface(gmrf_t *node, mmss_network_t *net, const char *name, const gmrf_addr_t *address) {
+ gmrf_iface_t *iface = new gmrf_iface_t;
+
+ iface->name = strdup(name);
+ iface->address = *address;
+
+ iface->node = node;
+ iface->net = net;
+
+ iface->node_next = node->interfaces;
+ node->interfaces = iface;
+
+ iface->network_next = net->interfaces;
+ net->interfaces = iface;
+
+ node->proto->add_iface(node, node->ctx, iface);
+}