NEW: ebus-daemon merged into ebusd.
This commit is contained in:
+7
-17
@@ -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
|
||||
|
||||
@@ -1,5 +1 @@
|
||||
ebus Daemon (ebusd) - AUTHORS
|
||||
=============================
|
||||
|
||||
Current maintainer:
|
||||
Roland Jax <roland.jax@liwest.at>
|
||||
Roland Jax <roland.jax@liwest.at>
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
ebus Daemon (ebusd) - ChangeLog
|
||||
===============================
|
||||
ebusd - ChangeLog
|
||||
-----------------
|
||||
|
||||
2014-05-11 Roland Jax <roland.jax@liwest.at>
|
||||
* ebus-daemon merged into ebusd.
|
||||
|
||||
2014-05-11 Roland Jax <roland.jax@liwest.at>
|
||||
* Beta-Test for ebus-daemon started.
|
||||
|
||||
2014-01-09 Roland Jax <roland.jax@liwest.at>
|
||||
* Initial commit.
|
||||
|
||||
---
|
||||
|
||||
2014-03-16:
|
||||
* Specific vaillant data type "ttm" (time table minutes) added.
|
||||
|
||||
+29
-7
@@ -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)
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
ebus Daemon (ebusd) - NEWS
|
||||
==========================
|
||||
ebusd - NEWS
|
||||
------------
|
||||
|
||||
2014-05-11 Roland Jax <roland.jax@liwest.at>
|
||||
* ebus-daemon merged into ebusd.
|
||||
|
||||
2014-05-11 Roland Jax <roland.jax@liwest.at>
|
||||
* Beta-Test for ebus-daemon started.
|
||||
|
||||
---
|
||||
|
||||
2014-03-16:
|
||||
* Specific vaillant data type "ttm" (time table minutes) added.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -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 <roland.jax@liwest.at>\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"
|
||||
+10
-25
@@ -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
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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=""
|
||||
@@ -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
|
||||
@@ -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;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
Binary file not shown.
@@ -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;-;-;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
Binary file not shown.
@@ -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;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
Binary file not shown.
@@ -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;-;-;-;-;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
Binary file not shown.
@@ -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;-;-;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
Binary file not shown.
@@ -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}"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
|
||||
-1279
File diff suppressed because it is too large
Load Diff
-339
@@ -1,339 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <sys/time.h>
|
||||
|
||||
#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_ */
|
||||
-1046
File diff suppressed because it is too large
Load Diff
-291
@@ -1,291 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <sys/time.h>
|
||||
|
||||
#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_ */
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
* 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_ */
|
||||
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
* 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_ */
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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_ */
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <algorithm>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
|
||||
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<Connection*>(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<std::string> 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<const char*>("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<const char*>("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<const char*>("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();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <string>
|
||||
|
||||
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<Message*>* getQueue() { return &m_queue; }
|
||||
void addMessage(Message* message) { m_queue.add(message); }
|
||||
|
||||
private:
|
||||
EBusLoop* m_ebusloop;
|
||||
CYCData* m_cycdata;
|
||||
Commands* m_commands;
|
||||
WQueue<Message*> 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_
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <string>
|
||||
|
||||
using namespace libebus;
|
||||
|
||||
typedef std::map<int, Command*> map_t;
|
||||
typedef map_t::const_iterator mapCI_t;
|
||||
typedef std::pair<int, Command*> 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_
|
||||
-752
@@ -1,752 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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_ */
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <iostream>
|
||||
|
||||
extern LogInstance& L;
|
||||
extern Appl& A;
|
||||
|
||||
EBusLoop::EBusLoop() : m_stop(false)
|
||||
{
|
||||
m_deviceName = A.getParam<const char*>("p_device");
|
||||
|
||||
m_bus = new Bus(m_deviceName,
|
||||
A.getParam<bool>("p_nodevicecheck"),
|
||||
A.getParam<const char*>("p_dumpfile"),
|
||||
A.getParam<long>("p_dumpsize"),
|
||||
A.getParam<bool>("p_dump"));
|
||||
|
||||
m_retries = A.getParam<int>("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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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<std::string> m_cycBuffer;
|
||||
bool m_stop;
|
||||
WQueue<BusCommand*> m_sendBuffer;
|
||||
WQueue<BusCommand*> m_recvBuffer;
|
||||
int m_retries;
|
||||
|
||||
};
|
||||
|
||||
#endif // EBUSLOOP_H_
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <iostream>
|
||||
#include <memory>
|
||||
#include <csignal>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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<bool>("p_help") == true) {
|
||||
A.printArgs();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// print Daemon settings
|
||||
if (A.getParam<bool>("p_settings") == true)
|
||||
A.printSettings();
|
||||
|
||||
// make me Daemon
|
||||
if (A.getParam<bool>("p_foreground") == true) {
|
||||
L += new LogConsole(calcArea(A.getParam<const char*>("p_logarea")),
|
||||
calcLevel(A.getParam<const char*>("p_loglevel")),
|
||||
"logConsole");
|
||||
} else {
|
||||
D.run("/var/run/ebusd.pid");
|
||||
L += new LogFile(calcArea(A.getParam<const char*>("p_logarea")),
|
||||
calcLevel(A.getParam<const char*>("p_loglevel")),
|
||||
"logFile", A.getParam<const char*>("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<const char*>("p_ebusconfdir"), CSV).getCommands();
|
||||
L.log(bas, debug, "ebus configuration dir: %s", A.getParam<const char*>("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<bool>("p_localhost"));
|
||||
|
||||
// create BaseLoop
|
||||
BaseLoop baseloop(ebusloop, cycdata, commands);
|
||||
|
||||
// start Network
|
||||
network->addQueue(baseloop.getQueue());
|
||||
network->start("netListener");
|
||||
|
||||
// start Baseloop
|
||||
baseloop.start();
|
||||
|
||||
shutdown();
|
||||
}
|
||||
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <sstream>
|
||||
#include <cstring>
|
||||
#include <sys/select.h>
|
||||
|
||||
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<int>("p_port"), "127.0.0.1");
|
||||
else
|
||||
m_Listener = new TCPListener(A.getParam<int>("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<Connection*>::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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <list>
|
||||
#include <unistd.h>
|
||||
|
||||
class Connection : public Thread
|
||||
{
|
||||
|
||||
public:
|
||||
Connection(TCPSocket* socket, WQueue<Message*>* 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<Message*>* m_data;
|
||||
WQueue<Message*> 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<Message*>* queue) { m_queue = queue; }
|
||||
|
||||
void* run();
|
||||
void stop() const { m_notify.notify(); usleep(100000); }
|
||||
|
||||
private:
|
||||
std::list<Connection*> m_connections;
|
||||
WQueue<Message*>* m_queue;
|
||||
TCPListener* m_Listener;
|
||||
Notify m_notify;
|
||||
bool m_listening;
|
||||
bool m_running;
|
||||
|
||||
void cleanConnections();
|
||||
|
||||
};
|
||||
|
||||
#endif // NETWORK_H_
|
||||
-414
@@ -1,414 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#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 <cr> 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;
|
||||
}
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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_ */
|
||||
Binary file not shown.
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
|
||||
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<bool>("p_help") == true) {
|
||||
A.printArgs();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
std::string dev(A.getParam<const char*>("p_device"));
|
||||
Port port(dev, true);
|
||||
|
||||
port.open();
|
||||
if(port.isOpen() == true)
|
||||
std::cout << "openPort successful." << std::endl;
|
||||
|
||||
std::fstream file(A.getParam<const char*>("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<unsigned>(byte) << std::endl;
|
||||
|
||||
port.send(&byte, 1);
|
||||
usleep(A.getParam<long>("p_time"));
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
port.close();
|
||||
if(port.isOpen() == false)
|
||||
std::cout << "closePort successful." << std::endl;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
-235
@@ -1,235 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2013 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#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] <ZZ PB SB NN DBx>\n\n"
|
||||
" <ZZ PB SB NN DBx> 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;
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <iostream>
|
||||
#include <iomanip>
|
||||
#include <cstdlib>
|
||||
|
||||
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<std::string> _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<bool>(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<int>(a_it->name) << std::endl;
|
||||
}
|
||||
else if (a_it->datatype == type_long) {
|
||||
std::cerr << getParam<long>(a_it->name) << std::endl;
|
||||
}
|
||||
else if (a_it->datatype == type_float) {
|
||||
std::cerr << getParam<float>(a_it->name) << std::endl;
|
||||
}
|
||||
else if (a_it->datatype == type_string) {
|
||||
std::cerr << getParam<const char*>(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<float>(strtod(arg.c_str(), NULL));
|
||||
break;
|
||||
case type_string:
|
||||
m_params[name] = arg.c_str();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <string>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
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 <typename T>
|
||||
T getParam(const char* name)
|
||||
{
|
||||
p_it = m_params.find(name);
|
||||
return (reinterpret_cast<T&>(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<std::string> m_argv;
|
||||
|
||||
std::vector<Arg> m_args;
|
||||
std::vector<Arg>::const_iterator a_it;
|
||||
|
||||
std::map<const char*, Param> m_params;
|
||||
std::map<const char*, Param>::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_
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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_
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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<std::string> cmd;
|
||||
|
||||
while (std::getline(stream, token, ',') != 0)
|
||||
cmd.push_back(token);
|
||||
|
||||
for (std::vector<std::string>::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);
|
||||
}
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <string>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <cstdarg>
|
||||
|
||||
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<LogMessage*> 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<LogSink*> sink_t;
|
||||
typedef std::vector<LogSink*>::iterator sinkCI_t;
|
||||
|
||||
sink_t m_sinks;
|
||||
|
||||
WQueue<LogMessage*> m_messages;
|
||||
|
||||
bool m_running;
|
||||
|
||||
};
|
||||
|
||||
#endif // LOGGER_H_
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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_
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <fcntl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
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_
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <pthread.h>
|
||||
|
||||
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_
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) Roland Jax 2012-2014 <roland.jax@liwest.at>
|
||||
*
|
||||
* 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 <pthread.h>
|
||||
#include <list>
|
||||
|
||||
template <typename T> 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<T> m_queue;
|
||||
pthread_mutex_t m_mutex;
|
||||
pthread_cond_t m_condv;
|
||||
|
||||
};
|
||||
|
||||
#endif // WQUEUE_H_
|
||||
Reference in New Issue
Block a user