diff --git a/include/villas/node_type.h b/include/villas/node_type.h index d2f0ff094..b1ee0e51e 100644 --- a/include/villas/node_type.h +++ b/include/villas/node_type.h @@ -37,6 +37,7 @@ extern "C" { #include /* Forward declarations */ +struct super_node; struct node; struct sample; @@ -222,7 +223,7 @@ struct node_type { * * @see node_type::init */ -int node_type_start(struct node_type *vt); +int node_type_start(struct node_type *vt, struct super_node *sn); /** De-initialize node type subsystems. * diff --git a/include/villas/nodes/iec61850.h b/include/villas/nodes/iec61850.h index b580a2084..a5010defb 100644 --- a/include/villas/nodes/iec61850.h +++ b/include/villas/nodes/iec61850.h @@ -101,7 +101,7 @@ struct iec61850_receiver { }; /** @see node_type::type_start */ -int iec61850_type_start(); +int iec61850_type_start(struct super_node *sn); /** @see node_type::type_stop */ int iec61850_type_stop(); diff --git a/include/villas/nodes/mqtt.h b/include/villas/nodes/mqtt.h index 45ca5534a..b93d5828a 100644 --- a/include/villas/nodes/mqtt.h +++ b/include/villas/nodes/mqtt.h @@ -89,7 +89,7 @@ int mqtt_destroy(struct node *n); int mqtt_stop(struct node *n); /** @see node_type::type_start */ -int mqtt_type_start(); +int mqtt_type_start(struct super_node *sn); /** @see node_type::type_stop */ int mqtt_type_stop(); diff --git a/include/villas/nodes/ngsi.h b/include/villas/nodes/ngsi.h index fb20759fb..aae4304fe 100644 --- a/include/villas/nodes/ngsi.h +++ b/include/villas/nodes/ngsi.h @@ -72,7 +72,7 @@ struct ngsi { * * @see node_type::type_start */ -int ngsi_type_start(); +int ngsi_type_start(struct super_node *sn); /** Free global NGSI settings and unmaps shared memory regions. * diff --git a/include/villas/nodes/opal.h b/include/villas/nodes/opal.h index 89c1e7c20..3d7526e0c 100644 --- a/include/villas/nodes/opal.h +++ b/include/villas/nodes/opal.h @@ -60,7 +60,7 @@ struct opal { * * @see node_type::type_start */ -int opal_type_start(); +int opal_type_start(struct super_node *sn); /** Free global OPAL settings and unmaps shared memory regions. * diff --git a/include/villas/nodes/socket.h b/include/villas/nodes/socket.h index 31f038a2e..4a9a9ad51 100644 --- a/include/villas/nodes/socket.h +++ b/include/villas/nodes/socket.h @@ -111,7 +111,7 @@ struct socket { /** @see node_vtable::type_start */ -int socket_type_start(); +int socket_type_start(struct super_node *sn); /** @see node_type::type_stop */ int socket_type_stop(); diff --git a/include/villas/nodes/stats.h b/include/villas/nodes/stats.h index ba5457a3d..91de317d3 100644 --- a/include/villas/nodes/stats.h +++ b/include/villas/nodes/stats.h @@ -40,6 +40,7 @@ extern "C" { /* Forward declarations */ struct node; struct sample; +struct super_node; struct stats_node { double rate; @@ -51,7 +52,7 @@ struct stats_node { }; /** @see node_type::print */ -int stats_node_type_start(); +int stats_node_type_start(struct super_node *sn); /** @see node_type::print */ char *stats_node_print(struct node *n); diff --git a/include/villas/nodes/websocket.h b/include/villas/nodes/websocket.h index 22b2d98c9..77a12bde3 100644 --- a/include/villas/nodes/websocket.h +++ b/include/villas/nodes/websocket.h @@ -96,7 +96,7 @@ struct websocket_destination { int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); /** @see node_type::type_start */ -int websocket_type_start(); /// @todo: Port to C++ +int websocket_type_start(struct super_node *sn); /** @see node_type::type_stop */ int websocket_type_stop(); diff --git a/include/villas/nodes/zeromq.h b/include/villas/nodes/zeromq.h index bc2c47003..dbe15ecc7 100644 --- a/include/villas/nodes/zeromq.h +++ b/include/villas/nodes/zeromq.h @@ -91,7 +91,7 @@ char * zeromq_print(struct node *n); int zeromq_parse(struct node *n, json_t *cfg); /** @see node_type::type_start */ -int zeromq_type_start(); +int zeromq_type_start(struct super_node *sn); /** @see node_type::type_stop */ int zeromq_type_stop(); diff --git a/include/villas/super_node.h b/include/villas/super_node.h new file mode 100644 index 000000000..f8d6f531c --- /dev/null +++ b/include/villas/super_node.h @@ -0,0 +1,37 @@ +/** The super node object holding the state of the application (C-compatability header). + * + * @file + * @author Steffen Vogel + * @copyright 2017-2018, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +struct list; +struct super_node; + +struct list * super_node_get_nodes(struct super_node *sn); + +struct list * super_node_get_nodes(struct super_node *sn); + +struct lws_context * super_node_get_web_context(struct super_node *sn); + +struct lws_vhost * super_node_get_web_vhost(struct super_node *sn); + +enum state super_node_get_web_state(struct super_node *sn); + +int super_node_get_cli_argc(struct super_node *sn); diff --git a/include/villas/web.hpp b/include/villas/web.hpp index f20109ceb..255ab8007 100644 --- a/include/villas/web.hpp +++ b/include/villas/web.hpp @@ -82,6 +82,22 @@ public: return api; } + /* for C-compatability */ + lws_context * getContext() + { + return context; + } + + lws_vhost * getVHost() + { + return vhost; + } + + enum state getState() const + { + return state; + } + void callbackOnWritable(struct lws *wsi); }; diff --git a/lib/node_type.c b/lib/node_type.c index 2ba5914c6..c09a15a73 100644 --- a/lib/node_type.c +++ b/lib/node_type.c @@ -28,7 +28,7 @@ #include #include -int node_type_start(struct node_type *vt) +int node_type_start(struct node_type *vt, struct super_node *sn) { int ret; @@ -37,7 +37,7 @@ int node_type_start(struct node_type *vt) info("Initializing " CLR_YEL("%s") " node type which is used by %zu nodes", node_type_name(vt), list_length(&vt->instances)); - ret = vt->type.start ? vt->type.start() : 0; // @todo: port to C++ + ret = vt->type.start ? vt->type.start(sn) : 0; if (ret == 0) vt->state = STATE_STARTED; diff --git a/lib/nodes/CMakeLists.txt b/lib/nodes/CMakeLists.txt index 13fa3743f..6f625d439 100644 --- a/lib/nodes/CMakeLists.txt +++ b/lib/nodes/CMakeLists.txt @@ -22,8 +22,7 @@ set(NODE_SRC influxdb.c -# @todo: Port to C++ -# stats.c + stats.c signal_generator.c loopback.c ) diff --git a/lib/nodes/iec61850.c b/lib/nodes/iec61850.c index 142a0c303..8dcf789f2 100644 --- a/lib/nodes/iec61850.c +++ b/lib/nodes/iec61850.c @@ -157,7 +157,7 @@ int iec61850_parse_signals(json_t *json_signals, struct list *signals, struct li return total_size; } -int iec61850_type_start() +int iec61850_type_start(struct super_node *sn) { int ret; diff --git a/lib/nodes/mqtt.c b/lib/nodes/mqtt.c index ff0d31fd6..795cbe7e1 100644 --- a/lib/nodes/mqtt.c +++ b/lib/nodes/mqtt.c @@ -346,7 +346,7 @@ int mqtt_stop(struct node *n) return 0; } -int mqtt_type_start() +int mqtt_type_start(struct super_node *sn) { int ret; diff --git a/lib/nodes/ngsi.c b/lib/nodes/ngsi.c index f9ae90340..79031a027 100644 --- a/lib/nodes/ngsi.c +++ b/lib/nodes/ngsi.c @@ -389,7 +389,7 @@ out: json_decref(request); return ret; } -int ngsi_type_start() +int ngsi_type_start(struct super_node *sn) { return curl_global_init(CURL_GLOBAL_ALL); } diff --git a/lib/nodes/opal.c b/lib/nodes/opal.c index fdf62bed9..d9a9a47e2 100644 --- a/lib/nodes/opal.c +++ b/lib/nodes/opal.c @@ -48,7 +48,7 @@ int opal_register_region(int argc, char *argv[]) print_shmem_name = argv[3]; } -int opal_type_start() /// @todo: Port to C++ +int opal_type_start(struct super_node *sn) { int err; diff --git a/lib/nodes/socket.c b/lib/nodes/socket.c index 73eb0e411..fc3958ddb 100644 --- a/lib/nodes/socket.c +++ b/lib/nodes/socket.c @@ -53,7 +53,7 @@ static struct plugin p; /* Private static storage */ struct list interfaces = { .state = STATE_DESTROYED }; -int socket_type_start() +int socket_type_start(struct super_node *sn) { #ifdef WITH_NETEM int ret; @@ -454,7 +454,6 @@ int socket_read(struct node *n, struct sample *smps[], unsigned cnt, unsigned *r } ret = io_sscan(&s->io, ptr, bytes, &rbytes, smps, cnt); - if (ret < 0 || bytes != rbytes) warning("Received invalid packet from node: %s ret=%d, bytes=%zu, rbytes=%zu", node_name(n), ret, bytes, rbytes); diff --git a/lib/nodes/stats.c b/lib/nodes/stats.c index 425ed7f41..a3aab750e 100644 --- a/lib/nodes/stats.c +++ b/lib/nodes/stats.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include #include @@ -89,11 +89,11 @@ static void stats_init_signals(struct node *n) } } -int stats_node_type_start() /// @todo: Port to C++ +int stats_node_type_start(struct super_node *sn) { - nodes = NULL; + nodes = super_node_get_nodes(sn); - return -1; + return 0; } int stats_node_start(struct node *n) diff --git a/lib/nodes/websocket.c b/lib/nodes/websocket.c index 1b6701a70..d5f16fd06 100644 --- a/lib/nodes/websocket.c +++ b/lib/nodes/websocket.c @@ -35,14 +35,16 @@ #include #include #include +#include #define DEFAULT_WEBSOCKET_BUFFER_SIZE (1 << 12) /* Private static storage */ static struct list connections = { .state = STATE_DESTROYED }; /**< List of active libwebsocket connections which receive samples from all nodes (catch all) */ -// TODO: port to C++ +// @todo: port to C++ //static struct web *web; +static struct super_node *sn; /* Forward declarations */ static struct plugin p; @@ -164,8 +166,9 @@ static int websocket_connection_write(struct websocket_connection *c, struct sam debug(LOG_WEBSOCKET | 10, "Enqueued %u samples to %s", pushed, websocket_connection_name(c)); /* Client connections which are currently conecting don't have an associate c->wsi yet */ - if (c->wsi) - web_callback_on_writable(c->wsi); + // @todo: port to C++ + //if (c->wsi) + // web_callback_on_writable(c->wsi); return 0; } @@ -370,17 +373,17 @@ int websocket_protocol_cb(struct lws *wsi, enum lws_callback_reasons reason, voi return 0; } -int websocket_type_start() // @todo: Port to C++ +int websocket_type_start(struct super_node *ssn) { list_init(&connections); //web = NULL; /// @todo: Port to C++ &sn->web; + sn = ssn; - return -1; + info("web state: %d", super_node_get_web_state(sn)); - // @todo: Port to C++ - //if (web->state != STATE_STARTED) - // return -1; + if (super_node_get_web_state(sn) != STATE_STARTED) + return -1; return 0; } @@ -416,9 +419,8 @@ int websocket_start(struct node *n) c->node = n; c->destination = d; - // @todo: Port to C++ - //d->info.context = web->context; - //d->info.vhost = web->vhost; + d->info.context = super_node_get_web_context(sn); + d->info.vhost = super_node_get_web_vhost(sn); d->info.userdata = c; lws_client_connect_via_info(&d->info); diff --git a/lib/nodes/zeromq.c b/lib/nodes/zeromq.c index 0e3c97742..13e2356f1 100644 --- a/lib/nodes/zeromq.c +++ b/lib/nodes/zeromq.c @@ -240,7 +240,7 @@ char * zeromq_print(struct node *n) return buf; } -int zeromq_type_start() /// @todo: Port to C++ +int zeromq_type_start(struct super_node *sn) { context = zmq_ctx_new(); diff --git a/lib/super_node.cpp b/lib/super_node.cpp index c03a91093..cf9a44594 100644 --- a/lib/super_node.cpp +++ b/lib/super_node.cpp @@ -338,7 +338,7 @@ int SuperNode::start() for (size_t i = 0; i < list_length(&nodes); i++) { auto *n = (struct node *) list_at(&nodes, i); - ret = node_type_start(n->_vt);//, this); // @todo: port to C++ + ret = node_type_start(n->_vt, reinterpret_cast(this)); if (ret) throw new RuntimeError("Failed to start node-type: {}", node_type_name(n->_vt)); } @@ -515,3 +515,35 @@ int SuperNode::periodic() #endif return 0; } + + +/* C-compatability */ +extern "C" { + struct list * super_node_get_nodes(struct super_node *sn) + { + SuperNode *ssn = reinterpret_cast(sn); + + return ssn->getNodes(); + } + + struct lws_context * super_node_get_web_context(struct super_node *sn) + { + SuperNode *ssn = reinterpret_cast(sn); + + return ssn->getWeb()->getContext(); + } + + struct lws_vhost * super_node_get_web_vhost(struct super_node *sn) + { + SuperNode *ssn = reinterpret_cast(sn); + + return ssn->getWeb()->getVHost(); + } + + enum state super_node_get_web_state(struct super_node *sn) + { + SuperNode *ssn = reinterpret_cast(sn); + + return ssn->getWeb()->getState(); + } +} diff --git a/src/villas-pipe.cpp b/src/villas-pipe.cpp index f2644a073..84f72afb2 100644 --- a/src/villas-pipe.cpp +++ b/src/villas-pipe.cpp @@ -373,7 +373,7 @@ check: if (optarg == endptr) if (reverse) node_reverse(node); - ret = node_type_start(node->_vt);//, &sn); // @todo: port to C++ + ret = node_type_start(node->_vt, reinterpret_cast(&sn)); if (ret) throw new RuntimeError("Failed to intialize node type {}: reason={}", node_type_name(node->_vt), ret); @@ -419,7 +419,7 @@ check: if (optarg == endptr) if (ret) throw new RuntimeError("Failed to stop node {}: reason={}", node_name(node), ret); - ret = node_type_stop(node->_vt);//, &sn); // @todo: port to C++ + ret = node_type_stop(node->_vt); if (ret) throw new RuntimeError("Failed to stop node type {}: reason={}", node_type_name(node->_vt), ret); diff --git a/src/villas-signal.cpp b/src/villas-signal.cpp index 0ae25d92b..82e9c800d 100644 --- a/src/villas-signal.cpp +++ b/src/villas-signal.cpp @@ -209,7 +209,7 @@ int main(int argc, char *argv[]) } // nt == n._vt - ret = node_type_start(nt); /// @todo: Port to C++ + ret = node_type_start(nt, nullptr); if (ret) throw new RuntimeError("Failed to initialize node type: {}", node_type_name(nt)); diff --git a/src/villas-test-rtt.cpp b/src/villas-test-rtt.cpp index 8991fe708..caf20e169 100644 --- a/src/villas-test-rtt.cpp +++ b/src/villas-test-rtt.cpp @@ -162,7 +162,7 @@ check: if (optarg == endptr) if (!node) throw new RuntimeError("There's no node with the name '{}'", nodestr); - ret = node_type_start(node->_vt);//, &sn); // @todo: port to C++ + ret = node_type_start(node->_vt, reinterpret_cast(&sn)); if (ret) throw new RuntimeError("Failed to start node-type {}: reason={}", node_type_name(node->_vt), ret);