Encapsulate node and interface structures
This commit is contained in:
parent
08c6bcb98e
commit
efabc7a40d
10 changed files with 209 additions and 87 deletions
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
|
||||
class scheduled_t : public event_t {
|
||||
public:
|
||||
std::shared_ptr<node_t> node;
|
||||
std::weak_ptr<node_t> node;
|
||||
gmrf_scheduled_func f;
|
||||
void *arg;
|
||||
|
||||
|
|
|
@ -24,31 +24,33 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "iface.hpp"
|
||||
#include "mmss.hpp"
|
||||
#include "node.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
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_t*>(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_t*>(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_t*>(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_t*>(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<node_t*>(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_t*>(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<node_t*>(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<node_t*>(gmrf);
|
||||
|
||||
std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
|
||||
std::shared_ptr<scheduled_t> scheduled = std::make_shared<scheduled_t>();
|
||||
|
||||
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<node_t*>(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<node_t*>(gmrf)->random_byte();
|
||||
}
|
||||
|
||||
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
||||
node_t *node = static_cast<node_t*>(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);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "iface.hpp"
|
||||
#include "node.hpp"
|
||||
#include "mmss.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
@ -32,25 +34,19 @@
|
|||
namespace MMSS {
|
||||
|
||||
void add_iface(const std::shared_ptr<node_t> &node, const std::shared_ptr<network_t> &net, const std::string &name, const gmrf_addr_t *address) {
|
||||
std::shared_ptr<iface_t> iface = std::make_shared<iface_t>();
|
||||
|
||||
iface->name = name;
|
||||
iface->address = *address;
|
||||
|
||||
iface->node = node.get();
|
||||
iface->net = net.get();
|
||||
std::shared_ptr<iface_t> iface = std::make_shared<iface_t>(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<iface_t> &source, const std::shared_ptr<iface_t> &dest, const void *data, size_t len) {
|
||||
std::shared_ptr<packet_t> packet = std::make_shared<packet_t>();
|
||||
|
||||
packet->sent = mmss->now();
|
||||
packet->source_addr = source->address;
|
||||
packet->source_addr = *source->get_address();
|
||||
packet->dest = dest;
|
||||
packet->len = len;
|
||||
|
||||
|
|
69
mmss/iface.hpp
Normal file
69
mmss/iface.hpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace MMSS {
|
||||
|
||||
class iface_t : public ::gmrf_iface, public std::enable_shared_from_this<iface_t> {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
|
||||
#include "mmss.hpp"
|
||||
#include "node.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
@ -33,12 +34,6 @@
|
|||
|
||||
namespace MMSS {
|
||||
|
||||
static void init_nodes(std::list<std::shared_ptr<node_t>> &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<node_t> node1 = std::make_shared<node_t>(&mmss, "node1", 1, proto);
|
||||
std::shared_ptr<node_t> node2 = std::make_shared<node_t>(&mmss, "node2", 2, proto);
|
||||
std::shared_ptr<node_t> node3 = std::make_shared<node_t>(&mmss, "node3", 3, proto);
|
||||
std::shared_ptr<node_t> node1 = node_t::create(&mmss, "node1", 1, proto);
|
||||
std::shared_ptr<node_t> node2 = node_t::create(&mmss, "node2", 2, proto);
|
||||
std::shared_ptr<node_t> node3 = node_t::create(&mmss, "node3", 3, proto);
|
||||
|
||||
std::list<std::shared_ptr<node_t>> 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);
|
||||
|
|
|
@ -34,43 +34,6 @@
|
|||
#include <memory>
|
||||
|
||||
|
||||
struct gmrf : public std::enable_shared_from_this<MMSS::node_t> {
|
||||
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<const MMSS::protocol_t> &proto0) :
|
||||
mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {}
|
||||
|
||||
MMSS::context_t *mmss;
|
||||
|
||||
std::string name;
|
||||
|
||||
gmrf_context_t *ctx;
|
||||
std::list<std::shared_ptr<MMSS::iface_t>> interfaces;
|
||||
|
||||
unsigned rand_seed;
|
||||
|
||||
std::shared_ptr<const MMSS::protocol_t> proto;
|
||||
};
|
||||
|
||||
struct gmrf_iface : public std::enable_shared_from_this<MMSS::iface_t> {
|
||||
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 {
|
||||
|
|
89
mmss/node.hpp
Normal file
89
mmss/node.hpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "types.hpp"
|
||||
#include "iface.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace MMSS {
|
||||
|
||||
class node_t : public ::gmrf, public std::enable_shared_from_this<node_t> {
|
||||
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<const protocol_t> proto;
|
||||
|
||||
node_t(context_t *mmss0, const std::string &name0, unsigned rand_seed0, const std::shared_ptr<const protocol_t> &proto0) :
|
||||
mmss(mmss0), name(name0), gmrf_ctx(nullptr), rand_seed(rand_seed0), proto(proto0) {
|
||||
}
|
||||
public:
|
||||
std::list<std::shared_ptr<iface_t>> interfaces;
|
||||
|
||||
static std::shared_ptr<node_t> create(context_t *mmss, const std::string &name, unsigned rand_seed, const std::shared_ptr<const protocol_t> &proto) {
|
||||
auto node = std::shared_ptr<node_t>(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_t> &iface) {
|
||||
proto->add_iface(this, gmrf_ctx, iface.get());
|
||||
}
|
||||
|
||||
void handle_packet(const std::shared_ptr<iface_t> &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);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue