diff --git a/.gitignore b/.gitignore index dc298bdf..cb38b040 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,18 @@ /INSTALL -*Makefile -*Makefile.in +/Makefile +/Makefile.in /aclocal.m4 -/ar-lib /autom4te.cache/ -/config* +/config.* +/configure /depcomp -/libebus-*.pc -/libebus-*.tar.* +/ebus-daemon +/ebus-daemon*.tar.* /install-sh -/libtool -/ltmain.sh -/m4/ /missing /stamp-h? .deps/ -.libs/ -*.l[ao] *.o *.dirstamp -test_* /compile -*.a -/tools/check -/tools/csv -/tools/ebus_send -ebusd +/feed diff --git a/AUTHORS b/AUTHORS index aae6c796..f24a463e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1 @@ -ebus Daemon (ebusd) - AUTHORS -============================= - -Current maintainer: - Roland Jax +Roland Jax diff --git a/ChangeLog b/ChangeLog index 1c53e9b8..2d8ecc87 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ -ebus Daemon (ebusd) - ChangeLog -=============================== +ebusd - ChangeLog +----------------- + +2014-05-11 Roland Jax +* ebus-daemon merged into ebusd. + +2014-05-11 Roland Jax +* Beta-Test for ebus-daemon started. + +2014-01-09 Roland Jax +* Initial commit. + +--- 2014-03-16: * Specific vaillant data type "ttm" (time table minutes) added. diff --git a/Makefile.am b/Makefile.am index 60594b56..61465f80 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,30 @@ -SUBDIRS = lib src tools +AUTOMAKE_OPTIONS = subdir-objects -distclean-local: - -rm -rf autom4te.cache - -rm -f aclocal.m4 - -rm -f config.h.in - -rm -f configure - -rm -f Makefile.in +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + +AM_CXXFLAGS = $(LIBEBUS_CFLAGS) -I$(top_srcdir)/utils -fpic -Wall -Wextra + +bin_PROGRAMS = ebusd + +ebusd_SOURCES = src/main.cpp \ + src/baseloop.cpp \ + src/ebusloop.cpp \ + src/cycdata.cpp \ + src/network.cpp \ + utils/thread.cpp \ + utils/logger.cpp \ + utils/tcpsocket.cpp \ + utils/daemon.cpp \ + utils/appl.cpp + +ebusd_LDADD = $(LIBEBUS_LIBS) \ + -lpthread + +dist_noinst_SCRIPTS = autogen.sh + +noinst_PROGRAMS = feed + +feed_SOURCES = test/feed.cpp \ + utils/appl.cpp + +feed_LDADD = $(LIBEBUS_LIBS) diff --git a/NEWS b/NEWS index f60baffc..a4794804 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,13 @@ -ebus Daemon (ebusd) - NEWS -========================== +ebusd - NEWS +------------ + +2014-05-11 Roland Jax +* ebus-daemon merged into ebusd. + +2014-05-11 Roland Jax +* Beta-Test for ebus-daemon started. + +--- 2014-03-16: * Specific vaillant data type "ttm" (time table minutes) added. diff --git a/README b/README index 625e4c72..a32b00e3 100644 --- a/README +++ b/README @@ -1,39 +1,44 @@ -ebus Daemon (ebusd) - README -============================ +ebusd - README +-------------- -ebus (energy bus) is a bus system used in heating systems. -The 2-wire bus using a serial communication protocol. +The ebusd provides a communication interface to the energy bus (ebus) +which is used in various heating systems. -Features: -========= +Features +-------- - * ebus - send and receive ebus commands - - supported message types are Broadcast, Master-Master and Master-Slave - - escape/unescape byte sequences and calculate CRC for transfer + * send and receive ebus commands + - message types: Broadcast, Master-Master and Master-Slave - collect data of cycle messages - - * tcp socket based multi session server - - Commands: - - get fetch data from ebus participant - - set adjust data of ebus participant - - cyc fetch data from collected cycle messages - - loglevel change loglevel - - quit close connection - - shutdown stop daemon - -Build: -====== + * tcp socket multi session server (daemon commands) + - get fetch data from ebus participant + - set adjust data of ebus participant + - cyc fetch data from collected cycle messages + - hex send given hex value to ebus (ZZ PB SB NN Dx) + - dump toggle dump on/off + - log change loglevel + - quit close connection + - help print help page -$ ./autogen.sh -$ ./configure + +Dependency +---------- + * libebus (https://github.com/yuhu-/libebus) + * glibc + + +Build +----- + +$ ./autogen.sh [--prefix=/usr] $ make +$ make install -Daemon Configuration: -===================== +Daemon Configuration +-------------------- See ./ebusd -h diff --git a/build/ebusd-1.0_armhf.deb b/build/ebusd-1.0_armhf.deb deleted file mode 100644 index 22b715e4..00000000 Binary files a/build/ebusd-1.0_armhf.deb and /dev/null differ diff --git a/build/ebusd-1.0_i386.deb b/build/ebusd-1.0_i386.deb deleted file mode 100644 index 670c1ed2..00000000 Binary files a/build/ebusd-1.0_i386.deb and /dev/null differ diff --git a/build/make_ebusd_deb.sh b/build/make_ebusd_deb.sh deleted file mode 100755 index 6de81ce8..00000000 --- a/build/make_ebusd_deb.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh -# -# -# This file is part of ebusd. -# -# ebusd 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 -# (at your option) any later version. -# -# ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. -# - -BUILD_DIR=/tmp -VERSION='1.0' - -cd $BUILD_DIR -printf ">>> Build directory $BUILD_DIR create $BUILD_DIR/ebusd_build\n" -mkdir ebusd-build -cd ebusd-build - -printf ">>> Checkout sources\n" -#svn checkout https://svn.code.sf.net/p/openautomation/code/tools/ebusd -git clone https://github.com/yuhu-/ebusd.git -cd ebusd - -printf ">>> Remove hidden files\n" -find $PWD -name .svn -print0 | xargs -0 rm -r -find $PWD -name .gitignore -print0 | xargs -0 rm -r - -printf ">>> Build binarys from source\n" -./autogen.sh - -printf ">>> Create Debian package related files\n" -mkdir trunk -mkdir trunk/DEBIAN -mkdir trunk/etc -mkdir trunk/etc/init.d -mkdir trunk/usr -mkdir trunk/usr/sbin - -cp contrib/debian/init.d trunk/etc/init.d/ebusd -cp -R contrib/etc/* trunk/etc -cp src/ebusd trunk/usr/sbin/ebusd -cp -R contrib/csv/* /etc/ebusd/ - -cp ChangeLog trunk/DEBIAN/changelog -ARCH=`dpkg --print-architecture` -echo "Package: ebusd\nVersion: $VERSION\nSection: net\nPriority: required\nArchitecture: $ARCH\nMaintainer: Roland Jax \nDepends:\nDescription: ebus Daemon (ebusd)\n" > trunk/DEBIAN/control -echo "/etc/ebusd\n/usr/sbin/\n/etc/init.d\n/etc/logrotate.d\n/etc/udev\n/etc/udev/rules\n" > trunk/DEBIAN/dirs - -mkdir ebusd-$VERSION -cp -R trunk/* ebusd-$VERSION -dpkg -b ebusd-$VERSION - -printf ">>> Move Package to $BUILD_DIR\n" -mv ebusd-$VERSION.deb $BUILD_DIR/ebusd-${VERSION}_${ARCH}.deb - -printf ">>> Remove Files\n" -cd $BUILD_DIR -rm -R ebusd-build - -printf ">>> Debian Package created at $BUILD_DIR/ebusd-${VERSION}_${ARCH}.deb\n" diff --git a/configure.ac b/configure.ac index 42b6bbfc..7a97327a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,30 +1,15 @@ -AC_PREREQ([2.61]) -AC_INIT([ebusd], [0.1], [roland.jax@liwest.at]) -AC_CONFIG_SRCDIR([src/ebusd.c]) +AC_PREREQ([2.65]) +AC_INIT([ebusd], [0.2.0], [roland.jax@liwest.at], [ebusd], [https://github.com/yuhu-/ebusd]) + +AM_INIT_AUTOMAKE([1.11 -Wall no-define]) + +AC_CONFIG_MACRO_DIR([m4]) + AC_CONFIG_HEADERS([config.h]) -AM_INIT_AUTOMAKE +AC_PROG_CXX -# Checks for programs. -AC_PROG_CC -AM_PROG_CC_C_O - -# Compiler flags -CFLAGS="$CFLAGS -Wall -Wextra" - -# Checks for libraries. -AC_PROG_RANLIB - -# Checks for header files. -AC_CHECK_HEADERS([fcntl.h netdb.h stdlib.h string.h sys/socket.h sys/time.h syslog.h termios.h unistd.h]) - -# Checks for typedefs, structures, and compiler characteristics. -AC_TYPE_PID_T - -# Checks for library functions. -AC_FUNC_FORK -AC_CHECK_FUNCS([gettimeofday memset select socket strerror strrchr]) - -AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile tools/Makefile]) +PKG_CHECK_MODULES([LIBEBUS], [libebus-0.1 >= 0.1]) +AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/contrib/csv/vaillant/ci.ods b/contrib/csv/vaillant/ci.ods deleted file mode 100644 index 69613923..00000000 Binary files a/contrib/csv/vaillant/ci.ods and /dev/null differ diff --git a/contrib/csv/vaillant/vpm20s.ods b/contrib/csv/vaillant/vpm20s.ods deleted file mode 100644 index e33d3f52..00000000 Binary files a/contrib/csv/vaillant/vpm20s.ods and /dev/null differ diff --git a/contrib/csv/vaillant/vpm3035w.ods b/contrib/csv/vaillant/vpm3035w.ods deleted file mode 100644 index b5607c13..00000000 Binary files a/contrib/csv/vaillant/vpm3035w.ods and /dev/null differ diff --git a/contrib/csv/vaillant/vr603.ods b/contrib/csv/vaillant/vr603.ods deleted file mode 100644 index 84109af1..00000000 Binary files a/contrib/csv/vaillant/vr603.ods and /dev/null differ diff --git a/contrib/csv/vaillant/vwx.ods b/contrib/csv/vaillant/vwx.ods deleted file mode 100644 index 8b3cb273..00000000 Binary files a/contrib/csv/vaillant/vwx.ods and /dev/null differ diff --git a/contrib/gentoo/etc/conf.d/ebusd b/contrib/etc/conf.d/ebusd.gentoo similarity index 72% rename from contrib/gentoo/etc/conf.d/ebusd rename to contrib/etc/conf.d/ebusd.gentoo index 820e84d0..66ec000e 100644 --- a/contrib/gentoo/etc/conf.d/ebusd +++ b/contrib/etc/conf.d/ebusd.gentoo @@ -1,6 +1,6 @@ # /etc/conf.d/ebusd: config file for /etc/init.d/ebusd -# Options to pass to the ebusd daemon. +# Options to pass to the ebusd. # See the ebusd -h for more info. EBUSD_ARGS="" diff --git a/contrib/etc/ebusd/ebusd.conf b/contrib/etc/ebusd/ebusd.conf deleted file mode 100644 index af67168e..00000000 --- a/contrib/etc/ebusd/ebusd.conf +++ /dev/null @@ -1,61 +0,0 @@ -# configuration file for ebusd - -# bus address (FF) -#address=FF - -# configuration directory of command files (/etc/ebusd) -#cfgdir=/etc/ebusd - -# bus device (/dev/ttyUSB0 or host:port) -#device=/dev/ttyUSB0 - -# extension of command files (csv) -#extension=csv - -# run in foreground (NO | YES/NO) -#foreground=YES - -# log level (INF | INF, NOT, WAR, ERR, DBG, EBH, EBS, NET, ALL) -#loglevel=ALL - -# log file (/var/log/ebusd.log) -#logfile=/var/log/ebusd.log - -# don't check bus device (NO | YES/NO) -#nodevicecheck=YES - -# pid file (/var/run/ebusd.pid) -#pidfile=/var/run/ebusd.pid - -# port (8888) -#port=8888 - -# dump raw ebus data to file (NO | YES/NO) -#rawdump=YES - -# raw file (/tmp/ebusd.bin) -#rawfile=/tmp/ebusd.bin - -# print raw data (NO | YES/NO) -#showraw=YES - -# print daemon settings (NO | YES/NO) -#settings=YES - -# allow only connection from localhost -#localhost=YES - -# retry getting bus (3 | max: 10) -#get_retry=3 - -# skipped ACK bytes after get-bus error (1) -#skip_ack=1 - -# wait time for QQ compare (4000 uesc) -#max_wait=4000 - -# retry sending msg (2 | max: 10) -#send_retry=2 - -# number of printed hex bytes (30) -#print_size=30 diff --git a/contrib/csv/vaillant/ci.csv b/contrib/etc/ebusd/vaillant/ci.csv similarity index 77% rename from contrib/csv/vaillant/ci.csv rename to contrib/etc/ebusd/vaillant/ci.csv index d3137d6b..62554f51 100644 --- a/contrib/csv/vaillant/ci.csv +++ b/contrib/etc/ebusd/vaillant/ci.csv @@ -29,30 +29,30 @@ get;ci;NameHeatCircuit16;Name Heizkreis 16;MS;15;B509;3;0D4178;1;-;sd;1,10;str;- get;ci;PhoneNumber1;Telefonnummer 1;MS;15;B509;3;0D4200;1;-;sd;1,9;str;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;ci;PhoneNumber2;Telefonnummer 2;MS;15;B509;3;0D4208;1;-;sd;1,9;str;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;ci;HeatBufferAvailable;Bufferspeicher vorhanden;MS;15;B509;3;0D5C00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear1;Energieertrag aktuelles Jahr Monat 1;MS;15;B509;3;0D8400;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear2;Energieertrag aktuelles Jahr Monat 2;MS;15;B509;3;0D8408;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear3;Energieertrag aktuelles Jahr Monat 3;MS;15;B509;3;0D8410;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear4;Energieertrag aktuelles Jahr Monat 4;MS;15;B509;3;0D8418;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear5;Energieertrag aktuelles Jahr Monat 5;MS;15;B509;3;0D8420;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear6;Energieertrag aktuelles Jahr Monat 6;MS;15;B509;3;0D8428;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear7;Energieertrag aktuelles Jahr Monat 7;MS;15;B509;3;0D8430;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear8;Energieertrag aktuelles Jahr Monat 8;MS;15;B509;3;0D8438;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear9;Energieertrag aktuelles Jahr Monat 9;MS;15;B509;3;0D8440;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear10;Energieertrag aktuelles Jahr Monat 10;MS;15;B509;3;0D8448;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear11;Energieertrag aktuelles Jahr Monat 11;MS;15;B509;3;0D8450;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldThisYear12;Energieertrag aktuelles Jahr Monat 12;MS;15;B509;3;0D8458;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear1;Energieertrag letztes Jahr Monat 1;MS;15;B509;3;0D8500;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear2;Energieertrag letztes Jahr Monat 2;MS;15;B509;3;0D8508;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear3;Energieertrag letztes Jahr Monat 3;MS;15;B509;3;0D8510;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear4;Energieertrag letztes Jahr Monat 4;MS;15;B509;3;0D8518;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear5;Energieertrag letztes Jahr Monat 5;MS;15;B509;3;0D8520;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear6;Energieertrag letztes Jahr Monat 6;MS;15;B509;3;0D8528;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear7;Energieertrag letztes Jahr Monat 7;MS;15;B509;3;0D8530;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear8;Energieertrag letztes Jahr Monat 8;MS;15;B509;3;0D8538;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear9;Energieertrag letztes Jahr Monat 9;MS;15;B509;3;0D8540;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear10;Energieertrag letztes Jahr Monat 10;MS;15;B509;3;0D8548;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear11;Energieertrag letztes Jahr Monat 11;MS;15;B509;3;0D8550;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldLastYear12;Energieertrag letztes Jahr Monat 12;MS;15;B509;3;0D8558;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldDayTransfer;Energieertrag Tagesübertrag;MS;15;B509;3;0D8600;1;-;sd;1,2,3,4;ulg;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;ci;EnergyYieldSum;Energieertrag Gesamt;MS;15;B509;3;0D8700;1;-;sd;1,2,3,4;ulg;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear1;Energieertrag aktuelles Jahr Monat 1;MS;15;B509;3;0D8400;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear2;Energieertrag aktuelles Jahr Monat 2;MS;15;B509;3;0D8408;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear3;Energieertrag aktuelles Jahr Monat 3;MS;15;B509;3;0D8410;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear4;Energieertrag aktuelles Jahr Monat 4;MS;15;B509;3;0D8418;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear5;Energieertrag aktuelles Jahr Monat 5;MS;15;B509;3;0D8420;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear6;Energieertrag aktuelles Jahr Monat 6;MS;15;B509;3;0D8428;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear7;Energieertrag aktuelles Jahr Monat 7;MS;15;B509;3;0D8430;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear8;Energieertrag aktuelles Jahr Monat 8;MS;15;B509;3;0D8438;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear9;Energieertrag aktuelles Jahr Monat 9;MS;15;B509;3;0D8440;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear10;Energieertrag aktuelles Jahr Monat 10;MS;15;B509;3;0D8448;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear11;Energieertrag aktuelles Jahr Monat 11;MS;15;B509;3;0D8450;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldThisYear12;Energieertrag aktuelles Jahr Monat 12;MS;15;B509;3;0D8458;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear1;Energieertrag letztes Jahr Monat 1;MS;15;B509;3;0D8500;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear2;Energieertrag letztes Jahr Monat 2;MS;15;B509;3;0D8508;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear3;Energieertrag letztes Jahr Monat 3;MS;15;B509;3;0D8510;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear4;Energieertrag letztes Jahr Monat 4;MS;15;B509;3;0D8518;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear5;Energieertrag letztes Jahr Monat 5;MS;15;B509;3;0D8520;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear6;Energieertrag letztes Jahr Monat 6;MS;15;B509;3;0D8528;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear7;Energieertrag letztes Jahr Monat 7;MS;15;B509;3;0D8530;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear8;Energieertrag letztes Jahr Monat 8;MS;15;B509;3;0D8538;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear9;Energieertrag letztes Jahr Monat 9;MS;15;B509;3;0D8540;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear10;Energieertrag letztes Jahr Monat 10;MS;15;B509;3;0D8548;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear11;Energieertrag letztes Jahr Monat 11;MS;15;B509;3;0D8550;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldLastYear12;Energieertrag letztes Jahr Monat 12;MS;15;B509;3;0D8558;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldDayTransfer;Energieertrag Tagesübertrag;MS;15;B509;3;0D8600;1;-;sd;4,3,2,1;ulg;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;ci;EnergyYieldSum;Energieertrag Gesamt;MS;15;B509;3;0D8700;1;-;sd;4,3,2,1;ulg;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;ci;SystemMode;Modus (Heizen/Kühlen/Warmwasser);MS;15;B509;3;0D9700;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/contrib/etc/ebusd/vaillant/ci.ods b/contrib/etc/ebusd/vaillant/ci.ods new file mode 100644 index 00000000..9fd4ee17 Binary files /dev/null and b/contrib/etc/ebusd/vaillant/ci.ods differ diff --git a/contrib/csv/vaillant/old/vaillant_cyc.csv b/contrib/etc/ebusd/vaillant/old/vaillant_cyc.csv similarity index 100% rename from contrib/csv/vaillant/old/vaillant_cyc.csv rename to contrib/etc/ebusd/vaillant/old/vaillant_cyc.csv diff --git a/contrib/csv/vaillant/old/vaillant_cyc.ods b/contrib/etc/ebusd/vaillant/old/vaillant_cyc.ods similarity index 100% rename from contrib/csv/vaillant/old/vaillant_cyc.ods rename to contrib/etc/ebusd/vaillant/old/vaillant_cyc.ods diff --git a/contrib/csv/vaillant/old/vaillant_get.csv b/contrib/etc/ebusd/vaillant/old/vaillant_get.csv similarity index 100% rename from contrib/csv/vaillant/old/vaillant_get.csv rename to contrib/etc/ebusd/vaillant/old/vaillant_get.csv diff --git a/contrib/csv/vaillant/old/vaillant_get.ods b/contrib/etc/ebusd/vaillant/old/vaillant_get.ods similarity index 100% rename from contrib/csv/vaillant/old/vaillant_get.ods rename to contrib/etc/ebusd/vaillant/old/vaillant_get.ods diff --git a/contrib/csv/vaillant/old/vaillant_set.csv b/contrib/etc/ebusd/vaillant/old/vaillant_set.csv similarity index 100% rename from contrib/csv/vaillant/old/vaillant_set.csv rename to contrib/etc/ebusd/vaillant/old/vaillant_set.csv diff --git a/contrib/csv/vaillant/old/vaillant_set.ods b/contrib/etc/ebusd/vaillant/old/vaillant_set.ods similarity index 100% rename from contrib/csv/vaillant/old/vaillant_set.ods rename to contrib/etc/ebusd/vaillant/old/vaillant_set.ods diff --git a/contrib/csv/vaillant/vpm20s.csv b/contrib/etc/ebusd/vaillant/vpm20s.csv similarity index 83% rename from contrib/csv/vaillant/vpm20s.csv rename to contrib/etc/ebusd/vaillant/vpm20s.csv index c49bbe6a..e15f233f 100644 --- a/contrib/csv/vaillant/vpm20s.csv +++ b/contrib/etc/ebusd/vaillant/vpm20s.csv @@ -2,15 +2,15 @@ get;vpm20s;Date;Datum;MS;ED;B509;3;0D2400;1;-;sd;1,2,3;hda;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm20s;Time;Uhrzeit;MS;ED;B509;3;0D2300;1;-;sd;3,2,1;hti;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm20s;Country;Ländercode;MS;ED;B509;3;0D3900;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vpm20s;YieldDay;Tagesertrag;MS;ED;B509;3;0D3B00;1;-;sd;1,2;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vpm20s;YieldSum;Gesamtertrag;MS;ED;B509;3;0D5600;1;-;sd;1,2,3,4;ulg;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vpm20s;YieldDay;Tagesertrag;MS;ED;B509;3;0D3B00;1;-;sd;2,1;uin;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vpm20s;YieldSum;Gesamtertrag;MS;ED;B509;3;0D5600;1;-;sd;4,3,2,1;ulg;-;kWh;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm20s;SolarNtcFrom;vom Kollektor;MS;ED;B509;3;0D0500;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vpm20s;SolarNtcTo;zum Kollektor;MS;ED;B509;3;0D0600;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vpm20s;SolarPower;Solarpumpe Leistung;MS;ED;B509;3;0D1000;1;-;sd;1;uch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vpm20s;SolarHours;Solarpumpe Laufzeit;MS;ED;B509;3;0D1B00;1;-;sd;1,2;uin;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vpm20s;SolarHours;Solarpumpe Laufzeit;MS;ED;B509;3;0D1B00;1;-;sd;2,1;uin;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm20s;SolarRelay;Solarpumpe Relais;MS;ED;B509;3;0D0F00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm20s;BufferNtcFrom;vom Speicher;MS;ED;B509;3;0D0800;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vpm20s;BufferNtcTo;zum Speicher;MS;ED;B509;3;0D0700;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vpm20s;BufferPower;Speicherpumpe Leistung;MS;ED;B509;3;0D1100;1;-;sd;1;uch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vpm20s;BufferHours;Speicherpumpe Laufzeit;MS;ED;B509;3;0D4C00;1;-;sd;1,2;uin;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vpm20s;BufferFlow;Speicherpumpe Volumenstrom;MS;ED;B509;3;0D2E00;1;-;sd;1,2;uin;-;ml/min;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vpm20s;BufferHours;Speicherpumpe Laufzeit;MS;ED;B509;3;0D4C00;1;-;sd;2,1;uin;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vpm20s;BufferFlow;Speicherpumpe Volumenstrom;MS;ED;B509;3;0D2E00;1;-;sd;2,1;uin;-;ml/min;-;-;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/contrib/etc/ebusd/vaillant/vpm20s.ods b/contrib/etc/ebusd/vaillant/vpm20s.ods new file mode 100644 index 00000000..870e26b9 Binary files /dev/null and b/contrib/etc/ebusd/vaillant/vpm20s.ods differ diff --git a/contrib/csv/vaillant/vpm3035w.csv b/contrib/etc/ebusd/vaillant/vpm3035w.csv similarity index 77% rename from contrib/csv/vaillant/vpm3035w.csv rename to contrib/etc/ebusd/vaillant/vpm3035w.csv index 9a8e45a0..7f48036c 100644 --- a/contrib/csv/vaillant/vpm3035w.csv +++ b/contrib/etc/ebusd/vaillant/vpm3035w.csv @@ -1,11 +1,11 @@ # type;class;cmd;comment;msg type;ZZ;PBSB;NN;D1D2D3;elements;sub;part;position;datatype;factor;unit;valid;comment;sub;part;position;datatype;factor;unit;valid;comment;sub;part;position;datatype;factor;unit;valid;comment;sub;part;position;datatype;factor;unit;valid;comment -get;vpm3035w;Ntc1Sensor;Ntc1Sensor;MS;0A;B509;3;0D0000;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; -get;vpm3035w;Ntc2Sensor;Ntc2Sensor;MS;0A;B509;3;0D0100;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; -get;vpm3035w;Ntc3Sensor;Ntc3Sensor;MS;0A;B509;3;0D0200;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; -get;vpm3035w;Vortex;Wirbel, Bypass?;MS;0A;B509;3;0D0300;1;-;sd;1,2;uin;-;hz;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vpm3035w;Ntc1;Ntc1 Sensor;MS;0A;B509;3;0D0000;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; +get;vpm3035w;Ntc2;Ntc2 Sensor;MS;0A;B509;3;0D0100;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; +get;vpm3035w;Ntc3;Ntc3 Sensor;MS;0A;B509;3;0D0200;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; +get;vpm3035w;Vortex;Wirbel, Bypass?;MS;0A;B509;3;0D0300;1;-;sd;2,1;uin;-;hz;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm3035w;CircoPumpPower;Zirkulationspumpe Leistung;MS;0A;B509;3;0D0400;1;-;sd;1;uch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm3035w;PumpDutyCycle;Pumpe Einschaltdauer;MS;0A;B509;3;0D0500;1;-;sd;1;uch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vpm3035w;MixerPosition;Mischer Position max. 220 Schritte;MS;0A;B509;3;0D0600;1;-;sd;1,2;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vpm3035w;MixerPosition;Mischer Position max. 220 Schritte;MS;0A;B509;3;0D0600;1;-;sd;2,1;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm3035w;ElectricHeater;Elektrische Zusatzheizung;MS;0A;B509;3;0D0800;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm3035w;HeatDemand;Heizanforderung;MS;0A;B509;3;0D0900;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vpm3035w;OperatingMode;Betriebsart;MS;0A;B509;3;0D0A00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/contrib/etc/ebusd/vaillant/vpm3035w.ods b/contrib/etc/ebusd/vaillant/vpm3035w.ods new file mode 100644 index 00000000..c0d85950 Binary files /dev/null and b/contrib/etc/ebusd/vaillant/vpm3035w.ods differ diff --git a/contrib/csv/vaillant/vr603.csv b/contrib/etc/ebusd/vaillant/vr603.csv similarity index 82% rename from contrib/csv/vaillant/vr603.csv rename to contrib/etc/ebusd/vaillant/vr603.csv index 4a220575..6457fe0c 100644 --- a/contrib/csv/vaillant/vr603.csv +++ b/contrib/etc/ebusd/vaillant/vr603.csv @@ -6,24 +6,24 @@ get;vr603mk1;RemoteControlActive;Fernsteuerung aktiv;MS;52;B509;3;0D0A00;1;-;sd; get;vr603mk1;MixerDutyCycle;Mischer Einschaltdauer;MS;52;B509;3;0D0E00;1;-;sd;1;sch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;HolidayActive;Ferienprogramm aktiv;MS;52;B509;3;0D2700;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;OperatingMode;Betriebsart;MS;52;B509;3;0D2B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;FlowTempMin;Vorlaufsollwert MIN;MS;52;B509;3;0D3000;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;FlowTempMax;Vorlaufsollwert MAX;MS;52;B509;3;0D3100;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;DesiredTemp;Solltemperatur;MS;52;B509;3;0D3200;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;DesiredTempLow;Absenktemperatur;MS;52;B509;3;0D3300;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;HeatingCurve;Heizkurve;MS;52;B509;3;0D3500;1;-;sd;1,2;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;OutsideTempLimitShutdown;Abschaltgrenze Aussentempertur;MS;52;B509;3;0D3600;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;FlowTempMin;Vorlaufsollwert MIN;MS;52;B509;3;0D3000;1;-;sd;1;uch;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;FlowTempMax;Vorlaufsollwert MAX;MS;52;B509;3;0D3100;1;-;sd;1;uch;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;DesiredTemp;Solltemperatur;MS;52;B509;3;0D3200;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;DesiredTempLow;Absenktemperatur;MS;52;B509;3;0D3300;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;HeatingCurve;Heizkurve;MS;52;B509;3;0D3500;1;-;sd;2,1;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;OutsideTempLimitShutdown;Abschaltgrenze Aussentempertur;MS;52;B509;3;0D3600;1;-;sd;1;uch;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;PreHeatingTimeMax;Voraufheizung MAX;MS;52;B509;3;0D3800;1;-;sd;1;uch;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;FloorScreedDryingDay;Estrichtrocknung Tag;MS;52;B509;3;0D3B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;HeatingCircuitType;Heizkreistyp;MS;52;B509;3;0D3C00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;OperatingModeRemoteControl;Betriebsart Fernsteuerung;MS;52;B509;3;0D3F00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;FlowTempDesired;Vorlauftemperatur Soll;MS;52;B509;3;0D4600;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;FlowTempDesired;Vorlauftemperatur Soll;MS;52;B509;3;0D4600;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;TankHeatingActive;Speicherladung aktiv;MS;52;B509;3;0D4700;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;PowerSavingActive;Sparfunktion aktiv;MS;52;B509;3;0D4B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;PartyActive;Partyfunktion aktiv;MS;52;B509;3;0D4E00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;PumpCutOffTime;Pumpe Sperrzeit;MS;52;B509;3;0D4F00;1;-;sd;1;uch;-;min;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;PumpState;Pumpe Status;MS;52;B509;3;0D9100;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;CoolingDeltaStart;Kühlung Starttemperturdifferenz;MS;52;B509;3;0DBA00;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk1;CoolingHysteresisTempMin;Kühlung Hysteresis Vorlauftemperatur MIN;MS;52;B509;3;0DBE00;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;CoolingDeltaStart;Kühlung Starttemperturdifferenz;MS;52;B509;3;0DBA00;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk1;CoolingHysteresisTempMin;Kühlung Hysteresis Vorlauftemperatur MIN;MS;52;B509;3;0DBE00;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk1;CoolingOperatingMode;Kühlung Betriebsart;MS;52;B509;3;0DBF00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;FlowTempSensor;Vorlauftemperatur Ist;MS;53;B509;3;0D0300;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vr603mk2;OutsideTemp;Aussentemperatur;MS;53;B509;3;0D0600;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; @@ -31,21 +31,21 @@ get;vr603mk2;RemoteControlActive;Fernsteuerung aktiv;MS;53;B509;3;0D0A00;1;-;sd; get;vr603mk2;MixerDutyCycle;Mischer Einschaltdauer;MS;53;B509;3;0D0F00;1;-;sd;1;sch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;HolidayActive;Ferienprogramm aktiv;MS;53;B509;3;0D2700;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;OperatingMode;Betriebsart;MS;53;B509;3;0D2B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;FlowTempMin;Vorlaufsollwert MIN;MS;53;B509;3;0D3000;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;FlowTempMax;Vorlaufsollwert MAX;MS;53;B509;3;0D3100;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;DesiredTemp;Solltemperatur;MS;53;B509;3;0D3200;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;DesiredTempLow;Absenktemperatur;MS;53;B509;3;0D3300;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;HeatingCurve;Heizkurve;MS;53;B509;3;0D3500;1;-;sd;1,2;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;OutsideTempLimitShutdown;Abschaltgrenze Aussentempertur;MS;53;B509;3;0D3600;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;FlowTempMin;Vorlaufsollwert MIN;MS;53;B509;3;0D3000;1;-;sd;1;uch;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;FlowTempMax;Vorlaufsollwert MAX;MS;53;B509;3;0D3100;1;-;sd;1;uch;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;DesiredTemp;Solltemperatur;MS;53;B509;3;0D3200;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;DesiredTempLow;Absenktemperatur;MS;53;B509;3;0D3300;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;HeatingCurve;Heizkurve;MS;53;B509;3;0D3500;1;-;sd;2,1;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;OutsideTempLimitShutdown;Abschaltgrenze Aussentempertur;MS;53;B509;3;0D3600;1;-;sd;1;uch;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;PreHeatingTimeMax;Voraufheizung MAX;MS;53;B509;3;0D3800;1;-;sd;1;uch;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;FloorScreedDryingDay;Estrichtrocknung Tag;MS;53;B509;3;0D3B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;HeatingCircuitType;Heizkreistyp;MS;53;B509;3;0D3C00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;OperatingModeRemoteControl;Betriebsart Fernsteuerung;MS;53;B509;3;0D3F00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;FlowTempDesired;Vorlauftemperatur Soll;MS;53;B509;3;0D4600;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;FlowTempDesired;Vorlauftemperatur Soll;MS;53;B509;3;0D4600;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;TankHeatingActive;Speicherladung aktiv;MS;53;B509;3;0D4700;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;PowerSavingActive;Sparfunktion aktiv;MS;53;B509;3;0D4B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;PartyActive;Partyfunktion aktiv;MS;53;B509;3;0D4E00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;PumpCutOffTime;Pumpe Sperrzeit;MS;53;B509;3;0D4F00;1;-;sd;1;uch;-;min;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;PumpState;Pumpe Status;MS;53;B509;3;0D9400;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vr603mk2;CoolingDeltaStart;Kühlung Starttemperturdifferenz;MS;53;B509;3;0DBA00;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vr603mk2;CoolingDeltaStart;Kühlung Starttemperturdifferenz;MS;53;B509;3;0DBA00;1;-;sd;1;uch;0.5;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vr603mk2;CoolingOperatingMode;Kühlung Betriebsart;MS;53;B509;3;0DBF00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/contrib/etc/ebusd/vaillant/vr603.ods b/contrib/etc/ebusd/vaillant/vr603.ods new file mode 100644 index 00000000..7ab86f01 Binary files /dev/null and b/contrib/etc/ebusd/vaillant/vr603.ods differ diff --git a/contrib/csv/vaillant/vr903.csv b/contrib/etc/ebusd/vaillant/vr903.csv similarity index 100% rename from contrib/csv/vaillant/vr903.csv rename to contrib/etc/ebusd/vaillant/vr903.csv diff --git a/contrib/csv/vaillant/vr903.ods b/contrib/etc/ebusd/vaillant/vr903.ods similarity index 100% rename from contrib/csv/vaillant/vr903.ods rename to contrib/etc/ebusd/vaillant/vr903.ods diff --git a/contrib/csv/vaillant/vwx.csv b/contrib/etc/ebusd/vaillant/vwx.csv similarity index 84% rename from contrib/csv/vaillant/vwx.csv rename to contrib/etc/ebusd/vaillant/vwx.csv index 6217b9f4..37547615 100644 --- a/contrib/csv/vaillant/vwx.csv +++ b/contrib/etc/ebusd/vaillant/vwx.csv @@ -1,12 +1,12 @@ # type;class;cmd;comment;msg type;ZZ;PBSB;NN;D1D2D3;elements;sub;part;position;datatype;factor;unit;valid;comment;sub;part;position;datatype;factor;unit;valid;comment;sub;part;position;datatype;factor;unit;valid;comment;sub;part;position;datatype;factor;unit;valid;comment get;vwx;BivalentTemp;Bivalenztemperatur;MS;08;B509;3;0D6500;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;Bleeding;Entlüften;MS;08;B509;3;0D1300;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;BrinePress;Druck Solekreis;MS;08;B509;3;0D1600;2;press;sd;1,2;flt;0.001;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; -get;vwx;BrinePressSwitch;Soledruckschalter;MS;08;B509;3;0D2600;1;-;sd;1,2;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;BrinePumpCoolingRunTime;Kühlung Laufzeit Solepumpe;MS;08;B509;3;0D7D01;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;BrinePress;Druck Solekreis;MS;08;B509;3;0D1600;2;press;sd;2,1;flt;1.0;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; +get;vwx;BrinePressSwitch;Soledruckschalter;MS;08;B509;3;0D2600;1;-;sd;2,1;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;BrinePumpCoolingRunTime;Kühlung Laufzeit Solepumpe;MS;08;B509;3;0D7D01;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;BrinePumpPower;Solepumpe Leistung;MS;08;B509;3;0DAC01;1;-;sd;1;uch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;BrinePumpPowerHeating;Solepumpe Leistung beim Heizen;MS;08;B509;3;0DAE01;1;-;sd;1;uch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;BrinePumpPreRunTime;Vorlaufzeit Quellenpumpe;MS;08;B509;3;0D7600;1;-;sd;1,4;ulg;-;min;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;BrinePumpPreRunTime;Vorlaufzeit Quellenpumpe;MS;08;B509;3;0D7600;1;-;sd;4,3,2,1;ulg;-;min;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;BrinePumpState;Solepumpe Status;MS;08;B509;3;0D1900;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;BrinePumpState;Solepumpe Status;MS;08;B509;3;0DB801;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;BrineTempInput;T3 Sole Temperatur Vorlauf – von Quelle;MS;08;B509;3;0D0F00;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; @@ -14,55 +14,54 @@ get;vwx;BrineTempOutput;T8 Sole Temperatur Rücklauf – zur Quelle;MS;08;B509;3 get;vwx;CirculationPumpInput;Zirkulationspumpe Eingang;MS;08;B509;3;0D0B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;CirculationPumpPower;Zirkulationspumpe Leistung;MS;23;B509;3;0DE601;1;-;sd;1;uch;-;%;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;CirculationPumpState;Zirkulationspumpe Status;MS;08;B509;3;0D0C00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;Code1;Code 1;MS;08;B509;3;0D9700;1;-;sd;1,2;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;Code2;Code 2;MS;08;B509;3;0D9800;1;-;sd;1,2;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;Code1;Code 1;MS;08;B509;3;0D9700;1;-;sd;2,1;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;Code2;Code 2;MS;08;B509;3;0D9800;1;-;sd;2,1;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;CodeValid;Code 1 und 2 gültig;MS;08;B509;3;0D2400;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;CompressorStartsHotWater;Kompressor Starts Warmwasser;MS;08;B509;3;0DA800;1;-;sd;1,2,3,4;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;CompressorStartsHeating;Kompressor Starts Heizung;MS;08;B509;3;0DA900;1;-;sd;1,2,3,4;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;CompressorStarts;Kompressor Starts ;MS;08;B509;3;0DAA00;1;-;sd;1,2,3,4;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;CommutationState;Kompressor Kommunikationsstatus;MS;08;B509;3;0DAA00;1;-;sd;4,3,2,1;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;CompressorNumberStarts;Kompressor Starts pro Stunde;MS;08;B509;3;0D7400;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;CompressorState;Kompressor Status;MS;08;B509;3;0D1D00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;CompressorTempInput;T1 Kompressor Temperatur Eintritt;MS;08;B509;3;0D0200;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;CompressorTempOutput;T2 Kompressor Temperatur Austritt;MS;08;B509;3;0D0400;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;Date;Datum;MS;08;B509;3;0D2900;1;-;sd;1,2,3;hda;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;DeicingState;Enteisung Status;MS;08;B509;3;0DCE01;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;DeicingWaitTime;Enteisung Wartezeit zur nächsten Enteisung;MS;08;B509;3;0D7000;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;DeicingWaitTime;Enteisung Wartezeit zur nächsten Enteisung;MS;08;B509;3;0D7000;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;EvaporatorTemp;Verdampfer Temperatur;MS;08;B509;3;0D0500;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;ExpansionValveInputTemp;TEV Temperatur Eintritt;MS;08;B509;3;0D0D00;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;FlowTemp;VF2 Vorlauftemperatur IST;MS;08;B509;3;0D0300;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;FlowTempIntern;T6 interne Vorlauftempertur IST;MS;08;B509;3;0D0900;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;FrezzeProtectionTempMin;Einfrierschutz T81;MS;08;B509;3;0D7A01;1;-;sd;1;sch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;HeatPumpState;Heizkreispumpe Status;MS;08;B509;3;0D1700;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;HeatSystemPress;Heizanlagendruck;MS;08;B509;3;0D1200;2;press;sd;1,2;flt;0.001;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; +get;vwx;HeatSystemPress;Heizanlagendruck;MS;08;B509;3;0D1200;2;press;sd;2,1;flt;1.0;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;Hysteresis;Kompressor Hysterese;MS;08;B509;3;0D7D00;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;InitialCurrentLimitation;Anlaufstrombegrenzung;MS;08;B509;3;0D3F00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;Integral;Energieintegral;MS;08;B509;3;0D8000;1;-;sd;1,2;sin;-;°min;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;IntegralStartValue;Energieintegral Startwert;MS;08;B509;3;0D7C00;1;-;sd;1,2;sin;-;°min;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;Integral;Energieintegral;MS;08;B509;3;0D8000;1;-;sd;2,1;sin;-;°min;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;IntegralStartValue;Energieintegral Startwert;MS;08;B509;3;0D7C00;1;-;sd;2,1;sin;-;°min;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;MixerPosition;Mischer Position -100 – 100;MS;08;B509;3;0D0E00;1;-;sd;1;sch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;NoiseReductionFactor;Lautstärken Reduktion Faktor;MS;08;B509;3;0D2401;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;NoiseReductionState;Lautstärken Reduktion Status;MS;08;B509;3;0DA901;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;Overheating;Überhitzung;MS;08;B509;3;0D8D00;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;PhaseOrder;Drehfeld Status;MS;08;B509;3;0D5701;1;-;sd;1,2;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;PhaseOrder;Drehfeld Status;MS;08;B509;3;0D5701;1;-;sd;2,1;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;PhaseState;Phasen Status;MS;08;B509;3;0D8800;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;PowerCutOff;EVU Sperrzeit – Stromunterbrechung;MS;08;B509;3;0D1100;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;PumpState;Pumpen Status;MS;08;B509;3;0D1800;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;RetrurnTempMax;Heizkreis Rücklauftemperatur MAX;MS;08;B509;3;0D7300;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;ReturnTempIntern;T5 interne Rücklauftempertur IST;MS;08;B509;3;0D0A00;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; -get;vwx;RunTime;Kompressor Laufzeit Summe;MS;08;B509;3;0D9A00;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;RunTimeHeating;Kompressor Laufzeit Heizung;MS;08;B509;3;0D9B00;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;RunTimeHotWater;Kompressor Laufzeit Warmwasser;MS;08;B509;3;0D9C00;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;RunTime;Kompressor Laufzeit Summe;MS;08;B509;3;0D9A00;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;RunTimeHeating;Kompressor Laufzeit Heizung;MS;08;B509;3;0D9B00;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;RunTimeHotWater;Kompressor Laufzeit Warmwasser;MS;08;B509;3;0D9C00;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;ServiceMode;Servicezeit;MS;08;B509;3;0D6600;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;SoftwareState;Software Status;MS;08;B509;3;0DCF00;1;-;sd;1,2,3,4;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;SoftwareState;Software Status;MS;08;B509;3;0DCF00;1;-;sd;4,3,2,1;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;HeatPumpState;Heizungspumpe Status;MS;08;B509;3;0DD000;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;SwitchValve;Umschaltventil Heizen = 0 / Warmwasser = 1;MS;08;B509;3;0D1000;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;TempOutside;Aussentemperatur;MS;08;B509;3;0D0600;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwx;TempSpreadMax;Zulässige Temperaturspreizung T6 zu T7;MS;08;B509;3;0D6E00;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;Time;Uhrzeit;MS;08;B509;3;0D2800;1;-;sd;3,2,1;hti;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;Undercooling;Unterkühlung;MS;08;B509;3;0D8E00;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;VaporPressHigh;Hochdruck Kältekreis;MS;08;B509;3;0D1400;2;press;sd;1,2;flt;0.001;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; -get;vwx;VaporPressLow;Niederdruck Kältekreis;MS;08;B509;3;0D1500;2;press;sd;1,2;flt;0.001;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; -get;vwx;VaporPressostate;Kältekreis Über/Unterdruck Sicherheitsabschaltung;MS;08;B509;3;0D2500;1;-;sd;1,2;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;VaporPressHigh;Hochdruck Kältekreis;MS;08;B509;3;0D1400;2;press;sd;2,1;flt;1.0;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; +get;vwx;VaporPressLow;Niederdruck Kältekreis;MS;08;B509;3;0D1500;2;press;sd;2,1;flt;1.0;bar;-;Druck;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; +get;vwx;VaporPressostate;Kältekreis Über/Unterdruck Sicherheitsabschaltung;MS;08;B509;3;0D2500;1;-;sd;2,1;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwx;Weekday;Wochentag;MS;08;B509;3;0D2A00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwx;YieldEnvironmentEnergy;Energieertrag Umgebung;MS;08;B509;3;0DBC00;1;-;sd;1,2,3,4;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwx;YieldEnvironmentEnergy;Energieertrag Umgebung;MS;08;B509;3;0DBC00;1;-;sd;4,3,2,1;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxcal;BrineTempInput;Kalibrierung Quelle Eintritt;MS;08;B509;3;0DCD00;1;-;sd;1,2;d2c;1.0;K;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxcal;BrineTempOutput;Kalibrierung Quelle Austritt;MS;08;B509;3;0DC900;1;-;sd;1,2;d2c;1.0;K;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxcal;CompressorTempInput;Kalibrierung Kompressor Eintritt;MS;08;B509;3;0DC600;1;-;sd;1,2;d2c;1.0;K;-;-;;;;;;;;;;;;;;;;;;;;;;;; @@ -74,16 +73,16 @@ get;vwxcal;OutsideTemp;Kalibrierung Aussentemperatur;MS;08;B509;3;0DC300;1;-;sd; get;vwxcal;ReturnTemp;Kalibrierung Rücklauftemperatur RF1;MS;08;B509;3;0DCB00;1;-;sd;1,2;d2c;1.0;K;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxcal;TankTempBottom;Kalibrierung Speicher Bodentemperatur;MS;08;B509;3;0D3401;1;-;sd;1,2;d2c;1.0;K;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxcal;TankTempTop;Kalibrierung Speicher Kopftemperatur;MS;08;B509;3;0D3301;1;-;sd;1,2;d2c;1.0;K;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwxeh;CommutationState;Zusatzheizung Kommunikationsstatus;MS;08;B509;3;0DB100;1;-;sd;1,2,3,4;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwxeh;CommutationState;Zusatzheizung Kommunikationsstatus;MS;08;B509;3;0DB100;1;-;sd;4,3,2,1;ulg;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxeh;ElectricHeaterModeHeat;Zusatzheizung für Warmwasser;MS;08;B509;3;0D6300;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxeh;ElectricHeaterModeHotWater;Zusatzheizung für Heizung;MS;08;B509;3;0D6400;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxeh;ElectricHeaterState;Zusatzheizung Status;MS;08;B509;3;0D5F00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxeh;ElectricHeaterType;Zusatzheizung Typ;MS;08;B509;3;0D9200;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxeh;Hysteresis;Zusatzheizung Hysterese;MS;08;B509;3;0D7E00;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwxeh;IntegralStartValue;Zusatzheizung Energieintegral Startwert;MS;08;B509;3;0D7F00;1;-;sd;1,2;sin;-;°min;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwxeh;RunTime;Zusatzheizung Laufzeit Summe;MS;08;B509;3;0DA100;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwxeh;RunTimeHeating;Zusatzheizung Laufzeit Heizung;MS;08;B509;3;0DA200;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwxeh;RunTimeHotWater;Zusatzheizung Laufzeit Warmwasser;MS;08;B509;3;0DA300;1;-;sd;1,2,3,4;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwxeh;IntegralStartValue;Zusatzheizung Energieintegral Startwert;MS;08;B509;3;0D7F00;1;-;sd;2,1;sin;-;°min;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwxeh;RunTime;Zusatzheizung Laufzeit Summe;MS;08;B509;3;0DA100;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwxeh;RunTimeHeating;Zusatzheizung Laufzeit Heizung;MS;08;B509;3;0DA200;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwxeh;RunTimeHotWater;Zusatzheizung Laufzeit Warmwasser;MS;08;B509;3;0DA300;1;-;sd;4,3,2,1;ulg;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxhw;FlowTemp;VF1 Bufferspeicher Kopftemperatur;MS;08;B509;3;0D0100;2;temp;sd;1,2;d2c;1.0;°C;-;Temperatur;sensor;sd;3;uch;-;-;-;Fühler;;;;;;;;;;;;;;;; get;vwxhw;HotWaterTempMax;Warmwasser Termperatur MAX;MS;25;B509;3;0D8200;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxhw;HotWaterTempMin;Warmwasser Termperatur MIN;MS;25;B509;3;0D8300;1;-;sd;1,2;d2c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; @@ -96,12 +95,13 @@ get;vwxhw;TankTemp;Speichertemperatur IST;MS;08;B509;3;0D0000;2;temp;sd;1,2;d2c; get;vwxhw;TankTypePipe;Speichertyp ist Rohr;MS;25;B509;3;0DCD01;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;CoolingOperatingMode;Kühlung Betriebsart;MS;50;B509;3;0D8C01;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;DesiredTemp;Solltemperatur;MS;50;B509;3;0D3200;1;-;sd;1;d1c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; +set;vwxmk;DesiredTemp;Solltemperatur;MS;50;B509;4;0E3200;1;-;sd;1;d1c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;DesiredTempLow;Absenktemperatur;MS;50;B509;3;0D3300;1;-;sd;1;d1c;1.0;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;FloorProtectionTempLimit;Fußbodenschutz Temp > VF2;MS;50;B509;3;0D7B01;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;FloorScreedDryingDay;Estrichtrocknung Tag;MS;50;B509;3;0D3B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;FlowTempDesired;Vorlauftemperatur Soll;MS;50;B509;3;0D4600;1;-;sd;1;d1c;1.0;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwxmk;HeatingCircuitType;Heizkreistyp;MS;50;B509;3;0D3C00;1;-;sd;1,2;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; -get;vwxmk;HeatingCurve;Heizkurve;MS;50;B509;3;0D3500;1;-;sd;1,2;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwxmk;HeatingCircuitType;Heizkreistyp;MS;50;B509;3;0D3C00;1;-;sd;2,1;sin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; +get;vwxmk;HeatingCurve;Heizkurve;MS;50;B509;3;0D3500;1;-;sd;2,1;uin;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;OperatingMode;Betriebsart;MS;50;B509;3;0D2B00;1;-;sd;1;uch;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;OutsideTempLimitShutdown;Abschaltgrenze Aussentempertur;MS;50;B509;3;0D3600;1;-;sd;1;uch;-;°C;-;-;;;;;;;;;;;;;;;;;;;;;;;; get;vwxmk;PreHeatingTimeMax;Voraufheizung MAX;MS;50;B509;3;0D3800;1;-;sd;1;uch;-;h;-;-;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/contrib/etc/ebusd/vaillant/vwx.ods b/contrib/etc/ebusd/vaillant/vwx.ods new file mode 100644 index 00000000..3f3d9ce7 Binary files /dev/null and b/contrib/etc/ebusd/vaillant/vwx.ods differ diff --git a/contrib/csv/wolf/wolf_cycle.csv b/contrib/etc/ebusd/wolf/wolf_cycle.csv similarity index 100% rename from contrib/csv/wolf/wolf_cycle.csv rename to contrib/etc/ebusd/wolf/wolf_cycle.csv diff --git a/contrib/csv/wolf/wolf_cycle.ods b/contrib/etc/ebusd/wolf/wolf_cycle.ods similarity index 100% rename from contrib/csv/wolf/wolf_cycle.ods rename to contrib/etc/ebusd/wolf/wolf_cycle.ods diff --git a/contrib/debian/init.d b/contrib/etc/init.d/ebusd.debian similarity index 70% rename from contrib/debian/init.d rename to contrib/etc/init.d/ebusd.debian index 683fa968..cadd6900 100755 --- a/contrib/debian/init.d +++ b/contrib/etc/init.d/ebusd.debian @@ -5,28 +5,28 @@ # Required-Start: $network $remote_fs $syslog # Required-Stop: $network $remote_fs $syslog # Default-Start: 2 3 4 5 -# Default-Stop: -# Short-Description: Start EBUS daemon +# Default-Stop: +# Short-Description: Start ebusd ### END INIT INFO -PATH=/sbin:/bin:/usr/sbin:/usr/bin +PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin . /lib/lsb/init-functions -DAEMON=/usr/local/bin/ebusd +DAEMON=/usr/bin/ebusd PIDFILE=/var/run/ebusd.pid test -x $DAEMON || exit 5 case $1 in start) - log_daemon_msg "Starting EBUS server" "ebusd" - start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -P $PIDFILE + log_daemon_msg "Starting ebusd" "ebusd" + start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON status=$? log_end_msg $status ;; stop) - log_daemon_msg "Stopping EBUS server" "ebusd" + log_daemon_msg "Stopping ebusd" "ebusd" start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE log_end_msg $? rm -f $PIDFILE @@ -35,7 +35,7 @@ case $1 in $0 stop && sleep 2 && $0 start ;; status) - status_of_proc $DAEMON "EBUS server" + status_of_proc $DAEMON "ebusd" ;; *) echo "Usage: $0 {start|stop|restart|force-reload|status}" diff --git a/contrib/gentoo/etc/init.d/ebusd b/contrib/etc/init.d/ebusd.gentoo similarity index 94% rename from contrib/gentoo/etc/init.d/ebusd rename to contrib/etc/init.d/ebusd.gentoo index 767e62ee..404125e0 100755 --- a/contrib/gentoo/etc/init.d/ebusd +++ b/contrib/etc/init.d/ebusd.gentoo @@ -4,7 +4,7 @@ # $Header: $ #extra_started_commands="reload" -command="/usr/sbin/ebusd" +command="/usr/bin/ebusd" command_args="${EBUSD_ARGS}" start_stop_daemon_args="--quiet" description="Daemon for ebus Communication" diff --git a/contrib/etc/logrotate.d/ebusd b/contrib/etc/logrotate.d/ebusd index 9a8ed047..a1854f39 100644 --- a/contrib/etc/logrotate.d/ebusd +++ b/contrib/etc/logrotate.d/ebusd @@ -1,10 +1,9 @@ -# ebusd.log - /var/log/ebusd.log { - rotate 5 - size=100k - sharedscripts - postrotate - [ -f /var/run/ebusd.pid ] && /bin/kill -INT `cat /var/run/ebusd.pid` - endscript + rotate 7 + size 1M + copytruncate + compress + missingok + notifempty + daily } diff --git a/contrib/etc/udev/rules.d/ebus.rules b/contrib/etc/udev/rules.d/ebus.rules deleted file mode 100644 index d8c898b2..00000000 --- a/contrib/etc/udev/rules.d/ebus.rules +++ /dev/null @@ -1,19 +0,0 @@ -# There are a number of modifiers that are allowed to be used in some -# of the different fields. They provide the following subsitutions: -# -# %n the "kernel number" of the device. -# For example, 'sda3' has a "kernel number" of '3' -# %k the kernel name for the device -# %M the kernel major number for the device -# %m the kernel minor number for the device -# %b the bus id for the device -# %c the string returned by the PROGRAM -# %s{filename} the content of a sysfs attribute -# %% the '%' char itself -# udevadm info --attribute-walk --path=/sys/bus/usb-serial/devices/ttyUSB0 - -### eBus-Coupler / E-Service-Online ### - -SUBSYSTEMS=="usb", KERNEL=="ttyUSB*", \ - ATTRS{product}=="eBus Coupler", ATTRS{manufacturer}=="E-Service Online" \ - SYMLINK+="ebus-usb" diff --git a/lib/Makefile.am b/lib/Makefile.am deleted file mode 100644 index aaa87abf..00000000 --- a/lib/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -noinst_LIBRARIES = libebus.a liblog.a - -libebus_a_SOURCES = ebus-decode.c ebus-decode.h \ - ebus-cmd.c ebus-cmd.h \ - ebus-bus.c ebus-bus.h - -liblog_a_SOURCES = log.c log.h - -distclean-local: - -rm -f Makefile.in - diff --git a/lib/ebus-bus.c b/lib/ebus-bus.c deleted file mode 100644 index c73d4917..00000000 --- a/lib/ebus-bus.c +++ /dev/null @@ -1,1279 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -/** - * @file ebus-bus.c - * @brief ebus communication functions - * @author roland.jax@liwest.at - * @version 0.1 - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "ebus-decode.h" -#include "ebus-cmd.h" -#include "ebus-bus.h" - - - -static struct send_data send_data; - -static struct recv_data recv_data; - -static int nodevicecheck = NO; -static int rawdump = NO; -static int showraw = NO; - -static int get_retry = EBUS_GET_RETRY; -static int skip_ack = EBUS_SKIP_ACK; -static long max_wait = EBUS_MAX_WAIT; -static int send_retry = EBUS_SEND_RETRY; -static int print_size = EBUS_PRINT_SIZE; - -static unsigned char qq = EBUS_QQ; - -static unsigned char ack = EBUS_ACK; -static unsigned char nak = EBUS_NAK; -static unsigned char syn = EBUS_SYN; - -static int bfd; -static int devicetype = BUS_DEVICE_SERIAL; -static struct termios oldtio; - -static FILE *rawfp = NULL; - - - -void -eb_set_nodevicecheck(int check) -{ - nodevicecheck = check; -} - -void -eb_set_rawdump(int dump) -{ - rawdump = dump; -} - -void -eb_set_showraw(int show) -{ - showraw = show; -} - -void -eb_set_qq(unsigned char src) -{ - qq = src; -} - -void -eb_set_get_retry(int retry) -{ - get_retry = retry; -} - -void -eb_set_skip_ack(int skip) -{ - skip_ack = skip; -} - -void -eb_set_max_wait(long usec) -{ - max_wait = usec; -} - -void -eb_set_send_retry(int retry) -{ - send_retry = retry; -} - -void -eb_set_print_size(int size) -{ - print_size = size; -} - - -int -eb_diff_time(const struct timeval *tact, const struct timeval *tlast, struct timeval *tdiff) -{ - long diff; - - diff = (tact->tv_usec + 1000000 * tact->tv_sec) - - (tlast->tv_usec + 1000000 * tlast->tv_sec); - - tdiff->tv_sec = diff / 1000000; - tdiff->tv_usec = diff % 1000000; - - return (diff < 0); -} - - - -int -eb_raw_file_open(const char *file) -{ - rawfp = fopen(file, "w"); - err_ret_if(rawfp == NULL, -1); - - return 0; -} - -int -eb_raw_file_close(void) -{ - int ret; - - ret = fflush(rawfp); - err_ret_if(ret == EOF, -1); - - ret = fclose(rawfp); - err_ret_if(ret == EOF, -1); - - return 0; -} - -int -eb_raw_file_write(const unsigned char *buf, int buflen) -{ - int ret, i; - - for (i = 0; i < buflen; i++) { - ret = fputc(buf[i], rawfp); - err_ret_if(ret == EOF, -1); - } - - ret = fflush(rawfp); - err_ret_if(ret == EOF, -1); - - return 0; -} - - - -void -eb_print_result(void) -{ - int i; - //fprintf(stdout, ">>> "); - for (i = 0; i < recv_data.len; i++) - fprintf(stdout, " %02x", recv_data.msg[i]); - fprintf(stdout, "\n"); -} - -void -eb_print_hex(const unsigned char *buf, int buflen) -{ - int i, j, k; - char msg[3 * print_size]; - - memset(msg, '\0', sizeof(msg)); - k = 1; - - for (i = 0, j = 0; i < buflen; i++, j++) { - sprintf(&msg[3 * j], " %02x", buf[i]); - - if (j + 1 == print_size) { - log_print(L_EBH, "%d%s", k, msg); - memset(msg, '\0', sizeof(msg)); - j = -1; - k++; - } - } - - if (j > 0) { - if (k > 1) - log_print(L_EBH, "%d%s", k, msg); - else - log_print(L_EBH, " %s", msg); - } -} - - - -void -eb_recv_data_get(unsigned char *buf, int *buflen) -{ - memcpy(buf, recv_data.msg, recv_data.len); - *buflen = recv_data.len; -} - -void -eb_recv_data_prepare(const unsigned char *buf, int buflen) -{ - unsigned char tmp[BUS_DEVICE_BUFSIZE]; - int tmplen, crc; - - memset(tmp, '\0', sizeof(tmp)); - - /* reset struct */ - memset(&recv_data, '\0', sizeof(recv_data)); - - /* set recv_data.msg_esc */ - memcpy(&recv_data.msg_esc[0], buf, buflen); - recv_data.len_esc = buflen; - - /* set recv_data.crc_calc and .crc_recv */ - if (buf[buflen - 2] == EBUS_SYN_ESC_A9) { - recv_data.crc_calc = eb_calc_crc(buf, buflen - 2); - if (buf[buflen - 1] == EBUS_SYN_ESC_01) - recv_data.crc_recv = EBUS_SYN; - else - recv_data.crc_recv = EBUS_SYN_ESC_A9; - - crc = 2; - - } else { - recv_data.crc_calc = eb_calc_crc(buf, buflen - 1); - recv_data.crc_recv = buf[buflen - 1]; - - crc = 1; - } - - /* set recv_data.msg */ - memcpy(tmp, buf, buflen - crc); - tmplen = buflen - crc; - - eb_unesc(tmp, &tmplen); - - memcpy(&recv_data.msg[0], tmp, tmplen); - recv_data.len = tmplen; - -} - -int -eb_recv_data(unsigned char *buf, int *buflen) -{ - unsigned char tmp[BUS_DEVICE_BUFSIZE], msg[BUS_DEVICE_BUFSIZE]; - int tmplen, msglen, ret, i, esc, found; - - memset(msg, '\0', sizeof(msg)); - msglen = 0; - - esc = 0; - found = 99; - - /* do until found necessary string*/ - do { - memset(tmp, '\0', sizeof(tmp)); - tmplen = sizeof(tmp); - - ret = eb_bus_recv(tmp, &tmplen); - if (ret < 0) - return -1; - - if (tmplen > 0) { - - /* preset tmp buffer with not read bytes from get_bus */ - if (*buflen > 0) { - - /* save temporarily tmp in msg buffer */ - memcpy(msg, tmp, tmplen); - msglen = tmplen; - - /* copy input data into tmp buffer */ - memset(tmp, '\0', sizeof(tmp)); - memcpy(tmp, buf, *buflen); - tmplen = *buflen; - - /* set input data buffer len to 0 */ - *buflen = 0; - - /* copy saved bus data back to tmp buffer */ - memcpy(&tmp[tmplen], msg, msglen); - tmplen += msglen; - - /* reset msg buffer */ - memset(msg, '\0', sizeof(msg)); - msglen = 0; - } - - - i = 0; - while (i < tmplen) { - - msg[msglen] = tmp[i]; - msglen++; - - /* SYN */ - if (msg[0] == EBUS_SYN) { - found = -2; - break; - } - - /* get end of message */ - if (msglen > 1) { - - if (msg[msglen - 1] == EBUS_SYN_ESC_A9) - esc++; - - if (msglen == (2 + msg[0] + esc)) { - found = 0; - break; - } - } - - /* - * something went wrong - plz tell me - * we got some SYN during answer or - * msglen is out of spec. 1 - */ - if (msg[msglen] == EBUS_SYN || msg[0] > 16) { - - found = -3; - break; - } - - i++; - } - } - } while (found == 99); - - *buflen = msglen; - - memset(buf, '\0', sizeof(buf)); - for (i = 0; i < msglen; i++) - buf[i] = msg[i]; - - return found; -} - - - -int -eb_bus_wait_syn(int *skip) -{ - unsigned char buf[BUS_DEVICE_BUFSIZE]; - int buflen, ret, i, found; - - found = 99; - - /* do until SYN read*/ - do { - memset(buf, '\0', sizeof(buf)); - buflen = sizeof(buf); - - ret = eb_bus_recv(buf, &buflen); - if (ret < 0) - return -1; - - if (buflen > 0) { - - i = 0; - while (i < buflen) { - /* break if byte = SYN and it is last byte */ - if (buf[i] == EBUS_SYN && (i + 1) == buflen) { - found = 1; - break; - } - i++; - } - - if (*skip > 0) - *skip -= 1; - } - } while (found == 99); - - return 0; -} - -int -eb_bus_wait(void) -{ - unsigned char buf[BUS_DEVICE_BUFSIZE]; - int buflen, ret, skip, retry; - struct timeval tact, tlast, tdiff; - - skip = 0; - retry = 0; - - do { - ret = eb_bus_wait_syn(&skip); - if (ret < 0) - return -1; - - /* remember start time */ - gettimeofday(&tlast, NULL); - - /* send QQ */ - ret = eb_bus_send(&qq, 1); - if (ret < 0) - return -1; - - gettimeofday(&tact, NULL); - eb_diff_time(&tact, &tlast, &tdiff); - - /* wait ~4200 usec */ - if (max_wait - tdiff.tv_usec > 0.0 && - max_wait - tdiff.tv_usec <= max_wait) - usleep(max_wait - tdiff.tv_usec); - else - log_print(L_WAR, "usleep out of range - skipped"); - - /* receive 1 byte - must be QQ */ - memset(buf, '\0', sizeof(buf)); - buflen = sizeof(buf); - ret = eb_bus_recv(buf, &buflen); - if (ret < 0) - return -1; - - /* is sent and read qq byte is equal */ - if (buf[0] == qq && buflen == 1) - return 0; - - retry++; - skip = skip_ack + retry; - - } while (retry < get_retry); - - /* reached max retry */ - return 1; -} - -int -eb_bus_free(void) -{ - int ret, skip; - ret = 0; - skip = 0; - - ret = eb_bus_send(&syn, 1); - if (ret < 0) - return -1; - - ret = eb_bus_wait_syn(&skip); - if (ret < 0) - return -1; - - return 0; -} - -int -eb_bus_valid(void) -{ - int busdevice; - - if (ioctl(bfd, TIOCMGET, &busdevice) < 0 && nodevicecheck == NO) - return -1; - else - return 0; -} - -void -eb_bus_devicetype(const char *dev) -{ - if (strchr(dev, '/') == NULL && strchr(dev, ':') != NULL) { - - devicetype = BUS_DEVICE_SOCKET; - } -} - -int -eb_bus_open(const char *dev, int *fd) -{ - int ret; - - eb_bus_devicetype(dev); - - if (devicetype == BUS_DEVICE_SERIAL) { - struct termios newtio; - - bfd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY); - //~ err_ret_if(bfd < 0, -1); - if (bfd < 0) - return -1; - - ret = fcntl(bfd, F_SETFL, 0); - err_ret_if(ret < 0, -1); - - /* check if the serial device is working */ - ret = eb_bus_valid(); - err_ret_if(ret < 0, -2); - - /* save current settings of serial device */ - ret = tcgetattr(bfd, &oldtio); - err_ret_if(ret < 0, -1); - - memset(&newtio, '\0', sizeof(newtio)); - - newtio.c_cflag = SERIAL_BAUDRATE | CS8 | CLOCAL | CREAD; - newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - newtio.c_iflag = IGNPAR; - newtio.c_oflag &= ~OPOST; - - newtio.c_cc[VMIN] = 1; - newtio.c_cc[VTIME] = 0; - - ret = tcflush(bfd, TCIFLUSH); - err_ret_if(ret < 0, -1); - - /* activate new settings of serial device */ - ret = tcsetattr(bfd, TCSANOW, &newtio); - err_ret_if(ret < 0, -1); - - *fd = bfd; - } - - if (devicetype == BUS_DEVICE_SOCKET) { - struct sockaddr_in sock; - char *hostport; - - memset((char *) &sock, 0, sizeof(sock)); - - /* - * Create a local copy of the string - * before the strtok() calls change it. - */ - hostport = strdup(dev); - char *host = strtok(hostport, ":"); - char *port = strtok(NULL, ":"); - - if (inet_addr(host) == INADDR_NONE) { - struct hostent *he; - - he = gethostbyname(host); - err_ret_if(he == NULL, -1); - - memcpy(&sock.sin_addr, he->h_addr_list[0], he->h_length); - } else { - ret = inet_aton(host, &sock.sin_addr); - err_ret_if(ret == 0, -1); - } - - sock.sin_family = AF_INET; - sock.sin_port = htons(atoi(port)); - - bfd = socket(AF_INET, SOCK_STREAM, 0); - err_ret_if(bfd < 0, -1); - - ret = connect(bfd, (struct sockaddr *)&sock, sizeof(sock)); - err_ret_if(ret < 0, -1); - - *fd = bfd; - free(hostport); - } - - return 0; -} - -int -eb_bus_close(void) -{ - int ret; - - if (devicetype == BUS_DEVICE_SERIAL) { - /* activate old settings of serial device */ - ret = tcsetattr(bfd, TCSANOW, &oldtio); - /* Ignore this error otherwise USB port may stay unclosed */ - /* err_ret_if(ret < 0, -1); */ - } - - /* Close file descriptor from bus device */ - ret = close(bfd); - err_ret_if(ret < 0, -1); - - return 0; -} - -int -eb_bus_send(const unsigned char *buf, int buflen) -{ - int ret, val; - - /* write msg to bus device */ - val = write(bfd, buf, buflen); - err_ret_if(val < 0, -1); - - if (devicetype == BUS_DEVICE_SERIAL) { - ret = tcflush(bfd, TCIOFLUSH); - err_ret_if(ret < 0, -1); - } - - return val; -} - -int -eb_bus_recv(unsigned char *buf, int *buflen) -{ - int ret; - - /* if (devicetype == BUS_DEVICE_SERIAL) { */ - /* flush deactivated - brings us an error */ - /* tcflush(bfd, TCIOFLUSH); */ - /* } */ - - /* read msg from bus device */ - *buflen = read(bfd, buf, *buflen); - err_if(*buflen < 0); - - if (*buflen < 0) { - log_print(L_WAR, "error read bus device"); - return -1; - } - - if (*buflen > BUS_DEVICE_BUFSIZE) { - log_print(L_WAR, "read data len > %d", BUS_DEVICE_BUFSIZE); - return -3; - } - - /* print bus */ - if (showraw == YES) - eb_print_hex(buf, *buflen); - - /* dump raw data*/ - if (rawdump == YES) { - ret = eb_raw_file_write(buf, *buflen); - if (ret < 0) - log_print(L_WAR, "can't write rawdata"); - } - - return 0; -} - - - -int -eb_send_data_get_ack(unsigned char *buf, int *buflen) -{ - unsigned char tmp[BUS_DEVICE_BUFSIZE]; - int tmplen, ret, i, j, found; - - j = 0; - found = 99; - - /* do until found necessary string */ - do { - memset(tmp, '\0', sizeof(tmp)); - tmplen = sizeof(tmp); - - ret = eb_bus_recv(tmp, &tmplen); - if (ret < 0) - return -1; - - if (tmplen > 0) { - i = 0; - while (i < tmplen) { - - /* compare recv with sent - is this possible */ - if (tmp[i] != buf[j] && j < *buflen) - return -2; - - /* compare only slaves answer */ - if (j > (*buflen - 1)) { - - /* ACK */ - if (tmp[i] == EBUS_ACK) - found = 0; - - /* NAK */ - else if (tmp[i] == EBUS_NAK) - found = 0; - - /* SYN */ - else if (tmp[i] == EBUS_SYN) - found = -3; - - /* ??? */ - else - found = -4; - i++; - break; - - } - i++; - j++; - } - } - } while (found == 99); - - *buflen = tmplen - i; - - memset(buf, '\0', sizeof(buf)); - for (j = 0; i < tmplen; i++, j++) - buf[j] = tmp[i]; - - return found; -} - -void -eb_send_data_prepare(const unsigned char *buf, int buflen) -{ - unsigned char crc[2], tmp[BUS_DEVICE_BUFSIZE]; - int tmplen, crclen; - - /* reset struct */ - memset(&send_data, '\0', sizeof(send_data)); - - /* set send_data.msg */ - memcpy(&send_data.msg[0], buf, buflen); - send_data.len = buflen; - - - /* set send_data.msg_esc + send_data.crc */ - memset(tmp, '\0', sizeof(tmp)); - memcpy(tmp, buf, buflen); - tmplen = buflen; - - eb_esc(tmp, &tmplen); - - memcpy(&send_data.msg_esc[0], &qq, 1); - memcpy(&send_data.msg_esc[1], tmp, tmplen); - tmplen++; - - memset(crc, '\0', sizeof(crc)); - send_data.crc = eb_calc_crc(&send_data.msg_esc[0], tmplen); - crc[0] = send_data.crc; - crclen = 1; - - if (crc[0] == EBUS_SYN || crc[0] == EBUS_SYN_ESC_A9) { - /* esc crc */ - eb_esc(crc, &crclen); - send_data.msg_esc[tmplen] = crc[0]; - tmplen++; - send_data.msg_esc[tmplen] = crc[1]; - tmplen++; - } else { - send_data.msg_esc[tmplen] = crc[0]; - tmplen++; - } - - send_data.len_esc = tmplen; - -} - -int -eb_send_data(const unsigned char *buf, int buflen, int type, unsigned char *bus, int *buslen) -{ - unsigned char tmp[BUS_DEVICE_BUFSIZE]; - int tmplen, ret, val; - - ret = 0; - - eb_send_data_prepare(buf, buflen); - - /* fetch AA and send QQ */ - ret = eb_bus_wait(); - if (ret != 0) - return -1; - - memcpy(bus, send_data.msg_esc, send_data.len_esc); - *buslen = send_data.len_esc; - - /* send message to slave */ - ret = eb_bus_send(&send_data.msg_esc[1], send_data.len_esc - 1); - if (ret < 0) - return -1; - - if (type == EBUS_MSG_BROADCAST) { - /* free bus */ - ret = eb_bus_free(); - if (ret < 0) - return -1; - - return 0; - } - - /* get data from bus (we got our sent message too) */ - memset(tmp, '\0', sizeof(tmp)); - memcpy(tmp, &send_data.msg_esc[1], send_data.len_esc - 1); - tmplen = send_data.len_esc - 1; - - ret = eb_send_data_get_ack(tmp, &tmplen); - - if (ret < 0 || ret > 1) { - /* free bus */ - ret = eb_bus_free(); - if (ret < 0) - return -1; - - return -1; - } - - /* first answer from slave is NAK - send message again (inkl. QQ) */ - if (ret == 1) { - - memcpy(&bus[*buslen], &nak, 1); - *buslen += 1; - - memcpy(&bus[*buslen], send_data.msg_esc, send_data.len_esc); - *buslen += send_data.len_esc; - - /* send message to slave */ - ret = eb_bus_send(&send_data.msg_esc[0], send_data.len_esc); - if (ret < 0) - return -1; - - /* get ack from bus (we got our sent message too) */ - memset(tmp, '\0', sizeof(tmp)); - memcpy(tmp, &send_data.msg_esc[0], send_data.len_esc); - tmplen = send_data.len_esc; - - ret = eb_send_data_get_ack(tmp, &tmplen); - - if (ret == 1) { - - memcpy(&bus[*buslen], &nak, 1); - *buslen += 1; - - /* free bus */ - ret = eb_bus_free(); - if (ret < 0) - return -1; - - return -1; - } - - } - - memcpy(&bus[*buslen], &ack, 1); - *buslen += 1; - - if (type == EBUS_MSG_MASTER_MASTER) { - val = ret; - - /* free bus */ - ret = eb_bus_free(); - if (ret < 0) - return -1; - - return val; - } - - /* get data - dont reset buffer */ - ret = eb_recv_data(tmp, &tmplen); - if (ret < 0) - return -1; - - eb_recv_data_prepare(tmp, tmplen); - - memcpy(&bus[*buslen], recv_data.msg_esc, recv_data.len_esc); - *buslen += recv_data.len_esc; - - /* check crc's from recv_data */ - if (recv_data.crc_calc != recv_data.crc_recv) { - - memcpy(&bus[*buslen], &nak, 1); - *buslen += 1; - - /* send message to slave */ - ret = eb_bus_send(&nak, 1); - if (ret < 0) - return -1; - - /* get data from bus (we got our sent message too) */ - memset(tmp, '\0', sizeof(tmp)); - tmplen = 0; - - ret = eb_send_data_get_ack(tmp, &tmplen); - - /* we compare against nak ! */ - if (ret != 1) { - /* free bus */ - ret = eb_bus_free(); - if (ret < 0) - return -1; - - return -1; - } - - /* get data - don't reset buffer */ - ret = eb_recv_data(tmp, &tmplen); - if (ret < 0) - return -1; - - eb_recv_data_prepare(tmp, tmplen); - - memcpy(&bus[*buslen], recv_data.msg_esc, recv_data.len_esc); - *buslen += recv_data.len_esc; - - } - - if (recv_data.crc_calc != recv_data.crc_recv) { - - memcpy(&bus[*buslen], &nak, 1); - *buslen += 1; - - ret = eb_bus_send(&nak, 1); - if (ret < 0) - return -1; - - val = 1; - } else { - - memcpy(&bus[*buslen], &ack, 1); - *buslen += 1; - - ret = eb_bus_send(&ack, 1); - if (ret < 0) - return -1; - - val = 0; - } - - /* free bus */ - ret = eb_bus_free(); - if (ret < 0) - return -1; - - return val; -} - - - -void -eb_execute(int id, char *data, char *buf, int *buflen) -{ - unsigned char msg[BUS_DEVICE_BUFSIZE], hlp[CMD_DATA_SIZE], bus[TMP_BUFSIZE]; - char tmp[TMP_BUFSIZE]; - int ret, msglen, buslen, msgtype, retry, cycdata, pos, len; - - memset(msg, '\0', sizeof(msg)); - msglen = sizeof(msg); - - msgtype = eb_cmd_get_s_type(id); - if (msgtype < 0) - return; - - cycdata = NO; - ret = -1; - retry = 0; - - if (eb_cmd_check_type(id, "cyc") == YES) { - cycdata = YES; - } else { - /* prepare command - if prepare failed buflen > 0 */ - eb_cmd_prepare(id, data, msg, &msglen, buf); - /* eb_print_hex(msg, msglen); */ - } - - if (cycdata == NO && strlen(buf) == 0) { - /* send data to bus */ - while (ret < 0 && retry < send_retry) { - if (retry > 0) - log_print(L_NOT, "send retry: %d", retry); - - memset(bus, '\0', sizeof(bus)); - buslen = 0; - - ret = eb_send_data(msg, msglen, msgtype, bus, &buslen); - - if (buslen > 0) - eb_print_hex(bus, buslen); - - retry++; - } - } - - /* handle answer for sent messages */ - if (cycdata == NO && ret >= 0) { - - if (msgtype == EBUS_MSG_BROADCAST) - strcpy(buf, "broadcast done\n"); - - if (msgtype == EBUS_MSG_MASTER_MASTER) { - if (ret == 0) - strcpy(buf, "ACK\n"); - else - strcpy(buf, "NAK\n"); - } - - if (msgtype == EBUS_MSG_MASTER_SLAVE) { - if (ret == 0) { - memset(msg, '\0', sizeof(msg)); - msglen = sizeof(msg); - eb_recv_data_get(msg, &msglen); - /* eb_print_hex(msg, msglen); */ - - /* decode */ - if (eb_cmd_check_type(id, "set") == YES) { - strcpy(buf, "ACK\n"); - } else { - eb_cmd_decode(id, CMD_PART_SD, data, msg, buf); - if (strlen(buf) > 0) - strncat(buf, "\n", 1); - } - - } else { - strcpy(buf, "NAK\n"); - } - } - - } else if (cycdata == YES) { - memset(tmp, '\0', sizeof(tmp)); - memset(hlp, '\0', sizeof(hlp)); - - eb_cmd_get_cyc_buf(id, msg, &msglen); - - /* CMD_PART_MD */ - pos = 4; - len = 1 + (int) msg[4]; - memcpy(hlp, &msg[pos], len); - - - eb_cmd_decode(id, CMD_PART_MD, data, hlp, tmp); - strncpy(buf, tmp, strlen(tmp)); - - if (msgtype != EBUS_MSG_BROADCAST) { - /* CMD_PART_SA */ - memset(tmp, '\0', sizeof(tmp)); - memset(hlp, '\0', sizeof(hlp)); - - pos = 5 + (int) msg[4] + 1; - len = 2; - hlp[0] = 0x01; - memcpy(&hlp[1], &msg[pos], 1); - - eb_cmd_decode(id, CMD_PART_SA, data, hlp, tmp); - strncat(buf, tmp, strlen(tmp)); - } - - if (msgtype == EBUS_MSG_MASTER_SLAVE) { - /* CMD_PART_SD */ - memset(tmp, '\0', sizeof(tmp)); - memset(hlp, '\0', sizeof(hlp)); - - pos = 5 + (int) msg[4] + 2; - len = 1 + (int) msg[pos]; - memcpy(hlp, &msg[pos], len); - - eb_cmd_decode(id, CMD_PART_SD, data, hlp, tmp); - strncat(buf, tmp, strlen(tmp)); - memset(tmp, '\0', sizeof(tmp)); - memset(hlp, '\0', sizeof(hlp)); - - /* CMD_PART_MA */ - pos = 5 + (int) msg[4] + 2 +(int) msg[pos] + 2; - len = 2; - hlp[0] = 0x01; - memcpy(&hlp[1], &msg[pos], 1); - - eb_cmd_decode(id, CMD_PART_MA, data, hlp, tmp); - strncat(buf, tmp, strlen(tmp)); - } - - if (strlen(buf) > 0) - strncat(buf, "\n", 1); - else - strcpy(buf, "error get cyc data\n"); - - } else { - strcpy(buf, "error send ebus msg\n"); - } - - *buflen = strlen(buf); - -} - - - -int -eb_cyc_data_process(const unsigned char *buf, int buflen) -{ - unsigned char msg[CMD_DATA_SIZE], hlp[CMD_DATA_SIZE]; - unsigned char crcm_recv, crcm_calc, acks, crcs_recv, crcs_calc, ackm; - int id, msgtype, msglen, hlplen, mlen, slen, len; - - memset(msg, '\0', sizeof(msg)); - - /* search command definition */ - id = eb_cmd_search_com_cyc(&buf[1], buflen - 1); - - if (id >= 0) { - msgtype = eb_cmd_get_s_type(id); - err_ret_if(msgtype < 0, -1); - - /* unescape */ - memcpy(msg, buf, buflen); - msglen = buflen; - - eb_unesc(msg, &msglen); - - /* calc crc vom master */ - mlen = 5 + (int) msg[4]; - - if (((int) msg[4]) > EBUS_MSG_MASTER_MAX_DB_LEN) { - log_print(L_WAR, "%s (%d > %d)", "Master DB Len Error", - ((int) msg[4]), EBUS_MSG_MASTER_MAX_DB_LEN); - return -2; - } - - memset(hlp, '\0', sizeof(hlp)); - memcpy(hlp, msg, mlen); - hlplen = mlen; - - eb_esc(hlp, &hlplen); - - crcm_calc = eb_calc_crc(hlp, hlplen); - crcm_recv = msg[mlen]; - - if (crcm_calc != crcm_recv) { - log_print(L_WAR, "%s", "Master CRC Error"); - return -2; - } - - /* set len */ - len = mlen + 1; - - - if (msgtype != EBUS_MSG_BROADCAST) { - - /* get ack from slave */ - acks = msg[mlen + 1]; - - if (acks == EBUS_NAK) { - log_print(L_WAR, "%s", "Slave ACK Error"); - return -2; - } - - /* set len */ - len = mlen + 2; - } - - - if (msgtype == EBUS_MSG_MASTER_SLAVE) { - - /* calc crc vom slave */ - slen = 1 + (int) msg[mlen + 2]; - - if (((int) msg[mlen + 2]) > EBUS_MSG_SLAVE_MAX_DB_LEN) { - log_print(L_WAR, "%s (%d > %d)", "Slave DB Len Error", - ((int) msg[mlen + 2]), EBUS_MSG_SLAVE_MAX_DB_LEN); - return -2; - } - - memset(hlp, '\0', sizeof(hlp)); - memcpy(hlp, &msg[mlen + 2], slen); - hlplen = slen; - - eb_esc(hlp, &hlplen); - - crcs_calc = eb_calc_crc(hlp, hlplen); - crcs_recv = msg[mlen + 2 + slen]; - - if (crcs_calc != crcs_recv) { - log_print(L_WAR, "%s", "Slave CRC Error"); - return -2; - } - - /* get ack from master */ - ackm = msg[mlen + 2 + slen + 1]; - - if (ackm == EBUS_NAK) { - log_print(L_WAR, "%s", "Master ACK Error"); - return -2; - } - - /* set len */ - len = mlen + 2 + slen + 2; - } - - /* check len */ - if (msglen > len) { - log_print(L_WAR, "%s", "LEN Error"); - return -2; - - } - - /* save data */ - eb_cmd_set_cyc_buf(id, msg, msglen); - - } - - return id; -} - -int -eb_cyc_data_recv(void) -{ - static unsigned char msg[BUS_DEVICE_BUFSIZE]; - static int msglen = 0; - - unsigned char buf[BUS_DEVICE_BUFSIZE]; - int ret, i, buflen; - - char tmp[TMP_BUFSIZE]; - int tmplen; - - memset(buf, '\0', sizeof(buf)); - buflen = sizeof(buf); - - if (msglen == 0) - memset(msg, '\0', sizeof(msg)); - - /* get new data */ - ret = eb_bus_recv(buf, &buflen); - if (ret < 0) - return -1; - - i = 0; - while (i < buflen) { - - if (buf[i] != EBUS_SYN) { - msg[msglen] = buf[i]; - msglen++; - } - - /* ebus syn sign is reached - decode ebus message */ - if (buf[i] == EBUS_SYN && msglen > 0) { - eb_print_hex(msg, msglen); - - ret = eb_cyc_data_process(msg, msglen); - - if (ret > 0) { - memset(tmp, '\0', sizeof(tmp)); - eb_execute(ret, "-", tmp, &tmplen); - tmp[strcspn(tmp,"\n")] = '\0'; - log_print(L_EBS, "%s", tmp); - } - - memset(msg, '\0', sizeof(msg)); - msglen = 0; - } - - i++; - } - - return msglen; -} - diff --git a/lib/ebus-bus.h b/lib/ebus-bus.h deleted file mode 100644 index 2f37bc1e..00000000 --- a/lib/ebus-bus.h +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -/** - * @file ebus-bus.h - * @brief ebus communication functions - * @author roland.jax@liwest.at - * @version 0.1 - */ - -#ifndef EBUS_BUS_H_ -#define EBUS_BUS_H_ - - - -#include - -#include "ebus-common.h" - - - -#define TMP_BUFSIZE 1024 - - - -/** - * @brief sending data structure - */ -struct send_data { - unsigned char crc; /**< crc of escaped message */ - unsigned char msg[BUS_DEVICE_BUFSIZE + 1]; /**< original message */ - int len; /**< length of original message */ - unsigned char msg_esc[BUS_DEVICE_BUFSIZE + 1]; /**< esacaped message */ - int len_esc; /**< length of esacaped message */ -}; - -/** - * @brief receiving data structure - */ -struct recv_data { - unsigned char crc_recv; /**< received crc */ - unsigned char crc_calc; /**< calculated crc */ - unsigned char msg[BUS_DEVICE_BUFSIZE + 1]; /**< unescaped message */ - int len; /**< length of unescaped message */ - unsigned char msg_esc[BUS_DEVICE_BUFSIZE + 1]; /**< received message */ - int len_esc; /**< length of received message */ -}; - - - - - -/** - * @brief set nodevicecheck - * @param [in] YES | NO - * @return none - */ -void eb_set_nodevicecheck(int check); - -/** - * @brief set rawdump - * @param [in] YES | NO - * @return none - */ -void eb_set_rawdump(int dump); - -/** - * @brief set showraw - * @param [in] YES | NO - * @return none - */ -void eb_set_showraw(int show); - -/** - * @brief set own ebus address - * @param [in] src ebus address - * @return none - */ -void eb_set_qq(unsigned char src); - -/** - * @brief set number of retry to get bus - * @param [in] retry - * @return none - */ -void eb_set_get_retry(int retry); - -/** - * @brief set number of skipped SYN if an error occurred while getting the bus - * @param [in] skip is only the start value (skip = skip_ack + retry;) - * @return none - */ -void eb_set_skip_ack(int skip); - -/** - * @brief set max wait time between send and receive of own address (QQ) - * @param [in] usec wait time in usec - * @return none - */ -void eb_set_max_wait(long usec); - -/** - * @brief set number of retry to send message - * @param [in] retry - * @return none - */ -void eb_set_send_retry(int retry); - -/** - * @brief set number of printed hex bytes - * @param [in] size - * @return none - */ -void eb_set_print_size(int size); - - - -/** - * @brief calculate delte time of given time stamps - * @param [in] *tact newer time stamp - * @param [in] *tlast older time stamp - * @param [out] *tdiff calculated time difference - * @return 0 positive | -1 negative ??? lol - */ -int eb_diff_time(const struct timeval *tact, const struct timeval *tlast, struct timeval *tdiff); - - - -/** - * @brief Open a file in write mode. - * @param [in] *file device - * @return 0 ok | -1 error - */ -int eb_raw_file_open(const char *file); - -/** - * @brief close a file. - * @return 0 ok | -1 error - */ -int eb_raw_file_close(void); - -/** - * @brief write bytes into file - * @param [in] *buf pointer to a byte array - * @param [in] buflen length of byte array - * @return 0 ok | -1 error - */ -int eb_raw_file_write(const unsigned char *buf, int buflen); - - - -/** - * @brief print received results in a specific format - * @return none - */ -void eb_print_result(void); - -/** - * @brief print received data with hex format - * @param [in] *buf pointer to a byte array of received bytes - * @param [in] buflen length of received bytes - * @return none - */ -void eb_print_hex(const unsigned char *buf, int buflen); - - - -/** - * @brief get received data - * @param [out] *buf pointer to a byte array of received bytes - * @param [out] *buflen length of received bytes - * @return none - */ -void eb_recv_data_get(unsigned char *buf, int *buflen); - -/** - * @brief prepare received data - * @param [in] *buf pointer to a byte array of received bytes - * @param [in] buflen length of received bytes - * @return none - */ -void eb_recv_data_prepare(const unsigned char *buf, int buflen); - -/** - * @brief receive bytes from serial device - * @param [out] *buf pointer to a byte array of received bytes - * @param [out] buflen length of received bytes - * @return 0 ok | -1 error | -2 syn no answer from slave - * | -3 SYN received after answer from slave - */ -int eb_recv_data(unsigned char *buf, int *buflen); - - - -/** - * @brief receive bytes from serial device until SYN byte was received - * @param [in] *skip number skipped SYN bytes - * @return 0 ok | -1 error - */ -int eb_bus_wait_syn(int *skip); - -/** - * @brief try to get bus for sending - * \li wait SYN byte, send our ebus address and wait for minimun of ~4200 usec - * \li read at least one byte and compare it with sent byte. - * @return 0 ok | -1 error | 1 max retry was reached - */ -int eb_bus_wait(void); - -/** - * @brief free bus after syn was sent - * @return 0 ok | -1 error - */ -int eb_bus_free(void); - -/** - * @brief check device type - * @param [in] *dev bus device - * @return none - */ -void eb_bus_devicetype(const char *dev); - -/** - * @brief Check if bus FD is vaild. - * @return 0 ok | -1 error - */ -int eb_bus_valid(void); - -/** - * @brief Open bus device in raw mode. 1 Byte is then minimum input length. - * @param [in] *dev bus device - * @param [out] *fd file descriptor from opened bus device - * @return 0 ok | -1 error - */ -int eb_bus_open(const char *dev, int *fd); - -/** - * @brief close bus device (and reset settings) - * @return 0 ok | -1 error | -2 bad file descriptor - */ -int eb_bus_close(void); - -/** - * @brief send bytes to bus device - * @param [in] *buf pointer to a byte array - * @param [in] buflen length of byte array - * @return 0 ok | -1 error | -2 bad file descriptor - */ -int eb_bus_send(const unsigned char *buf, int buflen); - -/** - * @brief receive bytes from bus device - * @param [out] *buf pointer to a byte array received bytes - * @param [out] *buflen length of received bytes - * @return 0 ok | -1 error | -2 bad file descriptor | -3 received data > BUFFER - */ -int eb_bus_recv(unsigned char *buf, int *buflen); - - - - /** - * @brief receive ACK byte from serial device - * @param [out] *buf pointer to a byte array of received bytes - * @param [out] buflen length of received bytes - * @return 0 ok | 1 negative ACK | -1 error | -2 send and recv msg are different - * | -3 syn received (no answer from slave) | -4 we should never reach this - */ -int eb_send_data_get_ack(unsigned char *buf, int *buflen); - -/** - * @brief prepare send data - * @param [in] *buf pointer to a byte array of send bytes - * @param [in] buflen length of send bytes - * @return none - */ -void eb_send_data_prepare(const unsigned char *buf, int buflen); - -/** - * @brief handle sending ebus data - * - * \li Given input data will be prepared (escape, crc) and send to ebus. - * \li Answer will be received, prepared (unescape, crc) and return as result. - * - * @param [in] *buf pointer to a byte array - * @param [in] buflen length of byte array - * @param [in] type is the type of message to send - * @param [out] *bus pointer to answer array - * @param [out] *buslen point to answer length - * @return 0 ok | 1 neg. ACK from Slave | -1 error - */ -int eb_send_data(const unsigned char *buf, int buflen, int type, unsigned char *bus, int *buslen); - - - -/** - * @brief handle send ebus cmd - * @param [in] id is index in command array - * @param [in] *data pointer to data bytes for decode/encode - * @param [out] *buf pointer to answer array - * @param [out] *buflen point to answer length - * @return none - */ -void eb_execute(int id, char *data, char *buf, int *buflen); - - - -/** - * @brief handle one collected message - * @param [in] *buf pointer to a byte array - * @param [in] buflen length of byte array - * @return 0-x msg number of collected msg | -1 msg not found | -2 error - */ -int eb_cyc_data_process(const unsigned char *buf, int buflen); - -/** - * @brief handle reading cycle ebus data - * @return 0-x length of collected msg | -1 error - */ -int eb_cyc_data_recv(void); - - - -#endif /* EBUS_BUS_H_ */ diff --git a/lib/ebus-cmd.c b/lib/ebus-cmd.c deleted file mode 100644 index adb399e4..00000000 --- a/lib/ebus-cmd.c +++ /dev/null @@ -1,1046 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -/** - * @file ebus-cmd.c - * @brief ebus command file functions - * @author roland.jax@liwest.at - * @version 0.1 - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "ebus-decode.h" -#include "ebus-cmd.h" - -static struct cycbuf *cyc = NULL; -static int cyclen = 0; - -static struct commands *com = NULL; -static int comlen = 0; - -void -eb_cmd_uppercase(char *buf) -{ - while (*buf++ != '\0') - *buf = toupper((unsigned char) *buf); -} - - -int -eb_cmd_check_type(int id, const char *type) -{ - if (strncasecmp(com[id].type, type, 3) == 0) - return YES; - else - return NO; -} - - - -int -eb_cmd_get_s_type(int id) -{ - if (strncasecmp(com[id].s_type, EBUS_MSG_BROADCAST_TXT, 2) == 0) { - return EBUS_MSG_BROADCAST; - } else if(strncasecmp(com[id].s_type, EBUS_MSG_MASTER_MASTER_TXT, 2) == 0) { - return EBUS_MSG_MASTER_MASTER; - } else if(strncasecmp(com[id].s_type, EBUS_MSG_MASTER_SLAVE_TXT, 2) == 0) { - return EBUS_MSG_MASTER_SLAVE; - } else { - log_print(L_ERR, "message type %s unkown", com[id].s_type); - return -1; - } -} - - - -void -eb_cmd_set_cyc_buf(int id, const unsigned char *msg, int msglen) -{ - int i; - - for (i = 0; i < cyclen; i++) - if (cyc[i].id == com[id].id) - break; - - memcpy(cyc[i].buf, msg, msglen); - cyc[i].buflen = msglen; -} - -void -eb_cmd_get_cyc_buf(int id, unsigned char *msg, int *msglen) -{ - int i; - - for (i = 0; i < cyclen; i++) - if (cyc[i].id == com[id].id) - break; - - *msglen = cyc[i].buflen; - memcpy(msg, cyc[i].buf, *msglen); -} - - - -int -eb_cmd_search_com_cyc(const unsigned char *hex, int hexlen) -{ - unsigned char hlp[(CMD_SIZE_S_MSG * 2) + 1]; - int i; - - if (hexlen > (CMD_SIZE_S_MSG * 2)) { - log_print(L_ERR, "hexlen: %d > hlp: %d ", hexlen, (CMD_SIZE_S_MSG * 2)); - return -2; - } - - memset(hlp, '\0', sizeof(hlp)); - for (i = 0; i < hexlen; i++) - sprintf((char *) &hlp[2 * i], "%02X", hex[i]); - - for (i = 0; i < cyclen; i++) { - if (memcmp(hlp, cyc[i].msg, strlen((const char *) cyc[i].msg)) == 0) { - log_print(L_NOT, " found: %s type: %s ==> id: %d", - cyc[i].msg, com[cyc[i].id].s_type, cyc[i].id); - - return cyc[i].id; - } - } - - return -1; -} - -int -eb_cmd_search_com_id(const char *type, const char *class, const char *cmd) -{ - int i; - - for (i = 0; i < comlen; i++) { - if ((strncasecmp(type, com[i].type, strlen(com[i].type)) == 0) - && (strncasecmp(class, com[i].class, strlen(com[i].class)) == 0) - && strlen(class) == strlen(com[i].class) - && (strncasecmp(cmd, com[i].cmd, strlen(com[i].cmd)) == 0) - && strlen(cmd) == strlen(com[i].cmd)) { - - log_print(L_NOT, " found: %s%s%02X%s type: %s ==> id: %d", - com[i].s_zz, com[i].s_cmd, com[i].s_len, - com[i].s_msg, com[i].s_type, i); - return i; - } - - } - - return -1; -} - -int -eb_cmd_search_com(char *buf, char *data) -{ - char *type, *class, *cmd, *tok; - int id; - - type = strtok(buf, " "); - class = strtok(NULL, " ."); - cmd = strtok(NULL, " .\n\r\t"); - - if (class != NULL && cmd != NULL) { - - if (strncasecmp(type, "get", 3) == 0 || - strncasecmp(type, "set", 3) == 0 || - strncasecmp(type, "cyc", 3) == 0) { - log_print(L_NOT, "search: %s %s.%s", type, class, cmd); - - id = eb_cmd_search_com_id(type, class, cmd); - if (id < 0) - return -1; - - tok = strtok(NULL, "\n\r"); - - if (tok == NULL) - strncpy(data, "-", 1); - else - strncpy(data, tok, strlen(tok)); - - log_print(L_NOT, " data: %s", data); - return id; - - } - } - - return -1; -} - - - -int -eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf) -{ - char *c1, *c2, *c3, *c4; - char d_pos[CMD_SIZE_D_POS + 1]; - int ret, i, j, p1, p2, p3, p4; - - memset(d_pos, '\0', sizeof(d_pos)); - strncpy(d_pos, com[id].elem[elem].d_pos, strlen(com[id].elem[elem].d_pos)); - - c1 = strtok(d_pos, " ,\n"); - c2 = strtok(NULL, " ,\n"); - c3 = strtok(NULL, " ,\n"); - c4 = strtok(NULL, " ,\n"); - - p1 = c1 ? atoi(c1) : 0; - p2 = c2 ? atoi(c2) : 0; - p3 = c3 ? atoi(c3) : 0; - p4 = c4 ? atoi(c4) : 0; - - log_print(L_DBG, "id: %d elem: %d p1: %d p2: %d p3: %d p4: %d", id, elem, p1, p2, p3, p4); - - if (strncasecmp(com[id].elem[elem].d_type, "str", 3) == 0) { - sprintf(buf, "%s", &msg[1]); - - } else if (strncasecmp(com[id].elem[elem].d_type, "bcd", 3) == 0) { - if (p1 > 0) { - int ii; - ret = eb_bcd_to_int(msg[p1], &ii); - - ii *= com[id].elem[elem].d_fac; - sprintf(buf, "%d", ii); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d1b", 3) == 0) { - if (p1 > 0) { - int ii; - float ff; - ret = eb_d1b_to_int(msg[p1], &ii); - - ff = ii * com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d1c", 3) == 0) { - if (p1 > 0) { - float ff; - ret = eb_d1c_to_float(msg[p1], &ff); - - ff *= com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d2b", 3) == 0) { - if (p1 > 0 && p2 > 0) { - float ff; - if (p1 > p2) - ret = eb_d2b_to_float(msg[p2], msg[p1], &ff); - else - ret = eb_d2b_to_float(msg[p1], msg[p2], &ff); - - ff *= com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d2c", 3) == 0) { - if (p1 > 0 && p2 > 0) { - float ff; - if (p1 > p2) - ret = eb_d2c_to_float(msg[p2], msg[p1], &ff); - else - ret = eb_d2c_to_float(msg[p1], msg[p2], &ff); - - ff *= com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "bda", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0) { - int dd, mm, yy; - ret = eb_bcd_to_int(msg[p1], &dd); - ret = eb_bcd_to_int(msg[p2], &mm); - ret = eb_bcd_to_int(msg[p3], &yy); - - ret = eb_dat_to_str(dd, mm, yy, buf); - if (ret < 0) - sprintf(buf, "error %s ==> %02x %02x %02x", - com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "hda", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0) { - ret = eb_dat_to_str(msg[p1], msg[p2], msg[p3], buf); - if (ret < 0) - sprintf(buf, "error %s ==> %02x %02x %02x", - com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "bti", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0) { - int hh, mm, ss; - - ret = eb_bcd_to_int(msg[p1], &hh); - ret = eb_bcd_to_int(msg[p2], &mm); - ret = eb_bcd_to_int(msg[p3], &ss); - - ret = eb_tim_to_str(hh, mm, ss, buf); - if (ret < 0) - sprintf(buf, "error %s ==> %02x %02x %02x", - com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "hti", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0) { - ret = eb_tim_to_str(msg[p1], msg[p2], msg[p3], buf); - if (ret < 0) - sprintf(buf, "error %s ==> %02x %02x %02x", - com[id].elem[elem].d_sub, msg[p1], msg[p2], msg[p3]); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "bdy", 3) == 0) { - if (p1 > 0) - ret = eb_day_to_str(msg[p1], buf); - else - goto on_error; - - } else if (strncasecmp(com[id].elem[elem].d_type, "hdy", 3) == 0) { - if (p1 > 0) { - msg[p1] = msg[p1] - 0x01; - ret = eb_day_to_str(msg[p1], buf); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "ttm", 3) == 0) { - if (p1 > 0) { - int hh, mm; - hh = msg[p1] / 6; - mm = msg[p1] % 6 * 10; - sprintf(buf, "%02d:%02d", hh, mm); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "hex", 3) == 0) { - if (p1 > 0) { - if (p2 > msg[0]) - p2 = msg[0]; - - if (p2 == 0 || p2 < p1) - p2 = p1; - - for (i = 0, j = p1 - 1; i <= p2 - p1; i++, j++) - sprintf(&buf[3 * i], "%02x ", msg[j + 1]); - - buf[i * 3 - 1] = '\0'; - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "uch", 3) == 0) { - if (p1 > 0) { - unsigned char uch; - uch = msg[p1]; - sprintf(buf, "%u", uch); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "sch", 3) == 0) { - if (p1 > 0) { - char sch; - sch = msg[p1]; - sprintf(buf, "%d", sch); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "uin", 3) == 0) { - if (p1 > 0 && p2 > 0) { - unsigned int uin; - float ff; - uin = msg[p1] + (msg[p2] << 8); - - ff = uin * com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "sin", 3) == 0) { - if (p1 > 0 && p2 > 0) { - int sin; - float ff; - sin = msg[p1] + (msg[p2] << 8); - - ff = sin * com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "ulg", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) { - unsigned long ulg; - float ff; - ulg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24); - - ff = ulg * com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "slg", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) { - long slg; - float ff; - slg = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24); - - ff = slg * com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "flt", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0 && p4 > 0) { - float ff; - ff = msg[p1] + (msg[p2] << 8) + (msg[p3] << 16) + (msg[p4] << 24); - - ff *= com[id].elem[elem].d_fac; - sprintf(buf, "%f", ff); - } else { - goto on_error; - } - - } - - log_print(L_DBG, "buf: %s", buf); - - return 0; - -on_error: - strcpy(buf, "error decode"); - return -1; - -} - -int -eb_cmd_decode(int id, char *part, char *data, unsigned char *msg, char *buf) -{ - char *tok; - char tmp[CMD_DATA_SIZE], hlp[CMD_DATA_SIZE]; - int ret, i, found; - - /* walk through all elements */ - for (i = 0; i < com[id].d_elem; i++) { - memset(tmp, '\0', sizeof(tmp)); - strncpy(tmp, data, strlen(data)); - - /* "-" indicate no sub command, so we print all */ - tok = strtok(tmp, " \n\r\t"); - if (tok == NULL || strncasecmp(tok, "-", 1) == 0) - found = YES; - else - found = NO; - - /* search sub command */ - while (tok != NULL && found == NO) { - if (strncasecmp(com[id].elem[i].d_sub, tok, - strlen(com[id].elem[i].d_sub)) == 0 && - strncasecmp(com[id].elem[i].d_part, part, 2) == 0) { - - found = YES; - break; - } - tok = strtok(NULL, " \n\r\t"); - } - - if (strncasecmp(com[id].elem[i].d_part, part, 2) == 0 && - found == YES) { - memset(hlp, '\0', sizeof(hlp)); - - ret = eb_cmd_decode_value(id, i, msg, hlp); - if (ret < 0) { - strncat(buf, "\n", 1); - return -1; - } - - if (i > 0) - strncat(buf, " ", 1); - - strncat(buf, hlp, strlen(hlp)); - } - } - - return 0; -} - -int -eb_cmd_encode_value(int id, int elem, char *data, unsigned char *msg, char *buf) -{ - char *c1, *c2, *c3; - char d_pos[CMD_SIZE_D_POS + 1]; - unsigned char bcd, d1b, d1c, d2b[2], d2c[2]; - int ret, i, j, p1, p2, p3; - float f; - - memset(d_pos, '\0', sizeof(d_pos)); - strncpy(d_pos, com[id].elem[elem].d_pos, strlen(com[id].elem[elem].d_pos)); - - c1 = strtok(d_pos, " ,\n"); - c2 = strtok(NULL, " ,\n"); - c3 = strtok(NULL, " ,\n"); - - p1 = c1 ? atoi(c1) : 0; - p2 = c2 ? atoi(c2) : 0; - p3 = c3 ? atoi(c3) : 0; - - log_print(L_DBG, "id: %d elem: %d p1: %d p2: %d p3: %d data: %s", - id, elem, p1, p2, p3, data); - - if (strncasecmp(com[id].elem[elem].d_type, "str", 3) == 0) { - for (i = 0; i < (int) strlen(data); i++) - sprintf((char *) &msg[i * 2], "%02x", data[i]); - - } else if (strncasecmp(com[id].elem[elem].d_type, "bcd", 3) == 0) { - if (p1 > 0) { - i = (int) (atof(data) / com[id].elem[elem].d_fac); - - ret = eb_int_to_bcd(i, &bcd); - sprintf((char *) msg, "%02x", bcd); - - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d1b", 3) == 0) { - if (p1 > 0) { - i = (int) (atof(data) / com[id].elem[elem].d_fac); - - ret = eb_int_to_d1b(i, &d1b); - sprintf((char *) msg, "%02x", d1b); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d1c", 3) == 0) { - if (p1 > 0) { - f = (atof(data) / com[id].elem[elem].d_fac); - - ret = eb_float_to_d1c(f, &d1c); - sprintf((char *) msg, "%02x", d1c); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d2b", 3) == 0) { - if (p1 > 0 && p2 > 0) { - f = (atof(data) / com[id].elem[elem].d_fac); - - if (p1 > p2) - ret = eb_float_to_d2b(f, &d2b[1], &d2b[0]); - else - ret = eb_float_to_d2b(f, &d2b[0], &d2b[1]); - - sprintf((char *) msg, "%02x%02x", d2b[0], d2b[1]); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "d2c", 3) == 0) { - if (p1 > 0 && p2 > 0) { - f = (atof(data) / com[id].elem[elem].d_fac); - - if (p1 > p2) - ret = eb_float_to_d2c(f, &d2c[1], &d2c[0]); - else - ret = eb_float_to_d2c(f, &d2c[0], &d2c[1]); - - sprintf((char *) msg, "%02x%02x", d2c[0], d2c[1]); - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "hda", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0) { - int dd, mm, yy; - - dd = atoi(strtok(data, " .\n")); - mm = atoi(strtok(NULL, " .\n")); - yy = atoi(strtok(NULL, " .\n")); - - ret = eb_str_to_dat(dd, mm, yy, msg); - if (ret < 0) - sprintf(buf, "error ==> %d.%d.%d", dd, mm, yy); - - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "hti", 3) == 0) { - if (p1 > 0 && p2 > 0 && p3 > 0) { - int hh, mm, ss; - - hh = atoi(strtok(data, " :\n")); - mm = atoi(strtok(NULL, " :\n")); - ss = atoi(strtok(NULL, " :\n")); - - ret = eb_str_to_tim(hh, mm, ss, msg); - if (ret < 0) - sprintf(buf, "error ==> %d:%d:%d", hh, mm, ss); - - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "hdy", 3) == 0) { - if (p1 > 0) { - int day; - - day = atoi(data); - sprintf((char *) msg, "%02x", day); - - } else { - goto on_error; - } - - } else if (strncasecmp(com[id].elem[elem].d_type, "hex", 3) == 0) { - for (i = 0, j = 0; data[i]; i++) { - - if (isxdigit(data[i])) { - msg[j] = tolower(data[i]); - j++; - } else if (data[i] != ' ') { - goto on_error; - } - } - - } - - return 0; - -on_error: - strcpy(buf, "error encode"); - return -1; - -} - -int -eb_cmd_encode(int id, char *data, unsigned char *msg, char *buf) -{ - char *tok, *toksave; - unsigned char hlp[CMD_SIZE_S_MSG + 1]; - int ret, i; - - tok = strtok_r(data, " \n\r\t", &toksave); - - /* walk through all elements */ - for (i = 0; i < com[id].d_elem; i++) { - if (tok != NULL) { - memset(hlp, '\0', sizeof(hlp)); - ret = eb_cmd_encode_value(id, i, tok, hlp, buf); - if (ret < 0) { - strncat(buf, "\n", 1); - return -1; - } - - strncat((char *) msg, (const char *) hlp, strlen((const char *) hlp)); - - } else { - return -1; - } - - tok = strtok_r(NULL, " \n\r\t", &toksave); - } - - if (strlen(buf) > 0) - strncat(buf, "\n", 1); - - return 0; -} - -void -eb_cmd_prepare(int id, char *data, unsigned char *msg, int *msglen, char *buf) -{ - unsigned char tmp[CMD_SIZE_S_MSG + 1]; - char str[CMD_SIZE_S_ZZ + CMD_SIZE_S_CMD + 2 + CMD_SIZE_S_MSG + 1]; - char byte; - int ret, i, j, k; - int in[BUS_DEVICE_BUFSIZE]; - - /* encode msg */ - memset(tmp, '\0', sizeof(tmp)); - if (strncasecmp(com[id].type, "set", 3) == 0) - eb_cmd_encode(id, data, tmp, buf); - - memset(str, '\0', sizeof(str)); - sprintf(str, "%s%s%02X%s%s", - com[id].s_zz, com[id].s_cmd, com[id].s_len, com[id].s_msg, tmp); - - memset(in, '\0', sizeof(in)); - i = 0; - j = 0; - - while (str[j] != '\0') { - byte = str[j]; - if (i < (int) sizeof(in)) { - - ret = eb_htoi(&byte); - if (ret != -1) { - in[i] = ret; - i++; - } - } - j++; - } - - memset(msg, '\0', sizeof(msg)); - for (j = 0, k = 0; j < i; j += 2, k++) - msg[k] = (unsigned char) (in[j]*16 + in[j+1]); - - *msglen = k; - -} - - - -void -eb_cmd_print(const char *type, int all, int detail) -{ - int i, j; - - for (i = 0; i < comlen; i++) { - - if (strncasecmp(com[i].type, type, 1) == 0 || all) { - - log_print(L_INF, "[%03d] %s : %22s.%-42s\t(type: %s)" \ - " %s%s%-10s (len: %d) [%d] ==> %s", - com[i].id, - com[i].type, - com[i].class, - com[i].cmd, - com[i].s_type, - com[i].s_zz, - com[i].s_cmd, - com[i].s_msg, - com[i].s_len, - com[i].d_elem, - com[i].com - ); - - if (detail) { - for (j = 0; j < com[i].d_elem; j++) { - log_print(L_INF, "\t\t %-20s %-2s " \ - "pos: %-10s\t%s [%5.2f] [%s] \t%s\t%s", - com[i].elem[j].d_sub, - com[i].elem[j].d_part, - com[i].elem[j].d_pos, - com[i].elem[j].d_type, - com[i].elem[j].d_fac, - com[i].elem[j].d_unit, - com[i].elem[j].d_valid, - com[i].elem[j].d_com - - ); - } - log_print(L_INF, ""); - } - - - } - } -} - - - -int -eb_cmd_fill(const char *tok) -{ - int i; - - com = (struct commands *) realloc(com, (comlen + 1) * sizeof(struct commands)); - err_ret_if(com == NULL, -1); - - memset(com + comlen, '\0', sizeof(struct commands)); - - /* id */ - com[comlen].id = comlen; - - /* type */ - strncpy(com[comlen].type, tok, strlen(tok)); - - /* class */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].class, tok, strlen(tok)); - - - /* cmd */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].cmd, tok, strlen(tok)); - - /* com */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].com, tok, strlen(tok)); - - /* s_type */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].s_type, tok, strlen(tok)); - eb_cmd_uppercase(com[comlen].s_type); - - /* s_zz */ - tok = strtok(NULL, ";"); - - strncpy(com[comlen].s_zz, tok, strlen(tok)); - eb_cmd_uppercase(com[comlen].s_zz); - - /* s_cmd */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].s_cmd, tok, strlen(tok)); - eb_cmd_uppercase(com[comlen].s_cmd); - - /* s_len */ - tok = strtok(NULL, ";"); - com[comlen].s_len = atoi(tok); - - /* s_msg */ - tok = strtok(NULL, ";"); - if (strncasecmp(tok, "-", 1) != 0) { - strncpy(com[comlen].s_msg, tok, strlen(tok)); - eb_cmd_uppercase(com[comlen].s_msg); - } - - /* d_elem */ - tok = strtok(NULL, ";"); - com[comlen].d_elem = atoi(tok); - - com[comlen].elem = (struct element *) malloc(com[comlen].d_elem * sizeof(struct element)); - err_ret_if(com[comlen].elem == NULL, -1); - - memset(com[comlen].elem, '\0', com[comlen].d_elem * sizeof(struct element)); - - for (i = 0; i < com[comlen].d_elem; i++) { - - /* d_sub */ - tok = strtok(NULL, ";"); - if (strncasecmp(tok, "-", 1) != 0) - strncpy(com[comlen].elem[i].d_sub, tok, strlen(tok)); - - /* d_part */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].elem[i].d_part, tok, strlen(tok)); - - /* d_pos */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].elem[i].d_pos, tok, strlen(tok)); - - /* d_type */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].elem[i].d_type, tok, strlen(tok)); - - /* d_fac */ - tok = strtok(NULL, ";"); - com[comlen].elem[i].d_fac = atof(tok); - - /* d_unit */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].elem[i].d_unit, tok, strlen(tok)); - - /* d_valid */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].elem[i].d_valid, tok, strlen(tok)); - - /* d_com */ - tok = strtok(NULL, ";"); - strncpy(com[comlen].elem[i].d_com, tok, strlen(tok)); - com[comlen].elem[i].d_com[strcspn(com[comlen].elem[i].d_com, "\n")] = '\0'; - - } - - if (strncasecmp(com[comlen].type, "cyc", 3) == 0) { - - cyc = (struct cycbuf *) realloc(cyc, (cyclen + 1) * sizeof(struct cycbuf)); - err_ret_if(cyc == NULL, -1); - - memset(cyc + cyclen, '\0', sizeof(struct cycbuf)); - - /* id */ - cyc[cyclen].id = com[comlen].id; - - /* msg */ - sprintf((char *) cyc[cyclen].msg, "%s%s%02X%s", - com[comlen].s_zz, com[comlen].s_cmd, - com[comlen].s_len, com[comlen].s_msg); - - cyclen++; - - } - - comlen++; - - return 0; -} - -int -eb_cmd_num_c(const char *str, const char c) -{ - const char *p = str; - int i = 0; - - do { - if (*p == c) - i++; - } while (*(p++)); - - return i; -} - -int -eb_cmd_file_read(const char *file) -{ - int ret; - char line[CMD_LINELEN]; - char *tok; - FILE *fp = NULL; - - log_print(L_NOT, "%s", file); - - /* open config file */ - fp = fopen(file, "r"); - err_ret_if(fp == NULL, -1); - - /* read each line and fill cmd array */ - while (fgets(line, CMD_LINELEN, fp) != NULL) { - tok = strtok(line, ";\n"); - - if (tok != NULL && tok[0] != '#' ) { - - ret = eb_cmd_fill(tok); - if (ret < 0) - return -2; - - } - - } - - /* close config file */ - ret = fclose(fp); - err_ret_if(ret == EOF, -1); - - log_print(L_NOT, "%s success", file); - - return 0; -} - -int -eb_cmd_dir_read(const char *cfgdir, const char *extension) -{ - struct dirent **dir; - int ret, i, j, files, extlen; - char file[CMD_FILELEN], extprep[11]; - char *ext; - - extlen = strlen(extension) + 1; - - memset(extprep, '\0', sizeof(extprep)); - extprep[0] = '.'; - strncpy(&extprep[1], extension, strlen(extension)); - - files = scandir(cfgdir, &dir, 0, alphasort); - if (files < 0) { - log_print(L_WAR, "configuration directory %s not found.", cfgdir); - return 1; - } - - i = 0; - j = 0; - while (i < files) { - ext = strrchr(dir[i]->d_name, '.'); - if (ext != NULL) { - if ((int) strlen(ext) == extlen - && dir[i]->d_type == DT_REG - && strncasecmp(ext, extprep, extlen) == 0 ) { - memset(file, '\0', sizeof(file)); - sprintf(file, "%s/%s", cfgdir, dir[i]->d_name); - - ret = eb_cmd_file_read(file); - if (ret < 0) - return -1; - - j++; - } - } - - free(dir[i]); - i++; - } - - free(dir); - - if (j == 0) { - log_print(L_WAR, "no command files found ==> decode disabled."); - return 2; - } - - return 0; -} - -void -eb_cmd_dir_free(void) -{ - int i; - - if (comlen > 0) { - for (i = 0; i < comlen; i++) - free(&com[i].elem[0]); - - free(com); - } - - if (cyclen > 0) - free(cyc); - -} - diff --git a/lib/ebus-cmd.h b/lib/ebus-cmd.h deleted file mode 100644 index f4ddb7cf..00000000 --- a/lib/ebus-cmd.h +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -/** - * @file ebus-cmd.h - * @brief ebus command file functions - * @author roland.jax@liwest.at - * @version 0.1 - */ - -#ifndef EBUS_CMD_H_ -#define EBUS_CMD_H_ - - - -#include - -#include "ebus-common.h" - - - -#define CMD_LINELEN 512 -#define CMD_FILELEN 1024 - -#define CMD_SIZE_TYPE 3 -#define CMD_SIZE_CLASS 20 -#define CMD_SIZE_CMD 40 -#define CMD_SIZE_COM 256 -#define CMD_SIZE_S_TYPE 2 -#define CMD_SIZE_S_ZZ 2 -#define CMD_SIZE_S_CMD 4 -#define CMD_SIZE_S_MSG 32 - -#define CMD_SIZE_D_SUB 20 -#define CMD_SIZE_D_PART 2 -#define CMD_SIZE_D_POS 10 -#define CMD_SIZE_D_TYPE 3 -#define CMD_SIZE_D_UNIT 6 -#define CMD_SIZE_D_VALID 30 -#define CMD_SIZE_D_COM 256 - -#define CMD_PART_MD "MD" -#define CMD_PART_SA "SA" -#define CMD_PART_SD "SD" -#define CMD_PART_MA "MA" - - - -/** - * @brief cycbuf structure - */ -struct cycbuf { - int id; /**< command id from command buffer */ - unsigned char msg[CMD_SIZE_S_MSG + 1]; /**< zz + cmd + len + msg */ - unsigned char buf[CMD_DATA_SIZE + 1]; /**< whole message - unescaped */ - int buflen; /**< len of saved message */ -}; - -/** - * @brief commands structure - */ -struct commands { - int id; /**< command id */ - char type[CMD_SIZE_TYPE + 1]; /**< type of message */ - char class[CMD_SIZE_CLASS + 1]; /**< ci */ - char cmd[CMD_SIZE_CMD + 1]; /**< hydraulic */ - char com[CMD_SIZE_COM + 1]; /**< just a comment */ - char s_type[CMD_SIZE_S_TYPE + 1]; /**< message type */ - char s_zz[CMD_SIZE_S_ZZ + 1]; /**< zz */ - char s_cmd[CMD_SIZE_S_CMD + 1]; /**< pb sb */ - int s_len; /**< number of send bytes */ - char s_msg[CMD_SIZE_S_MSG + 1]; /**< max 15 data bytes */ - int d_elem; /**< number of elements */ - struct element *elem; /**< pointer of array with elements */ -}; - -/** - * @brief element structure - */ -struct element { - char d_sub[CMD_SIZE_D_SUB + 1]; /**< pin1 */ - char d_part[CMD_SIZE_D_PART + 1]; /**< part of message */ - char d_pos[CMD_SIZE_D_POS + 1]; /**< data position at bytes */ - char d_type[CMD_SIZE_D_TYPE + 1]; /**< data type */ - float d_fac; /**< facter */ - char d_unit[CMD_SIZE_D_UNIT + 1]; /**< unit of data like °C,...) */ - char d_valid[CMD_SIZE_D_VALID + 1]; /**< valid data */ - char d_com[CMD_SIZE_D_COM + 1]; /**< just a comment */ -}; - - - -/** - * @brief convert string to uppercase - * @param [out] *buf pointer to buffer array - */ -void eb_cmd_uppercase(char *buf); - - - -/** - * @brief compare given type with type of given command id - * @param [in] id is index in command array - * @param [in] type for lookup - * @return YES or NO - */ -int eb_cmd_check_type(int id, const char *type); - - - -/** - * @brief returns s_type of given id - * @param [in] id is index in command array - * @return type of ebus command | -1 wrong message type - */ -int eb_cmd_get_s_type(int id); - - - -/** - * @brief set buf from cyc array - * @param [in] id is index in command array - * @param [in] *msg pointer to message array - * @param [in] msglen pointer to message length - * @return none - */ -void eb_cmd_set_cyc_buf(int id, const unsigned char *msg, int msglen); - - -/** - * @brief get buf from cyc array - * @param [in] id is index in command array - * @param [out] *msg pointer to message array - * @param [out] *msglen pointer to message length - * @return none - */ -void eb_cmd_get_cyc_buf(int id, unsigned char *msg, int *msglen); - - - -/** - * @brief search given strings in cycbuf array - * @param [in] *hex pointer to hex string - * @return 0-x id of found ebus command in array - * -1 command not found | -2 hexlen too long - */ -int eb_cmd_search_com_cyc(const unsigned char *hex, int hexlen); - -/** - * @brief search given strings in command array - * @param [in] *type pointer to message type - * @param [in] *class pointer to a ebus class - * @param [in] *cmd pointer to a ebus command - * @return 0-x id of found ebus command in array | -1 command not found - */ -int eb_cmd_search_com_id(const char *type, const char *class, const char *cmd); - -/** - * @brief search given strings in command array - * @param [in] *buf pointer to a byte array - * @param [out] *data pointer to data array for passing to decode/encode - * @return 0-x id of found ebus command in array | -1 command not found - */ -int eb_cmd_search_com(char *buf, char *data); - - - -/** - * @brief decode given element - * @param [in] id is index in command array - * @param [in] elem is index of data position - * @param [out] *msg pointer to message array - * @param [out] *buf pointer to decoded answer - * @return 0 ok | -1 error at decode - */ -int eb_cmd_decode_value(int id, int elem, unsigned char *msg, char *buf); - -/** - * @brief decode msg - * @param [in] id is index in command array - * @param [in] *part point to part type for decode - * @param [in] *data pointer to data bytes for decode - * @param [out] *msg pointer to message array - * @param [out] *buf pointer to decoded answer - * @return 0 ok | -1 error at decode - */ -int eb_cmd_decode(int id, char *part, char *data, unsigned char *msg, char *buf); - -/** - * @brief decode given element - * @param [in] id is index in command array - * @param [in] elem is index of data position - * @param [in] *data pointer to data bytes for encode - * @param [out] *msg pointer to message array - * @param [out] *buf pointer to decoded answer - * @return 0 ok | -1 error at decode - */ -int eb_cmd_encode_value(int id, int elem, char *data, unsigned char *msg, char *buf); - -/** - * @brief encode msg - * @param [in] id is index in command array - * @param [in] *data pointer to data bytes for encode - * @param [out] *msg pointer to message array - * @param [out] *buf pointer to decoded answer - * @return 0 ok | -1 error at encode - */ -int eb_cmd_encode(int id, char *data, unsigned char *msg, char *buf); - -/** - * @brief prepare message string for given ebus cmd from array - * @param [in] id is index in command array - * @param [in] *data pointer to data bytes for decode/encode - * @param [out] *msg pointer to message array - * @param [out] *msglen pointer to message length - * @param [out] *buf pointer to decoded answer - * @return none - */ -void eb_cmd_prepare(int id, char *data, unsigned char *msg, int *msglen, char *buf); - - - -/** - * @brief print readed ebus commands - * @param [in] *type (get/set/cyc) - * @param [in] all print all - * @param [in] detail show details of command - * @return none - */ -void eb_cmd_print(const char *type, int all, int detail); - - - -/** - * @brief fill command structure - * @param [in] *tok pointer to given token - * @return 0 ok | -1 error - */ -int eb_cmd_fill(const char *tok); - -/** - * @brief prevent buffer overflow - * - * number of tokens must be >= number of columns - 1 of file - * - * @param [in] *buf pointer to a byte array - * @param [in] delimeter - * @return number of found delimeters - */ -int eb_cmd_num_c(const char *buf, const char c); - -/** - * @brief set cfgdir address - * @param [in] *file pointer to configuration file with *.csv - * @return 0 ok | -1 error | -2 read token error - */ -int eb_cmd_file_read(const char *file); - -/** - * @brief get all files with given extension from given configuration directory - * @param [in] *cfgdir pointer to configuration directory - * @param [in] *suffix pointer to given extension - * @return 0 ok | -1 error | 1 read file error | 2 no command files found - */ -int eb_cmd_dir_read(const char *cfgdir, const char *extension); - -/** - * @brief free mem for ebus commands - * @return none - */ -void eb_cmd_dir_free(void); - - - -#endif /* EBUS_CMD_H_ */ diff --git a/lib/ebus-common.h b/lib/ebus-common.h deleted file mode 100644 index d190ca7e..00000000 --- a/lib/ebus-common.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * crc calculations from http://www.mikrocontroller.net/topic/75698 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -/** - * @file ebus-common.h - * @brief ebus common defines - * @author roland.jax@liwest.at - * @version 0.1 - */ - -#ifndef EBUS_COMMON_H_ -#define EBUS_COMMON_H_ - - - -#define EBUS_SYN 0xAA -#define EBUS_SYN_ESC_A9 0xA9 -#define EBUS_SYN_ESC_01 0x01 -#define EBUS_SYN_ESC_00 0x00 - -#define EBUS_ACK 0x00 -#define EBUS_NAK 0xFF - -#define EBUS_QQ 0xFF - -#define EBUS_GET_RETRY 3 -#define EBUS_GET_RETRY_MAX 10 -#define EBUS_SKIP_ACK 1 -#define EBUS_MAX_WAIT 4000 -#define EBUS_SEND_RETRY 2 -#define EBUS_SEND_RETRY_MAX 10 -#define EBUS_PRINT_SIZE 30 - -#define EBUS_MSG_BROADCAST_TXT "BR" -#define EBUS_MSG_BROADCAST 1 -#define EBUS_MSG_MASTER_MASTER_TXT "MM" -#define EBUS_MSG_MASTER_MASTER 2 -#define EBUS_MSG_MASTER_SLAVE_TXT "MS" -#define EBUS_MSG_MASTER_SLAVE 3 - -#define EBUS_MSG_MASTER_MAX_DB_LEN 12 -#define EBUS_MSG_SLAVE_MAX_DB_LEN 12 - -#define BUS_DEVICE_SERIAL 0 -#define BUS_DEVICE_SOCKET 1 -#define BUS_DEVICE_BUFSIZE 100 - -#define SERIAL_DEVICE "/dev/ttyUSB0" -#define SERIAL_BAUDRATE B2400 - - -#define CMD_DATA_SIZE 50 /* 5+16+3+16+2 = 42 || 256 */ - -enum enum_bool {UNSET = -1, NO, YES}; - - - -#endif /* EBUS_COMMON_H_ */ diff --git a/lib/ebus-decode.c b/lib/ebus-decode.c deleted file mode 100644 index 2098150c..00000000 --- a/lib/ebus-decode.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * crc calculations from http://www.mikrocontroller.net/topic/75698 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -/** - * @file ebus-decode.c - * @brief ebus decode functions - * @author roland.jax@liwest.at - * @version 0.1 - */ - - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include - -#include "ebus-decode.h" - - - -const char *days[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; - - - -int -eb_htoi(const char *buf) -{ - int ret; - ret = -1; - - if (isxdigit(*buf)) { - if (isalpha(*buf)) - ret = 55; - else - ret = 48; - - ret = toupper(*buf) - ret; - } - - return ret; -} - - -void -eb_esc(unsigned char *buf, int *buflen) -{ - unsigned char tmp[BUS_DEVICE_BUFSIZE]; - int tmplen, i; - - memset(tmp, '\0', sizeof(tmp)); - i = 0; - tmplen = 0; - - while (i < *buflen) { - - if (buf[i] == EBUS_SYN) { - tmp[tmplen] = EBUS_SYN_ESC_A9; - tmplen++; - tmp[tmplen] = EBUS_SYN_ESC_01; - tmplen++; - } else if (buf[i] == EBUS_SYN_ESC_A9) { - tmp[tmplen] = EBUS_SYN_ESC_A9; - tmplen++; - tmp[tmplen] = EBUS_SYN_ESC_00; - tmplen++; - } else { - tmp[tmplen] = buf[i]; - tmplen++; - } - - i++; - } - - memset(buf, '\0', sizeof(buf)); - for (i = 0; i < tmplen; i++) - buf[i] = tmp[i]; - - *buflen = tmplen; -} - -void -eb_unesc(unsigned char *buf, int *buflen) -{ - unsigned char tmp[BUS_DEVICE_BUFSIZE]; - int tmplen, i, found; - - memset(tmp, '\0', sizeof(tmp)); - i = 0; - tmplen = 0; - found = 0; - - while (i < *buflen) { - - if (buf[i] == EBUS_SYN_ESC_A9) { - found = 1; - } else if (found == 1) { - if (buf[i] == EBUS_SYN_ESC_01) { - tmp[tmplen] = EBUS_SYN; - tmplen++; - } else { - tmp[tmplen] = EBUS_SYN_ESC_A9; - tmplen++; - } - - found = 0; - } else { - tmp[tmplen] = buf[i]; - tmplen++; - } - - i++; - } - - memset(buf, '\0', sizeof(buf)); - for (i = 0; i < tmplen; i++) - buf[i] = tmp[i]; - - *buflen = tmplen; -} - - - -int -eb_day_to_str(unsigned char day, char *tgt) -{ - int dd; - - if ((day & 0x0F) >= 0x00 && (day & 0x0F) <= 0x06) { - eb_bcd_to_int(day, &dd); - sprintf(tgt, "%s", days[dd]); - } else { - return -1; - } - - return 0; -} - - - -int -eb_dat_to_str(unsigned char dd, unsigned char mm, unsigned char yy, char *tgt) -{ - if ((dd & 0x7F) >= 0x00 && (dd & 0x7F) <= 0x1F && - (mm & 0x7F) >= 0x00 && (mm & 0x7F) <= 0x0C && - (yy & 0x7F) >= 0x00 && (yy & 0x7F) <= 0x63 ) - sprintf(tgt, "%02d.%02d.%04d", dd, mm, yy + 2000); - else - return -1; - - return 0; -} - -int -eb_str_to_dat(int dd, int mm, int yy, unsigned char *tgt) -{ - if (yy > 2000) - yy -= 2000; - - if (dd >= 0 && dd <= 31 && - mm >= 0 && mm <= 12 && - yy >= 0 && yy <= 99 ) - sprintf((char *) tgt, "%02x%02x%02x", dd, mm, yy); - - else - return -1; - - return 0; -} - - - -int -eb_tim_to_str(unsigned char hh, unsigned char mm, unsigned char ss, char *tgt) -{ - if ((hh & 0x7F) >= 0x00 && (hh & 0x7F) <= 0x17 && - (mm & 0x7F) >= 0x00 && (mm & 0x7F) <= 0x3B && - (ss & 0x7F) >= 0x00 && (ss & 0x7F) <= 0x3B ) - sprintf(tgt, "%02d:%02d:%02d", hh, mm, ss); - else - return -1; - - return 0; -} - -int -eb_str_to_tim(int hh, int mm, int ss, unsigned char *tgt) -{ - - if (hh >= 0 && hh <= 23 && - mm >= 0 && mm <= 59 && - ss >= 0 && ss <= 59 ) - sprintf((char *) tgt, "%02x%02x%02x", hh, mm, ss); - - else - return -1; - - return 0; -} - - - -int -eb_bcd_to_int(unsigned char src, int *tgt) -{ - if ((src & 0x0F) > 0x09 || ((src >> 4) & 0x0F) > 0x09) { - *tgt = (int) (0xFF); - return 0; - } else { - *tgt = (int) ( ( ((src & 0xF0) >> 4) * 10) + (src & 0x0F) ); - return 1; - } -} - -int -eb_int_to_bcd(int src, unsigned char *tgt) -{ - if (src > 99) { - *tgt = (unsigned char) (0xFF); - return 0; - } else { - *tgt = (unsigned char) ( ((src / 10) << 4) | (src % 10) ); - return 1; - } -} - - - -int -eb_d1b_to_int(unsigned char src, int *tgt) -{ - if ((src & 0x80) == 0x80) { - *tgt = (int) (- ( ((unsigned char) (~ src)) + 1) ); - - if (*tgt == -0x80) - return 0; - else - return -1; - - } else { - *tgt = (int) (src); - return 1; - } -} - -int -eb_int_to_d1b(int src, unsigned char *tgt) -{ - if (src < -127 || src > 127) { - *tgt = (unsigned char) (0x80); - return 0; - } else { - if (src >= 0) { - *tgt = (unsigned char) (src); - return 1; - } else { - *tgt = (unsigned char) (- (~ (src - 1) ) ); - return -1; - } - } -} - - - -int -eb_d1c_to_float(unsigned char src, float *tgt) -{ - if (src > 0xC8) { - *tgt = (float) (0xFF); - return 0; - } else { - *tgt = (float) (src / 2.0); - return 1; - } -} - -int -eb_float_to_d1c(float src, unsigned char *tgt) -{ - if (src < 0.0 || src > 100.0) { - *tgt = (unsigned char) (0xFF); - return 0; - } else { - *tgt = (unsigned char) (src * 2.0); - return 1; - } -} - - - -int -eb_d2b_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt) -{ - if ((src_msb & 0x80) == 0x80) { - *tgt = (float) - (- ( ((unsigned char) (~ src_msb)) + - ( ( ((unsigned char) (~ src_lsb)) + 1) / 256.0) ) ); - - if (src_msb == 0x80 && src_lsb == 0x00) - return 0; - else - return -1; - - } else { - *tgt = (float) (src_msb + (src_lsb / 256.0)); - return 1; - } -} - -int -eb_float_to_d2b(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb) -{ - if (src < -127.999 || src > 127.999) { - *tgt_msb = (unsigned char) (0x80); - *tgt_lsb = (unsigned char) (0x00); - return 0; - } else { - *tgt_lsb = (unsigned char) ((src - ((unsigned char) src)) * 256.0); - - if (src < 0.0 && *tgt_lsb != 0x00) - *tgt_msb = (unsigned char) (src - 1); - else - *tgt_msb = (unsigned char) (src); - - if (src >= 0.0) - return 1; - else - return -1; - - } -} - - - -int -eb_d2c_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt) -{ - if ((src_msb & 0x80) == 0x80) { - *tgt = (float) - (- ( ( ( ((unsigned char) (~ src_msb)) * 16.0) ) + - ( ( ((unsigned char) (~ src_lsb)) & 0xF0) >> 4) + - ( ( ( ((unsigned char) (~ src_lsb)) & 0x0F) +1 ) / 16.0) ) ); - - if (src_msb == 0x80 && src_lsb == 0x00) - return 0; - else - return -1; - - } else { - *tgt = (float) ( (src_msb * 16.0) + ((src_lsb & 0xF0) >> 4) + - ((src_lsb & 0x0F) / 16.0) ); - return 1; - } -} - -int -eb_float_to_d2c(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb) -{ - if (src < -2047.999 || src > 2047.999) { - *tgt_msb = (unsigned char) (0x80); - *tgt_lsb = (unsigned char) (0x00); - return 0; - } else { - *tgt_lsb = - ( ((unsigned char) ( ((unsigned char) src) % 16) << 4) + - ((unsigned char) ( (src - ((unsigned char) src)) * 16.0)) ); - - if (src < 0.0 && *tgt_lsb != 0x00) - *tgt_msb = (unsigned char) ((src / 16.0) - 1); - else - *tgt_msb = (unsigned char) (src / 16.0); - - if (src >= 0.0) - return 1; - else - return -1; - } -} - - - -unsigned char -eb_calc_crc_byte(unsigned char byte, unsigned char init_crc) -{ - unsigned char crc, polynom; - int i; - - crc = init_crc; - - for (i = 0; i < 8; i++) { - - if (crc & 0x80) - polynom = (unsigned char) 0x9B; - else - polynom = (unsigned char) 0; - - crc = (unsigned char) ((crc & ~0x80) << 1); - - if (byte & 0x80) - crc = (unsigned char) (crc | 1); - - crc = (unsigned char) (crc ^ polynom); - byte = (unsigned char) (byte << 1); - } - - return crc; -} - -unsigned char -eb_calc_crc(const unsigned char *buf, int buflen) -{ - int i; - unsigned char crc = 0; - - for (i = 0 ; i < buflen ; i++, buf++) - crc = eb_calc_crc_byte(*buf, crc); - - return crc; -} - diff --git a/lib/ebus-decode.h b/lib/ebus-decode.h deleted file mode 100644 index 664c5456..00000000 --- a/lib/ebus-decode.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * crc calculations from http://www.mikrocontroller.net/topic/75698 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -/** - * @file ebus-decode.h - * @brief ebus decode functions - * @author roland.jax@liwest.at - * @version 0.1 - */ - -/* - * name type description resolution substitue - * BCD CHAR 0 ... + 99 1 FFh - * DATA1b SIGNED CHAR - 127 ... + 127 1 80h - * DATA1c CHAR 0 ... + 100 0,5 FFh - * DATA2b SIGNED INTEGER - 127,99 ... + 127,99 1/256 8000h - * DATA2c SIGNED INTEGER -2047,9 ... + 2047,9 1/16 8000h - */ - -#ifndef EBUS_DECODE_H_ -#define EBUS_DECODE_H_ - - -#include "ebus-common.h" - - - -/** - * @brief calculate integer value of given hex byte - * @param [in] *buf hex byte - * @return integer value | -1 if given byte is no hex value - */ -int eb_htoi(const char *buf); - - - -/** - * @brief print received results in a specific format - * @param [out] *buf pointer to a byte array - * @param [out] *buflen length of byte array - * @return none - */ -void eb_esc(unsigned char *buf, int *buflen); - -/** - * @brief print received results in a specific format - * @param [out] *buf pointer to a byte array - * @param [out] *buflen length of byte array - * @return none - */ -void eb_unesc(unsigned char *buf, int *buflen); - - - -/** - * @brief convert hex bytes to day - * @param [in] day hex byte - * @param [out] *tgt pointer to day string xxx - * @return 0 OK | -1 values out of range - */ -int eb_day_to_str(unsigned char day, char *tgt); - - - -/** - * @brief convert hex bytes to date - * @param [in] dd day hex byte - * @param [in] mm month hex byte - * @param [in] yy year hex byte - * @param [out] *tgt pointer to date string dd.mm.yyyy - * @return 0 OK | -1 values out of range - */ -int eb_dat_to_str(unsigned char dd, unsigned char mm, unsigned char yy, char *tgt); - -/** - * @brief convert char date string to hex - * @param [in] dd day int value - * @param [in] mm month int value - * @param [in] yy year int value - * @param [out] *tgt pointer to hex - * @return 0 OK | -1 values out of range - */ -int eb_str_to_dat(int dd, int mm, int yy, unsigned char *tgt); - - - -/** - * @brief convert hex bytes to date - * @param [in] hh hour hex byte - * @param [in] mm minute hex byte - * @param [in] ss second hex byte - * @param [out] *tgt pointer to date string hh:mm:ss - * @return 0 OK | -1 values out of range - */ -int eb_tim_to_str(unsigned char hh, unsigned char mm, unsigned char ss, char *tgt); - -/** - * @brief convert char time string to hex - * @param [in] hh hour int value - * @param [in] mm minute int value - * @param [in] ss second int value - * @param [out] *tgt pointer to hex - * @return 0 OK | -1 values out of range - */ -int eb_str_to_tim(int hh, int mm, int ss, unsigned char *tgt); - - - -/** - * @brief convert bcd hex byte to int - * @param [in] src bcd hex byte - * @param [out] *tgt pointer to int value - * @return 0 substitute value | 1 positive value - */ -int eb_bcd_to_int(unsigned char src, int *tgt); - -/** - * @brief convert int to bcd hex byte - * @param [in] src int value - * @param [out] *tgt pointer to hex byte - * @return 0 substitute value | 1 positive value - */ -int eb_int_to_bcd(int src, unsigned char *tgt); - - - -/** - * @brief convert data1b hex byte to int - * @param [in] src data1b hex byte - * @param [out] *tgt pointer to int value - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_d1b_to_int(unsigned char src, int *tgt); - -/** - * @brief convert int to data1b hex byte - * @param [in] src int value - * @param [out] *tgt pointer to data1b hex byte - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_int_to_d1b(int src, unsigned char *tgt); - - - -/** - * @brief convert data1c hex byte to float - * @param [in] src data1c hex byte - * @param [out] *tgt pointer to float value - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_d1c_to_float(unsigned char src, float *tgt); - -/** - * @brief convert float to data1c hex byte - * @param [in] src float value - * @param [out] *tgt pointer to data1c hex byte - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_float_to_d1c(float src, unsigned char *tgt); - - - -/** - * @brief convert data2b hex bytes to float - * @param [in] src_lsb least significant data2b hex byte - * @param [in] src_msb most significant data2b hex byte - * @param [out] *tgt pointer to float value - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_d2b_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt); - -/** - * @brief convert float to data2b hex bytes - * @param [in] src float value - * @param [out] *tgt_lsb pointer to least significant data2b hex byte - * @param [out] *tgt_msb pointer to most significant data2b hex byte - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_float_to_d2b(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb); - - - -/** - * @brief convert data2c hex bytes to float - * @param [in] src_lsb least significant data2c hex byte - * @param [in] src_msb most significant data2c hex byte - * @param [out] *tgt pointer to float value - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_d2c_to_float(unsigned char src_lsb, unsigned char src_msb, float *tgt); - -/** - * @brief convert float to data2c hex bytes - * @param [in] src float value - * @param [out] *tgt_lsb pointer to least significant data2c hex byte - * @param [out] *tgt_msb pointer to most significant data2c hex byte - * @return 0 substitute value | 1 positive value | -1 negative value - */ -int eb_float_to_d2c(float src, unsigned char *tgt_lsb, unsigned char *tgt_msb); - - - -/** - * @brief calculate crc of hex byte - * @param [in] byte byte to calculate - * @param [in] init_crc start value for calculation - * @return new calculated crc byte from byte and init crc byte - */ -unsigned char eb_calc_crc_byte(unsigned char byte, unsigned char init_crc); - -/** - * @brief calculate crc of given hex array - * - * \li crc calculation "CRC-8-WCDMA" with Polynom "x^8+x^7+x^4+x^3+x+1" - * \li crc calculations by http://www.mikrocontroller.net/topic/75698 - * - * @param [in] *bytes pointer to a byte array - * @param [in] size length of given bytes - * @return calculated crc byte - */ -unsigned char eb_calc_crc(const unsigned char *bytes, int size); - - - -#endif /* EBUS_DECODE_H_ */ diff --git a/lib/log.c b/lib/log.c deleted file mode 100644 index e4048252..00000000 --- a/lib/log.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" - -static unsigned char loglvl = L_NUL; -static const char *logtxt[] = {"INF","NOT","WAR","ERR","DBG","EBH","EBS","NET"}; -static int logtxtlen = sizeof(logtxt) / sizeof(char*); - -static FILE *logfp = NULL; - -char *log_time(char *time); -char *log_txt(unsigned char lvl); - -void -log_file(FILE *fp) -{ - if(logfp) - fclose(logfp); - - logfp = fp; -} - -void -log_level(char *lvl) -{ - unsigned char tmp; - int i; - char *par; - - loglvl = L_NUL; - - par = strtok(lvl, ", "); - while (par) { - if (strncasecmp(par, "ALL", 3) == 0) { - loglvl = L_ALL; - break; - } - - tmp = 0x01; - for (i = 0; i < logtxtlen; i++) { - if (strncasecmp(par, logtxt[i], 3) == 0) { - loglvl |= (tmp << i); - break; - } - } - par = strtok(NULL, ", "); - } -} - -int -log_open(const char *file, int foreground) -{ - FILE *fp = NULL; - - if (foreground) { - log_file(stdout); - } else { - if (file) { - if ((fp = fopen(file, "a+")) == 0) { - fprintf(stderr, "can't open logfile: %s\n", file); - - return -1; - } - - log_file(fp); - } - } - - openlog(NULL, LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); - - return 0; -} - -void -log_close(void) -{ - if (logfp) { - fflush(logfp); - fclose(logfp); - } - - closelog(); -} - -char * -log_time(char *time) -{ - struct timeval tv; - struct tm *tm; - - gettimeofday(&tv, NULL); - tm = localtime(&tv.tv_sec); - - sprintf(time, "%04d-%02d-%02d %02d:%02d:%02d.%03ld", - tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000); - - return time; -} - -char * -log_txt(unsigned char lvl) -{ - char *type = NULL; - if (logtxtlen > 0) { - unsigned char tmp; - int i; - - tmp = 0x01; - for (i = 0; i < logtxtlen; i++) { - if (lvl == L_ALL) { - type = "ALL"; - break; - } - - if ((lvl & (tmp << i)) != 0x00 && - (loglvl & (tmp << i)) != 0x00) { - type = (char *)logtxt[i]; - break; - } - } - } - return type; -} - -void -log_print(unsigned char lvl, const char *txt, ...) -{ - char time[24]; - char buf[512]; - va_list ap; - - va_start(ap, txt); - vsprintf(buf, txt, ap); - - if ((loglvl & lvl) != 0x00) { - if (logfp) { - //~ fprintf(logfp, "%s [0x%02x %s] %s\n", - //~ log_time(time), lvl , log_txt(lvl), buf); - fprintf(logfp, "%s [%s] %s\n", - log_time(time), log_txt(lvl), buf); - fflush(logfp); - - } else { - //~ syslog(LOG_INFO, "[0x%02x %s] %s\n", - //~ lvl, log_txt(lvl), txt); - syslog(LOG_INFO, "[%s] %s\n", log_txt(lvl), txt); - } - } - - va_end(ap); -} - diff --git a/lib/log.h b/lib/log.h deleted file mode 100644 index f0f08abd..00000000 --- a/lib/log.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef LOG_H_ -#define LOG_H_ - -#define L_NUL 0x00 -#define L_ALL 0xFF - -#define L_INF 0x01 -#define L_NOT 0x02 -#define L_WAR 0x04 -#define L_ERR 0x08 -#define L_DBG 0x10 -#define L_EBH 0x20 -#define L_EBS 0x40 -#define L_NET 0x80 - -#define LOGTXT "INF, NOT, WAR, ERR, DBG, EBH, EBS, NET, ALL" - -#define err_if(exp) \ - if (exp) { log_print(L_ERR, "%s: %d: %s: Error %s", \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, strerror(errno));\ - } - -#define err_ret_if(exp, ret) \ - if (exp) { log_print(L_ERR, "%s: %d: %s: Error %s", \ - __FILE__, __LINE__, __PRETTY_FUNCTION__, strerror(errno));\ - return (ret); \ - } - -void log_file(FILE *fp); -void log_level(char *lvl); - -int log_open(const char *logfile, int foreground); -void log_close(void); - -void log_print(unsigned char lvl, const char *txt, ...); - -#endif /* LOG_H_ */ diff --git a/m4/.info b/m4/.info new file mode 100644 index 00000000..e69de29b diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index a43c71c1..00000000 --- a/src/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ -bin_PROGRAMS = ebusd - -ebusd_SOURCES = ebusd.c ebusd.h utils.c utils.h -ebusd_LDADD = $(top_srcdir)/lib/libebus.a $(top_srcdir)/lib/liblog.a -ebusd_CFLAGS = -I$(top_srcdir)/lib - -distclean-local: - -rm -f Makefile.in - diff --git a/src/baseloop.cpp b/src/baseloop.cpp new file mode 100644 index 00000000..8cb402fb --- /dev/null +++ b/src/baseloop.cpp @@ -0,0 +1,285 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "baseloop.h" +#include "logger.h" +#include "appl.h" +#include "network.h" +#include +#include +#include + +extern LogInstance& L; +extern Appl& A; + +void BaseLoop::start() +{ + for (;;) { + // recv new message from client + Message* message = m_queue.remove(); + std::string data = message->getData(); + + data.erase(std::remove(data.begin(), data.end(), '\r'), data.end()); + data.erase(std::remove(data.begin(), data.end(), '\n'), data.end()); + + L.log(bas, event, ">>> %s", data.c_str()); + + // decode message + std::string result(decodeMessage(data)); + + L.log(bas, event, "<<< %s", result.c_str()); + + // send result to client + result += '\n'; + Connection* connection = static_cast(message->getSource()); + connection->addResult(Message(result)); + + delete message; + } +} + +std::string BaseLoop::decodeMessage(const std::string& data) +{ + std::ostringstream result; + std::string cycdata; + int index; + + // prepare data + std::string token; + std::istringstream stream(data); + std::vector cmd; + + while (std::getline(stream, token, ' ') != 0) + cmd.push_back(token); + + if (cmd.size() == 0) + return "command missing"; + + switch (getCase(cmd[0])) { + case notfound: + result << "command not found"; + break; + + case get: + if (cmd.size() < 3 || cmd.size() > 4) { + result << "format: [get class cmd (sub)]"; + break; + } + + index = m_commands->findCommand(data); + + if (index >= 0) { + + std::string type = m_commands->getType(index); + std::string ebusCommand(A.getParam("p_address")); + ebusCommand += m_commands->getEbusCommand(index); + std::transform(ebusCommand.begin(), ebusCommand.end(), ebusCommand.begin(), tolower); + + L.log(bas, trace, " type: %s msg: %s", type.c_str(), ebusCommand.c_str()); + // send busCommand + m_ebusloop->addBusCommand(new BusCommand(type, ebusCommand)); + BusCommand* busCommand = m_ebusloop->getBusCommand(); + + if (busCommand->getResult().c_str()[0] != '-') { + // decode data + Command* command = new Command(index, (*m_commands)[index], busCommand->getResult()); + + // return result + result << command->calcResult(cmd); + + delete command; + } else { + L.log(bas, error, " %s", busCommand->getResult().c_str()); + result << busCommand->getResult(); + } + + + delete busCommand; + + } else { + result << "ebus command not found"; + } + + break; + + case set: + if (cmd.size() != 4) { + result << "format: [set class cmd value]"; + break; + } + + index = m_commands->findCommand(data.substr(0, data.find(cmd[3])-1)); + + if (index >= 0) { + + std::string type = m_commands->getType(index); + std::string ebusCommand(A.getParam("p_address")); + ebusCommand += m_commands->getEbusCommand(index); + + // encode data + Command* command = new Command(index, (*m_commands)[index], cmd[3]); + std::string value = command->calcData(); + if (value[0] != '-') { + ebusCommand += value; + } else { + L.log(bas, error, " %s", value.c_str()); + delete command; + break; + } + + std::transform(ebusCommand.begin(), ebusCommand.end(), ebusCommand.begin(), tolower); + + L.log(bas, event, " type: %s msg: %s", type.c_str(), ebusCommand.c_str()); + // send busCommand + m_ebusloop->addBusCommand(new BusCommand(type, ebusCommand)); + BusCommand* busCommand = m_ebusloop->getBusCommand(); + + if (busCommand->getResult().c_str()[0] != '-') { + // decode result + if (busCommand->getResult().substr(busCommand->getResult().length()-8) == "00000000") + result << "done"; + else + result << "error"; + + } else { + L.log(bas, error, " %s", busCommand->getResult().c_str()); + result << busCommand->getResult(); + } + + delete busCommand; + delete command; + + } else { + result << "ebus command not found"; + } + + break; + + case cyc: + if (cmd.size() < 3 || cmd.size() > 4) { + result << "format: [cyc class cmd (sub)]"; + break; + } + + index = m_commands->findCommand(data); + + if (index >= 0) { + // get cycdata + cycdata = m_cycdata->getData(index); + if (cycdata != "") { + // decode data + Command* command = new Command(index, (*m_commands)[index], cycdata); + + // return result + result << command->calcResult(cmd); + + delete command; + } else { + result << "no data stored"; + } + } else { + result << "ebus command not found"; + } + + break; + + case hex: + if (cmd.size() != 3) { + result << "format: [hex type value] (ZZ PB SB NN Dx)"; + break; + } + + if ((strcasecmp(cmd[1].c_str(), "MS") == 0) + || (strcasecmp(cmd[1].c_str(), "MM") == 0) + || (strcasecmp(cmd[1].c_str(), "BC") == 0)) { + + std::string type = cmd[1]; + std::string ebusCommand(A.getParam("p_address")); + cmd[2].erase(std::remove_if(cmd[2].begin(), cmd[2].end(), isspace), cmd[2].end()); + ebusCommand += cmd[2]; + std::transform(ebusCommand.begin(), ebusCommand.end(), ebusCommand.begin(), tolower); + + L.log(bas, trace, " type: %s msg: %s", type.c_str(), ebusCommand.c_str()); + // send busCommand + m_ebusloop->addBusCommand(new BusCommand(type, ebusCommand)); + BusCommand* busCommand = m_ebusloop->getBusCommand(); + + if (busCommand->getResult().c_str()[0] == '-') + L.log(bas, error, " %s", busCommand->getResult().c_str()); + + result << busCommand->getResult(); + + delete busCommand; + } else { + result << "specified message type is incorrect"; + } + + break; + + case dump: + if (cmd.size() != 2) { + result << "format: [dump state] (on|off)"; + break; + } + + if (cmd[1] == "on") m_ebusloop->dump(true); + if (cmd[1] == "off") m_ebusloop->dump(false); + result << "done"; + break; + + case logarea: + if (cmd.size() != 2) { + result << "format: [logarea area,area,..] (bas|net|bus|cyc|all)"; + break; + } + + L.getSink(0)->setAreas(calcArea(cmd[1])); + result << "done"; + break; + + case loglevel: + if (cmd.size() != 2) { + result << "format: [loglevel level] (error|event|trace|debug)"; + break; + } + + L.getSink(0)->setLevel(calcLevel(cmd[1])); + result << "done"; + break; + + case help: + result << std::endl + << " get - fetch ebus data [get class cmd (sub)]" << std::endl + << " set - set ebus values [set class cmd value]" << std::endl + << " cyc - fetch cycle data [cyc class cmd (sub)]" << std::endl + << " hex - send given hex value [hex type value] (ZZ PB SB NN Dx)" << std::endl + << " dump - change dump state [dump state] (on|off)" << std::endl + << " logarea - change log area [logarea area,area,..] (bas|net|bus|cyc|all)" << std::endl + << " loglevel - change log level [loglevel level] (error|event|trace|debug)" << std::endl + << " quit - close connection" << std::endl + << " help - print this page"; + break; + + default: + break; + } + + return result.str(); +} + diff --git a/src/baseloop.h b/src/baseloop.h new file mode 100644 index 00000000..1ca4d660 --- /dev/null +++ b/src/baseloop.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef BASELOOP_H_ +#define BASELOOP_H_ + +#include "libebus.h" +#include "ebusloop.h" +#include "cycdata.h" +#include "wqueue.h" +#include + +using namespace libebus; + +class Connection; + +class Message +{ + +public: + Message(const std::string data, void* source = NULL) : m_data(data), m_source(source) {} + Message(const Message& src) : m_data(src.m_data), m_source(src.m_source) {} + + std::string getData() const { return m_data; } + void* getSource() const { return m_source; } + +private: + std::string m_data; + void* m_source; + +}; + +class BaseLoop +{ + +public: + BaseLoop(EBusLoop* ebusloop, CYCData* cycdata, Commands* commands) + : m_ebusloop(ebusloop), m_cycdata(cycdata), m_commands(commands) {} + + void start(); + + WQueue* getQueue() { return &m_queue; } + void addMessage(Message* message) { m_queue.add(message); } + +private: + EBusLoop* m_ebusloop; + CYCData* m_cycdata; + Commands* m_commands; + WQueue m_queue; + + enum ClientCommand { + get, // get ebus data + set, // set ebus value + cyc, // fetch cycle data + hex, // send hex value + dump, // change dump state + logarea, // change log area + loglevel, // change log level + help, // print commands + + notfound + }; + + ClientCommand getCase(const std::string& item) + { + if (strcasecmp(item.c_str(), "get") == 0) return get; + if (strcasecmp(item.c_str(), "set") == 0) return set; + if (strcasecmp(item.c_str(), "cyc") == 0) return cyc; + if (strcasecmp(item.c_str(), "hex") == 0) return hex; + if (strcasecmp(item.c_str(), "dump") == 0) return dump; + if (strcasecmp(item.c_str(), "logarea") == 0) return logarea; + if (strcasecmp(item.c_str(), "loglevel") == 0) return loglevel; + if (strcasecmp(item.c_str(), "help") == 0) return help; + + return notfound; + } + + std::string decodeMessage(const std::string& data); + +}; + +#endif // BASELOOP_H_ diff --git a/src/cycdata.cpp b/src/cycdata.cpp new file mode 100644 index 00000000..92c38b0d --- /dev/null +++ b/src/cycdata.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "cycdata.h" +#include "logger.h" +#include +#include + +extern LogInstance& L; + +CYCData::CYCData(EBusLoop* ebusloop, Commands* commands) + : m_ebusloop(ebusloop), m_commands(commands), m_stop(false) +{ + for (size_t index = 0; index < commands->size(); index++) { + if (strcasecmp((*m_commands)[index][0].c_str(),"cyc") == 0) { + Command* cmd = new Command(index, (*m_commands)[index]); + m_cycDB.insert(pair_t(index, cmd)); + } + } + +} + +CYCData::~CYCData() +{ + for (mapCI_t iter = m_cycDB.begin(); iter != m_cycDB.end(); ++iter) + delete iter->second; +} + +void* CYCData::run() +{ + bool skipfirst = false; + + for (;;) { + std::string data = m_ebusloop->getData(); + + if (skipfirst == true) { + L.log(cyc, trace, "%s", data.c_str()); + + int index = findData(data); + + if (index >= 0) { + std::string tmp; + tmp += (*m_commands)[index][0]; + tmp += " "; + tmp += (*m_commands)[index][1]; + tmp += " "; + tmp += (*m_commands)[index][2]; + L.log(cyc, trace, " [%d] %s", index, tmp.c_str()); + storeData(index, data); + } + } + + skipfirst = true; + + if (m_stop == true) + return NULL; + } + + return NULL; +} + +std::string CYCData::getData(int index) +{ + mapCI_t iter = m_cycDB.find(index); + if (iter != m_cycDB.end()) + return iter->second->getData(); + else + return ""; +} + +int CYCData::findData(const std::string& data) const +{ + // no commands definend + if (m_cycDB.size() == 0) + return -2; + + // skip to small search string length + if (data.length() < 10) + return -3; + + // preapre string for searching command + std::string search(data.substr(2, 8 + strtol(data.substr(8,2).c_str(), NULL, 16) * 2)); + + std::size_t index; + mapCI_t i = m_cycDB.begin(); + + // walk through commands + for (index = 0; i != m_cycDB.end(); i++, index++) { + cmd_t cmd = i->second->getCommand(); + // prepare string for defined command + std::string command(cmd[5]); + command += cmd[6]; + std::stringstream sstr; + sstr << std::setw(2) << std::hex << std::setfill('0') << cmd[7]; + command += sstr.str(); + command += cmd[8]; + + // skip wrong search string length + if (command.length() > search.length()) + continue; + + if (strcasecmp(command.c_str(), search.substr(0,command.length()).c_str()) == 0) + return i->first; + + } + + // command not found + return -1; +} + +void CYCData::storeData(int index, std::string data) +{ + mapCI_t iter = m_cycDB.find(index); + + if (iter != m_cycDB.end()) { + iter->second->setData(data); + L.log(cyc, debug, " [%d] data saved", index); + } +} + diff --git a/src/cycdata.h b/src/cycdata.h new file mode 100644 index 00000000..b1843c35 --- /dev/null +++ b/src/cycdata.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef CYCDATA_H_ +#define CYCDATA_H_ + +#include "libebus.h" +#include "ebusloop.h" +#include "thread.h" +#include + +using namespace libebus; + +typedef std::map map_t; +typedef map_t::const_iterator mapCI_t; +typedef std::pair pair_t; + +class CYCData : public Thread +{ + +public: + CYCData(EBusLoop* ebusloop, Commands* commands); + ~CYCData(); + + void* run(); + void stop() { m_stop = true; } + + std::string getData(int index); + +private: + EBusLoop* m_ebusloop; + Commands* m_commands; + map_t m_cycDB; + bool m_stop; + + int findData(const std::string& data) const; + void storeData(int index, std::string data); + +}; + +#endif // CYCDATA_H_ diff --git a/src/ebusd.c b/src/ebusd.c deleted file mode 100644 index 1441fe48..00000000 --- a/src/ebusd.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "utils.h" -#include "ebus-decode.h" -#include "ebus-cmd.h" -#include "ebus-bus.h" -#include "ebusd.h" - - -/* global variables */ -const char *progname; - -static int pidfile_locked = NO; -static int msg_queue_on = NO; - -static int pidfd = UNSET; /* pidfile file descriptor */ -static int busfd = UNSET; /* bus file descriptor */ -static int socketfd = UNSET; /* socket file descriptor */ - - -static char address[3]; -static char cfgdir[CFG_LINELEN]; -static char cfgfile[CFG_LINELEN]; -static char device[CFG_LINELEN]; -static char extension[10]; -static int foreground = UNSET; -static char loglevel[CFG_LINELEN]; -static char logfile[CFG_LINELEN]; -static int nodevicecheck = UNSET; -static char pidfile[CFG_LINELEN]; -static int port = UNSET; -static int rawdump = UNSET; -static char rawfile[CFG_LINELEN]; -static int showraw = UNSET; -static int settings = UNSET; -static int localhost = UNSET; -static int get_retry = UNSET; -static int skip_ack = UNSET; -static int max_wait = UNSET; -static int send_retry = UNSET; -static int print_size = UNSET; - - - -static char options[] = "a:c:C:d:e:fl:L:nP:p:rR:sStvh"; - -static struct option opts[] = { - {"address", required_argument, NULL, 'a'}, - {"cfgfdir", required_argument, NULL, 'c'}, - {"cfgfile", required_argument, NULL, 'C'}, - {"device", required_argument, NULL, 'd'}, - {"extension", required_argument, NULL, 'e'}, - {"foreground", no_argument, NULL, 'f'}, - {"loglevel", required_argument, NULL, 'l'}, - {"logfile", required_argument, NULL, 'L'}, - {"nodevicecheck", no_argument, NULL, 'n'}, - {"pidfile", required_argument, NULL, 'P'}, - {"port", required_argument, NULL, 'p'}, - {"rawdump", no_argument, NULL, 'r'}, - {"rawfile", required_argument, NULL, 'R'}, - {"showraw", no_argument, NULL, 's'}, - {"settings", no_argument, NULL, 'S'}, - {"localhost", no_argument, NULL, 't'}, - {"version", no_argument, NULL, 'v'}, - {"help", no_argument, NULL, 'h'}, - {NULL, no_argument, NULL, 0 }, -}; - -static struct config cfg[] = { - -{"address", STR, &address, "\tbus address (" NUMSTR(EBUS_QQ) ")"}, -{"cfgdir", STR, &cfgdir, "\tconfiguration directory of command files (" DAEMON_CFGDIR ")"}, -{"cfgfile", STR, &cfgfile, "\tdaemon configuration file (" DAEMON_CFGFILE ")"}, -{"device", STR, &device, "\tbus device (" SERIAL_DEVICE " or host:port)"}, -{"extension", STR, &extension, "extension of command files (" DAEMON_EXTENSION ")"}, -{"foreground", BOL, &foreground, "run in foreground"}, -{"loglevel", STR, &loglevel, "\tlog level (INF | " LOGTXT ")"}, -{"logfile", STR, &logfile, "\tlog file (" DAEMON_LOGFILE ")"}, -{"nodevicecheck", BOL, &nodevicecheck, "don't check bus device"}, -{"pidfile", STR, &pidfile, "\tpid file (" DAEMON_PIDFILE ")"}, -{"port", NUM, &port, "\tport (" NUMSTR(SOCKET_PORT) ")"}, -{"rawdump", BOL, &rawdump, "\tdump raw ebus data to file"}, -{"rawfile", STR, &rawfile, "\traw file (" DAEMON_RAWFILE ")"}, -{"showraw", BOL, &showraw, "\tprint raw data"}, -{"settings", BOL, &settings, "\tprint daemon settings"}, -{"localhost", BOL, &localhost, "allow only connection from localhost"}, -{"get_retry", NUM, &get_retry, NULL}, -{"skip_ack", NUM, &skip_ack, NULL}, -{"max_wait", NUM, &max_wait, NULL}, -{"send_retry", NUM, &send_retry, NULL}, -{"print_size", NUM, &print_size, NULL}, -{"version", STR, NULL, "\tprint version information"}, -{"help", STR, NULL, "\tprint this message"} -}; - -const int cfglen = sizeof(cfg) / sizeof(cfg[0]); - -void -usage(void) -{ - fprintf(stdout, "\nUsage: %s [OPTIONS]\n", progname); - - int i, skip; - - skip = 0; - - for (i = 0; i < cfglen; i++) { - if (cfg[i].info != NULL) { - fprintf(stdout, " -%c --%s\t%s\n", - opts[i - skip].val, - opts[i - skip].name, - cfg[i].info); - } else { - skip++; - } - } - - fprintf(stdout, "\n"); -} - -void -cmdline(int *argc, char ***argv) -{ - for (;;) { - int i; - - i = getopt_long(*argc, *argv, options, opts, NULL); - - if (i == -1) - break; - - switch (i) { - case 'a': - if (strlen(optarg) > 2) - strncpy(address, &optarg[strlen(optarg) - 2 ], 2); - else - strncpy(address, optarg, strlen(optarg)); - - break; - case 'c': - strncpy(cfgdir, optarg, strlen(optarg)); - break; - case 'C': - strncpy(cfgfile, optarg, strlen(optarg)); - break; - case 'd': - strncpy(device, optarg, strlen(optarg)); - break; - case 'e': - strncpy(extension, optarg, strlen(optarg)); - break; - case 'f': - foreground = YES; - break; - case 'l': - strncpy(loglevel, optarg, strlen(optarg)); - break; - case 'L': - strncpy(logfile, optarg, strlen(optarg)); - break; - case 'n': - nodevicecheck = YES; - break; - case 'P': - strncpy(pidfile, optarg, strlen(optarg)); - break; - case 'p': - if (isdigit(*optarg)) - port = atoi(optarg); - break; - case 'r': - rawdump = YES; - break; - case 'R': - strncpy(rawfile, optarg, strlen(optarg)); - rawdump = YES; - break; - case 's': - showraw = YES; - break; - case 'S': - settings = YES; - break; - case 't': - localhost = YES; - break; - case 'v': - fprintf(stdout, DAEMON_NAME " " DAEMON_VERSION "\n"); - exit(EXIT_SUCCESS); - case 'h': - default: - usage(); - exit(EXIT_FAILURE); - break; - } - } -} - -void -set_unset(void) -{ - - if (*address == '\0') - strncpy(address , &NUMSTR(EBUS_QQ)[2], 2); - - if (*cfgdir == '\0') - strncpy(cfgdir , DAEMON_CFGDIR, strlen(DAEMON_CFGDIR)); - - if (*device == '\0') - strncpy(device , SERIAL_DEVICE, strlen(SERIAL_DEVICE)); - - if (*extension == '\0') { - strncpy(extension , DAEMON_EXTENSION, strlen(DAEMON_EXTENSION)); - } - - if (foreground == UNSET) - foreground = NO; - - if (*loglevel == '\0') - strncpy(loglevel , DAEMON_LOGLEVEL, strlen(DAEMON_LOGLEVEL)); - - if (*logfile == '\0') - strncpy(logfile , DAEMON_LOGFILE, strlen(DAEMON_LOGFILE)); - - if (nodevicecheck == UNSET) - nodevicecheck = NO; - - if (*pidfile == '\0') - strncpy(pidfile , DAEMON_PIDFILE, strlen(DAEMON_PIDFILE)); - - if (port == UNSET) - port = SOCKET_PORT; - - if (rawdump == UNSET) - rawdump = NO; - - if (*rawfile == '\0') - strncpy(rawfile , DAEMON_RAWFILE, strlen(DAEMON_RAWFILE)); - - if (showraw == UNSET) - showraw = NO; - - if (settings == UNSET) - settings = NO; - - if (localhost == UNSET) - localhost = NO; - - if (get_retry == UNSET) - get_retry = EBUS_GET_RETRY; - /* set max */ - if (get_retry > EBUS_GET_RETRY_MAX) - get_retry = EBUS_GET_RETRY_MAX; - - if (skip_ack == UNSET) - skip_ack = EBUS_SKIP_ACK; - - if (max_wait == UNSET) - max_wait = EBUS_MAX_WAIT; - - if (send_retry == UNSET) - send_retry = EBUS_SEND_RETRY; - /* set max */ - if (send_retry > EBUS_SEND_RETRY_MAX) - send_retry = EBUS_SEND_RETRY_MAX; - - if (print_size == UNSET) - print_size = EBUS_PRINT_SIZE; - -} - -void -signal_handler(int sig) { - switch(sig) { - case SIGHUP: - log_print(L_ALL, "SIGHUP received"); - syslog(LOG_INFO, "SIGHUP received"); - break; - case SIGINT: - log_print(L_ALL, "SIGINT received - logfile reopen"); - syslog(LOG_INFO, "SIGINT received - logfile reopen"); - log_open(logfile, foreground); - break; - case SIGTERM: - log_print(L_ALL, "daemon exiting"); - syslog(LOG_INFO, "daemon exiting"); - cleanup(EXIT_SUCCESS); - break; - default: - log_print(L_ALL, "unknown signal %s", strsignal(sig)); - syslog(LOG_INFO, "unknown signal %s", strsignal(sig)); - break; - } -} - -void -daemonize(void) -{ - pid_t pid; - - /* fork off the parent process */ - pid = fork(); - if (pid < 0) { - err_if(1); - cleanup(EXIT_FAILURE); - } - /* If we got a good PID, then we can exit the parent process */ - if (pid > 0) { - /* printf("Child process created: %d\n", pid); */ - exit(EXIT_SUCCESS); - } - - /* At this point we are executing as the child process */ - - /* Set file permissions 750 */ - umask(027); - - /* Create a new SID for the child process and */ - /* detach the process from the parent (normally a shell) */ - if (setsid() < 0) { - err_if(1); - cleanup(EXIT_FAILURE); - } - - /* Change the current working directory. This prevents the current - directory from being locked; hence not being able to remove it. */ - if (chdir(DAEMON_WORKDIR) < 0) { - /* Log any failure here */ - err_if(1); - cleanup(EXIT_FAILURE); - } - - /* Route I/O connections */ - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - - /* write pidfile and try to lock it */ - if (pid_file_open(pidfile, &pidfd) == -1) { - log_print(L_ERR, "can't open pidfile: %s\n", pidfile); - cleanup(EXIT_FAILURE); - } else { - pidfile_locked = YES; - log_print(L_INF, "%s created.", pidfile); - } - - /* Cancel certain signals */ - signal(SIGCHLD, SIG_DFL); /* A child process dies */ - signal(SIGTSTP, SIG_IGN); /* Various TTY signals */ - signal(SIGTTOU, SIG_IGN); /* Ignore TTY background writes */ - signal(SIGTTIN, SIG_IGN); /* Ignore TTY background reads */ - - /* Trap signals that we expect to receive */ - signal(SIGHUP, signal_handler); - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); -} - -void -cleanup(int state) -{ - - /* free msg queue */ - if (msg_queue_on == YES) { - msg_queue_free(); - log_print(L_INF, "msg queue freeed"); - } - - /* close listing tcp socket */ - if (socketfd > 0) { - if (sock_close(socketfd) == -1) - log_print(L_ERR, "can't close port: %d", port); - else - log_print(L_INF, "port %d closed", port); - } - - /* close bus device */ - if (busfd > 0) { - if (eb_bus_close() == -1) - log_print(L_ERR, "can't close device: %s", device); - else - log_print(L_INF, "device %s closed", device); - } - - /* close rawfile */ - if (rawdump == YES) { - if (eb_raw_file_close() == -1) - log_print(L_ERR, "can't close rawfile: %s\n", rawfile); - else - log_print(L_INF, "%s closed", rawfile); - } - - - /* free mem for ebus commands */ - eb_cmd_dir_free(); - - if (foreground == NO) { - - /* delete PID file */ - if (pidfile_locked) - if (pid_file_close(pidfile, pidfd) == -1) - log_print(L_INF, "%s deleted", pidfile); - - /* Reset all signal handlers to default */ - signal(SIGCHLD, SIG_DFL); - signal(SIGTSTP, SIG_DFL); - signal(SIGTTOU, SIG_DFL); - signal(SIGTTIN, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - - /* print end message */ - log_print(L_ALL, DAEMON_NAME " " DAEMON_VERSION " stopped"); - syslog(LOG_INFO, DAEMON_NAME " " DAEMON_VERSION " stopped"); - } - - /* close logging system */ - log_close(); - - exit(state); -} - - -void -main_loop(void) -{ - int maxfd, sfd_closed, timeout_reached; - fd_set listenfds; - struct timeval timeout; - - sfd_closed = NO; - timeout_reached = NO; - - FD_ZERO(&listenfds); - FD_SET(busfd, &listenfds); - FD_SET(socketfd, &listenfds); - - maxfd = socketfd; - - /* busfd should be always lower then socketfd */ - if (busfd > socketfd) { - log_print(L_ERR, "busfd %d > %d socketfd", busfd, socketfd); - cleanup(EXIT_FAILURE); - } - - for (;;) { - fd_set readfds; - int readfd; - int ret; - - /* set select timeout 10 secs */ - timeout.tv_sec = 10; - timeout.tv_usec = 0; - - /* set readfds to inital listenfds */ - readfds = listenfds; - - /* check if the bus device is working */ - if (eb_bus_valid() < 0 || timeout_reached == YES) { - timeout_reached = NO; - - if (busfd > 0 && sfd_closed == NO) { - log_print(L_ERR, "bus device is invalid"); - sfd_closed = YES; - - /* close listing tcp socket */ - if (socketfd > 0) { - if (sock_close(socketfd) == -1) - log_print(L_ERR, "can't close port: %d", port); - else - log_print(L_INF, "port %d closed", port); - } - - /* close bus device */ - if (eb_bus_close() == -1) - log_print(L_ERR, "can't close device: %s", device); - else - log_print(L_INF, "device %s closed", device); - - } - - /* need sleep to prevent high cpu consumption */ - sleep(1); - - /* open bus device */ - if (eb_bus_open(device, &busfd) == 0) { - log_print(L_INF, "device %s opened", device); - sfd_closed = NO; - } - - /* open listing tcp socket */ - if (sfd_closed == NO && sock_open(&socketfd, port, localhost) == 0) - log_print(L_INF, "port %d opened", port); - - continue; - } - - ret = select(maxfd + 1, &readfds, NULL, NULL, &timeout); - - /* timeout after 10 secs means that ebus is probably - disconnected or BUS device is dead */ - if (ret == 0) { - log_print(L_WAR, "select timeout (%d) reached", timeout.tv_sec); - timeout_reached = YES; - continue; - - /* ignore signals */ - } else if ((ret < 0) && (errno == EINTR)) { - /* log_print(L_NOT, "get signal at select: %s", strerror(errno)); */ - continue; - - /* on other errors */ - } else if (ret < 0) { - err_if(1); - cleanup(EXIT_FAILURE); - } - - /* new data from bus device? */ - if (FD_ISSET(busfd, &readfds)) { - - /* get cycle message from bus */ - ret = eb_cyc_data_recv(); - - /* send msg to bus - only when cyc buf is empty */ - if (ret == 0 && msg_queue_entries() > 0) { - char tcpbuf[SOCKET_BUFSIZE]; - char data[MSG_QUEUE_MSG_SIZE]; - int tcpbuflen, id, clientfd; - - memset(tcpbuf, '\0', sizeof(tcpbuf)); - tcpbuflen = sizeof(tcpbuf); - - memset(data, '\0', sizeof(data)); - - /* get next entry from msg queue */ - msg_queue_msg_del(&id, data, &clientfd); - - /* just do it */ - eb_execute(id, data, tcpbuf, &tcpbuflen); - - /* send answer */ - sock_client_write(clientfd, tcpbuf, tcpbuflen); - } - - } - - /* new incoming connection at TCP port arrived? */ - if (FD_ISSET(socketfd, &readfds)) { - - /* get new TCP client fd*/ - ret = sock_client_accept(socketfd, &readfd); - if (readfd >= 0) { - /* add new TCP client fd to listenfds */ - FD_SET(readfd, &listenfds); - (readfd > maxfd) ? (maxfd = readfd) : (1); - } - } - - /* run through connected sockets for new data */ - for (readfd = socketfd + 1; readfd <= maxfd; ++readfd) { - - /* check all connected clients */ - if (FD_ISSET(readfd, &readfds)) { - char tcpbuf[SOCKET_BUFSIZE]; - char data[MSG_QUEUE_MSG_SIZE]; - int tcpbuflen; - - memset(tcpbuf, '\0', sizeof(tcpbuf)); - tcpbuflen = sizeof(tcpbuf); - - memset(data, '\0', sizeof(data)); - - /* get message from client */ - ret = sock_client_read(readfd, tcpbuf, &tcpbuflen); - - /* remove dead TCP client */ - if (ret < 0) { - FD_CLR(readfd, &listenfds); - continue; - } - - /* handle different commands */ - if (strncasecmp("shutdown", tcpbuf, 8) == 0) - cleanup(EXIT_SUCCESS); - - if (strncasecmp("loglevel", tcpbuf, 8) == 0) { - strncpy(loglevel, tcpbuf, strlen(tcpbuf)); - log_level(loglevel); - continue; - } - - /* search ebus command */ - if (tcpbuflen > 0) - ret = eb_cmd_search_com(tcpbuf, data); - else - ret = -1; - - /* command not found */ - if (ret < 0) { - memset(tcpbuf, '\0', sizeof(tcpbuf)); - strcpy(tcpbuf, "command not found\n"); - tcpbuflen = strlen(tcpbuf); - - /* send answer */ - sock_client_write(readfd, tcpbuf, tcpbuflen); - - } else { - msg_queue_msg_add(ret, data, readfd); - } - - } - } - } -} - -int -main(int argc, char *argv[]) -{ - int tmp; - - /* set progname */ - progname = (const char *)strrchr(argv[0], '/'); - progname = progname ? (progname + 1) : argv[0]; - - /* read command line */ - cmdline(&argc, &argv); - - /* set default cfgfile */ - if (*cfgfile == '\0') - strncpy(cfgfile , DAEMON_CFGFILE, strlen(DAEMON_CFGFILE)); - - /* read config file */ - if (cfg_file_read(cfgfile, cfg, cfglen) == -1) - fprintf(stderr, "can't open cfgfile: %s ==> " \ - "build in settings will be used\n", cfgfile); - - /* set unset configuration */ - set_unset(); - - /* print configuration */ - if (settings == YES) - cfg_print(cfg, cfglen); - - - /* set ebus configuration */ - eb_set_nodevicecheck(nodevicecheck); - eb_set_rawdump(rawdump); - eb_set_showraw(showraw); - - tmp = (eb_htoi(&address[0])) * 16 + (eb_htoi(&address[1])); - eb_set_qq((unsigned char) tmp); - - eb_set_get_retry(get_retry); - eb_set_skip_ack(skip_ack); - eb_set_max_wait(max_wait); - eb_set_send_retry(send_retry); - eb_set_print_size(print_size); - - /* open log */ - log_level(loglevel); - log_open(logfile, foreground); - - /* to be daemon */ - if (foreground == NO) { - log_print(L_ALL, DAEMON_NAME " " DAEMON_VERSION " started"); - syslog(LOG_INFO, DAEMON_NAME " " DAEMON_VERSION " started"); - daemonize(); - } - - /* read ebus command configuration files */ - if (eb_cmd_dir_read(cfgdir, extension) == -1) - log_print(L_WAR, "error during read command file"); - - /* open raw file */ - if (rawdump == YES) { - if (eb_raw_file_open(rawfile) == -1) { - log_print(L_ALL, "can't open rawfile: %s", rawfile); - cleanup(EXIT_FAILURE); - } else { - log_print(L_INF, "%s opened", rawfile); - } - - } - - /* open bus device */ - if (eb_bus_open(device, &busfd) == -1) { - log_print(L_ALL, "can't open device: %s", device); - cleanup(EXIT_FAILURE); - } else { - log_print(L_INF, "device %s opened", device); - } - - - /* open listing tcp socket */ - if (sock_open(&socketfd, port, localhost) == -1) { - log_print(L_ALL, "can't open port: %d", port); - cleanup(EXIT_FAILURE); - } else { - log_print(L_INF, "port %d opened", port); - } - - /* init msg queue */ - if (msg_queue_init() == -1) { - log_print(L_ALL, "can't initialize msg queue"); - cleanup(EXIT_FAILURE); - } else { - msg_queue_on = YES; - log_print(L_INF, "msg queue initialized"); - } - - /* enter main loop */ - main_loop(); - - cleanup(EXIT_SUCCESS); - - return 0; -} diff --git a/src/ebusd.h b/src/ebusd.h deleted file mode 100644 index 5dc67eb6..00000000 --- a/src/ebusd.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef MAIN_H_ -#define MAIN_H_ - -#define DAEMON_NAME "ebusd" -#define DAEMON_VERSION "0.1" - -#define DAEMON_WORKDIR "/tmp/" - -#define DAEMON_CFGDIR "/etc/ebusd" -#define DAEMON_CFGFILE DAEMON_CFGDIR"/ebusd.conf" -#define DAEMON_EXTENSION "csv" -#define DAEMON_LOGLEVEL "INF" -#define DAEMON_LOGFILE "/var/log/ebusd.log" -#define DAEMON_PIDFILE "/var/run/ebusd.pid" -#define DAEMON_RAWFILE "/tmp/ebusd.bin" - - -void usage(void); - -void cmdline(int *argc, char ***argv); - -void set_unset(void); - -void signal_handler(int sig); - -void daemonize(void); - -void cleanup(int state); - -void main_loop(void); - -#endif /* MAIN_H_ */ diff --git a/src/ebusloop.cpp b/src/ebusloop.cpp new file mode 100644 index 00000000..aaaf0aaf --- /dev/null +++ b/src/ebusloop.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "ebusloop.h" +#include "logger.h" +#include "appl.h" +#include + +extern LogInstance& L; +extern Appl& A; + +EBusLoop::EBusLoop() : m_stop(false) +{ + m_deviceName = A.getParam("p_device"); + + m_bus = new Bus(m_deviceName, + A.getParam("p_nodevicecheck"), + A.getParam("p_dumpfile"), + A.getParam("p_dumpsize"), + A.getParam("p_dump")); + + m_retries = A.getParam("p_retries"); + + m_bus->connect(); + + if (m_bus->isConnected() == false) + L.log(bus, error, "can't open %s", m_deviceName.c_str()); +} + +EBusLoop::~EBusLoop() +{ + m_bus->disconnect(); + + if (m_bus->isConnected() == true) + L.log(bus, error, "error during disconnect."); + + delete m_bus; +} + +void* EBusLoop::run() +{ + int busResult; + int retries = 0; + bool busCommandActive = false; + + for (;;) { + if (m_bus->isConnected() == true) { + + // work on bus + busResult = m_bus->proceed(); + + // new cyc message arrived + if (busResult == 2) { + std::string data = m_bus->getCycData(); + L.log(bus, debug, "%s", data.c_str()); + m_cycBuffer.add(data); + } + + // add new bus command to send + if (busResult == 4 && busCommandActive == false && m_sendBuffer.size() != 0) { + BusCommand* busCommand = m_sendBuffer.remove(); + L.log(bus, debug, " type: %s msg: %s", + busCommand->getType().c_str(), busCommand->getCommand().c_str()); + m_bus->addCommand(busCommand); + L.log(bus, debug, " addCommand success"); + busCommandActive = true; + } + + // send bus command + if (busResult == 1 && busCommandActive == true) { + L.log(bus, trace, " getBus success"); + m_bus->sendCommand(); + BusCommand* busCommand = m_bus->recvCommand(); + L.log(bus, trace, " %s", busCommand->getResult().c_str()); + + if (busCommand->getResult().c_str()[0] == '-' && retries < m_retries) { + retries++; + L.log(bus, trace, " retry number: %d", retries); + busCommand->setResult(std::string()); + m_bus->addCommand(busCommand); + } else { + retries = 0; + m_recvBuffer.add(busCommand); + busCommandActive = false; + } + } + + if (busResult == 0) + L.log(bus, trace, " getBus failure"); + + if (busResult == -1) + L.log(bus, event, " getBus error"); + + } else { + sleep(10); + m_bus->connect(); + + if (m_bus->isConnected() == false) + L.log(bus, error, "can't open %s", m_deviceName.c_str()); + } + + if (m_stop == true) { + m_bus->disconnect(); + return NULL; + } + } + + return NULL; +} + diff --git a/src/ebusloop.h b/src/ebusloop.h new file mode 100644 index 00000000..44efc05c --- /dev/null +++ b/src/ebusloop.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef EBUSLOOP_H_ +#define EBUSLOOP_H_ + +#include "libebus.h" +#include "wqueue.h" +#include "thread.h" + +using namespace libebus; + + +class EBusLoop : public Thread +{ + +public: + EBusLoop(); + ~EBusLoop(); + + void* run(); + void stop() { m_stop = true; } + + std::string getData() { return m_cycBuffer.remove(); } + + void addBusCommand(BusCommand* busCommand) { m_sendBuffer.add(busCommand); } + BusCommand* getBusCommand() { return m_recvBuffer.remove(); } + + void dump(const bool dumpState) { m_bus->setDumpState(dumpState); } + +private: + std::string m_deviceName; + Bus* m_bus; + WQueue m_cycBuffer; + bool m_stop; + WQueue m_sendBuffer; + WQueue m_recvBuffer; + int m_retries; + +}; + +#endif // EBUSLOOP_H_ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 00000000..91472c14 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,248 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "libebus.h" +#include "logger.h" +#include "daemon.h" +#include "appl.h" +#include "network.h" +#include "ebusloop.h" +#include "cycdata.h" +#include "baseloop.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace libebus; + +Appl& A = Appl::Instance(); +Daemon& D = Daemon::Instance(); +LogInstance& L = LogInstance::Instance(); + +Network* network; +Commands* commands; +EBusLoop* ebusloop; +CYCData* cycdata; + +void define_args() +{ + A.addItem("p_address", Appl::Param("FF"), "a", "address", + "\tebus device address (FF)", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_device", Appl::Param("/dev/ttyUSB0"), "d", "device", + "\tebus device (serial or network) (/dev/ttyUSB0)", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_nodevicecheck", Appl::Param(false), "n", "nodevicecheck", + "disable valid ebus device test\n", + Appl::type_bool, Appl::opt_none); + + A.addItem("p_retries", Appl::Param(2), "r", "retries", + "\tnumber retries send ebus command (2)\n", + Appl::type_int, Appl::opt_mandatory); + + A.addItem("p_ebusconfdir", Appl::Param("/etc/ebusd"), "e", "ebusconfdir", + "directory for ebus configuration (/etc/ebusd)\n", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_foreground", Appl::Param(false), "f", "foreground", + "run in foreground\n", + Appl::type_bool, Appl::opt_none); + + A.addItem("p_port", Appl::Param(8888), "p", "port", + "\tlisten port (8888)", + Appl::type_int, Appl::opt_mandatory); + + A.addItem("p_localhost", Appl::Param(false), "", "localhost", + "listen localhost only\n", + Appl::type_bool, Appl::opt_none); + + A.addItem("p_logfile", Appl::Param("/var/log/ebusd.log"), "l", "logfile", + "\tlog file name (/var/log/ebusd.log)", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_logarea", Appl::Param("all"), "", "logarea", + "\tlogging area - bas|net|bus|cyc|all (all)", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_loglevel", Appl::Param("trace"), "", "loglevel", + "\tlogging level - error|event|trace|debug (event)\n", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_dump", Appl::Param(false), "D", "dump", + "\tenable dump", + Appl::type_bool, Appl::opt_none); + + A.addItem("p_dumpfile", Appl::Param("/tmp/ebus_dump.bin"), "", "dumpfile", + "\tdump file name (/tmp/ebus_dump.bin)", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_dumpsize", Appl::Param(100), "", "dumpsize", + "\tmax size for dump file in kB (100)\n", + Appl::type_long, Appl::opt_mandatory); + + A.addItem("p_settings", Appl::Param(false), "", "settings", + "\tprint daemon settings\n", + Appl::type_bool, Appl::opt_none); + + A.addItem("p_help", Appl::Param(false), "h", "help", + "\tprint this message", + Appl::type_bool, Appl::opt_none); +} + +void shutdown() +{ + // free Network + if (network != NULL) + delete network; + + // free CYCData + if (cycdata != NULL) { + cycdata->stop(); + delete cycdata; + } + + // free EBusLoop + if (ebusloop != NULL) { + ebusloop->stop(); + ebusloop->join(); + delete ebusloop; + } + + // free Commands DB + if (commands != NULL) + delete commands; + + // reset all signal handlers to default + signal(SIGHUP, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGTERM, SIG_DFL); + + // delete Daemon pid file + if (D.status() == true) + D.stop(); + + // stop Logger + L.log(bas, event, "ebusd stopped"); + L.stop(); + L.join(); + + exit(EXIT_SUCCESS); +} + +void signal_handler(int sig) +{ + switch (sig) { + case SIGHUP: + L.log(bas, event, "SIGHUP received"); + break; + case SIGINT: + L.log(bas, event, "SIGINT received"); + shutdown(); + break; + case SIGTERM: + L.log(bas, event, "SIGTERM received"); + shutdown(); + break; + default: + L.log(bas, event, "undefined signal %s", strsignal(sig)); + break; + } +} + +int main(int argc, char* argv[]) +{ + // define Arguments and Application variables + define_args(); + + // parse Arguments + if (A.parseArgs(argc, argv) == false) { + A.printArgs(); + exit(EXIT_FAILURE); + } + + // print Help + if (A.getParam("p_help") == true) { + A.printArgs(); + exit(EXIT_SUCCESS); + } + + // print Daemon settings + if (A.getParam("p_settings") == true) + A.printSettings(); + + // make me Daemon + if (A.getParam("p_foreground") == true) { + L += new LogConsole(calcArea(A.getParam("p_logarea")), + calcLevel(A.getParam("p_loglevel")), + "logConsole"); + } else { + D.run("/var/run/ebusd.pid"); + L += new LogFile(calcArea(A.getParam("p_logarea")), + calcLevel(A.getParam("p_loglevel")), + "logFile", A.getParam("p_logfile")); + } + + // trap Signals that we expect to receive + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + + // start Logger + L.start("logInstance"); + // wait for Logger be ready + usleep(100000); + L.log(bas, event, "ebusd started"); + + // create Commands DB + commands = ConfigCommands(A.getParam("p_ebusconfdir"), CSV).getCommands(); + L.log(bas, debug, "ebus configuration dir: %s", A.getParam("p_ebusconfdir")); + L.log(bas, event, "commands DB with %d entries created", commands->size()); + + // create EBusLoop + ebusloop = new EBusLoop(); + ebusloop->start("ebusloop"); + + // create CYCData + cycdata = new CYCData(ebusloop, commands); + cycdata->start("cycdata"); + + // create Network + network = new Network(A.getParam("p_localhost")); + + // create BaseLoop + BaseLoop baseloop(ebusloop, cycdata, commands); + + // start Network + network->addQueue(baseloop.getQueue()); + network->start("netListener"); + + // start Baseloop + baseloop.start(); + + shutdown(); +} + diff --git a/src/network.cpp b/src/network.cpp new file mode 100644 index 00000000..d426fa2d --- /dev/null +++ b/src/network.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "network.h" +#include "logger.h" +#include "appl.h" +#include +#include +#include + +extern LogInstance& L; +extern Appl& A; + +int Connection::m_count = -1; + +void Connection::addResult(Message message) +{ + Message* tmp = new Message(Message(message)); + m_result.add(tmp); +} + +void* Connection::run() +{ + m_running = true; + + int maxfd; + fd_set checkfds; + struct timeval timeout; + + FD_ZERO(&checkfds); + FD_SET(m_notify.notifyFD(), &checkfds); + FD_SET(m_socket->getFD(), &checkfds); + + (m_notify.notifyFD() > m_socket->getFD()) ? + (maxfd = m_notify.notifyFD()) : (maxfd = m_socket->getFD()); + + for (;;) { + fd_set readfds; + int ret; + + // set select timeout 10 secs + timeout.tv_sec = 10; + timeout.tv_usec = 0; + + // set readfds to inital checkfds + readfds = checkfds; + + ret = select(maxfd + 1, &readfds, NULL, NULL, &timeout); + if (ret == 0) { + continue; + } + + // new data from notify + if (FD_ISSET(m_notify.notifyFD(), &readfds)) + break; + + // new data from socket + if (FD_ISSET(m_socket->getFD(), &readfds)) { + char data[256]; + size_t datalen; + + if (m_socket->isValid() == true) + datalen = m_socket->recv(data, sizeof(data)-1); + else + break; + + // removed closed socket + if (datalen <= 0 || strncasecmp(data, "quit", 4) == 0) + break; + + // send data + data[datalen] = '\0'; + m_data->add(new Message(data, this)); + + // wait for result + L.log(net, debug, "[%08x] wait for result", getID()); + Message* message = m_result.remove(); + + L.log(net, debug, "[%08x] result added", getID()); + std::string result(message->getData()); + + if (m_socket->isValid() == true) + m_socket->send(result.c_str(), result.size()); + else + break; + + delete message; + + } + + } + + delete m_socket; + m_running = false; + L.log(net, trace, "[%08x] connection closed", getID()); + + return NULL; +} + + + +Network::Network(const bool localhost) : m_listening(false), m_running(false) +{ + // Start Listener + if (localhost == true) + m_Listener = new TCPListener(A.getParam("p_port"), "127.0.0.1"); + else + m_Listener = new TCPListener(A.getParam("p_port"), "0.0.0.0"); + + if (m_Listener && m_Listener->start() == 0) + m_listening = true; + +} + +Network::~Network() +{ + while (m_connections.empty() == false) { + Connection* connection = m_connections.back(); + m_connections.pop_back(); + connection->stop(); + connection->join(); + delete connection; + } + + if (m_running == true) + stop(); + + delete m_Listener; +} + +void* Network::run() +{ + if (m_listening == false) + return NULL; + + m_running = true; + + int maxfd; + fd_set checkfds; + struct timeval timeout; + + FD_ZERO(&checkfds); + FD_SET(m_notify.notifyFD(), &checkfds); + FD_SET(m_Listener->getFD(), &checkfds); + + (m_notify.notifyFD() > m_Listener->getFD()) ? + (maxfd = m_notify.notifyFD()) : (maxfd = m_Listener->getFD()); + + for (;;) { + fd_set readfds; + int ret; + + // set select timeout 1 secs + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + // set readfds to inital checkfds + readfds = checkfds; + + ret = select(maxfd + 1, &readfds, NULL, NULL, &timeout); + if (ret == 0) { + cleanConnections(); + continue; + } + + // new data from notify + if (FD_ISSET(m_notify.notifyFD(), &readfds)) { + m_running = false; + break; + } + + // new data from socket + if (FD_ISSET(m_Listener->getFD(), &readfds)) { + TCPSocket* socket = m_Listener->newSocket(); + if (socket == NULL) + continue; + + Connection* connection = new Connection(socket, m_queue); + if (connection == NULL) + continue; + + connection->start("netConnection"); + m_connections.push_back(connection); + L.log(net, trace, "[%08x] connection opened %s", connection->getID(), socket->getIP().c_str()); + } + + } + + return NULL; +} + +void Network::cleanConnections() +{ + std::list::iterator c_it; + for (c_it = m_connections.begin(); c_it != m_connections.end(); c_it++) { + if ((*c_it)->isRunning() == false) { + Connection* connection = *c_it; + c_it = m_connections.erase(c_it); + delete connection; + L.log(net, debug, "dead connection removed - %d", m_connections.size()); + } + } +} + diff --git a/src/network.h b/src/network.h new file mode 100644 index 00000000..f4abcc32 --- /dev/null +++ b/src/network.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef NETWORK_H_ +#define NETWORK_H_ + +#include "tcpsocket.h" +#include "wqueue.h" +#include "thread.h" +#include "notify.h" +#include "baseloop.h" +#include +#include + +class Connection : public Thread +{ + +public: + Connection(TCPSocket* socket, WQueue* data) + : m_socket(socket), m_data(data), m_running(false) { m_count++; } + + ~Connection() { m_count--; } + + void addResult(Message message); + + void* run(); + void stop() const { m_notify.notify(); } + bool isRunning() const { return m_running; } + + pthread_t getID() { return this->self(); } + int numConnections() const { return m_count; } + +private: + TCPSocket* m_socket; + WQueue* m_data; + WQueue m_result; + Notify m_notify; + bool m_running; + + static int m_count; + +}; + +class Network : public Thread +{ + +public: + Network(const bool localhost); + ~Network(); + + void addQueue(WQueue* queue) { m_queue = queue; } + + void* run(); + void stop() const { m_notify.notify(); usleep(100000); } + +private: + std::list m_connections; + WQueue* m_queue; + TCPListener* m_Listener; + Notify m_notify; + bool m_listening; + bool m_running; + + void cleanConnections(); + +}; + +#endif // NETWORK_H_ diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index 39c8de44..00000000 --- a/src/utils.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "ebus-bus.h" -#include "utils.h" - - - -struct msg_queue *dummy; -static int msg_entries; - -int -msg_queue_entries(void) -{ - return msg_entries; -} - -int -msg_queue_init(void) -{ - dummy = (struct msg_queue *) malloc(sizeof(struct msg_queue)); - - if (dummy != NULL) { - dummy->id = -1; - memset(dummy->data, '\0', sizeof(dummy->data)); - dummy->clientfd = -1; - dummy->prev = NULL; - - msg_entries = 0; - return 0; - } - - return -1; -} - -void -msg_queue_free(void) -{ - while (dummy->prev != NULL) - msg_queue_get(); - - free(dummy); - msg_entries = 0; -} - -void -msg_queue_put(struct msg_queue *new) -{ - struct msg_queue *tmp; - - /* first element */ - if (dummy->prev == NULL) { - dummy->prev = new; - new->prev = NULL; - } else { - tmp = dummy; - /* get last element */ - while (tmp->prev != NULL) - tmp = tmp->prev; - - tmp->prev = new; - new->prev = NULL; - } -} - -void -msg_queue_get(void) -{ - struct msg_queue *tmp; - - /* delete element */ - if (dummy->prev != NULL) { - tmp = dummy->prev; - dummy->prev = tmp->prev; - free(tmp); - } else { - log_print(L_ERR, "msg queue empty - should never seen"); - } -} - -void -msg_queue_msg_add(int id, char *data, int clientfd) -{ - struct msg_queue *new; - - new = (struct msg_queue *) malloc(sizeof(struct msg_queue)); - - if (new != NULL) { - new->id = id; - memset(new->data, '\0', sizeof(new->data)); - strncpy(new->data, data, strlen(data)); - new->clientfd = clientfd; - new->prev = NULL; - - msg_queue_put(new); - msg_entries++; - - log_print(L_DBG, "add: id: %d clientfd: %d ==> entries: %d", - new->id, new->clientfd, msg_entries); - } -} - -void -msg_queue_msg_del(int *id, char *data, int *clientfd) -{ - if (dummy->prev != NULL) { - *id = dummy->prev->id; - memset(data, '\0', sizeof(data)); - strncpy(data, dummy->prev->data, strlen(dummy->prev->data)); - *clientfd = dummy->prev->clientfd; - - msg_queue_get(); - msg_entries--; - - log_print(L_DBG, "del: id: %d clientfd: %d ==> entries: %d", - *id, *clientfd, msg_entries); - - } else { - log_print(L_NOT, "msg queue empty"); - } -} - - - -void -cfg_print(struct config *cfg, int len) -{ - int i; - - fprintf(stdout, "\n"); - - for (i = 0; i < len; i++) { - - if (cfg[i].key != NULL && cfg[i].tgt != NULL) { - fprintf(stdout, "%s = ", cfg[i].key); - - switch (cfg[i].type) { - case STR: - fprintf(stdout, "%s\n", (char *) cfg[i].tgt); - break; - case BOL: - if (*(int *) cfg[i].tgt == NO) - fprintf(stdout, "NO\n"); - else if (*(int *) cfg[i].tgt == YES) - fprintf(stdout, "YES\n"); - else - fprintf(stdout, "UNSET\n"); - break; - case NUM: - fprintf(stdout, "%d\n", *(int *) cfg[i].tgt); - break; - default: - break; - } - } - } - fprintf(stdout, "\n"); -} - -int -cfg_file_set_param(char *par, struct config *cfg, int len) -{ - int i; - - for (i = 0; i < len; i++) { - - if (strncasecmp(par, cfg[i].key, strlen(cfg[i].key)) == 0 && - strlen(par) == strlen(cfg[i].key)) { - - par = strtok(NULL, "\t =\n\r"); - - switch (cfg[i].type) { - case STR: - if (strlen(cfg[i].tgt) == 0) - strncpy(cfg[i].tgt , par, strlen(par)); - break; - case BOL: - if (*(int *) cfg[i].tgt == UNSET) { - if (strncasecmp(par, "NO", 2) == 0) - *(int *) cfg[i].tgt = NO; - else if (strncasecmp(par, "YES", 3) == 0) - *(int *) cfg[i].tgt = YES; - else - *(int *) cfg[i].tgt = UNSET; - } - break; - case NUM: - if (*(int *) cfg[i].tgt == UNSET) - *(int *) cfg[i].tgt = atoi(par); - break; - default: - break; - } - - return 1; - } - } - - return 0; -} - -int -cfg_file_read(const char *file, struct config *cfg, int len) -{ - int ret; - char line[CFG_LINELEN]; - char *par, *tmp; - FILE *fp = NULL; - - - - /* open config file */ - fp = fopen(file, "r"); - - /* try local configuration file */ - if (fp == NULL) { - fprintf(stdout, "configuration file %s not found.\n", file); - - tmp = strrchr(file, '/'); - tmp++; - - /* open config file */ - fp = fopen(tmp, "r"); - err_ret_if(fp == NULL, -1); - - fprintf(stdout, "local configuration file %s used.\n", tmp); - } - - /* read each line and set parameter */ - while (fgets(line, CFG_LINELEN, fp) != NULL ) { - par = strtok(line, "\t =\n\r") ; - - if (par != NULL && par[0] != '#') - ret = cfg_file_set_param(par, cfg, len); - } - - /* close config file */ - ret = fclose(fp); - err_ret_if(ret == EOF, -1); - - return 0; -} - - - -int -pid_file_open(const char *file, int *fd) -{ - int ret; - char pid[10]; - - *fd = open(file, O_RDWR|O_CREAT, 0600); - err_ret_if(*fd < 0, -1); - - ret = lockf(*fd, F_TLOCK, 0); - err_ret_if(ret < 0, -1); - - sprintf(pid, "%d\n", getpid()); - ret = write(*fd, pid, strlen(pid)); - err_ret_if(ret < 0, -1); - - return 0; -} - -int -pid_file_close(const char *file, int fd) -{ - int ret; - - ret = close(fd); - err_ret_if(ret < 0, -1); - - ret = unlink(file); - err_ret_if(ret < 0, -1); - - return 0; -} - - - -int -sock_open(int *fd, int port, int localhost) -{ - int ret, opt; - struct sockaddr_in sock; - - *fd = socket(AF_INET, SOCK_STREAM, 0); - err_ret_if(*fd < 0, -1); - - /* todo: verify if this realy work */ - /* prevent "Error Address already in use" error message */ - opt = 1; - ret = setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)); - err_ret_if(ret < 0, -1); - - memset((char *) &sock, 0, sizeof(sock)); - sock.sin_family = AF_INET; - - if (localhost == YES) - sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - else - sock.sin_addr.s_addr = htonl(INADDR_ANY); - - sock.sin_port = htons(port); - - ret = bind(*fd, (struct sockaddr *) &sock, sizeof(sock)); - err_ret_if(ret < 0, -1); - - ret = listen(*fd, 5); - err_ret_if(ret < 0, -1); - - return 0; -} - -int -sock_close(int fd) -{ - int ret; - - ret = close(fd); - err_ret_if(ret < 0, -1); - - return 0; -} - -int -sock_client_accept(int listenfd, int *datafd) -{ - struct sockaddr_in sock; - socklen_t socklen; - - socklen = sizeof(sock); - - *datafd = accept(listenfd, (struct sockaddr *) &sock, &socklen); - err_ret_if(*datafd < 0, -1); - - log_print(L_DBG, "client [%d] from %s connected.", - *datafd, inet_ntoa(sock.sin_addr)); - - return 0; -} - -int -sock_client_read(int fd, char *buf, int *buflen) -{ - *buflen = read(fd, buf, *buflen); - err_ret_if(*buflen < 0, -1); - - if (strncasecmp("quit", buf , 4) == 0 || *buflen <= 0) { - /* close tcp connection */ - log_print(L_DBG, "client [%d] disconnected.", fd); - sock_close(fd); - return -1; - } - - if (strchr(buf, '\n') != NULL) { - buf[strcspn(buf, "\n")] = '\0'; - *buflen -= 1; - } - - log_print(L_NET, ">>> client [%d] %s", fd, buf); - - return 0; -} - -int -sock_client_write(int fd, char *buf, int buflen) -{ - int ret; - - /* add to each line */ - buf[buflen] = '\r'; - buflen++; - - ret = write(fd, buf, buflen); - err_ret_if(ret < 0, -1); - - buf[strcspn(buf,"\n")] = '\0'; - log_print(L_NET, "<<< client [%d] %s", fd, buf); - - return 0; -} diff --git a/src/utils.h b/src/utils.h deleted file mode 100644 index 2827e8f0..00000000 --- a/src/utils.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifndef UTILS_H_ -#define UTILS_H_ - -#define NUMSTR2(s) #s -#define NUMSTR(s) NUMSTR2(s) - -#define CFG_LINELEN 256 - -#define SOCKET_PORT 8888 -#define SOCKET_BUFSIZE 1024 - -#define MSG_QUEUE_MSG_SIZE 256 - -enum enum_config {STR, BOL, NUM}; - -struct config { - char *key; - int type; - void *tgt; - char *info; -}; - -struct msg_queue { - int id; - char data[MSG_QUEUE_MSG_SIZE + 1]; - int clientfd; - struct msg_queue *prev; -}; - -int msg_queue_entries(void); -int msg_queue_init(void); -void msg_queue_free(void); -void msg_queue_put(struct msg_queue *msg); -void msg_queue_get(void); -void msg_queue_msg_add(int id, char *data, int clientfd); -void msg_queue_msg_del(int *id, char *data, int *clientfd); - -void cfg_print(struct config *cfg, int len); -int cfg_file_set_param(char *param, struct config *cfg, int len); -int cfg_file_read(const char *file, struct config *cfg, int len); - -int pid_file_open(const char *file, int *fd); -int pid_file_close(const char *file, int fd); - -int sock_open(int *fd, int port, int localhost); -int sock_close(int fd); -int sock_client_accept(int listenfd, int *datafd); -int sock_client_read(int fd, char *buf, int *buflen); -int sock_client_write(int fd, char *buf, int buflen); - -#endif /* UTILS_H_ */ diff --git a/test/ebus_dump.bin b/test/ebus_dump.bin new file mode 100644 index 00000000..64299892 Binary files /dev/null and b/test/ebus_dump.bin differ diff --git a/test/feed.cpp b/test/feed.cpp new file mode 100644 index 00000000..759a6678 --- /dev/null +++ b/test/feed.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "libebus.h" +#include "appl.h" +#include +#include +#include +#include +#include +#include + +using namespace libebus; + +Appl& A = Appl::Instance(); + +void define_args() +{ + A.addItem("p_device", Appl::Param("/dev/ttyUSB60"), "d", "device", + "dummy serial device (default: /dev/ttyUSB60)\n\t\t(socat -d -d pty,raw,echo=0 pty,raw,echo=0)", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_file", Appl::Param("test/ebus_dump.bin"), "f", "file", + "dump file with raw data (default: test/ebus_dump.bin)", + Appl::type_string, Appl::opt_mandatory); + + A.addItem("p_time", Appl::Param(10000), "t", "time", + "wait time [ms] (default: 10000)", + Appl::type_long, Appl::opt_mandatory); + + A.addItem("p_help", Appl::Param(false), "h", "help", + "print this message", + Appl::type_bool, Appl::opt_none); +} + +int main(int argc, char* argv[]) +{ + // define Arguments and Application variables + define_args(); + + // parse Arguments + if (A.parseArgs(argc, argv) == false) { + A.printArgs(); + exit(EXIT_FAILURE); + } + + // print Help + if (A.getParam("p_help") == true) { + A.printArgs(); + exit(EXIT_SUCCESS); + } + + std::string dev(A.getParam("p_device")); + Port port(dev, true); + + port.open(); + if(port.isOpen() == true) + std::cout << "openPort successful." << std::endl; + + std::fstream file(A.getParam("p_file"), std::ios::in | std::ios::binary); + + if(file.is_open() == true) { + + while (file.eof() == false) { + unsigned char byte = file.get(); + std::cout << std::hex << std::setw(2) << std::setfill('0') + << static_cast(byte) << std::endl; + + port.send(&byte, 1); + usleep(A.getParam("p_time")); + } + + file.close(); + } + + port.close(); + if(port.isOpen() == false) + std::cout << "closePort successful." << std::endl; + + return 0; + +} diff --git a/tools/Makefile.am b/tools/Makefile.am deleted file mode 100644 index c71d45f7..00000000 --- a/tools/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -bin_PROGRAMS = ebus_send check csv - -ebus_send_SOURCES = ebus_send.c -ebus_send_LDADD = $(top_srcdir)/lib/libebus.a $(top_srcdir)/lib/liblog.a -ebus_send_CFLAGS = -I$(top_srcdir)/lib - -check_SOURCES = check.c -check_LDADD = $(top_srcdir)/lib/libebus.a $(top_srcdir)/lib/liblog.a -check_CFLAGS = -I$(top_srcdir)/lib - -csv_SOURCES = csv.c -csv_LDADD = $(top_srcdir)/lib/libebus.a $(top_srcdir)/lib/liblog.a -csv_CFLAGS = -I$(top_srcdir)/lib - -distclean-local: - -rm -f Makefile.in - diff --git a/tools/check.c b/tools/check.c deleted file mode 100644 index 45d3e740..00000000 --- a/tools/check.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include - -#include "ebus-decode.h" - -int main(void) { - - int i, j, end, ret; - - int bcd, d1b, data[BUS_DEVICE_BUFSIZE + 1]; - float d1c, d2b, d2c; - - char byte; - - unsigned char hex, tmp, crc, crc_calc[2] ; - - tmp = 0; - end = 0; - do { - i = 0; - printf("Input: "); - while ((byte = fgetc(stdin)) != EOF) { - - if (byte == '\n') { - break; - } - - if (byte == 'q') { - end = 1; - break; - } - - if (i < (int) sizeof(data)) { - ret = eb_htoi(&byte); - if (ret != -1) { - data[i] = ret; - i++; - } - } else { - break; - } - } - - if (!end) { - - for (j = 0; j < i; j += 2) { - - bcd = 0; - d1b = 0; - ret = 0; - d1c = 0.0; - d2b = 0.0; - d2c = 0.0; - - hex = (unsigned char) (data[j]*16 + data[j+1]); - - ret = eb_bcd_to_int(hex, &bcd); - ret = eb_d1b_to_int(hex, &d1b); - - ret = eb_d1c_to_float(hex, &d1c); - printf("hex %02x ->\tbcd: %3d\td1b: %4d" - "\td1c: %5.1f", hex, bcd, d1b, d1c); - - - if (j == 2) { - ret = eb_d2b_to_float(tmp, hex, &d2b); - ret = eb_d2c_to_float(tmp, hex, &d2c); - crc_calc[0] = tmp; - crc_calc[1] = hex; - crc = eb_calc_crc(crc_calc,2); - printf("\td2b: %10.5f\td2c: %12.6f" - "\tcrc: %02x\n", d2b, d2c, crc); - } - else { - tmp = hex; - printf("\n"); - } - } - } - - } while (end == 0); - - return 0; -} diff --git a/tools/csv.c b/tools/csv.c deleted file mode 100644 index eb838e8d..00000000 --- a/tools/csv.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - - -#include -#include -#include -#include -#include -#include - -#include "log.h" -#include "ebus-cmd.h" -#include "ebus-bus.h" - -/* global variables */ -const char *progname; - -static const char *cfgdir = NULL; -static int all = NO; -static int cyc = NO; -static int detail = NO; -static int get = NO; -static int set = NO; -static char loglevel[] = {"ALL"}; - - -void -usage(void) -{ - fprintf(stdout, "\nUsage: %s [OPTION] cfgdir\n\n" - " -a --all print ALL\n" - " -c --cyc print CYC\n" - " -d --detail print DETAIL\n" - " -g --get print GET\n" - " -s --set print SET\n" - " -h --help print this message.\n" - "\n", - progname); -} - -void -cmdline(int *argc, char ***argv) -{ - static struct option opts[] = { - {"all", no_argument, NULL, 'a'}, - {"cyc", no_argument, NULL, 'c'}, - {"detail", no_argument, NULL, 'd'}, - {"get", no_argument, NULL, 'g'}, - {"set", no_argument, NULL, 's'}, - {"help", no_argument, NULL, 'h'}, - {NULL, no_argument, NULL, 0 }, - }; - - for (;;) { - int i; - - i = getopt_long(*argc, *argv, "acdgsh", opts, NULL); - - if (i == -1) { - *argc = optind; - break; - } - - switch (i) { - case 'a': - cyc = YES; - get = YES; - set = YES; - break; - case 'c': - cyc = YES; - break; - case 'd': - detail = YES; - break; - case 'g': - get = YES; - break; - case 's': - set = YES; - break; - case 'h': - default: - usage(); - exit(EXIT_FAILURE); - break; - } - } -} - - - -int -main(int argc, char *argv[]) -{ - - /* set progname */ - progname = (const char *)strrchr(argv[0], '/'); - progname = progname ? (progname + 1) : argv[0]; - - cmdline(&argc, &argv); - - cfgdir = argv[argc]; - - /* open log */ - log_level(loglevel); - log_open("", 1); - - if (cfgdir) - eb_cmd_dir_read(cfgdir, "csv"); - else - usage(); - - if (cyc) - eb_cmd_print("cyc", all, detail); - - if (get) - eb_cmd_print("get", all, detail); - - if (set) - eb_cmd_print("set", all, detail); - - - - //~ Master Slave - //~ const unsigned char tmp[] = {'\x10','\x08','\xb5','\x10','\x09','\x00','\x02','\x40','\x00', - //~ '\x00','\x00','\x00','\x00','\x02','\x15','\x00','\x00','\x00','\x00'}; - //~ '\x00','\x00','\x00','\x00','\x02','\x15','\xff','\x00','\x00','\x00'}; - //~ '\x00','\x00','\x00','\x00','\x02','\x15','\x00','\x01','\x02','\x99','\x00'}; - //~ '\x00','\x00','\x00','\x00','\x02','\x15','\x00','\x02','\xe2','\x67','\x41','\x00'}; - //~ char cmd[] = "cyc ms test ma"; - //~ char cmd[] = "cyc ms test sd"; - //~ char cmd[] = "cyc ms test sa"; - //~ char cmd[] = "cyc ms test md"; - //~ char cmd[] = "cyc ms test"; - - //~ const unsigned char tmp[] = {'\x10','\x08','\xb5','\x09','\x03','\x29','\x0f','\x00','\x56','\x00', - //~ '\x05','\x0f','\x00','\xa9','\x01','\x00','\x00','\x86','\x00'}; - //~ char cmd[] = "cyc mv brine_in"; - - //~ const unsigned char tmp[] = {'\xff','\x08','\xb5','\x11','\x01','\x01','\x2d','\x00','\x09','\x62', - //~ '\xff','\x00','\x80','\x00','\x54','\x00','\x00','\xff','\x23','\x00'}; - - //~ char cmd[] = "cyc burner temps"; - //~ char cmd[] = "cyc burner temps_raw"; - - // 31835 - //~ const unsigned char tmp[] = {'\xff','\x08','\xb5','\x09','\x03','\x0d','\xbc','\x00','\x12', - //~ '\x00','\x04','\x5b','\x7c','\x00','\x00','\x75','\x00'}; -//~ -//~ - //~ char cmd[] = "cyc ms test"; - - //~ const unsigned char tmp[] = {'\x03','\xe0','\xb5','\x21','\x05','\x00','\x05','\x07','\x00','\xe7', - //~ '\x64','\x80','\x42','\x40','\x10','\x11','\xd0','\x05','\x74','\x64', - //~ '\xd2','\xea','\x01','\xa9','\x10','\x08','\xb5','\x09','\x03','\x29', - //~ '\xb8','\x01','\xfd','\x00','\x03','\xb8','\x01','\x00','\x70','\x00'}; - - //~ const unsigned char tmp[] = {'\x03','\xe0','\xb5','\x21','\x05','\x00','\x02','\x07','\x00','\xe7', - //~ '\x65','\x80','\x42','\x40','\xa0','\x10','\xd0','\x12','\xd0','\x10', - //~ '\x10','\x50','\x1b','\x90','\x0d','\xfc','\x23','\xb5','\x05','\x07', - //~ '\x2b','\x00','\x01','\x00','\x00','\x00','\x00','\x79','\x00','\x00', - //~ '\x00','\x00'}; -//~ - //~ char cmd[] = "cyc vwl OutUnitData"; - - //~ Master Master - //~ 10 03 05 07 09 bb 06 2e 02 00 80 ff 6e ff 8f 00 - //~ const unsigned char tmp[] = {'\x10','\x03','\x05','\x07','\x09','\xbb','\x06','\x1b','\x02','\x00', - //~ '\x80','\xff','\x6e','\xff','\xf2','\x00'}; - - //~ const unsigned char tmp[] = {'\x10','\x23','\xb5','\x04','\x01','\x31','\xf6','\x00'}; - //~ const unsigned char tmp[] = {'\x10','\x23','\xb5','\x04','\x01','\x31','\xf6','\xff'}; - //~ char cmd[] = "cyc mm test test"; - //~ char cmd[] = "cyc mm test stat"; - //~ char cmd[] = "cyc mm test"; - - //~ Broadcast - //~ const unsigned char tmp[] = {'\x10','\xfe','\xb5','\x16','\x08','\x00','\x02','\x23','\x16','\x28','\x02','\x04','\x13','\x92'}; - //~ char cmd[] = "cyc broad date_time day"; - //~ char cmd[] = "cyc broad date_time"; - - //~ 10 46 11 2e 03 00 02 11 02 - //~ const unsigned char tmp[] = {'\x10','\x46','\x11','\x2e','\x03','\x00','\x02','\x11','\x02'}; - //~ char cmd[] = "cyc broad 1"; - -//############################################################### - - //~ const int tmplen = sizeof(tmp) / sizeof(unsigned char); - //~ char data[CMD_DATA_SIZE], tcpbuf[CMD_DATA_SIZE]; - //~ memset(data, '\0', sizeof(data)); - //~ memset(tcpbuf, '\0', sizeof(tcpbuf)); - //~ int id, tcpbuflen; -//~ - //~ fprintf(stdout, "Test command >%s<\n", cmd); - //~ eb_print_hex(tmp, tmplen); -//~ - //~ eb_cyc_data_process(tmp, tmplen); -//~ - //~ id = eb_cmd_search_com_cyc(&tmp[1], tmplen - 1); -//~ - //~ eb_execute(id, data, tcpbuf, &tcpbuflen); -//~ - //~ fprintf(stdout, "tcpbuf: %s tcpbuflen: %d\n", tcpbuf, tcpbuflen); - -//############################################################### - -//~ unsigned long val; -//~ eb_print_hex(&tmp[11], 4); -//~ fprintf(stdout, "%d %d %d %d\n", tmp[11], (tmp[12] << 8), (tmp[13] << 16), (tmp[14] << 24)); -//~ fprintf(stdout, "%d\n", tmp[11] + (tmp[12] << 8) + (tmp[13] << 16) + (tmp[14] << 24)); - -//############################################################### - - eb_cmd_dir_free(); - - return 0; -} diff --git a/tools/ebus_send.c b/tools/ebus_send.c deleted file mode 100644 index 106dc2c2..00000000 --- a/tools/ebus_send.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (C) Roland Jax 2012-2013 - * - * This file is part of ebusd. - * - * ebusd 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 - * (at your option) any later version. - * - * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif /* HAVE_CONFIG_H */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ebus-decode.h" -#include "ebus-bus.h" - - -static int serialfd = -1; -static const char *device = SERIAL_DEVICE; -static const char *progname; -static int type = EBUS_MSG_MASTER_SLAVE; -static int prompt = NO; - -void -print_msg(const char *pre, const unsigned char *buf, int buflen, - const char *post) -{ - int i; - - fprintf(stdout, "%s", pre); - for (i = 0; i < buflen; i++) - fprintf(stdout, " %02x", buf[i]); - fprintf(stdout, "%s\n", post); -} - -void -usage(void) -{ - fprintf(stdout, "\nUsage: %s [OPTION] \n\n" - " spaces within message be removed.\n\n" - " -a --address set bus address. (%02x)\n" - " -d --device use a specified serial device. (%s)\n" - " -p --prompt stay on input prompt.\n" - " -r --retry max retry getting bus. (%d)\n" - " -s --skip skipped ACK bytes after get-bus error. (%d)\n" - " -t --type message type. (%d)\n" - " 1 = Broadcast, 2 = Master-Master, 3 = Master-Slave\n" - " -w --wait wait time for QQ compare. (~%d usec)\n" - " -h --help print this message.\n" - "\n", - progname, - EBUS_QQ, - device, - EBUS_GET_RETRY, - EBUS_SKIP_ACK, - type, - EBUS_MAX_WAIT); -} - -void -cmdline(int *argc, char ***argv) -{ - static struct option opts[] = { - {"address", required_argument, NULL, 'a'}, - {"device", required_argument, NULL, 'd'}, - {"prompt", no_argument, NULL, 'p'}, - {"retry", required_argument, NULL, 'r'}, - {"skip", required_argument, NULL, 's'}, - {"type", required_argument, NULL, 't'}, - {"wait", required_argument, NULL, 'w'}, - {"help", no_argument, NULL, 'h'}, - {NULL, no_argument, NULL, 0 }, - }; - - for (;;) { - int i; - - i = getopt_long(*argc, *argv, "a:d:pr:s:t:w:h", opts, NULL); - - if (i == -1) { - *argc = optind; - break; - } - - switch (i) { - case 'a': - if (isxdigit(*optarg) && strlen(optarg) == 2) { - int tmp; - tmp = (eb_htoi(&optarg[0])) * 16 + - (eb_htoi(&optarg[1])); - - eb_set_qq((unsigned char) tmp); - } - break; - case 'd': - device = optarg; - break; - case 'p': - prompt = YES; - break; - case 'r': - if (isdigit(*optarg)) { - eb_set_get_retry(atoi(optarg)); - } - break; - case 's': - if (isdigit(*optarg)) { - eb_set_skip_ack(atoi(optarg)); - } - break; - case 't': - if (isdigit(*optarg)) - type = atoi(optarg); - break; - case 'w': - if (isdigit(*optarg)) { - eb_set_max_wait(atol(optarg)); - } - break; - case 'h': - default: - usage(); - exit(EXIT_FAILURE); - break; - } - } -} - -int -main(int argc, char *argv[]) -{ - int i, j, k, end, ret, val, max_argc, buslen; - int in[BUS_DEVICE_BUFSIZE + 1]; - char byte; - unsigned char msg[BUS_DEVICE_BUFSIZE + 1], bus[TMP_BUFSIZE]; - - progname = (const char *)strrchr(argv[0], '/'); - progname = progname ? (progname + 1) : argv[0]; - - max_argc = argc; - cmdline(&argc, &argv); - - val = 0; - - if (prompt) { - - end = 0; - do { - byte = '\0'; - i = 0; - printf("msg: "); - while ((byte = fgetc(stdin)) != EOF) { - - if (byte == '\n') - break; - - if (byte == 'q') { - end = 1; - break; - } - - if (i < (int) sizeof(in)) { - - ret = eb_htoi(&byte); - if (ret != -1) { - in[i] = ret; - i++; - } - - } else { - break; - } - } - - if (!end && i > 0) { - - memset(msg, '\0', sizeof(msg)); - memset(bus, '\0', sizeof(bus)); - - for (j = 0, k = 0; j < i; j += 2, k++) - msg[k] = (unsigned char) - (in[j]*16 + in[j+1]); - - ret = eb_bus_open(device, &serialfd); - if (ret < 0) - fprintf(stdout, "Error open %s.\n", device); - - if (ret == 0) { - ret = eb_send_data(msg, k, type, bus, &buslen); - if (ret == 0) { - fprintf(stdout, "res:"); - eb_print_result(); - } - - } - - ret = eb_bus_close(); - if (ret < 0) - fprintf(stdout, "Error close %s.\n", device); - - } - - } while (end == 0); - } else { - - memset(in, '\0', sizeof(in)); - k = 0; - i = 0; - for (k = argc; k < max_argc; k++) { - j = 0; - while (argv[k][j] != '\0') { - byte = argv[k][j]; - if (i < (int) sizeof(in)) { - - ret = eb_htoi(&byte); - if (ret != -1) { - in[i] = ret; - i++; - } - } - j++; - } - } - - memset(bus, '\0', sizeof(bus)); - memset(msg, '\0', sizeof(msg)); - for (j = 0, k = 0; j < i; j += 2, k++) - msg[k] = (unsigned char) (in[j]*16 + in[j+1]); - - if (k > 0) { - - ret = eb_bus_open(device, &serialfd); - if (ret < 0) - fprintf(stdout, "Error open %s.\n", device); - - if (ret == 0) { - ret = eb_send_data(msg, k, type, bus, &buslen); - val = ret; - if (ret == 0) { - if (type == EBUS_MSG_MASTER_SLAVE) - eb_print_result(); - - if (type == EBUS_MSG_MASTER_MASTER) - fprintf(stdout, " %d\n", ret); - } - - } - - ret = eb_bus_close(); - if (ret < 0) - fprintf(stdout, "Error close %s.\n", device); - } - - } - - return val; -} diff --git a/utils/appl.cpp b/utils/appl.cpp new file mode 100644 index 00000000..af6014e1 --- /dev/null +++ b/utils/appl.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "appl.h" +#include +#include +#include + +Appl& Appl::Instance() +{ + static Appl instance; + return instance; +} + +Appl::~Appl() +{ + m_args.clear(); + m_params.clear(); +} + +void Appl::addItem(const char* name, Param param, const char* shortname, + const char* longname, const char* description, + Datatype datatype, Optiontype optiontype) +{ + if (strlen(name) != 0) + m_params[name] = param; + + if (strlen(longname) != 0) { + Arg arg; + arg.name = name; + arg.shortname = shortname; + arg.longname = longname; + arg.description = description; + arg.datatype = datatype; + arg.optiontype = optiontype; + m_args.push_back(arg); + } +} + +void Appl::printArgs() +{ + std::cerr << std::endl << "Usage:" << std::endl << " " + << m_argv[0].substr(2) << " [Options]" << std::endl + << std::endl << "Options:" << std::endl; + + for (a_it = m_args.begin(); a_it < m_args.end(); a_it++) { + const char* c = (strlen(a_it->shortname) == 1) ? a_it->shortname : " "; + std::cerr << ((strcmp(c, " ") == 0) ? " " : "-") << c + << " | --" << a_it->longname + << "\t" << a_it->description + << std::endl; + } + + std::cerr << std::endl; +} + +bool Appl::parseArgs(int argc, char* argv[]) +{ + std::vector _argv(argv, argv + argc); + m_argc = argc; + m_argv = _argv; + + for (int i = 1; i < m_argc; i++) { + + // find option with long format '--' + if (m_argv[i].rfind("--") == 0 && m_argv[i].size() > 2) { + // is next item an added argument? + if (i+1 < m_argc && m_argv[i+1].rfind("-", 0) == std::string::npos) { + if (checkArg(m_argv[i].substr(2), m_argv[i+1]) == false) + return false; + } else { + if (checkArg(m_argv[i].substr(2), "") == false) + return false; + } + + // find option with short format '-' + } else if (m_argv[i].rfind("-") == 0 && m_argv[i].size() > 1) { + + // walk through all characters + for (size_t j = 1; j < m_argv[i].size(); j++) { + + // only last charater could have an argument + if (i+1 < m_argc && m_argv[i+1].rfind("-", 0) == std::string::npos + && j+1 == m_argv[i].size()) { + if (checkArg(m_argv[i].substr(j,1), m_argv[i+1]) == false) + return false; + } else { + if (checkArg(m_argv[i].substr(j,1), "") == false) + return false; + } + } + } + + } + return true; +} + +void Appl::printSettings() +{ + std::cerr << std::endl << "Settings:" << std::endl; + + for (a_it = m_args.begin(); a_it < m_args.end(); a_it++) { + const char* c = (strlen(a_it->shortname) == 1) ? a_it->shortname : " "; + std::cerr << ((strcmp(c, " ") == 0) ? " " : "-") << c + << " | --" << a_it->longname + << " = "; + if (a_it->datatype == type_bool) { + if (getParam(a_it->name) == true) + std::cerr << "yes" << std::endl; + else + std::cerr << "no" << std::endl; + } + else if (a_it->datatype == type_int) { + std::cerr << getParam(a_it->name) << std::endl; + } + else if (a_it->datatype == type_long) { + std::cerr << getParam(a_it->name) << std::endl; + } + else if (a_it->datatype == type_float) { + std::cerr << getParam(a_it->name) << std::endl; + } + else if (a_it->datatype == type_string) { + std::cerr << getParam(a_it->name) << std::endl; + } + + } + + std::cerr << std::endl; +} + +bool Appl::checkArg(const std::string& name, const std::string& arg) +{ + for (a_it = m_args.begin(); a_it < m_args.end(); a_it++) { + if (a_it->shortname == name || a_it->longname == name) { + if (a_it->optiontype == opt_mandatory && arg.size() == 0) { + std::cerr << std::endl << "option requires an argument '" + << name << "'" << std::endl; + return false; + } + + if ((a_it->optiontype == opt_optional && arg.size() != 0) + || a_it->optiontype != opt_optional) + addParam(a_it->name, arg, a_it->datatype); + + return true; + } + } + + std::cerr << m_argv[0].substr(2) << ": Unknown Option -- " << name << std::endl; + return false; +} + +void Appl::addParam(const char* name, const std::string arg, Datatype datatype) +{ + switch (datatype) { + case type_bool: + m_params[name] = true; + break; + case type_int: + m_params[name] = strtol(arg.c_str(), NULL, 10); + break; + case type_long: + m_params[name] = strtol(arg.c_str(), NULL, 10); + break; + case type_float: + m_params[name] = static_cast(strtod(arg.c_str(), NULL)); + break; + case type_string: + m_params[name] = arg.c_str(); + break; + default: + break; + } +} + + diff --git a/utils/appl.h b/utils/appl.h new file mode 100644 index 00000000..7f8d4d09 --- /dev/null +++ b/utils/appl.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef APPL_H_ +#define APPL_H_ + +#include +#include +#include +#include + +class Appl +{ + +private: + struct Option; + +public: + enum Datatype { type_none, type_bool, type_int, type_long, type_float, type_string }; + enum Optiontype { opt_none, opt_optional, opt_mandatory }; + + union Param { + bool b; + int i; + long l; + float f; + const char* c; + + Param() { memset(this, 0, sizeof(Param)); } + Param(bool _b) : b(_b) {} + Param(int _i) : i(_i) {} + Param(long _l) : l(_l) {} + Param(float _f) : f(_f) {} + Param(const char* _c) : c(_c) {} + }; + + template + T getParam(const char* name) + { + p_it = m_params.find(name); + return (reinterpret_cast(p_it->second)); + } + + static Appl& Instance(); + + ~Appl(); + + void addItem(const char* name, Param param, const char* shortname, + const char* longname, const char* description, + Datatype datatype, Optiontype optiontype); + + void printArgs(); + + bool parseArgs(int argc, char* argv[]); + void printSettings(); + +private: + Appl() {} + Appl(const Appl&); + Appl& operator= (const Appl&); + + struct Arg { + const char* name; + const char* shortname; + const char* longname; + const char* description; + Datatype datatype; + Optiontype optiontype; + }; + + int m_argc; + std::vector m_argv; + + std::vector m_args; + std::vector::const_iterator a_it; + + std::map m_params; + std::map::iterator p_it; + + bool checkArg(const std::string& name, const std::string& arg); + + void addParam(const char* name, Param param) { m_params[name] = param; } + + void addParam(const char* name, const std::string arg, Datatype datatype); +}; + +#endif // APPL_H_ diff --git a/utils/daemon.cpp b/utils/daemon.cpp new file mode 100644 index 00000000..73cc07cc --- /dev/null +++ b/utils/daemon.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "daemon.h" +#include +#include +#include +#include +#include +#include +#include + +Daemon& Daemon::Instance() +{ + static Daemon instance; + return instance; +} + +void Daemon::run(const char* file) +{ + m_status = false; + m_pidfile = file; + m_pidfd = 0; + + pid_t pid; + + // fork off the parent process + pid = fork(); + + if (pid < 0) { + std::cerr << "daemon fork() failed." << std::endl; + exit(EXIT_FAILURE); + } + + // If we got a good PID, then we can exit the parent process + if (pid > 0) { + // printf("Child process created: %d\n", pid); + exit(EXIT_SUCCESS); + } + + // At this point we are executing as the child process + + // Set file permissions 750 + umask(027); + + // Create a new SID for the child process and + // detach the process from the parent (normally a shell) + if (setsid() < 0) { + std::cerr << "daemon setsid() failed." << std::endl; + exit(EXIT_FAILURE); + } + + // Change the current working directory. This prevents the current + // directory from being locked; hence not being able to remove it. + if (chdir("/tmp") < 0) { //DAEMON_WORKDIR + std::cerr << "daemon chdir() failed." << std::endl; + exit(EXIT_FAILURE); + } + + // Close stdin, stdout and stderr + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + // write pidfile and try to lock it + if (pidfile_open() == false) { + std::cerr << "can't open pidfile: %s" << m_pidfile << std::endl; + exit(EXIT_FAILURE); + } + + m_status = true; +} + +bool Daemon::pidfile_open() +{ + char pid[10]; + + m_pidfd = open(m_pidfile, O_RDWR|O_CREAT, 0600); + if (m_pidfd < 0) + return false; + + if (lockf(m_pidfd, F_TLOCK, 0) < 0) + return false; + + sprintf(pid, "%d\n", getpid()); + if (write(m_pidfd, pid, strlen(pid)) < 0) + return false; + + return true; +} + +bool Daemon::pidfile_close() +{ + if (close(m_pidfd) < 0) + return false; + + if (remove(m_pidfile) < 0) + return false; + + return true; +} diff --git a/utils/daemon.h b/utils/daemon.h new file mode 100644 index 00000000..2234557b --- /dev/null +++ b/utils/daemon.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef DAEMON_H_ +#define DAEMON_H_ + +class Daemon +{ + +public: + static Daemon& Instance(); + ~Daemon() {} + + void run(const char* file); + void stop() { pidfile_close(); } + bool status() { return m_status; } + +private: + bool m_status; + const char* m_pidfile; + int m_pidfd; + + Daemon() {} + Daemon(const Daemon&); + Daemon& operator= (const Daemon&); + + bool pidfile_open(); + bool pidfile_close(); + +}; + +#endif // DAEMON_H_ diff --git a/utils/logger.cpp b/utils/logger.cpp new file mode 100644 index 00000000..139994cb --- /dev/null +++ b/utils/logger.cpp @@ -0,0 +1,237 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "logger.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char* AreaNames[Size_of_Area] = { "bas", "net", "bus", "cyc" }; +static const char* LevelNames[Size_of_Level] = { "error", "event", "trace", "debug" }; + +int calcArea(const std::string area) +{ + int m_area = 0; + + // prepare data + std::string token; + std::istringstream stream(area); + std::vector cmd; + + while (std::getline(stream, token, ',') != 0) + cmd.push_back(token); + + for (std::vector::iterator it = cmd.begin() ; it != cmd.end(); ++it) + for (int i = 0; i < Size_of_Area; i++) { + if (strcasecmp("all", it->c_str()) == 0) + return (pow(2, (int)Size_of_Area) - 1); + + if (strcasecmp(AreaNames[i], it->c_str()) == 0) + m_area += pow(2, i); + } + + return m_area; +} + +int calcLevel(const std::string level) +{ + int m_level = event; + for (int i = 0; i < Size_of_Level; i++) + if (strcasecmp(LevelNames[i], level.c_str()) == 0) + return i; + + return m_level; +} + + +LogMessage::LogMessage(const int area, const int level, const std::string text, const Status status) + : m_area(area), m_level(level), m_text(text), m_status(status) +{ + char time[24]; + struct timeval tv; + struct timezone tz; + struct tm* tm; + + gettimeofday(&tv, &tz); + tm = localtime(&tv.tv_sec); + + sprintf(&time[0], "%04d-%02d-%02d %02d:%02d:%02d.%03ld", + tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000); + + m_time = std::string(time); +} + + + +void LogSink::addMessage(const LogMessage& message) +{ + LogMessage* tmp = new LogMessage(LogMessage(message)); + m_queue.add((tmp)); +} + +void* LogSink::run() +{ + while (1) { + LogMessage* message = m_queue.remove(); + if (message->getStatus() == LogMessage::End) { + delete message; + while (m_queue.size() == true) { + LogMessage* message = m_queue.remove(); + write(*message); + delete message; + } + return NULL; + } + + write(*message); + delete message; + } + return NULL; +} + + + +int LogConsole::m_numInstance = 0; + +void LogConsole::write(const LogMessage& message) const +{ + std::cout << message.getTime() << " [" + << AreaNames[(int)log2(message.getArea())] << " " + << LevelNames[message.getLevel()] << "] " + << message.getText() << std::endl; +} + + + +int LogFile::m_numInstance = 0; + +void LogFile::write(const LogMessage& message) const +{ + std::fstream file(m_filename.c_str(), std::ios::out | std::ios::app); + + if (file.is_open() == true) { + file << message.getTime() << " [" + << AreaNames[(int)log2(message.getArea())] << " " + << LevelNames[message.getLevel()] << "] " + << message.getText() << std::endl; + file.close(); + } +} + + + +LogInstance& LogInstance::Instance() +{ + static LogInstance instance; + return (instance); +} + +LogInstance::~LogInstance() +{ + while (m_sinks.empty() == false) + *this -= *(m_sinks.begin()); +} + +LogInstance& LogInstance::operator+= (LogSink* sink) +{ + sinkCI_t itEnd = m_sinks.end(); + sinkCI_t it = std::find(m_sinks.begin(), itEnd, sink); + + if (it == itEnd) + m_sinks.push_back(sink); + + return (*this); +} + +LogInstance& LogInstance::operator-= (const LogSink* sink) +{ + sinkCI_t itEnd = m_sinks.end(); + sinkCI_t it = std::find(m_sinks.begin(), itEnd, sink); + + if (it == itEnd) + return (*this); + + m_sinks.erase(it); + + delete (sink); + + return (*this); +} + +void LogInstance::log(const int area, const int level, const std::string& data, ...) +{ + if (m_running == true) { + char* tmp; + va_list ap; + va_start(ap, data); + + if (vasprintf(&tmp, data.c_str(), ap) != -1) { + std::string buffer(tmp); + m_messages.add(new LogMessage(LogMessage(area, level, buffer, LogMessage::Run))); + } + + va_end(ap); + free(tmp); + } + +} + +void* LogInstance::run() +{ + m_running = true; + + while (m_running == true) { + LogMessage* message = m_messages.remove(); + + sinkCI_t iter = m_sinks.begin(); + + for (; iter != m_sinks.end(); ++iter) { + if (*iter != 0) { + + if (((*iter)->getAreas() & message->getArea() + && (*iter)->getLevel() >= message->getLevel()) + && message->getStatus() == LogMessage::Run) { + (*iter)->addMessage(*message); + } else if (message->getStatus() == LogMessage::End) { + (*iter)->addMessage(*message); + m_running = false; + } + + } + } + + delete message; + + } + return NULL; +} + +void LogInstance::stop() +{ + m_messages.add(new LogMessage(LogMessage(bas, error, "", LogMessage::End))); + // TODO: Improve this method + usleep(100000); +} diff --git a/utils/logger.h b/utils/logger.h new file mode 100644 index 00000000..4bb543ae --- /dev/null +++ b/utils/logger.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include "wqueue.h" +#include "thread.h" +#include +#include +#include +#include +#include + +enum Area { bas=1, net=2, bus=4, cyc=8, all=15, Size_of_Area=4 }; +enum Level { error=0, event, trace, debug, Size_of_Level }; + +int calcArea(const std::string area); +int calcLevel(const std::string level); + + +class LogMessage +{ + +public: + enum Status { Run, End }; + + LogMessage(const int area, const int level, const std::string text, const Status status); + + ~LogMessage() {} + + LogMessage(const LogMessage& src) + : m_area(src.m_area), m_level(src.m_level), m_text(src.m_text), + m_status(src.m_status), m_time(src.m_time) {} + + void operator= (const LogMessage& src) + { m_area = src.m_area; m_level = src.m_level; m_text = src.m_text; + m_status = src.m_status; m_time = src.m_time; } + + int getArea() const { return (m_area); } + int getLevel() const { return(m_level); } + std::string getText() const { return (m_text.c_str()); } + Status getStatus() const { return (m_status); } + std::string getTime() const { return (m_time.c_str()); } + +private: + int m_area; + int m_level; + std::string m_text; + Status m_status; + std::string m_time; + +}; + +enum Type { Console, Logfile }; + +class LogSink : public Thread +{ + +public: + LogSink(const int areas, const int level, const Type type, const char* name) + : m_areas(areas), m_level(level), m_type(type), m_name(name) {} + + virtual ~LogSink() {} + + void addMessage(const LogMessage& message); + + void* run(); + + int getAreas() const { return (m_areas); } + void setAreas(const int& areas) { m_areas = areas; } + + int getLevel() const { return (m_level); } + void setLevel(const int& level) { m_level = level; } + + Type getType() const { return (m_type); } + const char* getName() const { return (m_name.c_str()); } + +protected: + WQueue m_queue; + +private: + int m_areas; + int m_level; + Type m_type; + std::string m_name; + + virtual void write(const LogMessage& message) const = 0; + +}; + +class LogConsole : public LogSink +{ + +public: + LogConsole(const int areas, const int level, const char* name) + : LogSink(areas, level, Console, name), m_instance(++m_numInstance) + { this->start(name); } + + ~LogConsole() {} + +private: + const int m_instance; + static int m_numInstance; + + void write(const LogMessage& message) const; + +}; + +class LogFile : public LogSink +{ + +public: + LogFile(const int areas, const int level, const char* name, const char* filename) + : LogSink(areas, level, Logfile, name), m_filename(filename), m_instance(++m_numInstance) + { this->start(name); } + + ~LogFile() {} + +private: + std::string m_filename; + const int m_instance; + static int m_numInstance; + + void write(const LogMessage& message) const; + +}; + +class LogInstance : public Thread +{ + +public: + static LogInstance& Instance(); + + ~LogInstance(); + + LogInstance& operator+= (LogSink* sink); + LogInstance& operator-= (const LogSink* sink); + + void log(const int area, const int level, const std::string& text, ...); + + int getNumberOfSinks() const { return(m_sinks.size()); } + LogSink* getSink(const int Index) const { return(m_sinks[Index]); } + + void* run(); + + void stop(); + +private: + LogInstance() {} + LogInstance(const LogInstance&); + LogInstance& operator= (const LogInstance&); + + typedef std::vector sink_t; + typedef std::vector::iterator sinkCI_t; + + sink_t m_sinks; + + WQueue m_messages; + + bool m_running; + +}; + +#endif // LOGGER_H_ diff --git a/utils/notify.h b/utils/notify.h new file mode 100644 index 00000000..acd5890d --- /dev/null +++ b/utils/notify.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef NOTIFY_H_ +#define NOTIFY_H_ + +#include +#include + +class Notify +{ + +public: + Notify() + { + int pipefd[2]; + int ret = pipe(pipefd); + + if (ret == 0) { + m_recvfd = pipefd[0]; + m_sendfd = pipefd[1]; + + fcntl(m_sendfd, F_SETFL, O_NONBLOCK); + } + + } + virtual ~Notify() { close(m_sendfd); close(m_recvfd); } + + int notifyFD() const { return m_recvfd; } + int notify() const { return write(m_sendfd,"1",1); } + +private: + int m_recvfd; + int m_sendfd; + +}; + +#endif // NOTIFY_H_ + + diff --git a/utils/tcpsocket.cpp b/utils/tcpsocket.cpp new file mode 100644 index 00000000..4a24ea3c --- /dev/null +++ b/utils/tcpsocket.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "tcpsocket.h" +#include +#include +#include + +TCPSocket::TCPSocket(int sfd, struct sockaddr_in* address) : m_sfd(sfd) +{ + char ip[17]; + inet_ntop(AF_INET, (struct in_addr*)&(address->sin_addr.s_addr), ip, sizeof(ip)-1); + m_ip = ip; + m_port = ntohs(address->sin_port); +} + +bool TCPSocket::isValid() +{ + if (fcntl(m_sfd, F_GETFL) == -1) + return false; + else + return true; +} + + +int TCPListener::start() +{ + if (m_listening == true) + return 0; + + m_lfd = socket(AF_INET, SOCK_STREAM, 0); + struct sockaddr_in address; + + memset(&address, 0, sizeof(address)); + + address.sin_family = AF_INET; + address.sin_port = htons(m_port); + + if (m_address.size() > 0) + inet_pton(AF_INET, m_address.c_str(), &(address.sin_addr)); + else + address.sin_addr.s_addr = INADDR_ANY; + + int optval = 1; + setsockopt(m_lfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); + + int result = bind(m_lfd, (struct sockaddr*) &address, sizeof(address)); + if (result != 0) + return result; + + result = listen(m_lfd, 5); + if (result != 0) + return result; + + m_listening = true; + return result; +} + +TCPSocket* TCPListener::newSocket() +{ + if (m_listening == false) + return NULL; + + struct sockaddr_in address; + socklen_t len = sizeof(address); + + memset(&address, 0, sizeof(address)); + + int sfd = accept(m_lfd, (struct sockaddr*) &address, &len); + + if (sfd < 0) + return NULL; + + return new TCPSocket(sfd, &address); +} + diff --git a/utils/tcpsocket.h b/utils/tcpsocket.h new file mode 100644 index 00000000..00f9c141 --- /dev/null +++ b/utils/tcpsocket.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef TCPSOCKET_H_ +#define TCPSOCKET_H_ + +#include +#include +#include +#include + +class TCPSocket +{ + +public: + friend class TCPListener; + + ~TCPSocket() { close(m_sfd); } + + ssize_t recv(char* buffer, size_t len) { return read(m_sfd, buffer, len); } + ssize_t send(const char* buffer, size_t len) { return write(m_sfd, buffer, len); } + + int getPort() const { return m_port; } + std::string getIP() const { return m_ip; } + + int getFD() const { return m_sfd; } + bool isValid(); + +private: + int m_sfd; + int m_port; + std::string m_ip; + + TCPSocket(int sd, struct sockaddr_in* address); + +}; + +class TCPListener +{ + +public: + TCPListener(int port, std::string address) + : m_lfd(0), m_port(port), m_address(address), m_listening(false) {} + + ~TCPListener() { if (m_lfd > 0) {close(m_lfd);} } + + int start(); + TCPSocket* newSocket(); + + int getFD() const { return m_lfd; } + +private: + int m_lfd; + int m_port; + std::string m_address; + bool m_listening; + +}; + +#endif // TCPSOCKET_H_ + diff --git a/utils/thread.cpp b/utils/thread.cpp new file mode 100644 index 00000000..3d913a05 --- /dev/null +++ b/utils/thread.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#include "thread.h" + +static void* runThread(void* arg) +{ + return ((Thread *)arg)->run(); +} + +Thread::~Thread() +{ + if (m_running == true && m_detached == false) + pthread_detach(m_threadid); + + if (m_running == true) + pthread_cancel(m_threadid); +} + +int Thread::start(const char* name) +{ + + int result = pthread_create(&m_threadid, NULL, runThread, this); + + if (result == 0) { + pthread_setname_np(m_threadid, name); + m_running = true; + } + + return result; +} + +int Thread::join() +{ + int result = -1; + + if (m_running == true) { + result = pthread_join(m_threadid, NULL); + + if (result == 0) + m_detached = false; + + } + + return result; +} + +int Thread::detach() +{ + int result = -1; + + if (m_running == true && m_detached == false) { + result = pthread_detach(m_threadid); + + if (result == 0) + m_detached = true; + + } + + return result; +} + diff --git a/utils/thread.h b/utils/thread.h new file mode 100644 index 00000000..b04fe264 --- /dev/null +++ b/utils/thread.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef THREAD_H_ +#define THREAD_H_ + +#include + +class Thread +{ + +public: + Thread() : m_threadid(0), m_running(false), m_detached(false) {} + virtual ~Thread(); + + int start(const char* name); + int join(); + int detach(); + pthread_t self() {return m_threadid; } + + virtual void* run() = 0; + +private: + pthread_t m_threadid; + bool m_running; + bool m_detached; + +}; + +#endif // THREAD_H_ diff --git a/utils/wqueue.h b/utils/wqueue.h new file mode 100644 index 00000000..7a5ac932 --- /dev/null +++ b/utils/wqueue.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) Roland Jax 2012-2014 + * + * This file is part of ebusd. + * + * ebusd 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 + * (at your option) any later version. + * + * ebusd 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 ebusd. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef WQUEUE_H_ +#define WQUEUE_H_ + +#include +#include + +template class WQueue +{ + +public: + WQueue() + { + pthread_mutex_init(&m_mutex, NULL); + pthread_cond_init(&m_condv, NULL); + } + + ~WQueue() + { + pthread_mutex_destroy(&m_mutex); + pthread_cond_destroy(&m_condv); + } + + void add(T item) + { + pthread_mutex_lock(&m_mutex); + + m_queue.push_back(item); + + pthread_cond_signal(&m_condv); + pthread_mutex_unlock(&m_mutex); + } + + T remove() + { + pthread_mutex_lock(&m_mutex); + + while (m_queue.size() == 0) + pthread_cond_wait(&m_condv, &m_mutex); + + T item = m_queue.front(); + m_queue.pop_front(); + + pthread_mutex_unlock(&m_mutex); + + return item; + } + + int size() + { + pthread_mutex_lock(&m_mutex); + + int size = m_queue.size(); + + pthread_mutex_unlock(&m_mutex); + + return size; + } + +private: + std::list m_queue; + pthread_mutex_t m_mutex; + pthread_cond_t m_condv; + +}; + +#endif // WQUEUE_H_