1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/node/ synced 2025-03-09 00:00:00 +01:00

drop legacy logger

This commit is contained in:
Steffen Vogel 2021-02-16 14:15:14 +01:00 committed by Steffen Vogel
parent 5f6a28ca11
commit 4f370ee1b2
147 changed files with 1804 additions and 1561 deletions

View file

@ -102,7 +102,7 @@ protected:
avail = shmem_int_alloc(&shm, outsmps, readcnt);
if (avail < readcnt)
logger->warn("Pool underrun: %d / %d\n", avail, readcnt);
logger->warn("Pool underrun: {} / {}", avail, readcnt);
for (int i = 0; i < avail; i++) {
outsmps[i]->sequence = insmps[i]->sequence;

2
common

@ -1 +1 @@
Subproject commit fdf5e6371606f247d5adb17caa701b19f9113ec5
Subproject commit dba712a0e7b2f38fb3a435f0c74c56cbc0024e48

78
etc/Shmem_mqtt.conf Normal file
View file

@ -0,0 +1,78 @@
nodes = {
sig = {
type = "signal1"
signal = "sine"
}
dpsim = {
enabled = false,
type = "shmem",
in = {
name = "/dpsim-villas", # Name of shared memory segment for sending side
hooks = (
{ type = "stats" }
),
signals = {
# count = 2,
# type = "float"
count = 1,
type = "complex"
}
},
out = {
name = "/villas-dpsim" # Name of shared memory segment for receiving side
signals = {
count = 1,
type = "complex"
}
},
queuelen = 1024, # Length of the queues
polling = true, # We can busy-wait or use pthread condition variables for synchronizations
},
broker = {
type = "mqtt",
format = "json",
#host = "localhost",
host = "137.226.133.157"
port = 1883,
retain = false,
out = {
publish = "dpsim->dist"
}
in = {
subscribe = "dist->dpsim",
signals = {
count = 1,
type = "complex"
}
}
}
}
paths = (
{
enabled = false
in = "sig",
out = "broker",
# mode: any/all
# Condition of which/how many source nodes have to receive
# at least one sample for the path to be triggered
mode = "any",
# reverse = true
}
# ,{
# in = "nano";
# out = "dpsim";
# mode = "any"
# }
)

37
etc/demo.json Normal file
View file

@ -0,0 +1,37 @@
{
"hugepages": 0,
"http": {
"htdocs": "/usr/share/villas/node/web"
},
"nodes": {
"sig": {
"type": "signal",
"signal": "mixed",
"values": 5,
"rate": 20
},
"ws_sig": {
"type": "websocket"
},
"ws_lo": {
"type": "websocket"
},
"lo": {
"type": "loopback"
}
},
"paths": [
{
"in": "sig",
"out": "ws_sig"
},
{
"in": "ws_lo",
"out": "lo"
},
{
"in": "lo",
"out": "ws_lo"
}
]
}

View file

@ -1,43 +0,0 @@
/** Test advanced file IO using libcurl.
*
* The syntax of this file is similar to JSON.
* A detailed description of the format can be found here:
* http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files
*
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
* @copyright 2014-2020, 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 <http://www.gnu.org/licenses/>.
*********************************************************************************/
nodes = {
remote_file = {
type = "file",
uri = "https://Q9ZHPBD5eRlZcAi:badpass@rwth-aachen.sciebo.de/public.php/webdav/data/demo_in.dat",
# The output path accepts all format tokens of (see strftime(3))
#uri = "https://Q9ZHPBD5eRlZcAi:badpass@rwth-aachen.sciebo.de/public.php/webdav/data/demo_%y-%m-%d_%H-%M-%S.dat",
out = {
mode = "a+" # You might want to use "a+" to append to a file
}
in = {
rate = 1
}
}
}

View file

@ -0,0 +1,33 @@
logging = {
level = "debug"
}
fpgas = {
vc707 = {
id = "10ee:7022"
do_reset = true
ips = "@include ../etc/examples/nodes/vc707_ips.conf"
}
}
nodes = {
dma_0 = {
type = "fpga",
card = "vc707"
datamover = "dma_0"
use_irqs = false
}
}
paths = (
{
in = "dma_0"
out = [ ]
hooks = (
{ type = "print" }
)
}
)

View file

@ -0,0 +1,253 @@
{
"timer_0_axi_timer_0": {
"vlnv": "xilinx.com:ip:axi_timer:2.0",
"irqs": {
"generateout0": "pcie_0_axi_pcie_intc_0:0"
}
},
"hier_0_axis_data_fifo_1": {
"ports": [
{
"role": "master",
"name": "AXIS",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S04_AXIS"
},
{
"role": "slave",
"name": "AXIS",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M04_AXIS"
}
],
"vlnv": "xilinx.com:ip:axis_data_fifo:2.0"
},
"hier_0_axis_interconnect_0_axis_interconnect_0_xbar": {
"ports": [
{
"role": "slave",
"name": "S00_AXIS",
"target": "hier_0_aurora_axis_0:m_axis"
},
{
"role": "master",
"name": "M00_AXIS",
"target": "hier_0_aurora_axis_0:s_axis"
},
{
"role": "slave",
"name": "S01_AXIS",
"target": "hier_0_axi_dma_axi_dma_0:MM2S"
},
{
"role": "master",
"name": "M01_AXIS",
"target": "hier_0_axi_dma_axi_dma_0:S2MM"
},
{
"role": "slave",
"name": "S02_AXIS",
"target": "hier_0_axi_fifo_mm_s_0:STR_TXD"
},
{
"role": "master",
"name": "M02_AXIS",
"target": "hier_0_axi_fifo_mm_s_0:STR_RXD"
},
{
"role": "slave",
"name": "S03_AXIS",
"target": "hier_0_axis_data_fifo_0:AXIS"
},
{
"role": "master",
"name": "M03_AXIS",
"target": "hier_0_axis_data_fifo_0:AXIS"
},
{
"role": "slave",
"name": "S04_AXIS",
"target": "hier_0_axis_data_fifo_1:AXIS"
},
{
"role": "master",
"name": "M04_AXIS",
"target": "hier_0_axis_data_fifo_1:AXIS"
}
],
"num_ports": 5,
"vlnv": "xilinx.com:ip:axis_switch:1.1"
},
"hier_0_axis_data_fifo_0": {
"ports": [
{
"role": "master",
"name": "AXIS",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S03_AXIS"
},
{
"role": "slave",
"name": "AXIS",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M03_AXIS"
}
],
"vlnv": "xilinx.com:ip:axis_data_fifo:2.0"
},
"hier_0_aurora_axis_0": {
"ports": [
{
"role": "master",
"name": "m_axis",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S00_AXIS"
},
{
"role": "slave",
"name": "s_axis",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M00_AXIS"
}
],
"vlnv": "acs.eonerc.rwth-aachen.de:user:aurora_axis:1.16"
},
"pcie_0_axi_reset_0": {
"vlnv": "xilinx.com:ip:axi_gpio:2.0"
},
"hier_0_axi_fifo_mm_s_0": {
"ports": [
{
"role": "master",
"name": "STR_TXD",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S02_AXIS"
},
{
"role": "slave",
"name": "STR_RXD",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M02_AXIS"
}
],
"vlnv": "xilinx.com:ip:axi_fifo_mm_s:4.2",
"irqs": {
"interrupt": "pcie_0_axi_pcie_intc_0:1"
}
},
"hier_0_axi_dma_axi_dma_0": {
"ports": [
{
"role": "master",
"name": "MM2S",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:S01_AXIS"
},
{
"role": "slave",
"name": "S2MM",
"target": "hier_0_axis_interconnect_0_axis_interconnect_0_xbar:M01_AXIS"
}
],
"vlnv": "xilinx.com:ip:axi_dma:7.1",
"memory-view": {
"M_AXI_MM2S": {
"pcie_0_axi_pcie_0": {
"BAR0": {
"highaddr": 4294967295,
"size": 4294967296,
"baseaddr": 0
}
}
},
"M_AXI_S2MM": {
"pcie_0_axi_pcie_0": {
"BAR0": {
"highaddr": 4294967295,
"size": 4294967296,
"baseaddr": 0
}
}
}
},
"irqs": {
"s2mm_introut": "pcie_0_axi_pcie_intc_0:3",
"mm2s_introut": "pcie_0_axi_pcie_intc_0:2"
}
},
"pcie_0_axi_pcie_intc_0": {
"vlnv": "acs.eonerc.rwth-aachen.de:user:axi_pcie_intc:1.4"
},
"pcie_0_axi_pcie_0": {
"vlnv": "xilinx.com:ip:axi_pcie:2.9",
"memory-view": {
"M_AXI": {
"timer_0_axi_timer_0": {
"Reg": {
"highaddr": 20479,
"size": 4096,
"baseaddr": 16384
}
},
"hier_0_axi_fifo_mm_s_0": {
"Mem0": {
"highaddr": 40959,
"size": 8192,
"baseaddr": 32768
},
"Mem1": {
"highaddr": 57343,
"size": 8192,
"baseaddr": 49152
}
},
"pcie_0_axi_pcie_0": {
"CTL0": {
"highaddr": 536870911,
"size": 268435456,
"baseaddr": 268435456
}
},
"hier_0_aurora_axis_0": {
"reg0": {
"highaddr": 12287,
"size": 4096,
"baseaddr": 8192
}
},
"pcie_0_axi_reset_0": {
"Reg": {
"highaddr": 32767,
"size": 4096,
"baseaddr": 28672
}
},
"hier_0_axis_interconnect_0_axis_interconnect_0_xbar": {
"Reg": {
"highaddr": 24575,
"size": 4096,
"baseaddr": 20480
}
},
"hier_0_axi_dma_axi_dma_0": {
"Reg": {
"highaddr": 16383,
"size": 4096,
"baseaddr": 12288
}
},
"pcie_0_axi_pcie_intc_0": {
"reg0": {
"highaddr": 8191,
"size": 4096,
"baseaddr": 4096
}
}
}
},
"pcie_bars": {
"BAR0": {
"translation": 0
}
},
"axi_bars": {
"BAR0": {
"highaddr": 4294967295,
"size": 4294967296,
"translation": 0,
"baseaddr": 0
}
}
}
}

138
etc/labs/lab17.conf Normal file
View file

@ -0,0 +1,138 @@
nodes = {
rtds_ss1 = {
type = "socket",
layer = "udp",
format = "gtnet.fake"
in = { # Local address, i.e. address of villas instance
address = "134.130.169.31:12000"
signals = (
{ name="trigger", type="integer" },
{ name="if1_tx_phA_dp0_mag", type="float" },
{ name="if1_tx_phA_dp0_phase", type="float" },
{ name="if1_tx_phA_dp1_mag", type="float" },
{ name="if1_tx_phA_dp1_phase", type="float" },
{ name="if1_tx_phA_dp2_mag", type="float" },
{ name="if1_tx_phA_dp2_phase", type="float" },
{ name="if1_tx_phA_dp3_mag", type="float" },
{ name="if1_tx_phA_dp3_phase", type="float" },
{ name="if1_tx_phB_dp0_mag", type="float" },
{ name="if1_tx_phB_dp0_phase", type="float" },
{ name="if1_tx_phB_dp1_mag", type="float" },
{ name="if1_tx_phB_dp1_phase", type="float" },
{ name="if1_tx_phB_dp2_mag", type="float" },
{ name="if1_tx_phB_dp2_phase", type="float" },
{ name="if1_tx_phB_dp3_mag", type="float" },
{ name="if1_tx_phB_dp3_phase", type="float" },
{ name="if1_tx_phC_dp0_mag", type="float" },
{ name="if1_tx_phC_dp0_phase", type="float" },
{ name="if1_tx_phC_dp1_mag", type="float" },
{ name="if1_tx_phC_dp1_phase", type="float" },
{ name="if1_tx_phC_dp2_mag", type="float" },
{ name="if1_tx_phC_dp2_phase", type="float" },
{ name="if1_tx_phC_dp3_mag", type="float" },
{ name="if1_tx_phC_dp3_phase", type="float" }
)
}
out = { # Remote address, i.e. address of GTNET card
address = "134.130.169.97:12000" # GTNET#4 -> Rack5(GPC4)
}
}
rtds_ss2 = {
type = "socket",
layer = "udp",
format = "gtnet.fake"
in = {
# Local address, i.e. address of villas instance
address = "134.130.169.31:12001"
signals = (
{ name="trigger", type="integer" },
{ name="if1_tx_phA_dp0_mag", type="float" },
{ name="if1_tx_phA_dp0_phase", type="float" },
{ name="if1_tx_phA_dp1_mag", type="float" },
{ name="if1_tx_phA_dp1_phase", type="float" },
{ name="if1_tx_phA_dp2_mag", type="float" },
{ name="if1_tx_phA_dp2_phase", type="float" },
{ name="if1_tx_phA_dp3_mag", type="float" },
{ name="if1_tx_phA_dp3_phase", type="float" },
{ name="if1_tx_phB_dp0_mag", type="float" },
{ name="if1_tx_phB_dp0_phase", type="float" },
{ name="if1_tx_phB_dp1_mag", type="float" },
{ name="if1_tx_phB_dp1_phase", type="float" },
{ name="if1_tx_phB_dp2_mag", type="float" },
{ name="if1_tx_phB_dp2_phase", type="float" },
{ name="if1_tx_phB_dp3_mag", type="float" },
{ name="if1_tx_phB_dp3_phase", type="float" },
{ name="if1_tx_phC_dp0_mag", type="float" },
{ name="if1_tx_phC_dp0_phase", type="float" },
{ name="if1_tx_phC_dp1_mag", type="float" },
{ name="if1_tx_phC_dp1_phase", type="float" },
{ name="if1_tx_phC_dp2_mag", type="float" },
{ name="if1_tx_phC_dp2_phase", type="float" },
{ name="if1_tx_phC_dp3_mag", type="float" },
{ name="if1_tx_phC_dp3_phase", type="float" }
)
}
out = {
# Remote address, i.e. address of GTNET card
address = "134.130.169.98:12000" # GTNET#5 -> Rack1(GPC4)
}
}
rtds_ss1_monitoring = {
type = "socket"
layer = "udp"
format = "gtnet.fake"
in = { # Local address, i.e. address of villas instance
address = "134.130.169.31:12002"
signals = (
{ name="orgn_V3phRMSintrf", type="float", unit="V" },
{ name="orgn_Pintrf", type="float", unit="W" },
{ name="orgn_Qintrf", type="float", unit="Var" },
{ name="orgn_Sintrf", type="float", unit="VA" },
{ name="if1_V3phRMS", type="float", unit="V" },
{ name="if1_I3phRMS", type="float", unit="A" },
{ name="if1_P", type="float", unit="W" },
{ name="if1_Q", type="float", unit="Var" },
{ name="if1_S", type="float", unit="VA" }
)
}
out = { # Remote address, i.e. address of GTNET card
address = "134.130.169.97:12000"
}
}
web_monitoring = {
type = "websocket"
destinations = [
"https://villas-new.k8s.eonerc.rwth-aachen.de//ws/relay/lab17"
]
}
}
paths = (
{
in = "rtds_ss1",
out = "rtds_ss2",
reverse = true
},
{
enabled = false,
in = "rtds_ss1_monitoring",
out = "web_monitoring",
reverse = true
}
)

View file

@ -43,6 +43,7 @@ namespace api {
class Request;
class Response;
class StatusRequest;
class RequestFactory;
/** A connection via HTTP REST or WebSockets to issue API requests. */
class Session {
@ -50,7 +51,7 @@ class Session {
public:
friend Request; /**< Requires access to wsi for getting URL args and headers */
friend StatusRequest; /**< Requires access to wsi for context status */
friend RequestFactory;
enum State {
ESTABLISHED,

View file

@ -33,7 +33,6 @@
#include <villas/node/config.h>
#include <villas/log.hpp>
#include <villas/advio.hpp>
namespace villas {
namespace node {
@ -65,9 +64,6 @@ protected:
/** Load configuration from local file. */
FILE * loadFromLocalFile(const std::string &u);
/** Load configuration from a remote URI via advio. */
AFILE * loadFromRemoteFile(const std::string &u);
/** Resolve custom include directives. */
json_t * resolveIncludes(json_t *in);

View file

@ -31,7 +31,7 @@
#include <libconfig.h>
/** Convert a libconfig object to a jansson object */
json_t *config_to_json(config_setting_t *cfg);
json_t *config_to_json(config_setting_t *json);
/** Convert a jansson object into a libconfig object. */
int json_to_config(json_t *json, config_setting_t *parent);

View file

@ -23,6 +23,8 @@
#pragma once
#include <villas/log.hpp>
#include <string>
namespace villas {
@ -35,6 +37,7 @@ protected:
std::string socketName;
bool supressRepeatedWarning;
uint64_t warningCounter;
Logger logger;
public:
Dumper(const std::string &socketNameIn);

View file

@ -72,7 +72,7 @@ protected:
struct vlist signals;
json_t *cfg; /**< A JSON object containing the configuration of the hook. */
json_t *config; /**< A JSON object containing the configuration of the hook. */
public:
Hook(struct vpath *p, struct vnode *n, int fl, int prio, bool en = true);
@ -142,7 +142,7 @@ public:
json_t * getConfig() const
{
return cfg;
return config;
}
bool isEnabled() const

View file

@ -57,7 +57,7 @@ int hook_list_destroy(struct vlist *hs) __attribute__ ((warn_unused_result));
* hooks = [ "print" ]
* }
*/
void hook_list_parse(struct vlist *hs, json_t *cfg, int mask, struct vpath *p, struct vnode *n);
void hook_list_parse(struct vlist *hs, json_t *json, int mask, struct vpath *p, struct vnode *n);
void hook_list_prepare(struct vlist *hs, struct vlist *sigs, int mask, struct vpath *p, struct vnode *n);
@ -75,4 +75,4 @@ void hook_list_stop(struct vlist *hs);
struct vlist * hook_list_get_signals(struct vlist *hs);
json_t * hook_list_to_json(struct vlist *hs);
json_t * hook_list_to_json(struct vlist *hs);

View file

@ -58,7 +58,7 @@ public:
virtual void start();
virtual void parse(json_t *cfg);
virtual void parse(json_t *json);
virtual Hook::Reason process(sample *smp);
};

View file

@ -56,7 +56,7 @@ public:
deadtime = 1.0 / rate;
}
virtual void parse(json_t *cfg);
virtual void parse(json_t *json);
virtual Hook::Reason process(sample *smp);
};

View file

@ -23,7 +23,6 @@
#pragma once
#include <villas/advio.hpp>
#include <villas/common.hpp>
#include <villas/node.h>
#include <villas/signal.h>
@ -43,7 +42,6 @@ enum class IOFlags {
enum class IOMode {
STDIO,
ADVIO,
CUSTOM
};
@ -58,10 +56,7 @@ struct io {
* format::{open,close,eof,rewind} functions and the private
* data in io::_vd.
*/
union {
FILE *std;
AFILE *adv;
} stream;
FILE *stream;
char *buffer;
size_t buflen;

View file

@ -51,12 +51,12 @@ typedef uint32_t tc_hdl_t;
/** Parse network emulator (netem) settings.
*
* @param cfg A jansson object containing the settings.
* @param json A jansson object containing the settings.
* @param[out] ne A pointer to a libnl3 qdisc object where setting will be written to.
* @retval 0 Success. Everything went well.
* @retval <0 Error. Something went wrong.
*/
int netem_parse(struct rtnl_qdisc **ne, json_t *cfg);
int netem_parse(struct rtnl_qdisc **ne, json_t *json);
/** Print network emulator (netem) setting into buffer.
*

View file

@ -107,13 +107,13 @@ int mapping_entry_init(struct mapping_entry *me);
int mapping_entry_destroy(struct mapping_entry *me);
int mapping_entry_parse(struct mapping_entry *me, json_t *cfg);
int mapping_entry_parse(struct mapping_entry *me, json_t *json);
int mapping_entry_parse_str(struct mapping_entry *e, const std::string &str);
int mapping_entry_to_str(const struct mapping_entry *me, unsigned index, char **str);
int mapping_list_parse(struct vlist *ml, json_t *cfg);
int mapping_list_parse(struct vlist *ml, json_t *json);
int mapping_list_prepare(struct vlist *ml, struct vlist *nodes);

View file

@ -40,6 +40,7 @@
#include <villas/queue.h>
#include <villas/common.hpp>
#include <villas/stats.hpp>
#include <villas/log.hpp>
#if defined(LIBNL3_ROUTE_FOUND) && defined(__linux__)
#define WITH_NETEM
@ -63,6 +64,7 @@ struct vnode {
bool enabled;
enum State state;
villas::Logger logger;
char *_name; /**< Singleton: A string used to print to screen. */
char *_name_long; /**< Singleton: A string used to print to screen. */
@ -97,7 +99,7 @@ struct vnode {
struct vnode_type *_vt; /**< Virtual functions (C++ OOP style) */
void *_vd; /**< Virtual data (used by struct vnode::_vt functions) */
json_t *cfg; /**< A JSON object containing the configuration of the node. */
json_t *config; /**< A JSON object containing the configuration of the node. */
};
/** Initialize node with default values */
@ -108,11 +110,11 @@ int node_prepare(struct vnode *n);
/** Parse settings of a node.
*
* @param cfg A JSON object containing the configuration of the node.
* @param json A JSON object containing the configuration of the node.
* @retval 0 Success. Everything went well.
* @retval <0 Error. Something went wrong.
*/
int node_parse(struct vnode *n, json_t *cfg, const uuid_t sn_uuid);
int node_parse(struct vnode *n, json_t *json, const uuid_t sn_uuid);
/** Parse an array or single node and checks if they exist in the "nodes" section.
*
@ -120,14 +122,14 @@ int node_parse(struct vnode *n, json_t *cfg, const uuid_t sn_uuid);
* out = [ "sintef", "scedu" ]
* out = "acs"
*
* @param cfg A JSON array or string. See examples above.
* @param json A JSON array or string. See examples above.
* @param nodes The nodes will be added to this list.
* @param all This list contains all valid nodes.
*/
int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all);
int node_list_parse(struct vlist *list, json_t *json, struct vlist *all);
/** Parse the list of signal definitions. */
int node_parse_signals(struct vlist *list, json_t *cfg);
int node_parse_signals(struct vlist *list, json_t *json);
/** Validate node configuration. */
int node_check(struct vnode *n);

View file

@ -37,8 +37,8 @@
struct vnode;
enum class NodeDir {
IN, /**< VILLASnode is receiving/reading */
OUT /**< VILLASnode is sending/writing */
IN, /**< VILLASnode is receiving/reading */
OUT /**< VILLASnode is sending/writing */
};
struct vnode_direction {
@ -47,19 +47,19 @@ struct vnode_direction {
int enabled;
int builtin; /**< This node should use built-in hooks by default. */
unsigned vectorize; /**< Number of messages to send / recv at once (scatter / gather) */
unsigned vectorize; /**< Number of messages to send / recv at once (scatter / gather) */
struct vlist hooks; /**< List of read / write hooks (struct hook). */
struct vlist signals; /**< Signal description. */
json_t *cfg; /**< A JSON object containing the configuration of the node. */
json_t *config; /**< A JSON object containing the configuration of the node. */
};
int node_direction_init(struct vnode_direction *nd, enum NodeDir dir, struct vnode *n) __attribute__ ((warn_unused_result));
int node_direction_destroy(struct vnode_direction *nd, struct vnode *n) __attribute__ ((warn_unused_result));
int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cfg);
int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *json);
int node_direction_check(struct vnode_direction *nd, struct vnode *n);

View file

@ -31,6 +31,7 @@
#include <villas/list.h>
#include <villas/common.hpp>
#include <villas/memory.h>
#include <villas/log.hpp>
/* Forward declarations */
struct vnode;
@ -103,11 +104,11 @@ struct vnode_type {
* This callback is optional. It will only be called if non-null.
*
* @param n A pointer to the node object.
* @param cfg A JSON object containing the configuration of the node.
* @param json A JSON object containing the configuration of the node.
* @retval 0 Success. Everything went well.
* @retval <0 Error. Something went wrong.
*/
int (*parse)(struct vnode *n, json_t *cfg);
int (*parse)(struct vnode *n, json_t *json);
/** Check the current node configuration for plausability and errors.
*

View file

@ -64,7 +64,7 @@ int can_init(struct vnode *n);
int can_destroy(struct vnode *n);
/** @see node_type::parse */
int can_parse(struct vnode *n, json_t *cfg);
int can_parse(struct vnode *n, json_t *json);
/** @see node_type::print */
char * can_print(struct vnode *n);

View file

@ -84,7 +84,7 @@ struct comedi {
char * comedi_print(struct vnode *n);
/** @see node_type::parse */
int comedi_parse(struct vnode *n, json_t *cfg);
int comedi_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int comedi_start(struct vnode *n);

View file

@ -94,7 +94,7 @@ int ethercat_init(struct vnode *n);
int ethercat_destroy(struct vnode *n);
/** @see node_type::parse */
int ethercat_parse(struct vnode *n, json_t *cfg);
int ethercat_parse(struct vnode *n, json_t *json);
/** @see node_type::check */
int ethercat_check(struct vnode *n);

View file

@ -58,7 +58,7 @@ int example_init(struct vnode *n);
int example_destroy(struct vnode *n);
/** @see node_type::parse */
int example_parse(struct vnode *n, json_t *cfg);
int example_parse(struct vnode *n, json_t *json);
/** @see node_type::print */
char * example_print(struct vnode *n);

View file

@ -57,7 +57,7 @@ struct exec {
char * exec_print(struct vnode *n);
/** @see node_type::parse */
int exec_parse(struct vnode *n, json_t *cfg);
int exec_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int exec_open(struct vnode *n);

View file

@ -73,7 +73,7 @@ struct file {
char * file_print(struct vnode *n);
/** @see node_type::parse */
int file_parse(struct vnode *n, json_t *cfg);
int file_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int file_start(struct vnode *n);

View file

@ -77,7 +77,7 @@ int fpga_init(struct vnode *n);
int fpga_destroy(struct vnode *n);
/** @see node_type::parse */
int fpga_parse(struct vnode *n, json_t *cfg);
int fpga_parse(struct vnode *n, json_t *json);
/** @see node_type::print */
char * fpga_print(struct vnode *n);

View file

@ -116,7 +116,7 @@ int ib_reverse(struct vnode *n);
char * ib_print(struct vnode *n);
/** @see node_type::parse */
int ib_parse(struct vnode *n, json_t *cfg);
int ib_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int ib_start(struct vnode *n);

View file

@ -52,7 +52,7 @@ struct influxdb {
char * influxdb_print(struct vnode *n);
/** @see node_type::parse */
int influxdb_parse(struct vnode *n, json_t *cfg);
int influxdb_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int influxdb_open(struct vnode *n);

View file

@ -49,7 +49,7 @@ struct loopback {
char * loopback_print(struct vnode *n);
/** @see node_type::parse */
int loopback_parse(struct vnode *n, json_t *cfg);
int loopback_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int loopback_open(struct vnode *n);

View file

@ -76,7 +76,7 @@ char * mqtt_print(struct vnode *n);
int mqtt_prepare(struct vnode *n);
/** @see node_type::parse */
int mqtt_parse(struct vnode *n, json_t *cfg);
int mqtt_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int mqtt_start(struct vnode *n);

View file

@ -53,7 +53,7 @@ struct nanomsg {
char * nanomsg_print(struct vnode *n);
/** @see node_type::parse */
int nanomsg_parse(struct vnode *n, json_t *cfg);
int nanomsg_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int nanomsg_start(struct vnode *n);

View file

@ -81,7 +81,7 @@ int ngsi_type_start(villas::node::SuperNode *sn);
int ngsi_type_stop();
/** @see node_type::parse */
int ngsi_parse(struct vnode *n, json_t *cfg);
int ngsi_parse(struct vnode *n, json_t *json);
/** @see node_type::print */
char * ngsi_print(struct vnode *n);

View file

@ -65,7 +65,7 @@ int opal_register_region(int argc, char *argv[]);
int opal_type_stop();
/** @see node_type::parse */
int opal_parse(struct vnode *n, json_t *cfg);
int opal_parse(struct vnode *n, json_t *json);
/** @see node_type::print */
char * opal_print(struct vnode *n);

View file

@ -64,8 +64,6 @@ enum class RTPHookType {
struct rtp {
struct rtp_sock *rs; /**< RTP socket */
villas::Logger logger;
struct {
struct sa saddr_rtp; /**< Local/Remote address of the RTP socket */
struct sa saddr_rtcp; /**< Local/Remote address of the RTCP socket */
@ -109,7 +107,7 @@ struct rtp {
char * rtp_print(struct vnode *n);
/** @see node_type::parse */
int rtp_parse(struct vnode *n, json_t *cfg);
int rtp_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int rtp_start(struct vnode *n);

View file

@ -51,7 +51,7 @@ struct shmem {
char * shmem_print(struct vnode *n);
/** @see node_type::parse */
int shmem_parse(struct vnode *n, json_t *cfg);
int shmem_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int shmem_start(struct vnode *n);

View file

@ -80,7 +80,7 @@ struct signal_generator {
char * signal_generator_print(struct vnode *n);
/** @see node_type::parse */
int signal_generator_parse(struct vnode *n, json_t *cfg);
int signal_generator_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int signal_generator_start(struct vnode *n);

View file

@ -84,7 +84,7 @@ int socket_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
int socket_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *release);
/** @see node_type::parse */
int socket_parse(struct vnode *n, json_t *cfg);
int socket_parse(struct vnode *n, json_t *json);
/** @see node_type::print */
char * socket_print(struct vnode *n);

View file

@ -59,9 +59,9 @@ int stats_node_type_start(villas::node::SuperNode *sn);
char *stats_node_print(struct vnode *n);
/** @see node_type::parse */
int stats_node_parse(struct vnode *n, json_t *cfg);
int stats_node_parse(struct vnode *n, json_t *json);
int stats_node_parse_signal(struct stats_node_signal *s, json_t *cfg);
int stats_node_parse_signal(struct stats_node_signal *s, json_t *json);
/** @see node_type::start */
int stats_node_start(struct vnode *n);

View file

@ -45,6 +45,8 @@ struct test_rtt_case {
char *filename;
char *filename_formatted;
struct vnode *node;
};
struct test_rtt {
@ -67,7 +69,7 @@ struct test_rtt {
char * test_rtt_print(struct vnode *n);
/** @see node_type::parse */
int test_rtt_parse(struct vnode *n, json_t *cfg);
int test_rtt_parse(struct vnode *n, json_t *json);
/** @see node_type::start */
int test_rtt_start(struct vnode *n);

View file

@ -78,7 +78,7 @@ struct zeromq {
char * zeromq_print(struct vnode *n);
/** @see node_type::parse */
int zeromq_parse(struct vnode *n, json_t *cfg);
int zeromq_parse(struct vnode *n, json_t *json);
/** @see node_type::type_start */
int zeromq_type_start(villas::node::SuperNode *sn);

View file

@ -90,7 +90,7 @@ struct vpath {
char *_name; /**< Singleton: A string which is used to print this path to screen. */
pthread_t tid; /**< The thread id for this path. */
json_t *cfg; /**< A JSON object containing the configuration of the path. */
json_t *config; /**< A JSON object containing the configuration of the path. */
villas::Logger logger;
@ -151,13 +151,13 @@ int path_reverse(struct vpath *p, struct vpath *r);
/** Parse a single path and add it to the global configuration.
*
* @param cfg A JSON object containing the configuration of the path.
* @param json A JSON object containing the configuration of the path.
* @param p Pointer to the allocated memory for this path
* @param nodes A linked list of all existing nodes
* @retval 0 Success. Everything went well.
* @retval <0 Error. Something went wrong.
*/
int path_parse(struct vpath *p, json_t *cfg, struct vlist *nodes, const uuid_t sn_uuid);
int path_parse(struct vpath *p, json_t *json, struct vlist *nodes, const uuid_t sn_uuid);
void path_parse_mask(struct vpath *p, json_t *json_mask, struct vlist *nodes);

View file

@ -30,6 +30,7 @@
#include <cstdio>
#include <ctime>
#include <villas/log.hpp>
#include <villas/signal.h>
/* Forward declarations */
@ -122,7 +123,7 @@ int sample_decref(struct sample *s);
int sample_copy(struct sample *dst, struct sample *src);
/** Dump all details about a sample to debug log */
void sample_dump(struct sample *s);
void sample_dump(villas::Logger logger, struct sample *s);
/** Compare two samples */
int sample_cmp(struct sample *a, struct sample *b, double epsilon, int flags);

View file

@ -76,7 +76,7 @@ int signal_decref(struct signal *s);
struct signal * signal_copy(struct signal *s);
/** Parse signal description. */
int signal_parse(struct signal *s, json_t *cfg);
int signal_parse(struct signal *s, json_t *json);
/** Initialize signal from a mapping_entry. */
int signal_init_from_mapping(struct signal *s, const struct mapping_entry *me, unsigned index);

View file

@ -67,7 +67,7 @@ int signal_data_print_str(const union signal_data *data, enum SignalType type, c
int signal_data_parse_str(union signal_data *data, enum SignalType type, const char *ptr, char **end);
int signal_data_parse_json(union signal_data *data, enum SignalType type, json_t *cfg);
int signal_data_parse_json(union signal_data *data, enum SignalType type, json_t *json);
json_t * signal_data_to_json(union signal_data *data, enum SignalType type);

View file

@ -25,6 +25,7 @@
#include <jansson.h>
#include <villas/log.hpp>
#include <villas/signal_type.h>
/* Forward declarations */
@ -36,13 +37,13 @@ int signal_list_destroy(struct vlist *list) __attribute__ ((warn_unused_result))
int signal_list_clear(struct vlist *list);
int signal_list_parse(struct vlist *list, json_t *cfg);
int signal_list_parse(struct vlist *list, json_t *json);
int signal_list_generate(struct vlist *list, unsigned len, enum SignalType fmt);
int signal_list_generate2(struct vlist *list, const char *dt);
void signal_list_dump(const struct vlist *list, const union signal_data *data = nullptr, unsigned len = 0);
void signal_list_dump(villas::Logger logger, const struct vlist *list, const union signal_data *data = nullptr, unsigned len = 0);
int signal_list_copy(struct vlist *dst, const struct vlist *src);

View file

@ -34,6 +34,7 @@
#include <villas/hist.hpp>
#include <villas/table.hpp>
#include <villas/signal.h>
#include <villas/log.hpp>
/* Forward declarations */
struct sample;
@ -94,6 +95,8 @@ protected:
static void setupTable();
Logger logger;
public:
Stats(int buckets, int warmup);

View file

@ -97,9 +97,9 @@ public:
/** Parse super-node configuration.
*
* @param cfg A libjansson object which contains the configuration.
* @param json A libjansson object which contains the configuration.
*/
void parse(json_t *cfg);
void parse(json_t *json);
/** Check validity of super node configuration. */
void check();
@ -199,6 +199,11 @@ public:
return affinity;
}
Logger getLogger()
{
return logger;
}
/** Destroy configuration object. */
~SuperNode();
};

View file

@ -75,7 +75,7 @@ public:
void stop();
/** Parse HTTPd and WebSocket related options */
int parse(json_t *cfg);
int parse(json_t *json);
Api * getApi()
{

View file

@ -43,7 +43,7 @@ Request::toString()
Request * RequestFactory::create(Session *s, const std::string &uri, Session::Method meth, unsigned long ct)
{
info("api: Trying to find request handler for: uri=%s", uri.c_str());
s->logger->info("Trying to find request handler for: uri={}", uri);
for (auto *rf : plugin::Registry::lookup<RequestFactory>()) {
std::smatch mr;

View file

@ -36,7 +36,7 @@ public:
virtual Response * execute()
{
json_t *cfg = session->getSuperNode()->getConfig();
json_t *json = session->getSuperNode()->getConfig();
if (method != Session::Method::GET)
throw InvalidMethod(this);
@ -44,8 +44,8 @@ public:
if (body != nullptr)
throw BadRequest("Config endpoint does not accept any body data");
auto *json_config = cfg
? json_incref(cfg)
auto *json_config = json
? json_incref(json)
: json_object();
return new JsonResponse(session, HTTP_STATUS_OK, json_config);

View file

@ -22,7 +22,6 @@
#include <jansson.h>
#include <villas/log.h>
#include <villas/node.h>
#include <villas/stats.hpp>
#include <villas/super_node.hpp>

View file

@ -22,7 +22,6 @@
#include <jansson.h>
#include <villas/log.h>
#include <villas/node.h>
#include <villas/stats.hpp>
#include <villas/super_node.hpp>

View file

@ -98,7 +98,7 @@ public:
else /* If no config is provided via request, we will use the previous one */
configUri = session->getSuperNode()->getConfigUri();
logger->info("Restarting to {}", configUri.c_str());
logger->info("Restarting to {}", configUri);
/* Increment API restart counter */
char *scnt = getenv("VILLAS_API_RESTART_COUNT");

View file

@ -75,23 +75,15 @@ json_t * Config::load(std::FILE *f, bool resolveInc, bool resolveEnvVars)
json_t * Config::load(const std::string &u, bool resolveInc, bool resolveEnvVars)
{
FILE *f;
AFILE *af = nullptr;
if (u == "-")
f = loadFromStdio();
else if (isLocalFile(u))
else
f = loadFromLocalFile(u);
else {
af = loadFromRemoteFile(u);
f = af->file;
}
json_t *root = load(f, resolveInc, resolveEnvVars);
if (af)
afclose(af);
else
fclose(f);
fclose(f);
return root;
}
@ -114,17 +106,6 @@ FILE * Config::loadFromLocalFile(const std::string &u)
return f;
}
AFILE * Config::loadFromRemoteFile(const std::string &u)
{
logger->info("Reading configuration from remote URI: {}", u);
AFILE *f = afopen(u.c_str(), "r");
if (!f)
throw RuntimeError("Failed to open configuration from: {}", u);
return f;
}
json_t * Config::decode(FILE *f)
{
json_error_t err;

View file

@ -29,7 +29,6 @@
#include <cstring>
#include <villas/dumper.hpp>
#include <villas/log.h>
using namespace villas;
using namespace villas::node;
@ -37,7 +36,8 @@ using namespace villas::node;
Dumper::Dumper(const std::string &socketNameIn) :
socketName(socketNameIn),
supressRepeatedWarning(true),
warningCounter(0)
warningCounter(0),
logger(logging.get("dumper"))
{
openSocket();
}
@ -50,7 +50,7 @@ int Dumper::openSocket()
{
socketFd = socket(AF_LOCAL, SOCK_STREAM, 0);
if (socketFd < 0) {
info("Error creating socket %s", socketName.c_str());
logger->info("Error creating socket {}", socketName);
return -1;
}
@ -89,7 +89,7 @@ void Dumper::writeData(unsigned len, double *yData, double *xData)
auto str = ss.str();
auto bytesWritten = write(socketFd, str.c_str(), str.length());
if ((long unsigned int) bytesWritten != str.length() && (!supressRepeatedWarning || warningCounter <1 )) {
warning("Could not send all content to socket %s", socketName.c_str());
logger->warn("Could not send all content to socket {}", socketName);
warningCounter++;
}
}

View file

@ -26,6 +26,9 @@
#include <villas/signal.h>
#include <villas/io.h>
#include <villas/formats/json.h>
#include <villas/exceptions.hpp>
using namespace villas;
static enum SignalType json_detect_format(json_t *val)
{
@ -203,11 +206,9 @@ static int json_unpack_sample(struct io *io, json_t *json_smp, struct sample *sm
return -1;
enum SignalType fmt = json_detect_format(json_value);
if (sig->type != fmt) {
error("Received invalid data type in JSON payload: Received %s, expected %s for signal %s (index %zu).",
if (sig->type != fmt)
throw RuntimeError("Received invalid data type in JSON payload: Received {}, expected {} for signal {} (index {}).",
signal_type_to_str(fmt), signal_type_to_str(sig->type), sig->name, i);
return -2;
}
ret = signal_data_parse_json(&smp->data[i], sig->type, json_value);
if (ret)

View file

@ -178,10 +178,8 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s
smp->flags = 0;
smp->signals = io->signals;
if (pb_smp->type != VILLAS__NODE__SAMPLE__TYPE__DATA) {
warning("Parsed non supported message type. Skipping");
continue;
}
if (pb_smp->type != VILLAS__NODE__SAMPLE__TYPE__DATA)
throw RuntimeError("Parsed non supported message type. Skipping");
if (pb_smp->has_sequence) {
smp->flags |= (int) SampleFlags::HAS_SEQUENCE;
@ -203,11 +201,9 @@ int protobuf_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, s
if (!sig)
return -1;
if (sig->type != fmt) {
error("Received invalid data type in Protobuf payload: Received %s, expected %s for signal %s (index %u).",
if (sig->type != fmt)
throw RuntimeError("Received invalid data type in Protobuf payload: Received {}, expected {} for signal {} (index {}).",
signal_type_to_str(fmt), signal_type_to_str(sig->type), sig->name, i);
return -2;
}
switch (sig->type) {
case SignalType::FLOAT:

View file

@ -56,7 +56,7 @@ int raw_sprint(struct io *io, char *buf, size_t len, size_t *wbytes, struct samp
int o = 0;
size_t nlen;
void *vbuf = (char *) buf; // avoid warning about invalid pointer cast
void *vbuf = (char *) buf; /* Avoid warning about invalid pointer cast */
int8_t *i8 = (int8_t *) vbuf;
int16_t *i16 = (int16_t *) vbuf;
@ -249,7 +249,7 @@ out: if (wbytes)
int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt)
{
void *vbuf = (void *) buf; // avoid warning about invalid pointer cast
void *vbuf = (void *) buf; /* Avoid warning about invalid pointer cast */
int8_t *i8 = (int8_t *) vbuf;
int16_t *i16 = (int16_t *) vbuf;
@ -272,16 +272,12 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct
if (cnt > 1)
return -1;
if (len % (bits / 8)) {
warning("Invalid RAW Payload length: %#zx", len);
return -1;
}
if (len % (bits / 8))
return -1; /* Invalid RAW Payload length */
if (io->flags & RAW_FAKE_HEADER) {
if (nlen < o + 3) {
warning("Received a packet with no fake header. Skipping...");
return -1;
}
if (nlen < o + 3)
return -1; /* Received a packet with no fake header. Skipping... */
switch (bits) {
case 8:
@ -397,17 +393,14 @@ int raw_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct
break;
case SignalType::INVALID:
warning("Unsupported format in RAW payload");
return -1;
return -1; /* Unsupported format in RAW payload */
}
}
smp->length = i;
if (smp->length > smp->capacity) {
warning("Received more values than supported: length=%u, capacity=%u", smp->length, smp->capacity);
smp->length = smp->capacity;
}
if (smp->length > smp->capacity)
smp->length = smp->capacity; /* Received more values than supported */
if (rbytes)
*rbytes = o * (bits / 8);

View file

@ -68,10 +68,8 @@ int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbyt
unsigned i = 0;
const char *ptr = buf;
if (len % 4 != 0) {
warning("Packet size is invalid: %zd Must be multiple of 4 bytes.", len);
return -1;
}
if (len % 4 != 0)
return -1; /* Packet size is invalid: Must be multiple of 4 bytes */
for (i = 0; i < cnt; i++) {
struct msg *msg = (struct msg *) ptr;
@ -84,18 +82,14 @@ int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbyt
break;
/* Check if header is still in buffer bounaries */
if (ptr + sizeof(struct msg) > buf + len) {
warning("Invalid msg received: reason=1");
break;
}
if (ptr + sizeof(struct msg) > buf + len)
return -2; /* Invalid msg received */
values = (io->flags & VILLAS_BINARY_WEB) ? msg->length : ntohs(msg->length);
/* Check if remainder of message is in buffer boundaries */
if (ptr + MSG_LEN(values) > buf + len) {
warning("Invalid msg received: reason=2, msglen=%zu, len=%zu, ptr=%p, buf=%p, i=%u", MSG_LEN(values), len, ptr, buf, i);
break;
}
if (ptr + MSG_LEN(values) > buf + len)
return -3; /*Invalid msg receive */
if (io->flags & VILLAS_BINARY_WEB) {
/** @todo convert from little endian */
@ -104,10 +98,8 @@ int villas_binary_sscan(struct io *io, const char *buf, size_t len, size_t *rbyt
msg_ntoh(msg);
ret = msg_to_sample(msg, smp, io->signals);
if (ret) {
warning("Invalid msg received: reason=3, ret=%d", ret);
break;
}
if (ret)
return ret; /* Invalid msg received */
ptr += MSG_LEN(smp->length);
}

View file

@ -46,7 +46,7 @@ Hook::Hook(struct vpath *p, struct vnode *n, int fl, int prio, bool en) :
enabled(en),
path(p),
node(n),
cfg(nullptr)
config(nullptr)
{
int ret;
@ -80,21 +80,21 @@ void Hook::prepare(struct vlist *sigs)
state = State::PREPARED;
}
void Hook::parse(json_t *c)
void Hook::parse(json_t *json)
{
int ret;
json_error_t err;
assert(state != State::STARTED);
ret = json_unpack_ex(c, &err, 0, "{ s?: i, s?: b }",
ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?: b }",
"priority", &priority,
"enabled", &enabled
);
if (ret)
throw ConfigError(c, err, "node-config-hook");
throw ConfigError(json, err, "node-config-hook");
cfg = c;
config = json;
state = State::PARSED;
}

View file

@ -25,12 +25,11 @@
#include <villas/hook_list.hpp>
#include <villas/list.h>
#include <villas/sample.h>
#include <villas/log.h>
using namespace villas;
using namespace villas::node;
int hook_list_init(vlist *hs)
int hook_list_init(struct vlist *hs)
{
int ret;
@ -48,7 +47,7 @@ static int hook_destroy(Hook *h)
return 0;
}
int hook_list_destroy(vlist *hs)
int hook_list_destroy(struct vlist *hs)
{
int ret;
@ -59,14 +58,14 @@ int hook_list_destroy(vlist *hs)
return 0;
}
void hook_list_parse(vlist *hs, json_t *cfg, int mask, struct vpath *o, struct vnode *n)
void hook_list_parse(struct vlist *hs, json_t *json, int mask, struct vpath *o, struct vnode *n)
{
if (!json_is_array(cfg))
throw ConfigError(cfg, "node-config-hook", "Hooks must be configured as a list of hook objects");
if (!json_is_array(json))
throw ConfigError(json, "node-config-hook", "Hooks must be configured as a list of hook objects");
size_t i;
json_t *json_hook;
json_array_foreach(cfg, i, json_hook) {
json_array_foreach(json, i, json_hook) {
int ret;
const char *type;
Hook *h;
@ -101,7 +100,7 @@ static int hook_is_enabled(const Hook *h)
return h->isEnabled() ? 0 : -1;
}
void hook_list_prepare(vlist *hs, vlist *sigs, int m, struct vpath *p, struct vnode *n)
void hook_list_prepare(struct vlist *hs, vlist *sigs, int m, struct vpath *p, struct vnode *n)
{
assert(hs->state == State::INITIALIZED);
@ -131,11 +130,12 @@ skip_add:
sigs = h->getSignals();
signal_list_dump(sigs);
auto logger = logging.get("hook");
signal_list_dump(logger, sigs);
}
}
int hook_list_process(vlist *hs, sample *smps[], unsigned cnt)
int hook_list_process(struct vlist *hs, struct sample *smps[], unsigned cnt)
{
unsigned current, processed = 0;
@ -172,7 +172,7 @@ skip: {}
stop: return processed;
}
void hook_list_periodic(vlist *hs)
void hook_list_periodic(struct vlist *hs)
{
for (size_t j = 0; j < vlist_length(hs); j++) {
Hook *h = (Hook *) vlist_at(hs, j);
@ -181,7 +181,7 @@ void hook_list_periodic(vlist *hs)
}
}
void hook_list_start(vlist *hs)
void hook_list_start(struct vlist *hs)
{
for (size_t i = 0; i < vlist_length(hs); i++) {
Hook *h = (Hook *) vlist_at(hs, i);
@ -190,7 +190,7 @@ void hook_list_start(vlist *hs)
}
}
void hook_list_stop(vlist *hs)
void hook_list_stop(struct vlist *hs)
{
for (size_t i = 0; i < vlist_length(hs); i++) {
Hook *h = (Hook *) vlist_at(hs, i);
@ -199,14 +199,14 @@ void hook_list_stop(vlist *hs)
}
}
vlist * hook_list_get_signals(vlist *hs)
struct vlist * hook_list_get_signals(struct vlist *hs)
{
Hook *h = (Hook *) vlist_last(hs);
return h->getSignals();
}
json_t * hook_list_to_json(vlist *hs)
json_t * hook_list_to_json(struct vlist *hs)
{
json_t *json_hooks = json_array();
@ -217,4 +217,4 @@ json_t * hook_list_to_json(vlist *hs)
}
return json_hooks;
}
}

View file

@ -98,7 +98,7 @@ public:
state = State::PREPARED;
}
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
size_t i;
@ -107,14 +107,14 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s: o }",
ret = json_unpack_ex(json, &err, 0, "{ s: i, s: o }",
"offset", &offset,
"signals", &json_signals
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-average");
throw ConfigError(json, err, "node-config-hook-average");
if (!json_is_array(json_signals))
throw ConfigError(json_signals, "node-config-hook-average-signals", "Setting 'signals' must be a list of signal names");

View file

@ -96,7 +96,7 @@ public:
state = State::PREPARED;
}
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
@ -105,20 +105,20 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
const char *name = nullptr;
const char *unit = nullptr;
const char *type = nullptr;
ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: s, s?: s, s?: s }",
ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: s, s?: s, s?: s }",
"signal", &json_signal,
"new_type", &type,
"new_name", &name,
"new_unit", &unit
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-cast");
throw ConfigError(json, err, "node-config-hook-cast");
switch (json_typeof(json_signal)) {
case JSON_STRING:

View file

@ -38,20 +38,20 @@ void DecimateHook::start()
state = State::STARTED;
}
void DecimateHook::parse(json_t *cfg)
void DecimateHook::parse(json_t *json)
{
int ret;
json_error_t err;
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: i }",
ret = json_unpack_ex(json, &err, 0, "{ s: i }",
"ratio", &ratio
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-decimate");
throw ConfigError(json, err, "node-config-hook-decimate");
state = State::PARSED;
}

View file

@ -235,13 +235,13 @@ public:
signalIndex.push_back(idx);
}
else
warning("Could not parse channel list. Please check documentation for syntax");
logger->warn("Could not parse channel list. Please check documentation for syntax");
}
else
throw ConfigError(jsonChannelList, "node-config-node-signal", "No parameter signalIndex given.");
if (!windowTypeC) {
info("No Window type given, assume no windowing");
logger->info("No Window type given, assume no windowing");
windowType = WindowType::NONE;
}
else if (strcmp(windowTypeC, "flattop") == 0)
@ -251,18 +251,18 @@ public:
else if (strcmp(windowTypeC, "hann") == 0)
windowType = WindowType::HANN;
else {
info("Window type %s not recognized, assume no windowing", windowTypeC);
logger->info("Window type {} not recognized, assume no windowing", windowTypeC);
windowType = WindowType::NONE;
}
if (!paddingTypeC) {
info("No Padding type given, assume no zeropadding");
logger->info("No Padding type given, assume no zeropadding");
paddingType = PaddingType::ZERO;
}
else if (strcmp(paddingTypeC, "signal_repeat") == 0)
paddingType = PaddingType::SIG_REPEAT;
else {
info("Padding type %s not recognized, assume zero padding", paddingTypeC);
logger->info("Padding type {} not recognized, assume zero padding", paddingTypeC);
paddingType = PaddingType::ZERO;
}
@ -326,7 +326,7 @@ public:
}
if ((smp->sequence - lastSequence) > 1)
warning("Calculation is not Realtime. %" PRIu64 " sampled missed", smp->sequence - lastSequence);
logger->warn("Calculation is not Realtime. {} sampled missed", smp->sequence - lastSequence);
lastSequence = smp->sequence;

View file

@ -159,18 +159,18 @@ public:
state = State::STARTED;
}
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
json_error_t err;
json_t *json_harmonics, *json_harmonic, *json_signal;
size_t i;
Hook::parse(cfg);
Hook::parse(json);
double rate = -1, dt = -1;
ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s: F, s?: F, s?: F, s: o, s?: b }",
ret = json_unpack_ex(json, &err, 0, "{ s: o, s: F, s?: F, s?: F, s: o, s?: b }",
"signal", &json_signal,
"f0", &f0,
"dt", &dt,
@ -179,14 +179,14 @@ public:
"inverse", &inverse
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-dp");
throw ConfigError(json, err, "node-config-hook-dp");
if (rate > 0)
timestep = 1. / rate;
else if (dt > 0)
timestep = dt;
else
throw ConfigError(cfg, "node-config-hook-dp", "Either on of the settings 'dt' or 'rate' must be given");
throw ConfigError(json, "node-config-hook-dp", "Either on of the settings 'dt' or 'rate' must be given");
if (!json_is_array(json_harmonics))
throw ConfigError(json_harmonics, "node-config-hook-dp-harmonics", "Setting 'harmonics' must be a list of integers");

View file

@ -41,7 +41,7 @@ public:
{
assert(state == State::STARTED);
sample_dump(smp);
sample_dump(logger, smp);
return Reason::OK;
}

View file

@ -27,7 +27,6 @@
#include <vector>
#include <villas/hook.hpp>
#include <villas/log.h>
#include <villas/sample.h>
#include <villas/timing.h>
@ -46,7 +45,7 @@ protected:
public:
using Hook::Hook;
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
@ -54,13 +53,13 @@ public:
json_error_t err;
json_t *json_phases, *json_phase;
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: o }",
ret = json_unpack_ex(json, &err, 0, "{ s: o }",
"phases", &json_phases
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-ebm");
throw ConfigError(json, err, "node-config-hook-ebm");
if (!json_is_array(json_phases))
throw ConfigError(json_phases, "node-config-hook-ebm-phases");
@ -72,7 +71,7 @@ public:
&voltage, &current
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-ebm-phases");
throw ConfigError(json, err, "node-config-hook-ebm-phases");
phases.emplace_back(voltage, current);
}
@ -94,7 +93,7 @@ public:
{
assert(state == State::STARTED);
info("Energy: %f", energy);
logger->info("Energy: {}", energy);
}
virtual Hook::Reason process(sample *smp)

View file

@ -71,7 +71,7 @@ public:
startSequence(0)
{ }
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
@ -82,9 +82,9 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: F, s?: F, s?: i, s?: s }",
ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: F, s?: F, s?: i, s?: s }",
"signal", &json_signal,
"threshold", &threshold,
"duration", &duration,
@ -92,7 +92,7 @@ public:
"mode", &mode_str
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-gate");
throw ConfigError(json, err, "node-config-hook-gate");
if (mode_str) {
if (!strcmp(mode_str, "above"))

View file

@ -98,7 +98,10 @@ public:
*/
jitter_val[(curr_count + 1) % GPS_NTP_DELAY_WIN_SIZE] = jitter_val[curr_count] + (labs(curr_delay_us) - jitter_val[curr_count]) / 16;
logger->info("{}: jitter={} usec, moving average={} usec, moving variance={} usec", __FUNCTION__, jitter_val[(curr_count + 1) % GPS_NTP_DELAY_WIN_SIZE], moving_avg[curr_count], moving_var[curr_count]);
logger->info("{}: jitter={} usec, moving average={} usec, moving variance={} usec", __FUNCTION__,
jitter_val[(curr_count + 1) % GPS_NTP_DELAY_WIN_SIZE],
moving_avg[curr_count],
moving_var[curr_count]);
curr_count++;
if (curr_count >= GPS_NTP_DELAY_WIN_SIZE)

View file

@ -33,7 +33,7 @@
namespace villas {
namespace node {
void LimitRateHook::parse(json_t *cfg)
void LimitRateHook::parse(json_t *json)
{
int ret;
json_error_t err;
@ -43,14 +43,14 @@ void LimitRateHook::parse(json_t *cfg)
double rate;
const char *m = nullptr;
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: F, s?: s }",
ret = json_unpack_ex(json, &err, 0, "{ s: F, s?: s }",
"rate", &rate,
"mode", &m
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-limit_rate");
throw ConfigError(json, err, "node-config-hook-limit_rate");
if (m) {
if (!strcmp(m, "origin"))
@ -60,7 +60,7 @@ void LimitRateHook::parse(json_t *cfg)
else if (!strcmp(m, "local"))
mode = LIMIT_RATE_LOCAL;
else
throw ConfigError(cfg, "node-config-hook-limit_rate-mode", "Invalid value '{}' for setting 'mode'", mode);
throw ConfigError(json, "node-config-hook-limit_rate-mode", "Invalid value '{}' for setting 'mode'", mode);
}
deadtime = 1.0 / rate;

View file

@ -101,7 +101,7 @@ public:
state = State::PREPARED;
}
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
size_t i;
@ -110,15 +110,15 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: f, s: f, s: o }",
ret = json_unpack_ex(json, &err, 0, "{ s: f, s: f, s: o }",
"min", &min,
"min", &max,
"signals", &json_signals
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-average");
throw ConfigError(json, err, "node-config-hook-average");
if (!json_is_array(json_signals))
throw ConfigError(json_signals, "node-config-hook-average-signals", "Setting 'signals' must be a list of signal names");

View file

@ -139,13 +139,10 @@ lua_tosignaldata(lua_State *L, union signal_data *data, enum SignalType targetTy
break;
default:
warning("Failed to convert Lua type %s to signal data", lua_typename(L, luaType));
return;
}
signal_data_cast(data, type, targetType);
return;
}
static void
@ -472,7 +469,7 @@ LuaHook::parseExpressions(json_t *json_sigs)
}
void
LuaHook::parse(json_t *c)
LuaHook::parse(json_t *json)
{
int ret;
const char *script_str = nullptr;
@ -482,15 +479,15 @@ LuaHook::parse(json_t *c)
assert(state != State::STARTED);
Hook::parse(c);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: o, s?: b }",
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: o, s?: b }",
"script", &script_str,
"signals", &json_signals,
"use_names", &names
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-lua");
throw ConfigError(json, err, "node-config-hook-lua");
useNames = names;
@ -522,7 +519,7 @@ LuaHook::lookupFunctions()
ret = lua_type(L, -1);
if (ret == LUA_TFUNCTION) {
logger->debug("Found Lua function: %s()", it.first);
logger->debug("Found Lua function: {}()", it.first);
*(it.second) = lua_gettop(L);
}
else {
@ -602,7 +599,7 @@ LuaHook::prepare()
luaL_openlibs(L);
/* Load our Lua script */
logger->debug("Loading Lua script: %s", script.c_str());
logger->debug("Loading Lua script: {}", script);
setupEnvironment();
loadScript();
@ -640,7 +637,7 @@ LuaHook::prepare()
logger->debug("Executing Lua function: prepare()");
lua_pushvalue(L, functions.prepare);
lua_pushjson(L, cfg);
lua_pushjson(L, config);
int ret = lua_pcall(L, 1, 0, 0);
if (ret)
throw LuaError(L, ret);

View file

@ -30,7 +30,6 @@
#include <villas/hook.hpp>
#include <villas/timing.h>
#include <villas/sample.h>
#include <villas/log.h>
namespace villas {
namespace node {
@ -78,28 +77,27 @@ public:
filterWindow(horizonEst + 1, 0)
{ }
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
json_error_t err;
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
double fSmps = 0;
ret = json_unpack_ex(cfg, &err, 0, "{ s: i, s?: f, s: F}",
ret = json_unpack_ex(json, &err, 0, "{ s: i, s?: f, s: F}",
"signal_index", &idx,
"threshold", &thresh,
"expected_smp_rate", &fSmps
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-pps_ts");
throw ConfigError(json, err, "node-config-hook-pps_ts");
period = 1.0 / fSmps;
debug(LOG_HOOK | 5, "parsed config thresh=%f signal_index=%d nominal_period=%f", thresh, idx, period);
logger->debug("Parsed config thresh={} signal_index={} nominal_period={}", thresh, idx, period);
state = State::PARSED;
}
@ -142,7 +140,7 @@ public:
cntSmps = 0;
cntEdges++;
debug(LOG_HOOK | 5, "Time Error is: %f periodEst %f periodErrComp %f", timeError, periodEst, periodErrComp);
logger->debug("Time Error is: {} periodEst {} periodErrComp {}", timeError, periodEst, periodErrComp);
}
cntSmps++;
@ -159,7 +157,7 @@ public:
if ((smp->sequence - lastSequence) > 1)
warning("Samples missed: %" PRIu64 " sampled missed", smp->sequence - lastSequence);
logger->warn("Samples missed: {} sampled missed", smp->sequence - lastSequence);
lastSequence = smp->sequence;

View file

@ -88,7 +88,7 @@ public:
state = State::STOPPED;
}
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
const char *f = nullptr, *p = nullptr, *u = nullptr;
int ret;
@ -96,15 +96,15 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: s, s?: s }",
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: s, s?: s }",
"output", &u,
"prefix", &p,
"format", &f
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-print");
throw ConfigError(json, err, "node-config-hook-print");
if (p)
prefix = strdup(p);
@ -115,7 +115,7 @@ public:
if (f) {
format = format_type_lookup(f);
if (!format)
throw ConfigError(cfg, "node-config-hook-print-format", "Invalid IO format '{}'", f);
throw ConfigError(json, "node-config-hook-print-format", "Invalid IO format '{}'", f);
}
state = State::PARSED;

View file

@ -69,7 +69,7 @@ public:
free(signal_name);
}
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
json_t *json_signal;
@ -77,15 +77,15 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s?: F, s?: F, s: o }",
ret = json_unpack_ex(json, &err, 0, "{ s?: F, s?: F, s: o }",
"scale", &scale,
"offset", &offset,
"signal", &json_signal
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-scale");
throw ConfigError(json, err, "node-config-hook-scale");
switch (json_typeof(json_signal)) {
case JSON_STRING:

View file

@ -39,20 +39,20 @@ public:
using Hook::Hook;
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
json_error_t err;
int ret;
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: i }",
ret = json_unpack_ex(json, &err, 0, "{ s: i }",
"offset", &offset
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-shift_seq");
throw ConfigError(json, err, "node-config-hook-shift_seq");
state = State::PARSED;
}

View file

@ -48,7 +48,7 @@ public:
mode(SHIFT_ORIGIN)
{ }
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
double o;
const char *m = nullptr;
@ -57,14 +57,14 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s: F }",
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s: F }",
"mode", &m,
"offset", &o
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-shift_ts");
throw ConfigError(json, err, "node-config-hook-shift_ts");
if (m) {
if (!strcmp(m, "origin"))
@ -72,7 +72,7 @@ public:
else if (!strcmp(m, "received"))
mode = SHIFT_RECEIVED;
else
throw ConfigError(cfg, "node-config-hook-shift_ts-mode", "Invalid mode parameter '{}'", m);
throw ConfigError(json, "node-config-hook-shift_ts-mode", "Invalid mode parameter '{}'", m);
}
offset = time_from_double(o);

View file

@ -60,7 +60,7 @@ protected:
public:
using Hook::Hook;
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
double s;
@ -69,9 +69,9 @@ public:
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
ret = json_unpack_ex(cfg, &err, 0, "{ s: F }", "seconds", &s);
ret = json_unpack_ex(json, &err, 0, "{ s: F }", "seconds", &s);
if (!ret) {
seconds.wait = time_from_double(s);
mode = Mode::SECONDS;
@ -80,7 +80,7 @@ public:
return;
}
ret = json_unpack_ex(cfg, &err, 0, "{ s: i }", "samples", &samples.wait);
ret = json_unpack_ex(json, &err, 0, "{ s: i }", "samples", &samples.wait);
if (!ret) {
mode = Mode::SAMPLES;
@ -88,7 +88,7 @@ public:
return;
}
throw ConfigError(cfg, err, "node-config-hook-skip_first");
throw ConfigError(json, err, "node-config-hook-skip_first");
}
virtual void start()

View file

@ -27,7 +27,6 @@
#include <memory>
#include <villas/common.hpp>
#include <villas/advio.hpp>
#include <villas/hook.hpp>
#include <villas/node/exceptions.hpp>
#include <villas/stats.hpp>
@ -109,7 +108,7 @@ protected:
std::shared_ptr<Stats> stats;
AFILE *output;
FILE *output;
std::string uri;
public:
@ -144,7 +143,7 @@ public:
assert(state == State::PREPARED);
if (!uri.empty()) {
output = afopen(uri.c_str(), "w+");
output = fopen(uri.c_str(), "w+");
if (!output)
throw RuntimeError("Failed to open file '{}' for writing", uri);
}
@ -156,10 +155,10 @@ public:
{
assert(state == State::STARTED);
stats->print(uri.empty() ? stdout : output->file, format, verbose);
stats->print(uri.empty() ? stdout : output, format, verbose);
if (!uri.empty())
afclose(output);
fclose(output);
state = State::STOPPED;
}
@ -184,22 +183,22 @@ public:
{
assert(state == State::STARTED);
stats->printPeriodic(uri.empty() ? stdout : output->file, format, node);
stats->printPeriodic(uri.empty() ? stdout : output, format, node);
}
virtual void parse(json_t *cfg)
virtual void parse(json_t *json)
{
int ret;
json_error_t err;
assert(state != State::STARTED);
Hook::parse(cfg);
Hook::parse(json);
const char *f = nullptr;
const char *u = nullptr;
ret = json_unpack_ex(cfg, &err, 0, "{ s?: s, s?: b, s?: i, s?: i, s?: s }",
ret = json_unpack_ex(json, &err, 0, "{ s?: s, s?: b, s?: i, s?: i, s?: s }",
"format", &f,
"verbose", &verbose,
"warmup", &warmup,
@ -207,13 +206,13 @@ public:
"output", &u
);
if (ret)
throw ConfigError(cfg, err, "node-config-hook-stats");
throw ConfigError(json, err, "node-config-hook-stats");
if (f) {
try {
format = Stats::lookupFormat(f);
} catch (const std::invalid_argument &e) {
throw ConfigError(cfg, "node-config-hook-stats", "Invalid statistic output format: {}", f);
throw ConfigError(json, "node-config-hook-stats", "Invalid statistic output format: {}", f);
}
}

View file

@ -171,35 +171,24 @@ int io_stream_open(struct io *io, const char *uri)
if (!strcmp(uri, "-")) {
goto stdio;
}
else if (aislocal(uri) == 1) {
else {
io->mode = IOMode::STDIO;
io->out.stream.std = fopen(uri, "a+");
if (io->out.stream.std == nullptr)
io->out.stream = fopen(uri, "a+");
if (io->out.stream == nullptr)
return -1;
io->in.stream.std = fopen(uri, "r");
if (io->in.stream.std == nullptr)
io->in.stream = fopen(uri, "r");
if (io->in.stream == nullptr)
return -1;
}
else {
io->mode = IOMode::ADVIO;
io->out.stream.adv = afopen(uri, "a+");
if (io->out.stream.adv == nullptr)
return -1;
io->in.stream.adv = afopen(uri, "a+");
if (io->in.stream.adv == nullptr)
return -2;
}
}
else {
stdio: io->mode = IOMode::STDIO;
io->flags |= (int) IOFlags::FLUSH;
io->in.stream.std = stdin;
io->out.stream.std = stdout;
io->in.stream = stdin;
io->out.stream = stdout;
}
/* Make stream non-blocking if desired */
@ -223,11 +212,11 @@ stdio: io->mode = IOMode::STDIO;
/* Enable line buffering on stdio */
if (io->mode == IOMode::STDIO) {
ret = setvbuf(io->in.stream.std, nullptr, _IOLBF, BUFSIZ);
ret = setvbuf(io->in.stream, nullptr, _IOLBF, BUFSIZ);
if (ret)
return -1;
ret = setvbuf(io->out.stream.std, nullptr, _IOLBF, BUFSIZ);
ret = setvbuf(io->out.stream, nullptr, _IOLBF, BUFSIZ);
if (ret)
return -1;
}
@ -240,26 +229,15 @@ int io_stream_close(struct io *io)
int ret;
switch (io->mode) {
case IOMode::ADVIO:
ret = afclose(io->in.stream.adv);
if (ret)
return ret;
ret = afclose(io->out.stream.adv);
if (ret)
return ret;
return 0;
case IOMode::STDIO:
if (io->in.stream.std == stdin)
if (io->in.stream == stdin)
return 0;
ret = fclose(io->in.stream.std);
ret = fclose(io->in.stream);
if (ret)
return ret;
ret = fclose(io->out.stream.std);
ret = fclose(io->out.stream);
if (ret)
return ret;
@ -275,10 +253,8 @@ int io_stream_close(struct io *io)
int io_stream_flush(struct io *io)
{
switch (io->mode) {
case IOMode::ADVIO:
return afflush(io->out.stream.adv);
case IOMode::STDIO:
return fflush(io->out.stream.std);
return fflush(io->out.stream);
case IOMode::CUSTOM:
return 0;
}
@ -289,10 +265,8 @@ int io_stream_flush(struct io *io)
int io_stream_eof(struct io *io)
{
switch (io->mode) {
case IOMode::ADVIO:
return afeof(io->in.stream.adv);
case IOMode::STDIO:
return feof(io->in.stream.std);
return feof(io->in.stream);
case IOMode::CUSTOM:
return 0;
}
@ -303,11 +277,8 @@ int io_stream_eof(struct io *io)
void io_stream_rewind(struct io *io)
{
switch (io->mode) {
case IOMode::ADVIO:
arewind(io->in.stream.adv);
break;
case IOMode::STDIO:
rewind(io->in.stream.std);
rewind(io->in.stream);
break;
case IOMode::CUSTOM: { }
}
@ -316,10 +287,8 @@ void io_stream_rewind(struct io *io)
int io_stream_fd(struct io *io)
{
switch (io->mode) {
case IOMode::ADVIO:
return afileno(io->in.stream.adv);
case IOMode::STDIO:
return fileno(io->in.stream.std);
return fileno(io->in.stream);
case IOMode::CUSTOM:
return -1;
}
@ -482,18 +451,14 @@ FILE * io_stream_output(struct io *io) {
if (io->state != State::OPENED)
return 0;
return io->mode == IOMode::ADVIO
? io->out.stream.adv->file
: io->out.stream.std;
return io->out.stream;
}
FILE * io_stream_input(struct io *io) {
if (io->state != State::OPENED)
return 0;
return io->mode == IOMode::ADVIO
? io->in.stream.adv->file
: io->in.stream.std;
return io->in.stream;
}
int io_sscan(struct io *io, const char *buf, size_t len, size_t *rbytes, struct sample *smps[], unsigned cnt)

View file

@ -51,13 +51,13 @@ struct nl_sock * villas::kernel::nl::init()
ret = nl_connect(sock, NETLINK_ROUTE);
if (ret)
error("Failed to connect to kernel: %s", nl_geterror(ret));
throw RuntimeError("Failed to connect to kernel: {}", nl_geterror(ret));
/* Fill some caches */
struct nl_cache *cache;
ret = rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache);
if (ret)
error("Failed to get list of interfaces: %s", nl_geterror(ret));
throw RuntimeError("Failed to get list of interfaces: {}", nl_geterror(ret));
nl_cache_mngt_provide(cache);
}
@ -150,7 +150,7 @@ struct rtnl_link * villas::kernel::nl::get_egress_link(struct sockaddr *sa)
ifindex = nl::get_egress(addr); nl_addr_put(addr);
if (ifindex < 0)
error("Netlink error: %s", nl_geterror(ifindex));
throw RuntimeError("Netlink error: {}", nl_geterror(ifindex));
break;
}

View file

@ -28,7 +28,7 @@
#include <linux/if_ether.h>
#include <villas/utils.hpp>
#include <villas/exceptions.hpp>
#include <villas/kernel/kernel.hpp>
#include <villas/kernel/if.hpp>
#include <villas/kernel/tc.hpp>
@ -45,7 +45,7 @@ int villas::kernel::tc::prio(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t hand
ret = kernel::module_load("sch_prio");
if (ret)
error("Failed to load kernel module: sch_prio (%d)", ret);
throw RuntimeError("Failed to load kernel module: sch_prio ({})", ret);
/* This is the default priomap used by the tc-prio qdisc
* We will use the first 'bands' bands internally */
@ -65,7 +65,8 @@ int villas::kernel::tc::prio(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t hand
*qd = q;
debug(LOG_TC | 3, "Added prio qdisc with %d bands to interface '%s'", bands, rtnl_link_get_name(i->nl_link));
auto logger = logging.get("kernel");
logger->debug("Added prio qdisc with {} bands to interface '{}'", bands, rtnl_link_get_name(i->nl_link));
return ret;
}
@ -78,7 +79,7 @@ int villas::kernel::tc::mark(Interface *i, struct rtnl_cls **cls, tc_hdl_t flowi
ret = kernel::module_load("cls_fw");
if (ret)
error("Failed to load kernel module: cls_fw");
throw RuntimeError("Failed to load kernel module: cls_fw");
rtnl_tc_set_link(TC_CAST(c), i->nl_link);
rtnl_tc_set_handle(TC_CAST(c), mark);
@ -93,7 +94,8 @@ int villas::kernel::tc::mark(Interface *i, struct rtnl_cls **cls, tc_hdl_t flowi
*cls = c;
debug(LOG_TC | 3, "Added fwmark classifier with mark %d to interface '%s'", mark, rtnl_link_get_name(i->nl_link));
auto logger = logging.get("kernel");
logger->debug("Added fwmark classifier with mark {} to interface '{}'", mark, rtnl_link_get_name(i->nl_link));
return ret;
}

View file

@ -95,7 +95,7 @@ static int set_delay_distribution(struct rtnl_qdisc *qdisc, json_t *json)
return 0;
}
int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *json)
{
int ret, val;
@ -110,7 +110,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
json_error_t err;
ret = json_unpack_ex(cfg, &err, 0, "{ s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o }",
ret = json_unpack_ex(json, &err, 0, "{ s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o, s?: o }",
"distribution", &json_delay_distribution,
"correlation", &json_delay_correlation,
"limit", &json_limit,
@ -121,7 +121,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
"corruption", &json_corruption
);
if (ret)
jerror(&err, "Failed to parse setting network emulation settings");
throw ConfigError(json, err, "node-config-netem", "Failed to parse setting network emulation settings");
struct rtnl_qdisc *ne = rtnl_qdisc_alloc();
if (!ne)
@ -131,14 +131,14 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
if (json_delay_distribution) {
if (set_delay_distribution(ne, json_delay_distribution))
error("Invalid delay distribution in netem config");
throw ConfigError(json_delay_distribution, "Invalid delay distribution in netem config");
}
if (json_delay_correlation) {
double dval = json_number_value(json_delay_correlation);
if (!json_is_number(json_delay_correlation) || dval < 0 || dval > 100)
error("Setting 'correlation' must be a positive integer within the range [ 0, 100 ]");
throw ConfigError(json_delay_correlation, "Setting 'correlation' must be a positive integer within the range [ 0, 100 ]");
unsigned *pval = (unsigned *) &val;
*pval = (unsigned) rint((dval / 100.) * max_percent_value);
@ -152,7 +152,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
val = json_integer_value(json_limit);
if (!json_is_integer(json_limit) || val <= 0)
error("Setting 'limit' must be a positive integer");
throw ConfigError(json_limit, "Setting 'limit' must be a positive integer");
rtnl_netem_set_limit(ne, val);
}
@ -163,7 +163,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
val = json_integer_value(json_delay);
if (!json_is_integer(json_delay) || val <= 0)
error("Setting 'delay' must be a positive integer");
throw ConfigError(json_delay, "Setting 'delay' must be a positive integer");
rtnl_netem_set_delay(ne, val);
}
@ -172,7 +172,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
val = json_integer_value(json_jitter);
if (!json_is_integer(json_jitter) || val <= 0)
error("Setting 'jitter' must be a positive integer");
throw ConfigError(json_jitter, "Setting 'jitter' must be a positive integer");
rtnl_netem_set_jitter(ne, val);
}
@ -181,7 +181,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
double dval = json_number_value(json_loss);
if (!json_is_number(json_loss) || dval < 0 || dval > 100)
error("Setting 'loss' must be a positive integer within the range [ 0, 100 ]");
throw ConfigError(json_loss, "Setting 'loss' must be a positive integer within the range [ 0, 100 ]");
unsigned *pval = (unsigned *) &val;
*pval = (unsigned) rint((dval / 100.) * max_percent_value);
@ -193,7 +193,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
double dval = json_number_value(json_duplicate);
if (!json_is_number(json_duplicate) || dval < 0 || dval > 100)
error("Setting 'duplicate' must be a positive integer within the range [ 0, 100 ]");
throw ConfigError(json_duplicate, "Setting 'duplicate' must be a positive integer within the range [ 0, 100 ]");
unsigned *pval = (unsigned *) &val;
*pval = (unsigned) rint((dval / 100.) * max_percent_value);
@ -205,7 +205,7 @@ int villas::kernel::tc::netem_parse(struct rtnl_qdisc **netem, json_t *cfg)
double dval = json_number_value(json_corruption);
if (!json_is_number(json_corruption) || dval < 0 || dval > 100)
error("Setting 'corruption' must be a positive integer within the range [ 0, 100 ]");
throw ConfigError(json_corruption, "Setting 'corruption' must be a positive integer within the range [ 0, 100 ]");
unsigned *pval = (unsigned *) &val;
*pval = (unsigned) rint((dval / 100.) * max_percent_value);
@ -275,7 +275,7 @@ int villas::kernel::tc::netem(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t han
ret = kernel::module_load("sch_netem");
if (ret)
error("Failed to load kernel module: sch_netem (%d)", ret);
throw RuntimeError("Failed to load kernel module: sch_netem ({})", ret);
rtnl_tc_set_link(TC_CAST(q), i->nl_link);
rtnl_tc_set_parent(TC_CAST(q), parent);
@ -286,7 +286,8 @@ int villas::kernel::tc::netem(Interface *i, struct rtnl_qdisc **qd, tc_hdl_t han
*qd = q;
debug(LOG_TC | 3, "Added netem qdisc to interface '%s'", rtnl_link_get_name(i->nl_link));
auto logger = logging.get("kernel");
logger->debug("Added netem qdisc to interface '{}'", rtnl_link_get_name(i->nl_link));
return ret;
}

View file

@ -129,18 +129,18 @@ int mapping_entry_destroy(struct mapping_entry *me)
return 0;
}
int mapping_entry_parse(struct mapping_entry *me, json_t *cfg)
int mapping_entry_parse(struct mapping_entry *me, json_t *json)
{
const char *str;
str = json_string_value(cfg);
str = json_string_value(json);
if (!str)
return -1;
return mapping_entry_parse_str(me, str);
}
int mapping_list_parse(struct vlist *ml, json_t *cfg)
int mapping_list_parse(struct vlist *ml, json_t *json)
{
int ret;
@ -148,12 +148,12 @@ int mapping_list_parse(struct vlist *ml, json_t *cfg)
json_t *json_entry;
json_t *json_mapping;
if (json_is_string(cfg)) {
if (json_is_string(json)) {
json_mapping = json_array();
json_array_append(json_mapping, cfg);
json_array_append(json_mapping, json);
}
else if (json_is_array(cfg))
json_mapping = json_incref(cfg);
else if (json_is_array(json))
json_mapping = json_incref(json);
else
return -1;

View file

@ -31,7 +31,7 @@
#include <sys/resource.h>
#include <sys/mman.h>
#include <villas/log.h>
#include <villas/log.hpp>
#include <villas/memory.h>
#include <villas/utils.hpp>
#include <villas/kernel/kernel.hpp>
@ -39,12 +39,15 @@
using namespace villas;
static std::unordered_map<void *, struct memory_allocation *> allocations;
static Logger logger;
int memory_init(int hugepages)
{
int ret;
info("Initialize memory sub-system: #hugepages=%d", hugepages);
logger = logging.get("memory");
logger->info("Initialize memory sub-system: #hugepages={}", hugepages);
ret = memory_mmap_init(hugepages);
if (ret < 0)
@ -76,8 +79,8 @@ int memory_lock(size_t lock)
if (l.rlim_cur < lock) {
if (l.rlim_max < lock) {
if (getuid() != 0) {
warning("Failed to in increase ressource limit of locked memory. Please increase manually by running as root:");
warning(" $ ulimit -Hl %zu", lock);
logger->warn("Failed to in increase ressource limit of locked memory. Please increase manually by running as root:");
logger->warn(" $ ulimit -Hl {}", lock);
return 0;
}
@ -91,7 +94,7 @@ int memory_lock(size_t lock)
if (ret)
return ret;
debug(LOG_MEM | 2, "Increased ressource limit of locked memory to %zd bytes", lock);
logger->debug("Increased ressource limit of locked memory to {} bytes", lock);
}
#endif /* __arm__ */
@ -116,13 +119,13 @@ void * memory_alloc_aligned(size_t len, size_t alignment, struct memory_type *m)
{
struct memory_allocation *ma = m->alloc(len, alignment, m);
if (ma == nullptr) {
warning("Memory allocation of type %s failed. reason=%s", m->name, strerror(errno));
logger->warn("Memory allocation of type {} failed. reason={}", m->name, strerror(errno));
return nullptr;
}
allocations[ma->address] = ma;
debug(LOG_MEM | 5, "Allocated %#zx bytes of %#zx-byte-aligned %s memory: %p", ma->length, ma->alignment, ma->type->name, ma->address);
logger->debug("Allocated {:#x} bytes of {:#x}-byte-aligned {} memory: {}", ma->length, ma->alignment, ma->type->name, ma->address);
return ma->address;
}
@ -136,7 +139,7 @@ int memory_free(void *ptr)
if (!ma)
return -1;
debug(LOG_MEM | 5, "Releasing %#zx bytes of %s memory: %p", ma->length, ma->type->name, ma->address);
logger->debug("Releasing {:#x} bytes of {} memory: {}", ma->length, ma->type->name, ma->address);
ret = ma->type->free(ma, ma->type);
if (ret)

View file

@ -30,10 +30,10 @@
#include <sys/resource.h>
#include <sys/types.h>
#include <villas/log.h>
#include <villas/memory.h>
#include <villas/utils.hpp>
#include <villas/exceptions.hpp>
#include <villas/log.hpp>
using namespace villas;
using namespace villas::utils;
@ -166,7 +166,8 @@ struct memory_type * memory_managed(void *ptr, size_t len)
char *cptr = (char *) ptr;
if (len < sizeof(struct memory_type) + sizeof(struct memory_block)) {
info("memory_managed: passed region too small");
auto logger = logging.get("memory:managed");
logger->info("Passed region is too small");
return nullptr;
}

View file

@ -35,11 +35,11 @@
#endif /* __MACH__ */
#include <villas/kernel/kernel.hpp>
#include <villas/log.h>
#include <villas/memory.h>
#include <villas/utils.hpp>
#include <villas/kernel/kernel.hpp>
#include <villas/exceptions.hpp>
#include <villas/log.hpp>
using namespace villas;
using namespace villas;
@ -47,9 +47,12 @@ using namespace villas::utils;
static size_t pgsz = -1;
static size_t hugepgsz = -1;
static Logger logger;
int memory_mmap_init(int hugepages)
{
logger = logging.get("memory:mmap");
pgsz = kernel::get_page_size();
if (pgsz < 0)
return -1;
@ -57,7 +60,7 @@ int memory_mmap_init(int hugepages)
if (hugepages > 0) {
hugepgsz = kernel::get_hugepage_size();
if (hugepgsz < 0) {
warning("Failed to determine hugepage size.");
logger->warn("Failed to determine hugepage size.");
memory_default = &memory_mmap;
return 0;
@ -71,16 +74,16 @@ int memory_mmap_init(int hugepages)
if (getuid() == 0) {
ret = kernel::set_nr_hugepages(hugepages);
if (ret) {
warning("Failed to increase number of reserved hugepages");
logger->warn("Failed to increase number of reserved hugepages");
memory_default = &memory_mmap;
}
debug(LOG_MEM | 2, "Increased number of reserved hugepages from %d to %d", pagecnt, hugepages);
logger->debug("Increased number of reserved hugepages from {} to {}", pagecnt, hugepages);
memory_default = &memory_mmap_hugetlb;
}
else {
warning("Failed to reserved hugepages. Please reserve manually by running as root:");
warning(" $ echo %d > /proc/sys/vm/nr_hugepages", hugepages);
logger->warn("Failed to reserved hugepages. Please reserve manually by running as root:");
logger->warn(" $ echo {} > /proc/sys/vm/nr_hugepages", hugepages);
memory_default = &memory_mmap;
}
}
@ -91,7 +94,7 @@ int memory_mmap_init(int hugepages)
#endif
}
else {
warning("Hugepage allocator disabled.");
logger->warn("Hugepage allocator disabled.");
memory_default = &memory_mmap;
}

View file

@ -63,6 +63,9 @@ int node_init(struct vnode *n, struct vnode_type *vt)
using stats_ptr = std::shared_ptr<Stats>;
new (&n->stats) stats_ptr();
new (&n->logger) Logger();
n->logger = logging.get(fmt::format("node:{}", node_type_name(vt)));
uuid_clear(n->uuid);
@ -151,6 +154,9 @@ int node_parse(struct vnode *n, json_t *json, const uuid_t sn_uuid)
if (ret)
return ret;
if (name_str)
n->logger = logging.get(fmt::format("node:{}", name_str));
#ifdef __linux__
ret = json_unpack_ex(json, &err, 0, "{ s?: { s?: o, s?: i } }",
"out",
@ -227,7 +233,7 @@ int node_parse(struct vnode *n, json_t *json, const uuid_t sn_uuid)
if (ret)
return ret;
n->cfg = json;
n->config = json;
n->state = State::PARSED;
return 0;
@ -262,7 +268,7 @@ int node_start(struct vnode *n)
assert(n->state == State::PREPARED);
assert(node_type(n)->state == State::STARTED);
info("Starting node %s", node_name_long(n));
n->logger->info("Starting node");
ret = node_direction_start(&n->in, n);
if (ret)
@ -289,7 +295,7 @@ int node_start(struct vnode *n)
if (ret)
throw RuntimeError("Failed to set FW mark for outgoing packets");
else
debug(LOG_SOCKET | 4, "Set FW mark for socket (sd=%u) to %u", fd, n->fwmark);
n->logger->debug("Set FW mark for socket (sd={}) to {}", fd, n->fwmark);
}
}
#endif /* __linux__ */
@ -307,7 +313,7 @@ int node_stop(struct vnode *n)
if (n->state != State::STOPPING && n->state != State::STARTED && n->state != State::CONNECTED && n->state != State::PENDING_CONNECT)
return 0;
info("Stopping node %s", node_name(n));
n->logger->info("Stopping node");
ret = node_direction_stop(&n->in, n);
if (ret)
@ -332,7 +338,7 @@ int node_pause(struct vnode *n)
if (n->state != State::STARTED)
return -1;
info("Pausing node %s", node_name(n));
n->logger->info("Pausing node");
ret = node_type(n)->pause ? node_type(n)->pause(n) : 0;
@ -349,7 +355,7 @@ int node_resume(struct vnode *n)
if (n->state != State::PAUSED)
return -1;
info("Resuming node %s", node_name(n));
n->logger->info("Resuming node");
ret = node_type(n)->resume ? node_type(n)->resume(n) : 0;
@ -366,7 +372,7 @@ int node_restart(struct vnode *n)
if (n->state != State::STARTED)
return -1;
info("Restarting node %s", node_name(n));
n->logger->info("Restarting node");
if (node_type(n)->restart)
ret = node_type(n)->restart(n);
@ -475,14 +481,14 @@ int node_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re
if (n->stats != nullptr)
n->stats->update(Stats::Metric::SMPS_SKIPPED, skipped);
debug(LOG_NODE | 5, "Received %u samples from node %s of which %d have been skipped", nread, node_name(n), skipped);
n->logger->debug("Received {} samples of which {} have been skipped", nread, skipped);
}
else
debug(LOG_NODE | 5, "Received %u samples from node %s", nread, node_name(n));
n->logger->debug( "Received {} samples", nread);
return rread;
#else
debug(LOG_NODE | 5, "Received %u samples from node %s", nread, node_name(n));
n->logger->debug("Received {} samples", nread);
return nread;
#endif /* WITH_HOOKS */
@ -518,7 +524,7 @@ int node_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *r
return sent;
nsent += sent;
debug(LOG_NODE | 5, "Sent %u samples to node %s", sent, node_name(n));
n->logger->debug("Sent {} samples", sent);
}
return nsent;
@ -593,7 +599,7 @@ struct memory_type * node_memory_type(struct vnode *n)
return node_type(n)->memory_type ? node_type(n)->memory_type(n, memory_default) : memory_default;
}
int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all)
int node_list_parse(struct vlist *list, json_t *json, struct vlist *all)
{
struct vnode *node;
const char *str;
@ -602,9 +608,11 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all)
size_t index;
json_t *elm;
switch (json_typeof(cfg)) {
auto logger = logging.get("node");
switch (json_typeof(json)) {
case JSON_STRING:
str = json_string_value(cfg);
str = json_string_value(json);
node = vlist_lookup_name<struct vnode>(all, str);
if (!node)
goto invalid2;
@ -613,7 +621,7 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all)
break;
case JSON_ARRAY:
json_array_foreach(cfg, index, elm) {
json_array_foreach(json, index, elm) {
if (!json_is_string(elm))
goto invalid;
@ -632,7 +640,7 @@ int node_list_parse(struct vlist *list, json_t *cfg, struct vlist *all)
return 0;
invalid:
error("The node list must be an a single or an array of strings referring to the keys of the 'nodes' section");
throw RuntimeError("The node list must be an a single or an array of strings referring to the keys of the 'nodes' section");
return -1;
@ -643,7 +651,7 @@ invalid2:
strcatf(&allstr, " %s", node_name_short(n));
}
error("Unknown node %s. Choose of one of: %s", str, allstr);
throw RuntimeError("Unknown node {}. Choose of one of: {}", str, allstr);
return 0;
}
@ -708,7 +716,7 @@ json_t * node_to_json(struct vnode *n)
/* Add all additional fields of node here.
* This can be used for metadata */
json_object_update(json_node, n->cfg);
json_object_update(json_node, n->config);
return json_node;
}

View file

@ -94,7 +94,7 @@ int node_direction_destroy(struct vnode_direction *nd, struct vnode *n)
return 0;
}
int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cfg)
int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *json)
{
int ret;
@ -104,9 +104,9 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf
json_t *json_hooks = nullptr;
json_t *json_signals = nullptr;
nd->cfg = cfg;
nd->config = json;
ret = json_unpack_ex(cfg, &err, 0, "{ s?: o, s?: o, s?: i, s?: b, s?: b }",
ret = json_unpack_ex(json, &err, 0, "{ s?: o, s?: o, s?: i, s?: b, s?: b }",
"hooks", &json_hooks,
"signals", &json_signals,
"vectorize", &nd->vectorize,
@ -114,7 +114,7 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf
"enabled", &nd->enabled
);
if (ret)
jerror(&err, "Failed to parse node %s", node_name(n));
throw ConfigError(json, err, "node-config-node-in");
if (n->_vt->flags & (int) NodeFlags::PROVIDES_SIGNALS) {
/* Do nothing.. Node-type will provide signals */
@ -122,7 +122,7 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf
else if (json_is_array(json_signals)) {
ret = signal_list_parse(&nd->signals, json_signals);
if (ret)
error("Failed to parse signal definition of node %s", node_name(n));
throw ConfigError(json_signals, "node-config-node-signals", "Failed to parse signal definition");
}
else if (json_is_string(json_signals)) {
const char *dt = json_string_value(json_signals);
@ -146,7 +146,7 @@ int node_direction_parse(struct vnode_direction *nd, struct vnode *n, json_t *cf
enum SignalType type = signal_type_from_str(type_str);
if (type == SignalType::INVALID)
error("Invalid signal type %s", type_str);
throw ConfigError(json_signals, "node-config-node-signals", "Invalid signal type {}", type_str);
ret = signal_list_generate(&nd->signals, count, type);
if (ret)
@ -171,7 +171,7 @@ int node_direction_check(struct vnode_direction *nd, struct vnode *n)
assert(n->state != State::DESTROYED);
if (nd->vectorize <= 0)
error("Invalid setting 'vectorize' with value %d for node %s. Must be natural number!", nd->vectorize, node_name(n));
throw RuntimeError("Invalid setting 'vectorize' with value {}. Must be natural number!", nd->vectorize);
nd->state = State::CHECKED;

View file

@ -29,6 +29,8 @@
#include <villas/node/config.h>
#include <villas/plugin.h>
using namespace villas;
int node_type_start(struct vnode_type *vt, villas::node::SuperNode *sn)
{
int ret;
@ -36,7 +38,8 @@ int node_type_start(struct vnode_type *vt, villas::node::SuperNode *sn)
if (vt->state == State::STARTED)
return 0;
info("Initializing " CLR_YEL("%s") " node type which is used by %zu nodes", node_type_name(vt), vlist_length(&vt->instances));
auto logger = logging.get(fmt::format("node:{}", node_type_name(vt)));
logger->info("Initializing node type which is used by {} nodes", vlist_length(&vt->instances));
ret = vt->type.start ? vt->type.start(sn) : 0;
if (ret == 0)
@ -52,7 +55,8 @@ int node_type_stop(struct vnode_type *vt)
if (vt->state != State::STARTED)
return 0;
info("De-initializing " CLR_YEL("%s") " node type", node_type_name(vt));
auto logger = logging.get(fmt::format("node:{}", node_type_name(vt)));
logger->info("De-initializing node type");
ret = vt->type.stop ? vt->type.stop() : 0;
if (ret == 0)

View file

@ -29,7 +29,9 @@
#include <villas/nodes/amqp.hpp>
#include <villas/utils.hpp>
#include <villas/format_type.h>
#include <villas/exceptions.hpp>
using namespace villas;
using namespace villas::utils;
static void amqp_default_ssl_info(struct amqp_ssl_info *s)
@ -148,7 +150,7 @@ int amqp_parse(struct vnode *n, json_t *json)
"ssl", &json_ssl
);
if (ret)
jerror(&err, "Failed to parse configuration of node %s", node_name(n));
throw ConfigError(json, err, "node-config-node-amqp");
a->exchange = amqp_bytes_strdup(exchange);
a->routing_key = amqp_bytes_strdup(routing_key);
@ -159,9 +161,8 @@ int amqp_parse(struct vnode *n, json_t *json)
a->uri = strf("amqp://%s:%s@%s:%d/%s", username, password, host, port, vhost);
ret = amqp_parse_url(a->uri, &a->connection_info);
if (ret != AMQP_STATUS_OK)
error("Failed to parse URI '%s' of node %s", uri, node_name(n));
throw ConfigError(json, "node-config-node-uri", "Failed to parse URI '{}'", uri);
if (json_ssl) {
const char *ca_cert = nullptr;
@ -176,7 +177,7 @@ int amqp_parse(struct vnode *n, json_t *json)
"client_cert", &client_cert
);
if (ret)
jerror(&err, "Failed to parse configuration of node %s", node_name(n));
throw ConfigError(json_ssl, err, "node-config-node-amqp-ssl", "Failed to parse SSL configuration");
if (ca_cert)
a->ssl_info.ca_cert = strdup(ca_cert);
@ -190,7 +191,7 @@ int amqp_parse(struct vnode *n, json_t *json)
a->format = format_type_lookup(format);
if (!a->format)
error("Invalid format '%s' for node %s", format, node_name(n));
throw ConfigError(json, "node-config-node-amqp-format", "Invalid format '{}'", format);
return 0;
}

View file

@ -40,11 +40,13 @@
#include <villas/plugin.h>
#include <villas/signal.h>
#include <villas/node.h>
#include <villas/exceptions.hpp>
/* Forward declarations */
static struct plugin p;
using namespace villas;
using namespace villas::node;
using namespace villas::utils;
@ -72,8 +74,12 @@ int can_destroy(struct vnode *n)
close(c->socket);
free(c->sample_buf);
free(c->in);
free(c->out);
if (c->in)
free(c->in);
if (c->out)
free(c->out);
return 0;
}
@ -94,21 +100,14 @@ int can_parse_signal(json_t *json, struct vlist *node_signals, struct can_signal
"can_size", &can_size,
"can_offset", &can_offset
);
if (ret)
throw ConfigError(json, err, "node-config-node-can-signals");
if (ret) {
jerror(&err, "Failed to parse signal configuration for can");
goto out;
}
if (can_size > 8 || can_size <= 0)
throw ConfigError(json, "node-config-node-can-can-size", "can_size of {} for signal '{}' is invalid. You must satisfy 0 < can_size <= 8.", can_size, name);
if (can_size > 8 || can_size <= 0) {
error("can_size of %d for signal \"%s\" is invalid. You must satisfy 0 < can_size <= 8.", can_size, name);
goto out;
}
if (can_offset > 8 || can_offset < 0) {
error("can_offset of %d for signal \"%s\" is invalid. You must satisfy 0 <= can_offset <= 8.", can_offset, name);
goto out;
}
if (can_offset > 8 || can_offset < 0)
throw ConfigError(json, "node-config-node-can-can-offset", "can_offset of {} for signal '{}' is invalid. You must satisfy 0 <= can_offset <= 8.", can_offset, name);
sig = (struct signal*)vlist_at(node_signals, signal_index);
if ((!name && !sig->name) || (name && strcmp(name, sig->name) == 0)) {
@ -119,12 +118,12 @@ int can_parse_signal(json_t *json, struct vlist *node_signals, struct can_signal
goto out;
}
else
error("Signal configuration inconsistency detected: Signal with index %zu (\"%s\") does not match can_signal \"%s\"\n", signal_index, sig->name, name);
throw ConfigError(json, "node-config-node-can-signa;s", "Signal configuration inconsistency detected: Signal with index {} '{}' does not match can_signal '{}'", signal_index, sig->name, name);
out: return ret;
}
int can_parse(struct vnode *n, json_t *cfg)
int can_parse(struct vnode *n, json_t *json)
{
int ret = 1;
struct can *c = (struct can *) n->_vd;
@ -137,7 +136,7 @@ int can_parse(struct vnode *n, json_t *cfg)
c->in = nullptr;
c->out = nullptr;
ret = json_unpack_ex(cfg, &err, 0, "{ s: s, s: F, s?: { s?: o }, s?: { s?: o } }",
ret = json_unpack_ex(json, &err, 0, "{ s: s, s: F, s?: { s?: o }, s?: { s?: o } }",
"interface_name", &c->interface_name,
"sample_rate", &c->sample_rate,
"in",
@ -145,47 +144,35 @@ int can_parse(struct vnode *n, json_t *cfg)
"out",
"signals", &json_out_signals
);
if (ret) {
jerror(&err, "Failed to parse configuration of node %s", node_name(n));
goto out;
}
if (ret)
throw ConfigError(json, err, "node-config-node-can");
if ((c->in = (struct can_signal*)calloc(
c->in = (struct can_signal*) calloc(
json_array_size(json_in_signals),
sizeof(struct can_signal))) == nullptr) {
error("failed to allocate memory for input ids");
goto out;
}
if ((c->out = (struct can_signal*)calloc(
sizeof(struct can_signal));
if (!c->in)
throw MemoryAllocationError();
c->out = (struct can_signal*)calloc(
json_array_size(json_out_signals),
sizeof(struct can_signal))) == nullptr) {
error("failed to allocate memory for output ids");
goto out;
}
sizeof(struct can_signal));
if (c->out)
throw MemoryAllocationError();
json_array_foreach(json_in_signals, i, json_signal) {
if (can_parse_signal(json_signal, &n->in.signals, c->in, i) != 0) {
error("at signal %zu in node %s.",i , node_name(n));
goto out;
}
ret = can_parse_signal(json_signal, &n->in.signals, c->in, i);
if (ret)
throw RuntimeError("at signal {}.",i);
}
json_array_foreach(json_out_signals, i, json_signal) {
if (can_parse_signal(json_signal, &n->out.signals, c->out, i) != 0) {
error("at signal %zu in node %s.",i , node_name(n));
goto out;
}
ret = can_parse_signal(json_signal, &n->out.signals, c->out, i);
if (ret)
throw RuntimeError("at signal {}.", i);
}
ret = 0;
out: if (ret != 0) {
free(c->in);
free(c->out);
c->in = nullptr;
c->out = nullptr;
}
return ret;
}
@ -193,17 +180,15 @@ char * can_print(struct vnode *n)
{
struct can *c = (struct can *) n->_vd;
return strf("interface_name=%s", c->interface_name);
return strf("interface_name={}", c->interface_name);
}
int can_check(struct vnode *n)
{
struct can *c = (struct can *) n->_vd;
if (c->interface_name == nullptr || strlen(c->interface_name) == 0) {
error("interface_name is empty. Please specify the name of the CAN interface!");
return 1;
}
if (c->interface_name == nullptr || strlen(c->interface_name) == 0)
throw RuntimeError("Empty interface_name. Please specify the name of the CAN interface!");
return 0;
}
@ -226,28 +211,24 @@ int can_start(struct vnode *n)
struct can *c = (struct can *) n->_vd;
c->start_time = time_now();
if ((c->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
error("Error while opening CAN socket");
goto out;
}
c->socket = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (c->socket < 0)
throw SystemError("Error while opening CAN socket");
strcpy(ifr.ifr_name, c->interface_name);
if (ioctl(c->socket, SIOCGIFINDEX, &ifr) != 0) {
error("Could not find interface with name \"%s\".", c->interface_name);
goto out;
}
ret = ioctl(c->socket, SIOCGIFINDEX, &ifr);
if (ret != 0)
throw SystemError("Could not find interface with name '{}'.", c->interface_name);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if (bind(c->socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
error("Could not bind to interface with name \"%s\" (%d).", c->interface_name, ifr.ifr_ifindex);
goto out;
}
ret = bind(c->socket, (struct sockaddr *)&addr, sizeof(addr));
if (ret < 0)
throw SystemError("Could not bind to interface with name '{}' ({}).", c->interface_name, ifr.ifr_ifindex);
ret = 0;
out: return ret;
return 0;
}
int can_stop(struct vnode *n)
@ -264,10 +245,8 @@ int can_stop(struct vnode *n)
int can_conv_to_raw(union signal_data* sig, struct signal *from, void* to, int size)
{
if (size <= 0 || size > 8) {
error("signal size cannot be larger than 8!");
return 1;
}
if (size <= 0 || size > 8)
throw RuntimeError("Signal size cannot be larger than 8!");
switch(from->type) {
case SignalType::BOOLEAN:
@ -327,17 +306,16 @@ int can_conv_to_raw(union signal_data* sig, struct signal *from, void* to, int s
goto fail;
}
fail: error("unsupported conversion to %s from raw (%p, %d)", signal_type_to_str(from->type), to, size);
fail:
throw RuntimeError("Unsupported conversion to {} from raw ({}, {})", signal_type_to_str(from->type), to, size);
return 1;
}
int can_conv_from_raw(union signal_data* sig, void* from, int size, struct signal *to)
{
if (size <= 0 || size > 8) {
error("signal size cannot be larger than 8!");
return 1;
}
if (size <= 0 || size > 8)
throw RuntimeError("Signal size cannot be larger than 8!");
switch(to->type) {
case SignalType::BOOLEAN:
@ -394,7 +372,7 @@ int can_conv_from_raw(union signal_data* sig, void* from, int size, struct signa
goto fail;
}
fail:
error("unsupported conversion from %s to raw (%p, %d)", signal_type_to_str(to->type), from, size);
throw RuntimeError("Unsupported conversion from {} to raw ({}, {})", signal_type_to_str(to->type), from, size);
return 1;
}
@ -413,17 +391,13 @@ int can_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel
assert(cnt >= 1 && smps[0]->capacity >= 1);
nbytes = read(c->socket, &frame, sizeof(struct can_frame));
if (nbytes == -1) {
error("CAN read() returned -1. Is the CAN interface up?");
goto out;
}
if (nbytes == -1)
throw RuntimeError("CAN read() returned -1. Is the CAN interface up?");
if ((unsigned)nbytes != sizeof(struct can_frame)) {
error("CAN read() error. read() returned %d bytes but expected %zu", nbytes, sizeof(struct can_frame));
goto out;
}
if ((unsigned)nbytes != sizeof(struct can_frame))
throw RuntimeError("CAN read() error. Returned {} bytes but expected {}", nbytes, sizeof(struct can_frame));
debug(0,"received can message: (id:%d, len:%u, data: 0x%x:0x%x)",
n->logger->debug("Received can message: (id={}, len={}, data={:#x}:{:#x})",
frame.can_id,
frame.can_dlc,
((uint32_t*)&frame.data)[0],
@ -448,12 +422,10 @@ int can_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *rel
}
}
if (!found_id) {
error("did not find signal for can id %d\n", frame.can_id);
return 0;
}
if (!found_id)
throw RuntimeError("Did not find signal for can id {}", frame.can_id);
debug(0, "received %zu signals\n", c->sample_buf_num);
n->logger->debug("Received {} signals", c->sample_buf_num);
/* Copy signal data to sample only when all signals have been received */
if (c->sample_buf_num == vlist_length(&n->in.signals)) {
@ -524,23 +496,19 @@ int can_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *re
}
for (size_t j=0; j < fsize; j++) {
debug(0,"writing can message: (id:%d, dlc:%u, data:0x%x:0x%x)",
n->logger->debug("Writing CAN message: (id={}, dlc={}, data={:#x}:{:#x})",
frame[j].can_id,
frame[j].can_dlc,
((uint32_t*)&frame[j].data)[0],
((uint32_t*)&frame[j].data)[1]
);
if ((nbytes = write(c->socket, &frame[j], sizeof(struct can_frame))) == -1) {
error("CAN write() returned -1. Is the CAN interface up?");
return nwrite;
}
if ((nbytes = write(c->socket, &frame[j], sizeof(struct can_frame))) == -1)
throw RuntimeError("CAN write() returned -1. Is the CAN interface up?");
if ((unsigned)nbytes != sizeof(struct can_frame)) {
error("CAN write() error. write() returned %d bytes but expected %zu",
if ((unsigned)nbytes != sizeof(struct can_frame))
throw RuntimeError("CAN write() returned {} bytes but expected {}",
nbytes, sizeof(struct can_frame));
return nwrite;
}
}
}

View file

@ -37,9 +37,9 @@ using namespace villas::utils;
/* Utility functions to dump a comedi_cmd graciously taken from comedilib demo */
static char* comedi_cmd_trigger_src(unsigned int src, char *buf);
static void comedi_dump_cmd(comedi_cmd *cmd, int debug_level);
static void comedi_dump_cmd(Logger logger, comedi_cmd *cmd);
static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d, json_t *cfg)
static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d, json_t *json)
{
int ret;
@ -50,14 +50,14 @@ static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d,
d->subdevice = -1;
d->buffer_size = 16;
ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: i, s: o, s: i }",
ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?: i, s: o, s: i }",
"subdevice", &d->subdevice,
"bufsize", &d->buffer_size,
"signals", &json_chans,
"rate", &d->sample_rate_hz
);
if (ret)
jerror(&err, "Failed to parse configuration");
throw ConfigError(json, err, "node-config-node-comedi");
if (!json_is_array(json_chans))
return -1;
@ -69,10 +69,8 @@ static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d,
json_t *json_chan;
d->chanlist_len = json_array_size(json_chans);
if (d->chanlist_len == 0) {
error("No channels configured");
return 0;
}
if (d->chanlist_len == 0)
throw ConfigError(json_chans, "node-config-node-channels", "No channels configured");
d->chanlist = new unsigned int[d->chanlist_len];
if (!d->chanlist)
@ -85,14 +83,15 @@ static int comedi_parse_direction(struct comedi *c, struct comedi_direction *d,
json_array_foreach(json_chans, i, json_chan) {
int num, range, aref;
ret = json_unpack_ex(json_chan, &err, 0, "{ s: i, s: i, s: i }",
"channel", &num,
"range", &range,
"aref", &aref);
"channel", &num,
"range", &range,
"aref", &aref
);
if (ret)
jerror(&err, "Failed to parse configuration");
throw ConfigError(json_chan, err, "node-config-node-comedi");
if (aref < AREF_GROUND || aref > AREF_OTHER)
error("Invalid value for analog reference: aref=%d", aref);
throw ConfigError(json_chan, "node-config-node-comedi-aref", "Invalid value for analog reference: aref={}", aref);
d->chanlist[i] = CR_PACK(num, range, aref);
}
@ -121,25 +120,22 @@ static int comedi_start_common(struct vnode *n)
ret = comedi_get_n_ranges(c->dev, d->subdevice, channel);
if (ret < 0)
error("Failed to get ranges for channel %d on subdevice %d",
channel, d->subdevice);
throw RuntimeError("Failed to get ranges for channel {} on subdevice {}", channel, d->subdevice);
if (range >= ret)
error("Invalid range for channel %d on subdevice %d: range=%d",
channel, d->subdevice, range);
throw RuntimeError("Invalid range for channel {} on subdevice {}: range={}", channel, d->subdevice, range);
ret = comedi_get_maxdata(c->dev, d->subdevice, channel);
if (ret <= 0)
error("Failed to get max. data value for channel %d on subdevice %d",
channel, d->subdevice);
throw RuntimeError("Failed to get max. data value for channel {} on subdevice {}", channel, d->subdevice);
d->chanspecs[i].maxdata = ret;
d->chanspecs[i].range = comedi_get_range(c->dev, d->subdevice,
channel, range);
info("%s channel: %d aref=%d range=%d maxdata=%d",
(d == &c->in ? "Input" : "Output"), channel,
CR_AREF(d->chanlist[i]), range, d->chanspecs[i].maxdata);
n->logger->info("{} channel: {} aref={} range={} maxdata={}",
(d == &c->in ? "Input" : "Output"), channel,
CR_AREF(d->chanlist[i]), range, d->chanspecs[i].maxdata);
}
const int flags = comedi_get_subdevice_flags(c->dev, d->subdevice);
@ -150,13 +146,13 @@ static int comedi_start_common(struct vnode *n)
comedi_set_max_buffer_size(c->dev, d->subdevice, d->buffer_size);
ret = comedi_get_buffer_size(c->dev, d->subdevice);
if (ret != d->buffer_size)
error("Failed to set buffer size for subdevice %d of node '%s'", d->subdevice, node_name(n));
throw RuntimeError("Failed to set buffer size for subdevice {}", d->subdevice);
info("Set buffer size for subdevice %d to %d bytes", d->subdevice, d->buffer_size);
n->logger->info("Set buffer size for subdevice {} to {} bytes", d->subdevice, d->buffer_size);
ret = comedi_lock(c->dev, d->subdevice);
if (ret)
error("Failed to lock subdevice %d for node '%s'", d->subdevice, node_name(n));
throw RuntimeError("Failed to lock subdevice {}", d->subdevice);
}
return 0;
@ -172,24 +168,23 @@ static int comedi_start_in(struct vnode *n)
if (d->subdevice < 0) {
d->subdevice = comedi_find_subdevice_by_type(c->dev, COMEDI_SUBD_AI, 0);
if (d->subdevice < 0)
error("Cannot find analog input device for node '%s'", node_name(n));
throw RuntimeError("Cannot find analog input device for node '{}'");
}
else {
/* Check if subdevice is usable */
ret = comedi_get_subdevice_type(c->dev, d->subdevice);
if (ret != COMEDI_SUBD_AI)
error("Input subdevice of node '%s' is not an analog input", node_name(n));
throw RuntimeError("Input subdevice is not an analog input");
}
ret = comedi_get_subdevice_flags(c->dev, d->subdevice);
if (ret < 0 || !(ret & SDF_CMD_READ))
error("Input subdevice of node '%s' does not support 'read' commands", node_name(n));
throw RuntimeError("Input subdevice does not support 'read' commands");
comedi_set_read_subdevice(c->dev, d->subdevice);
ret = comedi_get_read_subdevice(c->dev);
if (ret < 0 || ret != d->subdevice)
error("Failed to change 'read' subdevice from %d to %d of node '%s'",
ret, d->subdevice, node_name(n));
throw RuntimeError("Failed to change 'read' subdevice from {} to {}", ret, d->subdevice);
comedi_cmd cmd;
memset(&cmd, 0, sizeof(cmd));
@ -225,14 +220,14 @@ static int comedi_start_in(struct vnode *n)
ret = comedi_command_test(c->dev, &cmd);
ret = comedi_command_test(c->dev, &cmd);
if (ret < 0)
error("Invalid command for input subdevice of node '%s'", node_name(n));
throw RuntimeError("Invalid command for input subdevice");
info("Input command:");
comedi_dump_cmd(&cmd, 1);
n->logger->info("Input command:");
comedi_dump_cmd(n->logger, &cmd);
ret = comedi_command(c->dev, &cmd);
if (ret < 0)
error("Failed to issue command to input subdevice of node '%s'", node_name(n));
throw RuntimeError("Failed to issue command to input subdevice");
d->started = time_now();
d->counter = 0;
@ -245,9 +240,9 @@ static int comedi_start_in(struct vnode *n)
if (!c->buf)
throw MemoryAllocationError();
info("Compiled for kernel read() interface");
n->logger->info("Compiled for kernel read() interface");
#else
info("Compiled for kernel mmap() interface");
n->logger->info("Compiled for kernel mmap() interface");
#endif
return 0;
@ -263,23 +258,22 @@ static int comedi_start_out(struct vnode *n)
if (d->subdevice < 0) {
d->subdevice = comedi_find_subdevice_by_type(c->dev, COMEDI_SUBD_AO, 0);
if (d->subdevice < 0)
error("Cannot find analog output device for node '%s'", node_name(n));
throw RuntimeError("Cannot find analog output device");
}
else {
ret = comedi_get_subdevice_type(c->dev, d->subdevice);
if (ret != COMEDI_SUBD_AO)
error("Output subdevice of node '%s' is not an analog output", node_name(n));
throw RuntimeError("Output subdevice is not an analog output");
}
ret = comedi_get_subdevice_flags(c->dev, d->subdevice);
if (ret < 0 || !(ret & SDF_CMD_WRITE))
error("Output subdevice of node '%s' does not support 'write' commands", node_name(n));
throw RuntimeError("Output subdevice does not support 'write' commands");
comedi_set_write_subdevice(c->dev, d->subdevice);
ret = comedi_get_write_subdevice(c->dev);
if (ret < 0 || ret != d->subdevice)
error("Failed to change 'write' subdevice from %d to %d of node '%s'",
ret, d->subdevice, node_name(n));
throw RuntimeError("Failed to change 'write' subdevice from {} to {}", ret, d->subdevice);
comedi_cmd cmd;
memset(&cmd, 0, sizeof(cmd));
@ -311,24 +305,24 @@ static int comedi_start_out(struct vnode *n)
/* First run might change command, second should return successfully */
ret = comedi_command_test(c->dev, &cmd);
if (ret < 0)
error("Invalid command for input subdevice of node '%s'", node_name(n));
throw RuntimeError("Invalid command for input subdevice");
ret = comedi_command_test(c->dev, &cmd);
if (ret < 0)
error("Invalid command for input subdevice of node '%s'", node_name(n));
throw RuntimeError("Invalid command for input subdevice");
info("Output command:");
comedi_dump_cmd(&cmd, 1);
n->logger->info("Output command:");
comedi_dump_cmd(n->logger, &cmd);
ret = comedi_command(c->dev, &cmd);
if (ret < 0)
error("Failed to issue command to input subdevice of node '%s'", node_name(n));
throw RuntimeError("Failed to issue command to input subdevice of node '{}'");
/* Output will only start after the internal trigger */
d->running = false;
d->last_debug = time_now();
/* Allocate buffer for one complete villas sample */
/* Allocate buffer for one complete VILLAS sample */
/** @todo: maybe increase buffer size according to c->vectorize */
const size_t local_buffer_size = d->sample_size * d->chanlist_len;
d->buffer = new char[local_buffer_size];
@ -352,13 +346,13 @@ static int comedi_start_out(struct vnode *n)
for (unsigned i = 0; i < d->buffer_size / local_buffer_size; i++) {
size_t written = write(comedi_fileno(c->dev), d->buffer, local_buffer_size);
if (written != local_buffer_size) {
error("Cannot preload Comedi buffer");
throw RuntimeError("Cannot preload Comedi buffer");
}
}
const size_t villas_samples_in_kernel_buf = d->buffer_size / (d->sample_size * d->chanlist_len);
const double latencyMs = (double)villas_samples_in_kernel_buf / d->sample_rate_hz * 1e3;
info("Added latency due to buffering: %4.1f ms\n", latencyMs);
const double latencyMs = (double) villas_samples_in_kernel_buf / d->sample_rate_hz * 1e3;
n->logger->info("Added latency due to buffering: {:4.1f} ms", latencyMs);
return 0;
}
@ -373,7 +367,7 @@ static int comedi_stop_in(struct vnode *n)
ret = comedi_unlock(c->dev, d->subdevice);
if (ret)
error("Failed to lock subdevice %d for node '%s'", d->subdevice, node_name(n));
throw RuntimeError("Failed to lock subdevice {}", d->subdevice);
return 0;
}
@ -388,12 +382,12 @@ static int comedi_stop_out(struct vnode *n)
ret = comedi_unlock(c->dev, d->subdevice);
if (ret)
error("Failed to lock subdevice %d for node '%s'", d->subdevice, node_name(n));
throw RuntimeError("Failed to lock subdevice {}", d->subdevice);
return 0;
}
int comedi_parse(struct vnode *n, json_t *cfg)
int comedi_parse(struct vnode *n, json_t *json)
{
int ret;
struct comedi *c = (struct comedi *) n->_vd;
@ -404,13 +398,13 @@ int comedi_parse(struct vnode *n, json_t *cfg)
json_t *json_out = nullptr;
json_error_t err;
ret = json_unpack_ex(cfg, &err, 0, "{ s: s, s?: o, s?: o }",
"device", &device,
"in", &json_in,
"out", &json_out);
ret = json_unpack_ex(json, &err, 0, "{ s: s, s?: o, s?: o }",
"device", &device,
"in", &json_in,
"out", &json_out);
if (ret)
jerror(&err, "Failed to parse configuration of node %s", node_name(n));
throw ConfigError(json, err, "node-config-node-comedi");
c->in.present = json_in != nullptr;
c->in.enabled = false;
@ -456,15 +450,13 @@ int comedi_start(struct vnode *n)
struct comedi *c = (struct comedi *) n->_vd;
c->dev = comedi_open(c->device);
if (!c->dev) {
const char *err = comedi_strerror(comedi_errno());
error("Failed to open device: %s", err);
}
if (!c->dev)
throw RuntimeError("Failed to open device: {}", comedi_strerror(comedi_errno()));
/* Enable non-blocking syscalls */
/** @todo: verify if this works with both input and output, so comment out */
//if (fcntl(comedi_fileno(c->dev), F_SETFL, O_NONBLOCK))
// error("Failed to set non-blocking flag in Comedi FD of node '%s'", node_name(n));
// throw RuntimeError("Failed to set non-blocking flag in Comedi FD");
comedi_start_common(n);
@ -485,10 +477,10 @@ int comedi_start(struct vnode *n)
}
#if !COMEDI_USE_READ
info("Mapping Comedi buffer of %d bytes", c->in.buffer_size);
n->logger->info("Mapping Comedi buffer of {} bytes", c->in.buffer_size);
c->map = mmap(nullptr, c->in.buffer_size, PROT_READ, MAP_SHARED, comedi_fileno(c->dev), 0);
if (c->map == MAP_FAILED)
error("Failed to map comedi buffer of node '%s'", node_name(n));
throw RuntimeError("Failed to map Comedi buffer");
c->front = 0;
c->back = 0;
@ -528,9 +520,9 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
ret = comedi_get_buffer_contents(c->dev, d->subdevice);
if (ret < 0) {
if (comedi_errno() == EBUF_OVR)
error("Comedi buffer overflow");
throw RuntimeError("Comedi buffer overflow");
else
error("Comedi error: %s", comedi_strerror(comedi_errno()));
throw RuntimeError("Comedi error: {}", comedi_strerror(comedi_errno()));
}
fd_set rdset;
@ -543,7 +535,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
ret = select(comedi_fileno(c->dev) + 1, &rdset, nullptr, nullptr, &timeout);
if (ret < 0)
error("select");
throw RuntimeError("Failed select()");
else if (ret == 0) /* hit timeout */
return 0;
else if (FD_ISSET(comedi_fileno(c->dev), &rdset)) { /* comedi file descriptor became ready */
@ -553,12 +545,12 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
ret = read(comedi_fileno(c->dev), c->bufptr, MIN(bytes_requested, buffer_bytes_free));
if (ret < 0) {
if (errno == EAGAIN)
error("read");
throw RuntimeError("Failed read()");
else
return 0;
}
else if (ret == 0) {
warning("select timeout, no samples available");
n->logger->warn("Timeout in select(), no samples available");
return 0;
}
else {
@ -567,11 +559,8 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
const size_t raw_samples_available = bytes_available / d->sample_size;
const size_t villas_samples_available = raw_samples_available / d->chanlist_len;
info("there are %zd bytes available (%zu requested) => %zu villas samples",
bytes_available, bytes_requested, villas_samples_available);
info("there are %zu kB available (%zu kB requested)",
bytes_available / 1024, bytes_requested / 1024);
n->logger->info("There are {} bytes available ({} requested) => {} VILLAS samples",
bytes_available, bytes_requested, villas_samples_available);
if (cnt > villas_samples_available)
cnt = villas_samples_available;
@ -588,10 +577,8 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
smps[i]->length = d->chanlist_len;
if (smps[i]->capacity < d->chanlist_len) {
error("Sample has insufficient capacity: %d < %zd",
smps[i]->capacity, d->chanlist_len);
}
if (smps[i]->capacity < d->chanlist_len)
throw RuntimeError("Sample has insufficient capacity: {} < {}", smps[i]->capacity, d->chanlist_len);
for (unsigned si = 0; si < d->chanlist_len; si++) {
unsigned int raw;
@ -606,7 +593,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
smps[i]->data[si].f = comedi_to_phys(raw, d->chanspecs[si].range, d->chanspecs[si].maxdata);
if (std::isnan(smps[i]->data[si].f))
warning("Input: channel %d clipped", CR_CHAN(d->chanlist[si]));
n->logger->warn("Input: channel {} clipped", CR_CHAN(d->chanlist[si]));
}
}
@ -618,7 +605,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
memmove(c->buf, c->bufptr, bytes_left);
}
info("consumed %zd bytes", bytes_consumed);
n->logger->info("Consumed {} bytes", bytes_consumed);
/* Start at the beginning again */
c->bufptr = c->buf;
@ -626,10 +613,9 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
return cnt;
}
}
else {
else
/* unknown file descriptor became ready */
printf("unknown file descriptor ready\n");
}
n->logger->warn("Unknown file descriptor ready");
return -1;
}
@ -646,16 +632,16 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
comedi_set_read_subdevice(c->dev, d->subdevice);
info("current bufpos=%ld", c->bufpos);
n->logger->info("Current bufpos={}", c->bufpos);
#if 0
if (c->bufpos > (d->buffer_size - villas_sample_size)) {
ret = comedi_get_buffer_read_offset(c->dev, d->subdevice);
if (ret < 0)
error("Canot get offset");
throw RuntimeError("Canot get offset");
c->bufpos = ret;
info("change bufpos=%ld", c->bufpos);
n->logger->info("Change bufpos={}", c->bufpos);
}
#endif
@ -664,9 +650,9 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
return 0;
else if (ret < 0) {
if (comedi_errno() == EBUF_OVR)
error("Comedi buffer overflow");
throw RuntimeError("Comedi buffer overflow");
else
error("Comedi error: %s", comedi_strerror(comedi_errno()));
throw RuntimeError("Comedi error: {}", comedi_strerror(comedi_errno()));
}
const size_t bytes_available = ret;
@ -675,17 +661,17 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
if (villas_sample_count == 0)
return 0;
info("there are %ld villas samples (%ld raw bytes, %ld channels)", villas_sample_count, bytes_available, d->chanlist_len);
n->logger->info("There are {} VILLAS samples ({} raw bytes, {} channels)", villas_sample_count, bytes_available, d->chanlist_len);
#if 0
if (villas_sample_count == 1)
info("front=%ld back=%ld bufpos=%ld", c->front, c->back, c->bufpos);
n->logger->info("front={} back={} bufpos={}", c->front, c->back, c->bufpos);
if ((c->bufpos + bytes_available) >= d->buffer_size) {
/* Let comedi do the wraparound, only consume until end of buffer */
villas_sample_count = (d->buffer_size - c->bufpos) / villas_sample_size;
warning("Reducing consumption from %d to %ld bytes", ret, bytes_available);
warning("Only consume %ld villas samples b/c of buffer wraparound", villas_sample_count);
n->logger->warn("Reducing consumption from {} to {} bytes", ret, bytes_available);
n->logger->warn("Only consume {} VILLAS samples b/c of buffer wraparound", villas_sample_count);
}
#endif
@ -694,12 +680,11 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
#if 0
if (bytes_available != 0 && bytes_available < villas_sample_size) {
warning("Cannot consume samples, only %d bytes available, throw away", ret);
n->logger->warn("Cannot consume samples, only {} bytes available, throw away", ret);
ret = comedi_mark_buffer_read(c->dev, d->subdevice, bytes_available);
if (ret != bytes_available)
error("Cannot throw away %ld bytes, returned %d, wtf comedi?!",
bytes_available, ret);
throw RuntimeError("Cannot throw away {} bytes, returned {}", bytes_available, ret);
return 0;
}
@ -709,15 +694,15 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
ret = comedi_mark_buffer_read(c->dev, d->subdevice, samples_total_bytes);
if (ret == 0) {
warning("Marking read buffer (%ld bytes) not working, try again later", samples_total_bytes);
n->logger->warn("Marking read buffer ({} bytes) not working, try again later", samples_total_bytes);
return 0;
}
else if (ret != samples_total_bytes) {
warning("Can only mark %d bytes as read, reducing samples", ret);
n->logger->warn("Can only mark {} bytes as read, reducing samples", ret);
return 0;
}
else
info("Consume %d bytes", ret);
n->logger->info("Consume {} bytes", ret);
/* Align front to whole samples */
c->front = c->back + samples_total_bytes;
@ -734,8 +719,7 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
smps[i]->length = d->chanlist_len;
if (smps[i]->capacity < d->chanlist_len)
error("Sample has insufficient capacity: %d < %ld",
smps[i]->capacity, d->chanlist_len);
throw RuntimeError("Sample has insufficient capacity: {} < {}", smps[i]->capacity, d->chanlist_len);
for (int si = 0; si < d->chanlist_len; si++) {
unsigned int raw;
@ -747,15 +731,14 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
smps[i]->data[si].f = comedi_to_phys(raw, d->chanspecs[si].range, d->chanspecs[si].maxdata);
if (isnan(smps[i]->data[si].f)) {
error("got nan");
}
if (isnan(smps[i]->data[si].f))
throw RuntimeError("Got nan");
// smps[i]->data[si].i = raw;
c->bufpos += d->sample_size;
if (c->bufpos >= d->buffer_size) {
warning("read buffer wraparound");
n->logger->warn("Read buffer wraparound");
// c->bufpos = 0;
}
}
@ -763,52 +746,52 @@ int comedi_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned *
// const size_t bytes_consumed = c->front - c->back;
// info("advance comedi buffer by %ld bytes", bytes_consumed);
// n->logger->info("Advance Comedi buffer by {} bytes", bytes_consumed);
ret = comedi_get_buffer_read_offset(c->dev, d->subdevice);
if (ret < 0) {
if (comedi_errno() != EPIPE)
error("Failed to get read buffer offset: %d, comedi errno %d", ret, comedi_errno());
throw RuntimeError("Failed to get read buffer offset: {}, Comedi error {}", ret, comedi_strerror(comedi_errno()));
else
ret = c->bufpos;
}
warning("change bufpos: %ld to %d", c->bufpos, ret);
n->logger->warn("Change bufpos: {} to {}", c->bufpos, ret);
c->bufpos = ret;
#if 0
ret = comedi_mark_buffer_read(c->dev, d->subdevice, bytes_consumed);
if (ret < 0) //!= bytes_consumed)
error("Failed to mark buffer position (ret=%d) for input stream of node '%s'", ret, node_name(n));
throw RuntimeError("Failed to mark buffer position (ret={}) for input stream", ret);
// else if (ret == 0) {
else {
info("consumed %ld bytes", bytes_consumed);
info("mark buffer returned %d", ret);
n->logger->info("Consumed {} bytes", bytes_consumed);
n->logger->info("Mark buffer returned {}", ret);
if (ret == 0) {
ret = comedi_mark_buffer_read(c->dev, d->subdevice, bytes_consumed);
info("trying again, mark buffer returned now %d", ret);
n->logger->info("Trying again, mark buffer returned now {}", ret);
}
if (ret > 0) {
ret = comedi_get_buffer_read_offset(c->dev, d->subdevice);
if (ret < 0)
error("Failed to get read buffer offset");
throw RuntimeError("Failed to get read buffer offset");
warning("change bufpos1: %ld to %d", c->bufpos, ret);
n->logger->warn("Change bufpos1: {} to {}", c->bufpos, ret);
c->bufpos = ret;
}
else {
// warning("change bufpos2: %ld to %ld", c->bufpos, c->);
// n->logger->warn("Change bufpos2: {} to {}", c->bufpos, c->);
// c->bufpos += bytes_consumed;
warning("keep bufpos=%ld", c->bufpos);
n->logger->warn("Keep bufpos={}", c->bufpos);
}
// c->bufpos = 0;
}
#endif
// info("new bufpos: %ld", c->bufpos);
// n->logger->info("New bufpos: {}", c->bufpos);
c->back = c->front;
@ -824,7 +807,7 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
struct comedi_direction *d = &c->out;
if (!d->enabled) {
warning("Attempting to write, but output is not enabled");
n->logger->warn("Attempting to write, but output is not enabled");
return 0;
}
@ -832,13 +815,13 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
/* Output was not yet running, so start now */
ret = comedi_internal_trigger(c->dev, d->subdevice, 0);
if (ret < 0)
error("Failed to trigger-start output");
throw RuntimeError("Failed to trigger-start output");
d->started = time_now();
d->counter = 0;
d->running = true;
info("Starting output of node '%s'", node_name(n));
n->logger->info("Starting output");
}
const size_t buffer_capacity_raw = d->buffer_size / d->sample_size;
@ -848,9 +831,9 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
ret = comedi_get_buffer_contents(c->dev, d->subdevice);
if (ret < 0) {
if (comedi_errno() == EBUF_OVR)
error("Comedi buffer overflow");
throw RuntimeError("Comedi buffer overflow");
else
error("Comedi error: %s", comedi_strerror(comedi_errno()));
throw RuntimeError("Comedi error: {}", comedi_strerror(comedi_errno()));
}
const size_t bytes_in_buffer = ret;
@ -858,15 +841,15 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
const size_t villas_samples_in_buffer = raw_samples_in_buffer / d->chanlist_len;
if (villas_samples_in_buffer == buffer_capacity_villas) {
warning("Comedi buffer is full");
n->logger->warn("Comedi buffer is full");
return 0;
}
else {
struct timespec now = time_now();
if (time_delta(&d->last_debug, &now) >= 1) {
debug(LOG_COMEDI | 2, "Comedi write buffer: %4zd villas samples (%2.0f%% of buffer)",
villas_samples_in_buffer,
(100.0f * villas_samples_in_buffer / buffer_capacity_villas));
n->logger->debug("Comedi write buffer: {} VILLAS samples ({}% of buffer)",
villas_samples_in_buffer,
(100.0f * villas_samples_in_buffer / buffer_capacity_villas));
d->last_debug = time_now();
}
@ -877,8 +860,7 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
while (villas_samples_written < cnt) {
struct sample *sample = smps[villas_samples_written];
if (sample->length != d->chanlist_len)
error("Value count in sample (%d) != configured output channels (%zd)",
sample->length, d->chanlist_len);
throw RuntimeError("Value count in sample ({}) != configured output channels ({})", sample->length, d->chanlist_len);
d->bufptr = d->buffer;
@ -921,18 +903,17 @@ int comedi_write(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
/* Try to write one complete villas sample to comedi */
size_t written = write(comedi_fileno(c->dev), d->buffer, villas_sample_size);
if (written < 0)
error("write");
throw RuntimeError("write() failed");
else if (written == 0)
break; /* Comedi doesn't accept any more samples at the moment */
else if (written == villas_sample_size)
villas_samples_written++;
else
error("Only partial sample written (%zu bytes), oops", written);
throw RuntimeError("Only partial sample written ({} bytes), oops", written);
}
if (villas_samples_written == 0) {
warning("Nothing done");
}
if (villas_samples_written == 0)
n->logger->warn("Nothing done");
d->counter += villas_samples_written;
@ -960,27 +941,27 @@ char* comedi_cmd_trigger_src(unsigned int src, char *buf)
return buf;
}
void comedi_dump_cmd(comedi_cmd *cmd, int debug_level)
void comedi_dump_cmd(Logger logger, comedi_cmd *cmd)
{
char buf[256];
char* src;
debug(LOG_COMEDI | debug_level, "subdevice: %u", cmd->subdev);
logger->debug("subdevice: {}", cmd->subdev);
src = comedi_cmd_trigger_src(cmd->start_src, buf);
debug(LOG_COMEDI | debug_level, "start: %-8s %u", src, cmd->start_arg);
logger->debug("start: {:-8s} {}", src, cmd->start_arg);
src = comedi_cmd_trigger_src(cmd->scan_begin_src, buf);
debug(LOG_COMEDI | debug_level, "scan_begin: %-8s %u", src, cmd->scan_begin_arg);
logger->debug("scan_begin: {:-8s} {}", src, cmd->scan_begin_arg);
src = comedi_cmd_trigger_src(cmd->convert_src, buf);
debug(LOG_COMEDI | debug_level, "convert: %-8s %u", src, cmd->convert_arg);
logger->debug("convert: {:-8s} {}", src, cmd->convert_arg);
src = comedi_cmd_trigger_src(cmd->scan_end_src, buf);
debug(LOG_COMEDI | debug_level, "scan_end: %-8s %u", src, cmd->scan_end_arg);
logger->debug("scan_end: {:-8s} {}", src, cmd->scan_end_arg);
src = comedi_cmd_trigger_src(cmd->stop_src,buf);
debug(LOG_COMEDI | debug_level, "stop: %-8s %u", src, cmd->stop_arg);
logger->debug("stop: {:-8s} {}", src, cmd->stop_arg);
}
int comedi_poll_fds(struct vnode *n, int fds[])

View file

@ -27,7 +27,6 @@
#include <villas/super_node.hpp>
#include <villas/utils.hpp>
#include <villas/plugin.h>
#include <villas/log.h>
#include <villas/exceptions.hpp>
#include <villas/nodes/ethercat.hpp>
@ -75,7 +74,7 @@ static void ethercat_cyclic_task(struct vnode *n)
/* Receive process data */
smp = sample_alloc(&w->pool);
if (!smp) {
warning("Pool underrun in node %s", node_name(n));
n->logger->warn("Pool underrun");
continue;
}
@ -92,7 +91,7 @@ static void ethercat_cyclic_task(struct vnode *n)
ret = queue_signalled_push(&w->queue, smp);
if (ret)
warning("Ethercat: Failed to enqueue samples");
n->logger->warn("Failed to enqueue samples");
/* Write process data */
smp = w->send.exchange(nullptr);
@ -116,9 +115,9 @@ int ethercat_type_start(villas::node::SuperNode *sn)
int ret;
json_error_t err;
json_t *cfg = sn->getConfig();
if (cfg) {
ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?:i, s?: { s?: { s?: i, s?: i, s?: i } } }",
json_t *json = sn->getConfig();
if (json) {
ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?:i, s?: { s?: { s?: i, s?: i, s?: i } } }",
"ethernet",
"master", &master_id,
"alias", &alias,
@ -128,7 +127,7 @@ int ethercat_type_start(villas::node::SuperNode *sn)
"vendor_id", &coupler.vendor_id
);
if (ret)
jerror(&err, "Failed to parse EtherCAT configuration");
throw ConfigError(json, err, "node-config-node-ethercat");
}
master = ecrt_request_master(master_id);
@ -145,21 +144,23 @@ int ethercat_type_start(villas::node::SuperNode *sn)
int ethercat_type_stop()
{
info("Releasing EtherCAT master");
auto logger = logging.get("node:ethercat");
logger->info("Releasing EtherCAT master");
ecrt_release_master(master);
return 0;
}
int ethercat_parse(struct vnode *n, json_t *cfg)
int ethercat_parse(struct vnode *n, json_t *json)
{
struct ethercat *w = (struct ethercat *) n->_vd;
int ret;
json_error_t err;
ret = json_unpack_ex(cfg, &err, 0, "{ s?: F, s?: { s: i, s?: F, s?: i, s?: i, s?: i }, s?: { s: i, s?: F, s?: i, s?: i, s?: i } }",
ret = json_unpack_ex(json, &err, 0, "{ s?: F, s?: { s: i, s?: F, s?: i, s?: i, s?: i }, s?: { s: i, s?: F, s?: i, s?: i, s?: i } }",
"rate", &w->rate,
"out",
"num_channels", &w->out.num_channels,
@ -175,7 +176,7 @@ int ethercat_parse(struct vnode *n, json_t *cfg)
"vendor_id", &w->in.vendor_id
);
if (ret)
jerror(&err, "Failed to parse configuration of node %s", node_name(n));
throw ConfigError(json, err, "node-config-node-ethercat");
return 0;
}
@ -272,35 +273,25 @@ int ethercat_start(struct vnode *n)
/* Configure analog in */
w->in.sc = ecrt_master_slave_config(master, alias, w->in.position, w->in.vendor_id, w->in.product_code);
if (!w->in.sc) {
warning("Failed to get slave configuration.");
return -1;
}
if (!w->in.sc)
throw RuntimeError("Failed to get slave configuration.");
ret = ecrt_slave_config_pdos(w->in.sc, EC_END, slave_4_syncs);
if (ret) {
error("Failed to configure PDOs.");
return -1;
}
if (ret)
throw RuntimeError("Failed to configure PDOs.");
/* Configure analog out */
w->out.sc = ecrt_master_slave_config(master, alias, w->out.position, w->out.vendor_id, w->out.product_code);
if (!w->out.sc) {
warning("Failed to get slave configuration.");
return -1;
}
if (!w->out.sc)
throw RuntimeError("Failed to get slave configuration.");
ret = ecrt_slave_config_pdos(w->out.sc, EC_END, slave_3_syncs);
if (ret) {
warning("Failed to configure PDOs.");
return -1;
}
if (ret)
throw RuntimeError("Failed to configure PDOs.");
ret = ecrt_domain_reg_pdo_entry_list(w->domain, w->domain_regs);
if (ret) {
error("PDO entry registration failed!");
return -1;
}
if (ret)
throw RuntimeError("PDO entry registration failed!");
/** @todo Check that master is not already active... */
ret = ecrt_master_activate(master);
@ -338,7 +329,7 @@ int ethercat_read(struct vnode *n, struct sample *smps[], unsigned cnt, unsigned
avail = queue_signalled_pull_many(&w->queue, (void **) cpys, cnt);
if (avail < 0)
warning("Pool underrun for node %s: avail=%u", node_name(n), avail);
n->logger->warn("Pool underrun: avail={}", avail);
sample_copy_many(smps, cpys, avail);
sample_decref_many(cpys, avail);

View file

@ -24,11 +24,14 @@
#include <villas/utils.hpp>
#include <villas/sample.h>
#include <villas/plugin.h>
#include <villas/exceptions.hpp>
#include <villas/super_node.hpp>
#include <villas/exceptions.hpp>
/* Forward declartions */
static struct plugin p;
using namespace villas;
using namespace villas::node;
using namespace villas::utils;
@ -70,7 +73,7 @@ int example_destroy(struct vnode *n)
return 0;
}
int example_parse(struct vnode *n, json_t *cfg)
int example_parse(struct vnode *n, json_t *json)
{
int ret;
struct example *s = (struct example *) n->_vd;
@ -79,12 +82,12 @@ int example_parse(struct vnode *n, json_t *cfg)
/* TODO: Add implementation here. The following is just an example */
ret = json_unpack_ex(cfg, &err, 0, "{ s?: i, s?: s }",
ret = json_unpack_ex(json, &err, 0, "{ s?: i, s?: s }",
"setting1", &s->setting1,
"setting2", &s->setting2
);
if (ret)
jerror(&err, "Failed to parse configuration of node %s", node_name(n));
throw ConfigError(json, err, "node-config-node-example");
return 0;
}

View file

@ -31,7 +31,7 @@
using namespace villas;
using namespace villas::utils;
int exec_parse(struct vnode *n, json_t *cfg)
int exec_parse(struct vnode *n, json_t *json)
{
struct exec *e = (struct exec *) n->_vd;
@ -45,7 +45,7 @@ int exec_parse(struct vnode *n, json_t *cfg)
const char *format = "villas.human";
int shell = -1;
ret = json_unpack_ex(cfg, &err, 0, "{ s: o, s?: s, s?: b, s?: o, s?: b, s?: s }",
ret = json_unpack_ex(json, &err, 0, "{ s: o, s?: s, s?: b, s?: o, s?: b, s?: s }",
"exec", &json_exec,
"format", &format,
"flush", &flush,
@ -54,7 +54,7 @@ int exec_parse(struct vnode *n, json_t *cfg)
"working_directory", &wd
);
if (ret)
throw ConfigError(cfg, err, "node-config-node-exec");
throw ConfigError(json, err, "node-config-node-exec");
e->flush = flush;
e->shell = shell < 0 ? json_is_string(json_exec) : shell;
@ -101,16 +101,13 @@ int exec_parse(struct vnode *n, json_t *cfg)
}
}
json_t *json_format = json_object_get(json, "format");
e->format = format_type_lookup(format);
if (!e->format) {
json_t *json_format = json_object_get(cfg, "format");
if (!e->format)
throw ConfigError(json_format, "node-config-node-exec-format", "Invalid format: {)", format);
}
if (!(e->format->flags & (int) IOFlags::NEWLINES)) {
json_t *json_format = json_object_get(cfg, "format");
if (!(e->format->flags & (int) IOFlags::NEWLINES))
throw ConfigError(json_format, "node-config-node-exec-format", "Only line-delimited formats are currently supported");
}
return 0;
}
@ -127,7 +124,7 @@ int exec_prepare(struct vnode *n)
/* Start subprocess */
e->proc = std::make_unique<Popen>(e->command, e->arguments, e->environment, e->working_dir, e->shell);
debug(2, "Started sub-process with pid=%d", e->proc->getPid());
n->logger->debug("Started sub-process with pid={}", e->proc->getPid());
return 0;
}
@ -170,22 +167,15 @@ int exec_destroy(struct vnode *n)
return 0;
}
int exec_start(struct vnode *n)
{
// struct exec *e = (struct exec *) n->_vd;
return 0;
}
int exec_stop(struct vnode *n)
{
struct exec *e = (struct exec *) n->_vd;
/* Stop subprocess */
debug(2, "Killing sub-process with pid=%d", e->proc->getPid());
n->logger->debug("Killing sub-process with pid={}", e->proc->getPid());
e->proc->kill(SIGINT);
debug(2, "Waiting for sub-process with pid=%d to terminate", e->proc->getPid());
n->logger->debug("Waiting for sub-process with pid={} to terminate", e->proc->getPid());
e->proc->close();
/** @todo: Check exit code of subprocess? */
@ -275,7 +265,6 @@ static void register_plugin() {
p.node.prepare = exec_prepare;
p.node.init = exec_init;
p.node.destroy = exec_destroy;
p.node.start = exec_start;
p.node.stop = exec_stop;
p.node.read = exec_read;
p.node.write = exec_write;

Some files were not shown because too many files have changed in this diff Show more