Encapsulate node and interface structures

This commit is contained in:
Matthias Schiffer 2013-07-27 20:34:29 +02:00
parent 08c6bcb98e
commit efabc7a40d
10 changed files with 209 additions and 87 deletions

View file

@ -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));

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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
View 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;
}
};
}

View file

@ -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);

View file

@ -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
View 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);
}
};
}

View file

@ -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;
}