More cleanups
This commit is contained in:
parent
a615e395f2
commit
f706404e6e
11 changed files with 318 additions and 183 deletions
|
@ -5,6 +5,7 @@ BISON_TARGET(mmss_config_parse config.y ${CMAKE_CURRENT_BINARY_DIR}/config.yy.cp
|
||||||
|
|
||||||
add_executable(mmss
|
add_executable(mmss
|
||||||
config.cpp
|
config.cpp
|
||||||
|
gmrf.cpp
|
||||||
iface.cpp
|
iface.cpp
|
||||||
log.cpp
|
log.cpp
|
||||||
mmss.cpp
|
mmss.cpp
|
||||||
|
|
|
@ -40,13 +40,12 @@ namespace Config {
|
||||||
void add_network(context_t *mmss, config_t *conf, const char *name) {
|
void add_network(context_t *mmss, config_t *conf, const char *name) {
|
||||||
logf(mmss, LOG_NOTICE, "adding network `%s'", name);
|
logf(mmss, LOG_NOTICE, "adding network `%s'", name);
|
||||||
|
|
||||||
network_t *net = new network_t;
|
std::shared_ptr<network_t> net = std::make_shared<network_t>();
|
||||||
|
|
||||||
net->name = strdup(name);
|
net->name = name;
|
||||||
net->mtu = 1500;
|
net->mtu = 1500;
|
||||||
|
|
||||||
net->next = conf->networks;
|
conf->network.push_back(net);
|
||||||
conf->networks = net;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
143
mmss/gmrf.cpp
Normal file
143
mmss/gmrf.cpp
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
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 "util.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
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.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t gmrf_iface_get_mtu(gmrf_t *gmrf, gmrf_iface_t *iface) {
|
||||||
|
auto net = iface->net.lock();
|
||||||
|
if (!net)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return net->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->iface.lock();
|
||||||
|
assert(src_iface);
|
||||||
|
|
||||||
|
auto net = src_iface->net.lock();
|
||||||
|
if (!net)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto dest_iface : net->interfaces) {
|
||||||
|
if (gmrf_addr_equal(&dest_iface->address, dest)) {
|
||||||
|
MMSS::enqueue(gmrf->mmss, src_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) {
|
||||||
|
auto src_iface = iface->iface.lock();
|
||||||
|
assert(src_iface);
|
||||||
|
|
||||||
|
auto net = src_iface->net.lock();
|
||||||
|
if (!net)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto dest_iface : net->interfaces) {
|
||||||
|
if (dest_iface != src_iface)
|
||||||
|
MMSS::enqueue(gmrf->mmss, 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->node.lock();
|
||||||
|
assert(node);
|
||||||
|
|
||||||
|
std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
|
||||||
|
|
||||||
|
scheduled->node = node;
|
||||||
|
scheduled->f = f;
|
||||||
|
scheduled->arg = arg;
|
||||||
|
|
||||||
|
gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 inline const char* get_log_prefix(int log_level) {
|
||||||
|
switch(log_level) {
|
||||||
|
case LOG_CRIT:
|
||||||
|
return "Fatal: ";
|
||||||
|
case LOG_ERR:
|
||||||
|
return "Error: ";
|
||||||
|
case LOG_WARNING:
|
||||||
|
return "Warning: ";
|
||||||
|
case LOG_NOTICE:
|
||||||
|
return "Info: ";
|
||||||
|
case LOG_INFO:
|
||||||
|
return "Verbose: ";
|
||||||
|
case LOG_DEBUG:
|
||||||
|
return "DEBUG: ";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
||||||
|
char buf[1024];
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name.c_str(), get_log_prefix(priority));
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
MMSS::logf(gmrf->mmss, priority, "%s", buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -32,29 +32,34 @@
|
||||||
namespace MMSS {
|
namespace MMSS {
|
||||||
|
|
||||||
void dispatch(std::shared_ptr<packet_t> packet) {
|
void dispatch(std::shared_ptr<packet_t> packet) {
|
||||||
packet->dest->node->proto->handle_packet(packet->dest->node, packet->dest->node->ctx, packet->dest,
|
auto source = packet->source.lock();
|
||||||
&packet->source->address, packet->data.get(), packet->len);
|
auto dest = packet->dest.lock();
|
||||||
|
if (!source || !dest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto node = dest->node.lock();
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node->proto->handle_packet(node.get(), node->ctx, dest.get(), &source->address, packet->data.get(), packet->len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address) {
|
void add_iface(std::shared_ptr<node_t> node, std::shared_ptr<network_t> net, const std::string &name, const gmrf_addr_t *address) {
|
||||||
gmrf_iface_t *iface = new gmrf_iface_t;
|
std::shared_ptr<iface_t> iface = iface_t::create();
|
||||||
|
|
||||||
iface->name = strdup(name);
|
iface->name = name;
|
||||||
iface->address = *address;
|
iface->address = *address;
|
||||||
|
|
||||||
iface->node = node;
|
iface->node = node;
|
||||||
iface->net = net;
|
iface->net = net;
|
||||||
|
|
||||||
iface->node_next = node->interfaces;
|
node->interfaces.push_back(iface);
|
||||||
node->interfaces = iface;
|
net->interfaces.push_back(iface);
|
||||||
|
|
||||||
iface->network_next = net->interfaces;
|
node->proto->add_iface(node.get(), node->ctx, iface.get());
|
||||||
net->interfaces = iface;
|
|
||||||
|
|
||||||
node->proto->add_iface(node, node->ctx, iface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enqueue(context_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, const void *data, size_t len) {
|
void enqueue(context_t *mmss, std::shared_ptr<iface_t> source, std::shared_ptr<iface_t> dest, const void *data, size_t len) {
|
||||||
std::shared_ptr<packet_t> packet = std::make_shared<packet_t>();
|
std::shared_ptr<packet_t> packet = std::make_shared<packet_t>();
|
||||||
|
|
||||||
packet->sent = mmss->now;
|
packet->sent = mmss->now;
|
||||||
|
@ -69,38 +74,3 @@ static void enqueue(context_t *mmss, gmrf_iface_t *source, gmrf_iface_t *dest, c
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)) {
|
|
||||||
MMSS::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;
|
|
||||||
}
|
|
||||||
|
|
47
mmss/log.cpp
47
mmss/log.cpp
|
@ -25,41 +25,10 @@
|
||||||
|
|
||||||
|
|
||||||
#include "mmss.hpp"
|
#include "mmss.hpp"
|
||||||
|
#include "util.hpp"
|
||||||
#include <cstdarg>
|
|
||||||
#include <cstdio>
|
|
||||||
|
|
||||||
|
|
||||||
namespace MMSS {
|
namespace MMSS {
|
||||||
|
|
||||||
static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) {
|
|
||||||
std::va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
int ret = std::vsnprintf(buffer, size, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return ret < 0 ? 0 : ret > size ? size : ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const char* get_log_prefix(int log_level) {
|
|
||||||
switch(log_level) {
|
|
||||||
case LOG_CRIT:
|
|
||||||
return "Fatal: ";
|
|
||||||
case LOG_ERR:
|
|
||||||
return "Error: ";
|
|
||||||
case LOG_WARNING:
|
|
||||||
return "Warning: ";
|
|
||||||
case LOG_NOTICE:
|
|
||||||
return "Info: ";
|
|
||||||
case LOG_INFO:
|
|
||||||
return "Verbose: ";
|
|
||||||
case LOG_DEBUG:
|
|
||||||
return "DEBUG: ";
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void logf(context_t *mmss, int priority, const char *format, ...) {
|
void logf(context_t *mmss, int priority, const char *format, ...) {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
@ -75,17 +44,3 @@ void logf(context_t *mmss, int priority, const char *format, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gmrf_logf(gmrf_t *gmrf, int priority, const char *format, ...) {
|
|
||||||
char buf[1024];
|
|
||||||
size_t pos = 0;
|
|
||||||
|
|
||||||
pos += MMSS::snprintf_safe(buf, sizeof(buf), "%s: %s", gmrf->name, MMSS::get_log_prefix(priority));
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, format);
|
|
||||||
vsnprintf(buf+pos, sizeof(buf)-pos, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
MMSS::logf(gmrf->mmss, priority, "%s", buf);
|
|
||||||
}
|
|
||||||
|
|
|
@ -30,25 +30,11 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace MMSS {
|
namespace MMSS {
|
||||||
|
|
||||||
static void init_nodes(gmrf_t *nodes) {
|
static void init_nodes(std::list<std::shared_ptr<node_t>> &nodes) {
|
||||||
gmrf_t *node;
|
for (auto node : nodes)
|
||||||
for (node = nodes; node; node = node->next) {
|
node->ctx = node->proto->init(node.get());
|
||||||
node->ctx = node->proto->init(node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,22 +71,29 @@ void main(int argc, char *argv[]) {
|
||||||
|
|
||||||
read_config(&mmss, &conf, "babel_test.mmss");
|
read_config(&mmss, &conf, "babel_test.mmss");
|
||||||
|
|
||||||
network_t net0 = { .mtu = 1500 }, net1 = { .mtu = 1500 };
|
std::shared_ptr<network_t> net0 = std::make_shared<network_t>();
|
||||||
gmrf_t node1 = { .name = strdup("node1"), .mmss = &mmss, .rand_seed = 1, .proto = proto };
|
std::shared_ptr<network_t> net1 = std::make_shared<network_t>();
|
||||||
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;
|
*net0 = (network_t){ .mtu = 1500 };
|
||||||
node3.next = &node2;
|
*net1 = (network_t){ .mtu = 1500 };
|
||||||
gmrf_t *nodes = &node3;
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
nodes.push_back(node1);
|
||||||
|
nodes.push_back(node2);
|
||||||
|
nodes.push_back(node3);
|
||||||
|
|
||||||
init_nodes(nodes);
|
init_nodes(nodes);
|
||||||
|
|
||||||
gmrf_addr_t addr1 = {{1}}, addr2 = {{2}}, addr3 = {{3}}, addr4 = {{4}};
|
gmrf_addr_t addr1 = {{1}}, addr2 = {{2}}, addr3 = {{3}}, addr4 = {{4}};
|
||||||
add_iface(&node1, &net0, "mmss0", &addr1);
|
add_iface(node1, net0, "mmss0", &addr1);
|
||||||
add_iface(&node2, &net0, "mmss0", &addr2);
|
add_iface(node2, net0, "mmss0", &addr2);
|
||||||
add_iface(&node2, &net1, "mmss1", &addr3);
|
add_iface(node2, net1, "mmss1", &addr3);
|
||||||
add_iface(&node3, &net1, "mmss1", &addr4);
|
add_iface(node3, net1, "mmss1", &addr4);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int timeout = get_queue_timeout(&mmss);
|
int timeout = get_queue_timeout(&mmss);
|
||||||
|
|
112
mmss/mmss.hpp
112
mmss/mmss.hpp
|
@ -29,9 +29,67 @@
|
||||||
|
|
||||||
#include "queue.hpp"
|
#include "queue.hpp"
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
|
struct gmrf {
|
||||||
|
private:
|
||||||
|
gmrf(MMSS::context_t *mmss0, const std::string &name0, unsigned rand_seed0, const MMSS::protocol_t *proto0) :
|
||||||
|
mmss(mmss0), name(name0), rand_seed(rand_seed0), proto(proto0) {}
|
||||||
|
gmrf(gmrf const&) = delete;
|
||||||
|
gmrf& operator=(gmrf const&) = delete;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<MMSS::node_t> create(MMSS::context_t *mmss, const std::string &name, unsigned rand_seed, const MMSS::protocol_t *proto) {
|
||||||
|
MMSS::node_t *node = new MMSS::node_t(mmss, name, rand_seed, proto);
|
||||||
|
|
||||||
|
std::shared_ptr<MMSS::node_t> ptr(node);
|
||||||
|
node->node = ptr;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::weak_ptr<MMSS::node_t> node;
|
||||||
|
|
||||||
|
MMSS::context_t *mmss;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
gmrf_context_t *ctx;
|
||||||
|
std::list<std::shared_ptr<MMSS::iface_t>> interfaces;
|
||||||
|
|
||||||
|
unsigned rand_seed;
|
||||||
|
|
||||||
|
const MMSS::protocol_t *proto;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gmrf_iface {
|
||||||
|
private:
|
||||||
|
gmrf_iface() {}
|
||||||
|
gmrf_iface(gmrf_iface const&) = delete;
|
||||||
|
gmrf_iface& operator=(gmrf_iface const&) = delete;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<MMSS::iface_t> create() {
|
||||||
|
MMSS::iface_t *iface = new MMSS::iface_t;
|
||||||
|
|
||||||
|
std::shared_ptr<MMSS::iface_t> ptr(iface);
|
||||||
|
iface->iface = ptr;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::weak_ptr<MMSS::iface_t> iface;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
gmrf_addr_t address;
|
||||||
|
|
||||||
|
std::weak_ptr<MMSS::node_t> node;
|
||||||
|
std::weak_ptr<MMSS::network_t> net;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace MMSS {
|
namespace MMSS {
|
||||||
|
|
||||||
class context_t {
|
class context_t {
|
||||||
|
@ -45,17 +103,15 @@ public:
|
||||||
|
|
||||||
class config_t {
|
class config_t {
|
||||||
public:
|
public:
|
||||||
network_t *networks;
|
std::list<std::shared_ptr<network_t>> network;
|
||||||
gmrf_t *nodes;
|
std::list<std::shared_ptr<node_t>> nodes;
|
||||||
};
|
};
|
||||||
|
|
||||||
class network_t {
|
class network_t {
|
||||||
public:
|
public:
|
||||||
network_t *next;
|
std::string name;
|
||||||
|
|
||||||
char *name;
|
std::list<std::shared_ptr<iface_t>> interfaces;
|
||||||
|
|
||||||
gmrf_iface_t *interfaces;
|
|
||||||
size_t mtu;
|
size_t mtu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,8 +119,8 @@ class packet_t {
|
||||||
public:
|
public:
|
||||||
uint64_t sent;
|
uint64_t sent;
|
||||||
|
|
||||||
gmrf_iface_t *source;
|
std::weak_ptr<iface_t> source;
|
||||||
gmrf_iface_t *dest;
|
std::weak_ptr<iface_t> dest;
|
||||||
|
|
||||||
size_t len;
|
size_t len;
|
||||||
std::unique_ptr<uint8_t> data;
|
std::unique_ptr<uint8_t> data;
|
||||||
|
@ -72,7 +128,7 @@ public:
|
||||||
|
|
||||||
class scheduled_t {
|
class scheduled_t {
|
||||||
public:
|
public:
|
||||||
gmrf_t *node;
|
std::shared_ptr<node_t> node;
|
||||||
gmrf_scheduled_func f;
|
gmrf_scheduled_func f;
|
||||||
void *arg;
|
void *arg;
|
||||||
};
|
};
|
||||||
|
@ -80,20 +136,15 @@ public:
|
||||||
|
|
||||||
const protocol_t* load_protocol(const char *module);
|
const protocol_t* load_protocol(const char *module);
|
||||||
|
|
||||||
namespace Config {
|
|
||||||
|
|
||||||
void add_network(context_t *mmss, config_t *conf, const char *name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool read_config(context_t *mmss, config_t *conf, const char *filename);
|
bool read_config(context_t *mmss, config_t *conf, const char *filename);
|
||||||
|
|
||||||
void add_iface(gmrf_t *node, network_t *net, const char *name, const gmrf_addr_t *address);
|
void add_iface(std::shared_ptr<node_t> node, std::shared_ptr<network_t> net, const std::string &name, const gmrf_addr_t *address);
|
||||||
|
|
||||||
uint64_t now(const context_t *mmss);
|
uint64_t now(const context_t *mmss);
|
||||||
|
|
||||||
void dispatch(std::shared_ptr<packet_t> packet);
|
void dispatch(std::shared_ptr<packet_t> packet);
|
||||||
void run_scheduled(std::shared_ptr<scheduled_t> scheduled);
|
void run_scheduled(std::shared_ptr<scheduled_t> scheduled);
|
||||||
|
void enqueue(context_t *mmss, std::shared_ptr<iface_t> source, std::shared_ptr<iface_t> dest, const void *data, size_t len);
|
||||||
|
|
||||||
void logf(context_t *mmss, int priority, const char *format, ...);
|
void logf(context_t *mmss, int priority, const char *format, ...);
|
||||||
|
|
||||||
|
@ -111,31 +162,14 @@ static inline size_t alignto(size_t l, size_t a) {
|
||||||
return ((l+a-1)/a)*a;
|
return ((l+a-1)/a)*a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace Config {
|
||||||
|
|
||||||
|
void add_network(context_t *mmss, config_t *conf, const char *name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gmrf {
|
}
|
||||||
gmrf_t *next;
|
|
||||||
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
MMSS::context_t *mmss;
|
|
||||||
gmrf_context_t *ctx;
|
|
||||||
gmrf_iface_t *interfaces;
|
|
||||||
|
|
||||||
unsigned rand_seed;
|
|
||||||
|
|
||||||
const MMSS::protocol_t *proto;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gmrf_iface {
|
|
||||||
gmrf_iface_t *node_next;
|
|
||||||
gmrf_iface_t *network_next;
|
|
||||||
|
|
||||||
char *name;
|
|
||||||
gmrf_addr_t address;
|
|
||||||
|
|
||||||
gmrf_t *node;
|
|
||||||
MMSS::network_t *net;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* _GMRF_MMSS_MMSS_HPP_ */
|
#endif /* _GMRF_MMSS_MMSS_HPP_ */
|
||||||
|
|
|
@ -33,21 +33,21 @@
|
||||||
namespace MMSS {
|
namespace MMSS {
|
||||||
|
|
||||||
const protocol_t* load_protocol(const char *module) {
|
const protocol_t* load_protocol(const char *module) {
|
||||||
void *handle = dlopen(module, RTLD_NOW);
|
void *handle = ::dlopen(module, RTLD_NOW);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
std::fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dlerror();
|
::dlerror();
|
||||||
const protocol_t *proto = reinterpret_cast<const protocol_t*>(dlsym(handle, "mmss_protocol_info"));
|
const protocol_t *proto = reinterpret_cast<const protocol_t*>(::dlsym(handle, "mmss_protocol_info"));
|
||||||
if (!proto) {
|
if (!proto) {
|
||||||
fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
std::fprintf(stderr, "unable to load protocol from `%s': %s\n", module, dlerror());
|
||||||
dlclose(handle);
|
::dlclose(handle);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "loaded protocol `%s' version %s\n", proto->get_name(), proto->get_version());
|
std::fprintf(stderr, "loaded protocol `%s' version %s\n", proto->get_name(), proto->get_version());
|
||||||
|
|
||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,17 +30,7 @@
|
||||||
namespace MMSS {
|
namespace MMSS {
|
||||||
|
|
||||||
void run_scheduled(std::shared_ptr<scheduled_t> scheduled) {
|
void run_scheduled(std::shared_ptr<scheduled_t> scheduled) {
|
||||||
scheduled->f(scheduled->node, scheduled->node->ctx, scheduled->arg);
|
scheduled->f(scheduled->node.get(), scheduled->node->ctx, scheduled->arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gmrf_schedule(gmrf_t *gmrf, gmrf_scheduled_func f, void *arg, unsigned delay) {
|
|
||||||
std::shared_ptr<MMSS::scheduled_t> scheduled = std::make_shared<MMSS::scheduled_t>();
|
|
||||||
|
|
||||||
scheduled->node = gmrf;
|
|
||||||
scheduled->f = f;
|
|
||||||
scheduled->arg = arg;
|
|
||||||
|
|
||||||
gmrf->mmss->scheduled_queue.put(scheduled, gmrf->mmss->now+delay);
|
|
||||||
}
|
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
#include <gmrf/gmrf.h>
|
|
||||||
#include <mmss/protocol.h>
|
#include <mmss/protocol.h>
|
||||||
|
#include <gmrf/gmrf.h>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@ class scheduled_t;
|
||||||
|
|
||||||
typedef ::mmss_protocol_t protocol_t;
|
typedef ::mmss_protocol_t protocol_t;
|
||||||
|
|
||||||
|
typedef ::gmrf_t node_t;
|
||||||
|
typedef ::gmrf_iface_t iface_t;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _GMRF_MMSS_TYPES_HPP_ */
|
#endif /* _GMRF_MMSS_TYPES_HPP_ */
|
||||||
|
|
47
mmss/util.hpp
Normal file
47
mmss/util.hpp
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _GMRF_MMSS_UTIL_HPP_
|
||||||
|
#define _GMRF_MMSS_UTIL_HPP_
|
||||||
|
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
|
||||||
|
namespace MMSS {
|
||||||
|
|
||||||
|
static inline int snprintf_safe(char *buffer, size_t size, const char *format, ...) {
|
||||||
|
std::va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
int ret = std::vsnprintf(buffer, size, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret < 0 ? 0 : ret > size ? size : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _GMRF_MMSS_UTIL_HPP_ */
|
Reference in a new issue