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:
parent
5f6a28ca11
commit
4f370ee1b2
147 changed files with 1804 additions and 1561 deletions
|
@ -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
2
common
|
@ -1 +1 @@
|
|||
Subproject commit fdf5e6371606f247d5adb17caa701b19f9113ec5
|
||||
Subproject commit dba712a0e7b2f38fb3a435f0c74c56cbc0024e48
|
78
etc/Shmem_mqtt.conf
Normal file
78
etc/Shmem_mqtt.conf
Normal 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
37
etc/demo.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
33
etc/examples/nodes/fpga.conf
Normal file
33
etc/examples/nodes/fpga.conf
Normal 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" }
|
||||
)
|
||||
}
|
||||
)
|
253
etc/examples/nodes/vc707_ips.conf
Normal file
253
etc/examples/nodes/vc707_ips.conf
Normal 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
138
etc/labs/lab17.conf
Normal 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
|
||||
}
|
||||
)
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include <jansson.h>
|
||||
|
||||
#include <villas/log.h>
|
||||
#include <villas/node.h>
|
||||
#include <villas/stats.hpp>
|
||||
#include <villas/super_node.hpp>
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include <jansson.h>
|
||||
|
||||
#include <villas/log.h>
|
||||
#include <villas/node.h>
|
||||
#include <villas/stats.hpp>
|
||||
#include <villas/super_node.hpp>
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
10
lib/hook.cpp
10
lib/hook.cpp
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
{
|
||||
assert(state == State::STARTED);
|
||||
|
||||
sample_dump(smp);
|
||||
sample_dump(logger, smp);
|
||||
|
||||
return Reason::OK;
|
||||
}
|
||||
|
|
|
@ -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, ¤t
|
||||
);
|
||||
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)
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
71
lib/io.cpp
71
lib/io.cpp
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
44
lib/node.cpp
44
lib/node.cpp
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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[])
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue