From efabc7a40d74904385d9dd55eb0312aeb538d4ed Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 27 Jul 2013 20:34:29 +0200 Subject: Encapsulate node and interface structures --- mmss/context.cpp | 4 ++- mmss/event.cpp | 16 ++++++---- mmss/event.hpp | 2 +- mmss/gmrf.cpp | 40 +++++++++++++------------ mmss/iface.cpp | 14 ++++----- mmss/iface.hpp | 69 +++++++++++++++++++++++++++++++++++++++++++ mmss/mmss.cpp | 15 +++------- mmss/mmss.hpp | 37 ----------------------- mmss/node.hpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ mmss/types.hpp | 10 ++++--- 10 files changed, 209 insertions(+), 87 deletions(-) create mode 100644 mmss/iface.hpp create mode 100644 mmss/node.hpp diff --git a/mmss/context.cpp b/mmss/context.cpp index 5fcb72f..36f2ea5 100644 --- a/mmss/context.cpp +++ b/mmss/context.cpp @@ -25,6 +25,8 @@ #include "mmss.hpp" +#include "node.hpp" + namespace MMSS { @@ -62,7 +64,7 @@ void context_t::vlogf_orig(const node_t *orig, int priority, const char *format, size_t pos; if (orig) - pos = snprintf_safe(buf, sizeof(buf), "[% 6u.%03u] %s: %s", now()/1000, now()%1000, orig->name.c_str(), get_log_prefix(priority)); + 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)); diff --git a/mmss/event.cpp b/mmss/event.cpp index 6326e98..5246e87 100644 --- a/mmss/event.cpp +++ b/mmss/event.cpp @@ -25,23 +25,27 @@ #include "event.hpp" +#include "iface.hpp" #include "mmss.hpp" +#include "node.hpp" namespace MMSS { void packet_t::handle(context_t *mmss) { - auto dest_ptr = dest.lock(); - if (!dest_ptr) + auto iface = dest.lock(); + if (!iface) return; - node_t *node = dest_ptr->node; - - node->proto->handle_packet(node, node->ctx, dest_ptr.get(), &source_addr, data.get(), len); + iface->get_node()->handle_packet(iface, &source_addr, data.get(), len); } void scheduled_t::handle(context_t *mmss) { - f(node.get(), node->ctx, arg); + auto node_ptr = node.lock(); + if (!node_ptr) + return; + + node_ptr->handle_scheduled(f, arg); } } diff --git a/mmss/event.hpp b/mmss/event.hpp index d0fe092..e531c7c 100644 --- a/mmss/event.hpp +++ b/mmss/event.hpp @@ -55,7 +55,7 @@ public: class scheduled_t : public event_t { public: - std::shared_ptr node; + std::weak_ptr node; gmrf_scheduled_func f; void *arg; diff --git a/mmss/gmrf.cpp b/mmss/gmrf.cpp index 1eaa656..0fc8527 100644 --- a/mmss/gmrf.cpp +++ b/mmss/gmrf.cpp @@ -24,31 +24,33 @@ */ +#include "iface.hpp" #include "mmss.hpp" +#include "node.hpp" -#include +using namespace MMSS; extern "C" { gmrf_addr_t gmrf_iface_get_addr(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->address; + return *(static_cast(iface)->get_address()); } const char* gmrf_iface_get_name(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->name.c_str(); + return static_cast(iface)->get_name().c_str(); } size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) { - return iface->net->mtu; + return static_cast(iface)->get_network()->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->shared_from_this(); + auto src_iface = static_cast(iface)->shared_from_this(); - for (auto dest_iface : src_iface->net->interfaces) { - if (gmrf_addr_equal(&dest_iface->address, dest)) { - MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len); + for (auto dest_iface : src_iface->get_network()->interfaces) { + if (gmrf_addr_equal(dest_iface->get_address(), dest)) { + enqueue(static_cast(gmrf)->get_context(), src_iface, dest_iface, data, len); break; } } @@ -57,30 +59,30 @@ bool gmrf_iface_send(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t } bool gmrf_iface_send_bc(gmrf_t *gmrf, gmrf_iface_t *iface, const void *data, size_t len) { - auto src_iface = iface->shared_from_this(); + auto src_iface = static_cast(iface)->shared_from_this(); - for (auto dest_iface : src_iface->net->interfaces) { + for (auto dest_iface : src_iface->get_network()->interfaces) { if (dest_iface != src_iface) - MMSS::enqueue(gmrf->mmss, src_iface, dest_iface, data, len); + enqueue(static_cast(gmrf)->get_context(), 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->shared_from_this(); + node_t *node = static_cast(gmrf); - std::shared_ptr scheduled = std::make_shared(); + std::shared_ptr scheduled = std::make_shared(); - scheduled->node = std::move(node); + scheduled->node = node->shared_from_this(); scheduled->f = f; scheduled->arg = arg; - gmrf->mmss->event_queue.put(std::move(scheduled), gmrf->mmss->now()+delay); + node->get_context()->event_queue.put(std::move(scheduled), node->get_context()->now()+delay); } gmrf_time_t gmrf_now(gmrf_t *gmrf) { - return gmrf->mmss->now(); + return static_cast(gmrf)->get_context()->now(); } void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) { @@ -88,13 +90,15 @@ void gmrf_random_bytes(gmrf_t *gmrf, void *buffer, size_t len) { size_t i; for (i = 0; i < len; i++) - data[i] = rand_r(&gmrf->rand_seed); + data[i] = static_cast(gmrf)->random_byte(); } void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) { + node_t *node = static_cast(gmrf); + va_list ap; va_start(ap, format); - gmrf->mmss->vlogf_orig(gmrf, priority, format, ap); + node->get_context()->vlogf_orig(node, priority, format, ap); va_end(ap); } diff --git a/mmss/iface.cpp b/mmss/iface.cpp index 7e43dd2..7de4789 100644 --- a/mmss/iface.cpp +++ b/mmss/iface.cpp @@ -24,6 +24,8 @@ */ +#include "iface.hpp" +#include "node.hpp" #include "mmss.hpp" #include @@ -32,25 +34,19 @@ namespace MMSS { void add_iface(const std::shared_ptr &node, const std::shared_ptr &net, const std::string &name, const gmrf_addr_t *address) { - std::shared_ptr iface = std::make_shared(); - - iface->name = name; - iface->address = *address; - - iface->node = node.get(); - iface->net = net.get(); + std::shared_ptr iface = std::make_shared(node.get(), net.get(), name, address); node->interfaces.push_back(iface); net->interfaces.push_back(iface); - node->proto->add_iface(node.get(), node->ctx, iface.get()); + node->add_iface(iface); } void enqueue(context_t *mmss, const std::shared_ptr &source, const std::shared_ptr &dest, const void *data, size_t len) { std::shared_ptr packet = std::make_shared(); packet->sent = mmss->now(); - packet->source_addr = source->address; + packet->source_addr = *source->get_address(); packet->dest = dest; packet->len = len; diff --git a/mmss/iface.hpp b/mmss/iface.hpp new file mode 100644 index 0000000..322fcc1 --- /dev/null +++ b/mmss/iface.hpp @@ -0,0 +1,69 @@ +/* + Copyright (c) 2013, Matthias Schiffer + 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 +#include + + +namespace MMSS { + +class iface_t : public ::gmrf_iface, public std::enable_shared_from_this { +private: + iface_t(iface_t const&) = delete; + iface_t& operator=(iface_t const&) = delete; + + node_t *node; + network_t *net; + + std::string name; + gmrf_addr_t address; + +public: + iface_t(node_t *node0, network_t *net0, const std::string &name0, const gmrf_addr_t *address0) + : node(node0), net(net0), name(name0), address(*address0) {} + + node_t* get_node() const { + return node; + } + + network_t* get_network() const { + return net; + } + + const std::string& get_name() const { + return name; + } + + const gmrf_addr_t* get_address() const { + return &address; + } +}; + +} diff --git a/mmss/mmss.cpp b/mmss/mmss.cpp index 8b94c20..62f818d 100644 --- a/mmss/mmss.cpp +++ b/mmss/mmss.cpp @@ -25,6 +25,7 @@ #include "mmss.hpp" +#include "node.hpp" #include #include @@ -33,12 +34,6 @@ namespace MMSS { -static void init_nodes(std::list> &nodes) { - for (auto node : nodes) - node->ctx = node->proto->init(node.get()); -} - - void main(int argc, char *argv[]) { if (argc != 2) { std::fprintf(stderr, "usage: %s protocol_module\n", argv[0]); @@ -60,9 +55,9 @@ void main(int argc, char *argv[]) { net0->mtu = 1500; net1->mtu = 1500; - std::shared_ptr node1 = std::make_shared(&mmss, "node1", 1, proto); - std::shared_ptr node2 = std::make_shared(&mmss, "node2", 2, proto); - std::shared_ptr node3 = std::make_shared(&mmss, "node3", 3, proto); + std::shared_ptr node1 = node_t::create(&mmss, "node1", 1, proto); + std::shared_ptr node2 = node_t::create(&mmss, "node2", 2, proto); + std::shared_ptr node3 = node_t::create(&mmss, "node3", 3, proto); std::list> nodes; @@ -70,8 +65,6 @@ void main(int argc, char *argv[]) { nodes.push_back(node2); nodes.push_back(node3); - init_nodes(nodes); - gmrf_addr_t addr1 = {{1}}, addr2 = {{2}}, addr3 = {{3}}, addr4 = {{4}}; add_iface(node1, net0, "mmss0", &addr1); add_iface(node2, net0, "mmss0", &addr2); diff --git a/mmss/mmss.hpp b/mmss/mmss.hpp index 2789b24..3931254 100644 --- a/mmss/mmss.hpp +++ b/mmss/mmss.hpp @@ -34,43 +34,6 @@ #include -struct gmrf : public std::enable_shared_from_this { -private: - gmrf(gmrf const&) = delete; - gmrf& operator=(gmrf const&) = delete; - -public: - gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr &proto0) : - mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {} - - MMSS::context_t *mmss; - - std::string name; - - gmrf_context_t *ctx; - std::list> interfaces; - - unsigned rand_seed; - - std::shared_ptr proto; -}; - -struct gmrf_iface : public std::enable_shared_from_this { -private: - gmrf_iface(gmrf_iface const&) = delete; - gmrf_iface& operator=(gmrf_iface const&) = delete; - -public: - gmrf_iface() = default; - - std::string name; - gmrf_addr_t address; - - MMSS::node_t *node; - MMSS::network_t *net; -}; - - namespace MMSS { class context_t : public now_t { diff --git a/mmss/node.hpp b/mmss/node.hpp new file mode 100644 index 0000000..8d95384 --- /dev/null +++ b/mmss/node.hpp @@ -0,0 +1,89 @@ +/* + Copyright (c) 2013, Matthias Schiffer + 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 "iface.hpp" + +#include +#include +#include + + +namespace MMSS { + +class node_t : public ::gmrf, public std::enable_shared_from_this { +private: + node_t(node_t const&) = delete; + node_t& operator=(node_t const&) = delete; + + context_t *mmss; + + std::string name; + + gmrf_context_t *gmrf_ctx; + unsigned rand_seed; + std::shared_ptr proto; + + node_t(context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr &proto0) : + mmss(mmss0), name(name0), gmrf_ctx(nullptr), rand_seed(rand_seed0), proto(proto0) { + } +public: + std::list> interfaces; + + static std::shared_ptr create(context_t *mmss, const std::string &name, unsigned rand_seed, const std::shared_ptr &proto) { + auto node = std::shared_ptr(new node_t(mmss, name, rand_seed, proto)); + node->gmrf_ctx = proto->init(node.get()); + return node; + } + + context_t* get_context() const { + return mmss; + } + + const std::string& get_name() const { + return name; + } + + uint8_t random_byte() { + return rand_r(&rand_seed); + } + + void add_iface(const std::shared_ptr &iface) { + proto->add_iface(this, gmrf_ctx, iface.get()); + } + + void handle_packet(const std::shared_ptr &iface, const gmrf_addr_t *source, const void *data, size_t len) { + proto->handle_packet(this, gmrf_ctx, iface.get(), source, data, len); + } + + void handle_scheduled(gmrf_scheduled_func f, void *arg) { + f(this, gmrf_ctx, arg); + } +}; + +} diff --git a/mmss/types.hpp b/mmss/types.hpp index ca1d290..6c8be97 100644 --- a/mmss/types.hpp +++ b/mmss/types.hpp @@ -37,19 +37,21 @@ extern "C" { } +struct gmrf {}; +struct gmrf_iface {}; + + namespace MMSS { class context_t; class config_t; +class iface_t; class network_t; +class node_t; class now_t; class packet_t; class scheduled_t; typedef ::mmss_protocol_t protocol_t; -typedef ::gmrf_t node_t; -typedef ::gmrf_iface_t iface_t; - - } -- cgit v1.2.3