diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..514148b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,79 @@
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+# Precompiled Headers
+*.gch
+*.pch
+# Compiled Dynamic libraries
+*.so
+*.so.1.0.0
+*.dylib
+*.dll
+# Fortran module files
+*.mod
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+# Executables
+*.exe
+*.out
+*.app
+
+*.pydevproject
+.metadata
+.gradle
+lib/
+bin/
+obj/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.settings/
+.loadpath
+# External tool builders
+.externalToolBuilders/
+# Locally stored "Eclipse launch configurations"
+*.launch
+# CDT-specific
+.cproject
+# PDT-specific
+.buildpath
+# sbteclipse plugin
+.target
+# TeXlipse plugin
+.texlipse
+autom4te.cache
+*.in~
+config.log
+homegear
+core
+vgcore.*
+
+#Autotools
+autoscan.*
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache/
+config.*
+configure
+depcomp
+install-sh
+libtool
+ltmain.sh
+cfg/
+m4/
+missing
+stamp-h?
+.deps/
+.dirstamp
+.libs/
+*.l[ao]
+*~
diff --git a/.project b/.project
new file mode 100644
index 0000000..de382b3
--- /dev/null
+++ b/.project
@@ -0,0 +1,41 @@
+
+
+ homegear-enocean
+
+
+
+
+
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder (13).launch
+
+
+
+
+ org.eclipse.ui.externaltools.ExternalToolBuilder
+ full,incremental,
+
+
+ LaunchConfigHandle
+ <project>/.externalToolBuilders/homegear-intertechno-builder.launch
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.core.ccnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..6067ea9
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,3 @@
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4 -I cfg
+SUBDIRS = src
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/bootstrap b/bootstrap
new file mode 100755
index 0000000..a36d6be
--- /dev/null
+++ b/bootstrap
@@ -0,0 +1,7 @@
+#!/bin/sh
+libtoolize || exit 1
+aclocal || exit 1
+autoheader || exit 1
+automake --add-missing || exit 1
+autoconf || exit 1
+#./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --libdir=/usr/lib || exit 1
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..22c79f3
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,65 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT(homegar-intertechno, m4_esyscmd_s([./getVersion.sh]), sathya@laufers.net)
+AC_CONFIG_AUX_DIR(cfg)
+AM_INIT_AUTOMAKE
+AC_CONFIG_SRCDIR([src/MyFamily.h])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+AC_PREFIX_DEFAULT(/usr)
+
+dnl AM_MAINTAINER_MODE
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+AC_PROG_INSTALL
+
+# Libraries
+LT_INIT
+
+# Checks for header files.
+AC_CHECK_HEADERS([stdlib.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_CHECK_HEADER_STDBOOL
+AC_C_INLINE
+AC_C_CONST
+AC_TYPE_INT32_T
+AC_TYPE_INT64_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT64_T
+AC_TYPE_UINT8_T
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_CHOWN
+AC_FUNC_ERROR_AT_LINE
+AC_FUNC_FORK
+AC_CHECK_FUNCS([floor memchr memset pow select socket strchr strerror strstr strtol])
+
+AC_CANONICAL_HOST
+case $host_os in
+ darwin* )
+ CPPFLAGS="$CPPFLAGS -DMACOSSYSTEM"
+ ;;
+ linux*)
+ CPPFLAGS="$CPPFLAGS -DLINUXSYSTEM"
+ ;;
+ *BSD*)
+ CPPFLAGS="$CPPFLAGS -DBSDSYSTEM -D_GLIBCXX_USE_C99 -D_GLIBCXX_USE_C99_MATH -D_GLIBCXX_USE_C99_MATH_TR1 -D_WITH_DPRINTF"
+ ;;
+ *)
+ AC_MSG_ERROR([Your platform is not currently supported])
+ ;;
+esac
+
+#AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [enable debugging, default: no]), [case "${enableval}" in yes) debug=true ;; no) debug=false ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;; esac], [debug=false])
+#AM_CONDITIONAL(DEBUG, test x"$debug" = x"true")
+
+AC_OUTPUT(Makefile src/Makefile)
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..d72e46a
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,5 @@
+homegear-intertechno (0.0.1-1) UNRELEASED; urgency=low
+
+ * Initial release.
+
+ -- Sathya Laufer Sat, 17 Aug 2013 12:00:47 +0200
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+8
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..53713ca
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,14 @@
+Source: homegear-intertechno
+Maintainer: Sathya Laufer
+Section: misc
+Priority: optional
+Standards-Version: 3.9.6
+Build-Depends: debhelper (>= 8), libhomegear-base (= ), libgcrypt20-dev, libgpg-error-dev (>= 1.10), libgnutls28-dev
+Homepage: https://homegear.eu
+
+Package: homegear-intertechno
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libhomegear-base (= ), homegear (= ), libgcrypt20, libgnutlsxx28, libgpg-error0 (>= 1.10)
+Description: Intertechno module for Homegear
+ Homegear is a program to interface your home automation software
+ with your smart home devices.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..ce5ec21
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,36 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: homegear-intertechno
+Upstream-Contact: Sathya Laufer
+
+Files: *
+Copyright: 2013-2016 Sathya Laufer
+License: GPL-3+
+ Homegear 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.
+ .
+ Homegear 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 Homegear. If not, see .
+ .
+ On Debian systems, the full text of the GNU General Public
+ License version 3 can be found in the file
+ `/usr/share/common-licenses/GPL-3'.
+ .
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of portions of this program with the
+ OpenSSL library under certain conditions as described in each
+ individual source file, and distribute linked combinations
+ including the two.
+ You must obey the GNU General Public License in all respects
+ for all of the code used other than OpenSSL. If you modify
+ file(s) with this exception, you may extend this exception to your
+ version of the file(s), but you are not obligated to do so. If you
+ do not wish to do so, delete this exception statement from your
+ version. If you delete this exception statement from all source
+ files in the program, then also delete it here.
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000..87e1bd7
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+case $1 in
+ # Configure this package. If the package must prompt the user for
+ # information, do it here.
+ configure)
+ chown -R homegear:homegear /var/lib/homegear/modules
+ chmod -R 550 /var/lib/homegear/modules
+ homegear -e mls > /dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ homegear -e mld mod_intertechno.so
+ fi
+ echo "##########################################################################"
+ echo "##########################################################################"
+ echo "### Please modify the file /etc/homegear/families/intertechno.conf ###"
+ echo "### according to your needs and restart Homegear. ###"
+ echo "##########################################################################"
+ echo "##########################################################################"
+ ;;
+
+ # Back out of an attempt to upgrade this package FROM THIS VERSION
+ # to version $2. Undo the effects of "prerm upgrade $2".
+ abort-upgrade)
+ ;;
+
+ # Back out of an attempt to remove this package, which was due to
+ # a conflict with package $3 (version $4). Undo the effects of
+ # "prerm remove in-favour $3 $4".
+ abort-remove)
+ ;;
+
+ # Back out of an attempt to deconfigure this package, which was
+ # due to package $6 (version $7) which we depend on being removed
+ # to make way for package $3 (version $4). Undo the effects of
+ # "prerm deconfigure in-favour $3 $4 removing $6 $7".
+ abort-deconfigure)
+ ;;
+
+ *)
+ echo "$0: didn't understand being called with \`$1'" 1>&2
+ exit 1;
+ ;;
+
+esac
+
+#DEBHELPER#
diff --git a/debian/postrm b/debian/postrm
new file mode 100644
index 0000000..9cade8e
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+case "$1" in
+ remove|abort-install|abort-upgrade)
+ # This package is being removed, but its configuration has not yet
+ # been purged.
+
+ ;;
+
+ purge)
+ rm -Rf /etc/homegear/devices/16 > /dev/null 2>&1
+ rm -f /var/lib/homegear/modules/mod_intertechno.so > /dev/null 2>&1
+ ;;
+
+ disappear)
+ ;;
+
+ upgrade)
+ ;;
+
+ failed-upgrade)
+ ;;
+
+ *) echo "$0: didn't understand being called with \`$1'" 1>&2
+ exit 1;;
+esac
+
+exit 0
+
+#DEBHELPER#
diff --git a/debian/preinst b/debian/preinst
new file mode 100644
index 0000000..357d8e9
--- /dev/null
+++ b/debian/preinst
@@ -0,0 +1,15 @@
+#!/bin/sh
+set -e
+
+case "$1" in
+ install)
+ ;;
+
+ upgrade|abort-upgrade)
+ service homegear stop
+ ;;
+esac
+
+#DEBHELPER#
+
+exit 0
\ No newline at end of file
diff --git a/debian/prerm b/debian/prerm
new file mode 100644
index 0000000..728ede3
--- /dev/null
+++ b/debian/prerm
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+case "$1" in
+ remove|purge|abort-install|abort-upgrade)
+ # This package is being removed, but its configuration has not yet
+ # been purged.
+ service homegear stop
+ ;;
+
+ disappear)
+ ;;
+
+ upgrade)
+ ;;
+
+ failed-upgrade)
+ ;;
+
+ *) echo "$0: didn't understand being called with \`$1'" 1>&2
+ exit 1;;
+esac
+
+exit 0
+
+#DEBHELPER#
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..5e0417e
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,20 @@
+#!/usr/bin/make -f
+
+override_dh_auto_install:
+ dh_auto_install
+
+ mkdir -p $(CURDIR)/debian/homegear-intertechno/etc/homegear/families
+ cp -R $(CURDIR)/misc/Config\ Directory/* $(CURDIR)/debian/homegear-intertechno/etc/homegear/families
+ chmod 755 $(CURDIR)/debian/homegear-intertechno/etc/homegear/families
+ chmod 644 $(CURDIR)/debian/homegear-intertechno/etc/homegear/families/*
+
+ mkdir -p $(CURDIR)/debian/homegear-intertechno/etc/homegear/devices/16
+ cp $(CURDIR)/misc/Device\ Description\ Files/* $(CURDIR)/debian/homegear-intertechno/etc/homegear/devices/16
+ chmod 755 $(CURDIR)/debian/homegear-intertechno/etc/homegear/devices/16
+ chmod 644 $(CURDIR)/debian/homegear-intertechno/etc/homegear/devices/16/*
+
+override_dh_strip:
+ dh_strip --dbg-package=homegear-intertechno
+
+%:
+ dh $@ --parallel
diff --git a/debian/source.lintian-overrides b/debian/source.lintian-overrides
new file mode 100644
index 0000000..e69de29
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/getVersion.sh b/getVersion.sh
new file mode 100755
index 0000000..a33c9b5
--- /dev/null
+++ b/getVersion.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+dir=`mktemp -d`
+cat > "$dir/libhomegear-base-version.cpp" <<-'EOF'
+#include "homegear-base/BaseLib.h"
+
+int main(int argc, char** argv)
+{
+ std::cout << BaseLib::Obj::version() << std::endl;
+ return 0;
+}
+EOF
+g++ -std=c++11 -o $dir/libhomegear-base-version $dir/libhomegear-base-version.cpp -lhomegear-base -lgcrypt -lgnutls
+chmod 755 $dir/libhomegear-base-version
+$dir/libhomegear-base-version
+rm -Rf $dir
diff --git a/makeDebug.sh b/makeDebug.sh
new file mode 100755
index 0000000..793050c
--- /dev/null
+++ b/makeDebug.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+if [ -n "$1" ]; then
+ BUILDTHREADS=$1
+else
+ BUILDTHREADS=2
+fi
+
+SCRIPTDIR="$( cd "$(dirname $0)" && pwd )"
+cd $SCRIPTDIR
+rm -Rf autom4te.cache
+./bootstrap || exit 1
+./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --libdir=/usr/lib || exit 1
+CPPFLAGS=-DDEBUG CXXFLAGS="-g -O0" && make -j${BUILDTHREADS} && make install
diff --git a/makeRelease.sh b/makeRelease.sh
new file mode 100755
index 0000000..1a63dcc
--- /dev/null
+++ b/makeRelease.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+if [ -n "$1" ]; then
+ BUILDTHREADS=$1
+else
+ BUILDTHREADS=2
+fi
+SCRIPTDIR="$( cd "$(dirname $0)" && pwd )"
+cd $SCRIPTDIR
+rm -Rf autom4te.cache
+./bootstrap || exit 1
+./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc --libdir=/usr/lib || exit 1
+make -j${BUILDTHREADS} || exit 1
+strip -s src/.libs/mod_enocean.so
+make install
diff --git a/misc/Config Directory/intertechno.conf b/misc/Config Directory/intertechno.conf
new file mode 100644
index 0000000..6560d66
--- /dev/null
+++ b/misc/Config Directory/intertechno.conf
@@ -0,0 +1,42 @@
+___________________________________________________________________________
+
+------------------------------- Intertechno -------------------------------
+___________________________________________________________________________
+
+#######################################
+################# CUL #################
+#######################################
+
+## The device family this interface is for
+#[CUL]
+
+## Specify an unique id here to identify this device in Homegear
+#id = My-IT-CUL-1
+
+## When default is set to "true" Homegear will assign this device
+## to new peers.
+#default = true
+
+## Options: cul, coc, cc1100
+#deviceType = cul
+
+#device = /dev/ttyACM0
+
+#######################################
+################# CUL #################
+#######################################
+
+## The device family this interface is for
+#[CUL]
+
+## Specify an unique id here to identify this device in Homegear
+#id = My-IT-CUL-2
+
+## When default is set to "true" Homegear will assign this device
+## to new peers.
+#default = true
+
+## Options: cul, coc, cc1100
+#deviceType = cul
+
+#device = /dev/ttyACM1
diff --git a/misc/Device Description Files/Switch.xml b/misc/Device Description Files/Switch.xml
new file mode 100644
index 0000000..9f858b5
--- /dev/null
+++ b/misc/Device Description Files/Switch.xml
@@ -0,0 +1,100 @@
+
+
+
+
+ Intertechno Switch
+ 1
+
+
+
+
+
+ true
+
+ IntertechnoConfig
+ maint_ch_values
+
+
+ IntertechnoVariables
+
+
+
+
+
+
+
+ true
+ false
+ true
+
+
+
+ internal
+
+
+
+
+ true
+ true
+ true
+ true
+
+
+
+ internal
+
+
+
+
+
+
+
+ false
+ true
+
+
+
+ command
+
+
+
+
+ false
+ true
+
+
+
+ command
+
+
+
+
+ true
+ true
+
+
+
+ command
+
+
+
+
+ false
+ true
+
+
+
+ command
+
+
+
+
+
diff --git a/src/Factory.cpp b/src/Factory.cpp
new file mode 100644
index 0000000..d9a6f37
--- /dev/null
+++ b/src/Factory.cpp
@@ -0,0 +1,57 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "Factory.h"
+#include "../config.h"
+#include "GD.h"
+
+BaseLib::Systems::DeviceFamily* MyFactory::createDeviceFamily(BaseLib::Obj* bl, BaseLib::Systems::DeviceFamily::IFamilyEventSink* eventHandler)
+{
+ return new MyFamily::MyFamily(bl, eventHandler);
+}
+
+std::string getVersion()
+{
+ return VERSION;
+}
+
+int32_t getFamilyId()
+{
+ return MY_FAMILY_ID;
+}
+
+std::string getFamilyName()
+{
+ return MY_FAMILY_NAME;
+}
+
+BaseLib::Systems::SystemFactory* getFactory()
+{
+ return (BaseLib::Systems::SystemFactory*)(new MyFactory);
+}
diff --git a/src/Factory.h b/src/Factory.h
new file mode 100644
index 0000000..cf660f1
--- /dev/null
+++ b/src/Factory.h
@@ -0,0 +1,47 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef FACTORY_H
+#define FACTORY_H
+
+#include
+#include "MyFamily.h"
+
+class MyFactory : BaseLib::Systems::SystemFactory
+{
+public:
+ virtual BaseLib::Systems::DeviceFamily* createDeviceFamily(BaseLib::Obj* bl, BaseLib::Systems::DeviceFamily::IFamilyEventSink* eventHandler);
+};
+
+extern "C" std::string getVersion();
+extern "C" int32_t getFamilyId();
+extern "C" std::string getFamilyName();
+extern "C" BaseLib::Systems::SystemFactory* getFactory();
+
+#endif
diff --git a/src/GD.cpp b/src/GD.cpp
new file mode 100644
index 0000000..da07751
--- /dev/null
+++ b/src/GD.cpp
@@ -0,0 +1,39 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "GD.h"
+
+namespace MyFamily
+{
+ BaseLib::Obj* GD::bl = nullptr;
+ MyFamily* GD::family = nullptr;
+ std::map> GD::physicalInterfaces;
+ std::shared_ptr GD::defaultPhysicalInterface;
+ BaseLib::Output GD::out;
+}
diff --git a/src/GD.h b/src/GD.h
new file mode 100644
index 0000000..499b5ab
--- /dev/null
+++ b/src/GD.h
@@ -0,0 +1,59 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef GD_H_
+#define GD_H_
+
+#define MY_FAMILY_ID 16
+#define MY_FAMILY_NAME "Intertechno"
+
+#include
+#include "MyFamily.h"
+#include "PhysicalInterfaces/IIntertechnoInterface.h"
+
+namespace MyFamily
+{
+
+class GD
+{
+public:
+ virtual ~GD();
+
+ static BaseLib::Obj* bl;
+ static MyFamily* family;
+ static std::map> physicalInterfaces;
+ static std::shared_ptr defaultPhysicalInterface;
+ static BaseLib::Output out;
+private:
+ GD();
+};
+
+}
+
+#endif /* GD_H_ */
diff --git a/src/Interfaces.cpp b/src/Interfaces.cpp
new file mode 100644
index 0000000..c76b11e
--- /dev/null
+++ b/src/Interfaces.cpp
@@ -0,0 +1,80 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "Interfaces.h"
+#include "GD.h"
+#include "PhysicalInterfaces/Cul.h"
+
+namespace MyFamily
+{
+
+Interfaces::Interfaces(BaseLib::Obj* bl, std::map physicalInterfaceSettings) : Systems::PhysicalInterfaces(bl, GD::family->getFamily(), physicalInterfaceSettings)
+{
+ create();
+}
+
+Interfaces::~Interfaces()
+{
+}
+
+void Interfaces::create()
+{
+ try
+ {
+ for(std::map::iterator i = _physicalInterfaceSettings.begin(); i != _physicalInterfaceSettings.end(); ++i)
+ {
+ std::shared_ptr device;
+ if(!i->second) continue;
+ GD::out.printDebug("Debug: Creating physical device. Type defined in intertechno.conf is: " + i->second->type);
+ if(i->second->type == "cul") device.reset(new Cul(i->second));
+ else GD::out.printError("Error: Unsupported physical device type: " + i->second->type);
+ if(device)
+ {
+ if(_physicalInterfaces.find(i->second->id) != _physicalInterfaces.end()) GD::out.printError("Error: id used for two devices: " + i->second->id);
+ _physicalInterfaces[i->second->id] = device;
+ GD::physicalInterfaces[i->second->id] = device;
+ if(i->second->isDefault || !GD::defaultPhysicalInterface) GD::defaultPhysicalInterface = device;
+ }
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+}
diff --git a/src/Interfaces.h b/src/Interfaces.h
new file mode 100644
index 0000000..a2a9e38
--- /dev/null
+++ b/src/Interfaces.h
@@ -0,0 +1,52 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef INTERFACES_H_
+#define INTERFACES_H_
+
+#include
+
+namespace MyFamily
+{
+
+using namespace BaseLib;
+
+class Interfaces : public BaseLib::Systems::PhysicalInterfaces
+{
+public:
+ Interfaces(BaseLib::Obj* bl, std::map physicalInterfaceSettings);
+ virtual ~Interfaces();
+
+protected:
+ virtual void create();
+};
+
+}
+
+#endif
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..26262a6
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,12 @@
+AUTOMAKE_OPTIONS = subdir-objects
+
+AM_CPPFLAGS = -Wall -std=c++11 -DFORTIFY_SOURCE=2 -DGCRYPT_NO_DEPRECATED
+AM_LDFLAGS = -Wl,-rpath=/lib/homegear -Wl,-rpath=/usr/lib/homegear -Wl,-rpath=/usr/local/lib/homegear
+LIBS += -Wl,-Bdynamic
+
+libdir = $(localstatedir)/lib/homegear/modules
+lib_LTLIBRARIES = mod_intertechno.la
+mod_intertechno_la_SOURCES = MyFamily.cpp MyFamily.h MyPacket.cpp MyPacket.h MyPeer.cpp MyPeer.h Factory.cpp Factory.h GD.cpp GD.h MyCentral.cpp MyCentral.h Interfaces.h Interfaces.cpp PhysicalInterfaces/IIntertechnoInterface.h PhysicalInterfaces/IIntertechnoInterface.cpp PhysicalInterfaces/Cul.h PhysicalInterfaces/Cul.cpp
+mod_intertechno_la_LDFLAGS =-module -avoid-version -shared
+install-exec-hook:
+ rm -f $(DESTDIR)$(libdir)/mod_intertechno.la
diff --git a/src/MyCentral.cpp b/src/MyCentral.cpp
new file mode 100644
index 0000000..68e758f
--- /dev/null
+++ b/src/MyCentral.cpp
@@ -0,0 +1,948 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "MyCentral.h"
+#include "GD.h"
+
+namespace MyFamily {
+
+MyCentral::MyCentral(ICentralEventSink* eventHandler) : BaseLib::Systems::ICentral(MY_FAMILY_ID, GD::bl, eventHandler)
+{
+ init();
+}
+
+MyCentral::MyCentral(uint32_t deviceID, std::string serialNumber, ICentralEventSink* eventHandler) : BaseLib::Systems::ICentral(MY_FAMILY_ID, GD::bl, deviceID, serialNumber, -1, eventHandler)
+{
+ init();
+}
+
+MyCentral::~MyCentral()
+{
+ dispose();
+}
+
+void MyCentral::dispose(bool wait)
+{
+ try
+ {
+ if(_disposing) return;
+ _disposing = true;
+ GD::out.printDebug("Removing device " + std::to_string(_deviceId) + " from physical device's event queue...");
+ for(std::map>::iterator i = GD::physicalInterfaces.begin(); i != GD::physicalInterfaces.end(); ++i)
+ {
+ //Just to make sure cycle through all physical devices. If event handler is not removed => segfault
+ i->second->removeEventHandler(_physicalInterfaceEventhandlers[i->first]);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyCentral::init()
+{
+ try
+ {
+ if(_initialized) return; //Prevent running init two times
+ _initialized = true;
+
+ for(std::map>::iterator i = GD::physicalInterfaces.begin(); i != GD::physicalInterfaces.end(); ++i)
+ {
+ _physicalInterfaceEventhandlers[i->first] = i->second->addEventHandler((BaseLib::Systems::IPhysicalInterface::IPhysicalInterfaceEventSink*)this);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyCentral::loadPeers()
+{
+ try
+ {
+ std::shared_ptr rows = _bl->db->getPeers(_deviceId);
+ for(BaseLib::Database::DataTable::iterator row = rows->begin(); row != rows->end(); ++row)
+ {
+ int32_t peerID = row->second.at(0)->intValue;
+ GD::out.printMessage("Loading Intertechno peer " + std::to_string(peerID));
+ std::shared_ptr peer(new MyPeer(peerID, row->second.at(2)->intValue, row->second.at(3)->textValue, _deviceId, this));
+ if(!peer->load(this)) continue;
+ if(!peer->getRpcDevice()) continue;
+ std::lock_guard peersGuard(_peersMutex);
+ if(!peer->getSerialNumber().empty()) _peersBySerial[peer->getSerialNumber()] = peer;
+ _peersById[peerID] = peer;
+ _peers[peer->getAddress()] = peer;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+std::shared_ptr MyCentral::getPeer(uint64_t id)
+{
+ try
+ {
+ std::lock_guard peersGuard(_peersMutex);
+ if(_peersById.find(id) != _peersById.end())
+ {
+ std::shared_ptr peer(std::dynamic_pointer_cast(_peersById.at(id)));
+ return peer;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return std::shared_ptr();
+}
+
+std::shared_ptr MyCentral::getPeer(int32_t address)
+{
+ try
+ {
+ std::lock_guard peersGuard(_peersMutex);
+ if(_peers.find(address) != _peers.end())
+ {
+ std::shared_ptr peer(std::dynamic_pointer_cast(_peers.at(address)));
+ return peer;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return std::shared_ptr();
+}
+
+std::shared_ptr MyCentral::getPeer(std::string serialNumber)
+{
+ try
+ {
+ std::lock_guard peersGuard(_peersMutex);
+ if(_peersBySerial.find(serialNumber) != _peersBySerial.end())
+ {
+ std::shared_ptr peer(std::dynamic_pointer_cast(_peersBySerial.at(serialNumber)));
+ return peer;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return std::shared_ptr();
+}
+
+bool MyCentral::onPacketReceived(std::string& senderId, std::shared_ptr packet)
+{
+ try
+ {
+ if(_disposing) return false;
+ PMyPacket myPacket(std::dynamic_pointer_cast(packet));
+ if(!myPacket) return false;
+
+ PMyPeer peer = getPeer(myPacket->senderAddress());
+ if(!peer) return false;
+ if(senderId != peer->getPhysicalInterfaceId()) return false;
+
+ peer->packetReceived(myPacket);
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return false;
+}
+
+void MyCentral::savePeers(bool full)
+{
+ try
+ {
+ std::lock_guard peersGuard(_peersMutex);
+ for(std::map>::iterator i = _peersById.begin(); i != _peersById.end(); ++i)
+ {
+ GD::out.printInfo("Info: Saving Intertechno peer " + std::to_string(i->second->getID()));
+ i->second->save(full, full, full);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyCentral::deletePeer(uint64_t id)
+{
+ try
+ {
+ std::shared_ptr peer(getPeer(id));
+ if(!peer) return;
+ peer->deleting = true;
+ PVariable deviceAddresses(new Variable(VariableType::tArray));
+ deviceAddresses->arrayValue->push_back(PVariable(new Variable(peer->getSerialNumber())));
+
+ PVariable deviceInfo(new Variable(VariableType::tStruct));
+ deviceInfo->structValue->insert(StructElement("ID", PVariable(new Variable((int32_t)peer->getID()))));
+ PVariable channels(new Variable(VariableType::tArray));
+ deviceInfo->structValue->insert(StructElement("CHANNELS", channels));
+
+ for(Functions::iterator i = peer->getRpcDevice()->functions.begin(); i != peer->getRpcDevice()->functions.end(); ++i)
+ {
+ deviceAddresses->arrayValue->push_back(PVariable(new Variable(peer->getSerialNumber() + ":" + std::to_string(i->first))));
+ channels->arrayValue->push_back(PVariable(new Variable(i->first)));
+ }
+
+ raiseRPCDeleteDevices(deviceAddresses, deviceInfo);
+ peer->deleteFromDatabase();
+ _peersMutex.lock();
+ if(_peersBySerial.find(peer->getSerialNumber()) != _peersBySerial.end()) _peersBySerial.erase(peer->getSerialNumber());
+ if(_peersById.find(id) != _peersById.end()) _peersById.erase(id);
+ std::unordered_map>::iterator peerIterator = _peers.find(peer->getAddress());
+ if(peerIterator != _peers.end() && peerIterator->second->getID() == id) _peers.erase(peerIterator);
+ _peersMutex.unlock();
+ GD::out.printMessage("Removed Intertechno peer " + std::to_string(peer->getID()));
+ }
+ catch(const std::exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+std::string MyCentral::handleCliCommand(std::string command)
+{
+ try
+ {
+ std::ostringstream stringStream;
+ std::vector arguments;
+ bool showHelp = false;
+ if(_currentPeer)
+ {
+ if(BaseLib::HelperFunctions::checkCliCommand(command, "unselect", "u", "", 0, arguments, showHelp))
+ {
+ _currentPeer.reset();
+ return "Peer unselected.\n";
+ }
+ return _currentPeer->handleCliCommand(command);
+ }
+ else if(BaseLib::HelperFunctions::checkCliCommand(command, "help", "h", "", 0, arguments, showHelp))
+ {
+ stringStream << "List of commands:" << std::endl << std::endl;
+ stringStream << "For more information about the individual command type: COMMAND help" << std::endl << std::endl;
+ stringStream << "peers create (pc) Creates a new peer" << std::endl;
+ stringStream << "peers list (ls) List all peers" << std::endl;
+ stringStream << "peers remove (pr) Remove a peer" << std::endl;
+ stringStream << "peers select (ps) Select a peer" << std::endl;
+ stringStream << "peers setname (pn) Name a peer" << std::endl;
+ stringStream << "unselect (u) Unselect this device" << std::endl;
+ return stringStream.str();
+ }
+ else if(BaseLib::HelperFunctions::checkCliCommand(command, "peers create", "pc", "", 3, arguments, showHelp))
+ {
+ if(showHelp)
+ {
+ stringStream << "Description: This command creates a new peer." << std::endl;
+ stringStream << "Usage: peers create INTERFACE TYPE ADDRESS" << std::endl << std::endl;
+ stringStream << "Parameters:" << std::endl;
+ stringStream << " INTERFACE: The id of the interface to associate the new device to as defined in the familie's configuration file." << std::endl;
+ stringStream << " TYPE: The 2 byte hexadecimal device type. Example: 0xF602" << std::endl;
+ stringStream << " ADDRESS: The 4 byte address/ID printed on the device. Example: 0x01952B7A" << std::endl;
+ return stringStream.str();
+ }
+
+ std::string interfaceId = arguments.at(0);
+ int32_t deviceType = BaseLib::Math::getNumber(arguments.at(1), true);
+ if(deviceType == 0) return "Invalid device type. Device type has to be provided in hexadecimal format.\n";
+ int32_t address = BaseLib::Math::getNumber(arguments.at(2), true);
+ std::string serial = "ITD" + BaseLib::HelperFunctions::getHexString(address, 8);
+
+ if(peerExists(serial) || peerExists(address)) stringStream << "A peer with this address is already paired to this central." << std::endl;
+ else
+ {
+ std::shared_ptr peer = createPeer(deviceType, address, serial, false);
+ if(!peer || !peer->getRpcDevice()) return "Device type not supported.\n";
+ try
+ {
+ _peersMutex.lock();
+ if(!peer->getSerialNumber().empty()) _peersBySerial[peer->getSerialNumber()] = peer;
+ _peersMutex.unlock();
+ peer->save(true, true, false);
+ peer->initializeCentralConfig();
+ peer->setPhysicalInterfaceId(interfaceId);
+ _peersMutex.lock();
+ _peers[peer->getAddress()] = peer;
+ _peersById[peer->getID()] = peer;
+ _peersMutex.unlock();
+ }
+ catch(const std::exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+
+ PVariable deviceDescriptions(new Variable(VariableType::tArray));
+ deviceDescriptions->arrayValue = peer->getDeviceDescriptions(nullptr, true, std::map());
+ raiseRPCNewDevices(deviceDescriptions);
+ GD::out.printMessage("Added peer " + std::to_string(peer->getID()) + ".");
+ stringStream << "Added peer " << std::to_string(peer->getID()) << " with address 0x" << BaseLib::HelperFunctions::getHexString(address, 8) << " and serial number " << serial << "." << std::dec << std::endl;
+ }
+ return stringStream.str();
+ }
+ else if(BaseLib::HelperFunctions::checkCliCommand(command, "peers remove", "pr", "", 1, arguments, showHelp))
+ {
+ if(showHelp)
+ {
+ stringStream << "Description: This command removes a peer." << std::endl;
+ stringStream << "Usage: peers remove PEERID" << std::endl << std::endl;
+ stringStream << "Parameters:" << std::endl;
+ stringStream << " PEERID: The id of the peer to remove. Example: 513" << std::endl;
+ return stringStream.str();
+ }
+
+ uint64_t peerID = BaseLib::Math::getNumber(arguments.at(0), false);
+ if(peerID == 0) return "Invalid id.\n";
+
+ if(!peerExists(peerID)) stringStream << "This peer is not paired to this central." << std::endl;
+ else
+ {
+ if(_currentPeer && _currentPeer->getID() == peerID) _currentPeer.reset();
+ stringStream << "Removing peer " << std::to_string(peerID) << std::endl;
+ deletePeer(peerID);
+ }
+ return stringStream.str();
+ }
+ else if(BaseLib::HelperFunctions::checkCliCommand(command, "peers list", "pl", "ls", 0, arguments, showHelp))
+ {
+ try
+ {
+ if(showHelp)
+ {
+ stringStream << "Description: This command lists information about all peers." << std::endl;
+ stringStream << "Usage: peers list [FILTERTYPE] [FILTERVALUE]" << std::endl << std::endl;
+ stringStream << "Parameters:" << std::endl;
+ stringStream << " FILTERTYPE: See filter types below." << std::endl;
+ stringStream << " FILTERVALUE: Depends on the filter type. If a number is required, it has to be in hexadecimal format." << std::endl << std::endl;
+ stringStream << "Filter types:" << std::endl;
+ stringStream << " ID: Filter by id." << std::endl;
+ stringStream << " FILTERVALUE: The id of the peer to filter (e. g. 513)." << std::endl;
+ stringStream << " SERIAL: Filter by serial number." << std::endl;
+ stringStream << " FILTERVALUE: The serial number of the peer to filter (e. g. JEQ0554309)." << std::endl;
+ stringStream << " ADDRESS: Filter by saddress." << std::endl;
+ stringStream << " FILTERVALUE: The address of the peer to filter (e. g. 128)." << std::endl;
+ stringStream << " NAME: Filter by name." << std::endl;
+ stringStream << " FILTERVALUE: The part of the name to search for (e. g. \"1st floor\")." << std::endl;
+ stringStream << " TYPE: Filter by device type." << std::endl;
+ stringStream << " FILTERVALUE: The 2 byte device type in hexadecimal format." << std::endl;
+ return stringStream.str();
+ }
+
+ std::string filterType;
+ std::string filterValue;
+
+ if(arguments.size() >= 2)
+ {
+ filterType = BaseLib::HelperFunctions::toLower(arguments.at(0));
+ filterValue = arguments.at(1);
+ if(filterType == "name") BaseLib::HelperFunctions::toLower(filterValue);
+ }
+
+ if(_peersById.empty())
+ {
+ stringStream << "No peers are paired to this central." << std::endl;
+ return stringStream.str();
+ }
+ std::string bar(" │ ");
+ const int32_t idWidth = 8;
+ const int32_t nameWidth = 25;
+ const int32_t serialWidth = 13;
+ const int32_t addressWidth = 8;
+ const int32_t typeWidth1 = 8;
+ const int32_t typeWidth2 = 45;
+ std::string nameHeader("Name");
+ nameHeader.resize(nameWidth, ' ');
+ std::string typeStringHeader("Type Description");
+ typeStringHeader.resize(typeWidth2, ' ');
+ stringStream << std::setfill(' ')
+ << std::setw(idWidth) << "ID" << bar
+ << nameHeader << bar
+ << std::setw(serialWidth) << "Serial Number" << bar
+ << std::setw(addressWidth) << "Address" << bar
+ << std::setw(typeWidth1) << "Type" << bar
+ << typeStringHeader
+ << std::endl;
+ stringStream << "─────────┼───────────────────────────┼───────────────┼──────────┼──────────┼───────────────────────────────────────────────" << std::endl;
+ stringStream << std::setfill(' ')
+ << std::setw(idWidth) << " " << bar
+ << std::setw(nameWidth) << " " << bar
+ << std::setw(serialWidth) << " " << bar
+ << std::setw(addressWidth) << " " << bar
+ << std::setw(typeWidth1) << " " << bar
+ << std::setw(typeWidth2)
+ << std::endl;
+ _peersMutex.lock();
+ for(std::map>::iterator i = _peersById.begin(); i != _peersById.end(); ++i)
+ {
+ if(filterType == "id")
+ {
+ uint64_t id = BaseLib::Math::getNumber(filterValue, false);
+ if(i->second->getID() != id) continue;
+ }
+ else if(filterType == "name")
+ {
+ std::string name = i->second->getName();
+ if((signed)BaseLib::HelperFunctions::toLower(name).find(filterValue) == (signed)std::string::npos) continue;
+ }
+ else if(filterType == "serial")
+ {
+ if(i->second->getSerialNumber() != filterValue) continue;
+ }
+ else if(filterType == "address")
+ {
+ int32_t address = BaseLib::Math::getNumber(filterValue, true);
+ if(i->second->getAddress() != address) continue;
+ }
+ else if(filterType == "type")
+ {
+ int32_t deviceType = BaseLib::Math::getNumber(filterValue, true);
+ if((int32_t)i->second->getDeviceType() != deviceType) continue;
+ }
+
+ stringStream << std::setw(idWidth) << std::setfill(' ') << std::to_string(i->second->getID()) << bar;
+ std::string name = i->second->getName();
+ size_t nameSize = BaseLib::HelperFunctions::utf8StringSize(name);
+ if(nameSize > (unsigned)nameWidth)
+ {
+ name = BaseLib::HelperFunctions::utf8Substring(name, 0, nameWidth - 3);
+ name += "...";
+ }
+ else name.resize(nameWidth + (name.size() - nameSize), ' ');
+ stringStream << name << bar
+ << std::setw(serialWidth) << i->second->getSerialNumber() << bar
+ << std::setw(addressWidth) << BaseLib::HelperFunctions::getHexString(i->second->getAddress(), 8) << bar
+ << std::setw(typeWidth1) << BaseLib::HelperFunctions::getHexString(i->second->getDeviceType(), 6) << bar;
+ if(i->second->getRpcDevice())
+ {
+ PSupportedDevice type = i->second->getRpcDevice()->getType(i->second->getDeviceType(), i->second->getFirmwareVersion());
+ std::string typeID;
+ if(type) typeID = type->description;
+ if(typeID.size() > (unsigned)typeWidth2)
+ {
+ typeID.resize(typeWidth2 - 3);
+ typeID += "...";
+ }
+ else typeID.resize(typeWidth2, ' ');
+ stringStream << std::setw(typeWidth2) << typeID;
+ }
+ else stringStream << std::setw(typeWidth2);
+ stringStream << std::endl << std::dec;
+ }
+ _peersMutex.unlock();
+ stringStream << "─────────┴───────────────────────────┴───────────────┴──────────┴──────────┴───────────────────────────────────────────────" << std::endl;
+
+ return stringStream.str();
+ }
+ catch(const std::exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ }
+ else if(command.compare(0, 13, "peers setname") == 0 || command.compare(0, 2, "pn") == 0)
+ {
+ uint64_t peerID = 0;
+ std::string name;
+
+ std::stringstream stream(command);
+ std::string element;
+ int32_t offset = (command.at(1) == 'n') ? 0 : 1;
+ int32_t index = 0;
+ while(std::getline(stream, element, ' '))
+ {
+ if(index < 1 + offset)
+ {
+ index++;
+ continue;
+ }
+ else if(index == 1 + offset)
+ {
+ if(element == "help") break;
+ else
+ {
+ peerID = BaseLib::Math::getNumber(element, false);
+ if(peerID == 0) return "Invalid id.\n";
+ }
+ }
+ else if(index == 2 + offset) name = element;
+ else name += ' ' + element;
+ index++;
+ }
+ if(index == 1 + offset)
+ {
+ stringStream << "Description: This command sets or changes the name of a peer to identify it more easily." << std::endl;
+ stringStream << "Usage: peers setname PEERID NAME" << std::endl << std::endl;
+ stringStream << "Parameters:" << std::endl;
+ stringStream << " PEERID:\tThe id of the peer to set the name for. Example: 513" << std::endl;
+ stringStream << " NAME:\tThe name to set. Example: \"1st floor light switch\"." << std::endl;
+ return stringStream.str();
+ }
+
+ if(!peerExists(peerID)) stringStream << "This peer is not paired to this central." << std::endl;
+ else
+ {
+ std::shared_ptr peer = getPeer(peerID);
+ peer->setName(name);
+ stringStream << "Name set to \"" << name << "\"." << std::endl;
+ }
+ return stringStream.str();
+ }
+ else if(command.compare(0, 12, "peers select") == 0 || command.compare(0, 2, "ps") == 0)
+ {
+ uint64_t id = 0;
+
+ std::stringstream stream(command);
+ std::string element;
+ int32_t offset = (command.at(1) == 's') ? 0 : 1;
+ int32_t index = 0;
+ while(std::getline(stream, element, ' '))
+ {
+ if(index < 1 + offset)
+ {
+ index++;
+ continue;
+ }
+ else if(index == 1 + offset)
+ {
+ if(element == "help") break;
+ id = BaseLib::Math::getNumber(element, false);
+ if(id == 0) return "Invalid id.\n";
+ }
+ index++;
+ }
+ if(index == 1 + offset)
+ {
+ stringStream << "Description: This command selects a peer." << std::endl;
+ stringStream << "Usage: peers select PEERID" << std::endl << std::endl;
+ stringStream << "Parameters:" << std::endl;
+ stringStream << " PEERID:\tThe id of the peer to select. Example: 513" << std::endl;
+ return stringStream.str();
+ }
+
+ _currentPeer = getPeer(id);
+ if(!_currentPeer) stringStream << "This peer is not paired to this central." << std::endl;
+ else
+ {
+ stringStream << "Peer with id " << std::hex << std::to_string(id) << " and device type 0x" << _bl->hf.getHexString(_currentPeer->getDeviceType()) << " selected." << std::dec << std::endl;
+ stringStream << "For information about the peer's commands type: \"help\"" << std::endl;
+ }
+ return stringStream.str();
+ }
+ else return "Unknown command.\n";
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return "Error executing command. See log file for more details.\n";
+}
+
+std::shared_ptr MyCentral::createPeer(uint32_t deviceType, int32_t address, std::string serialNumber, bool save)
+{
+ try
+ {
+ std::shared_ptr peer(new MyPeer(_deviceId, this));
+ peer->setDeviceType(deviceType);
+ peer->setAddress(address);
+ peer->setSerialNumber(serialNumber);
+ peer->setRpcDevice(GD::family->getRpcDevices()->find(deviceType, 0x10, -1));
+ if(!peer->getRpcDevice()) return std::shared_ptr();
+ if(save) peer->save(true, true, false); //Save and create peerID
+ return peer;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return std::shared_ptr();
+}
+
+PVariable MyCentral::createDevice(BaseLib::PRpcClientInfo clientInfo, int32_t deviceType, std::string serialNumber, int32_t address, int32_t firmwareVersion, std::string interfaceId)
+{
+ try
+ {
+ std::string serial = "ITD" + BaseLib::HelperFunctions::getHexString(address, 8);
+ if(peerExists(serial)) return Variable::createError(-5, "This peer is already paired to this central.");
+
+ std::shared_ptr peer = createPeer(deviceType, address, serial, false);
+ if(!peer || !peer->getRpcDevice()) return Variable::createError(-6, "Unknown device type.");
+
+ try
+ {
+ peer->save(true, true, false);
+ peer->initializeCentralConfig();
+ peer->setPhysicalInterfaceId(interfaceId);
+ _peersMutex.lock();
+ _peers[peer->getAddress()] = peer;
+ _peersById[peer->getID()] = peer;
+ _peersBySerial[peer->getSerialNumber()] = peer;
+ _peersMutex.unlock();
+ }
+ catch(const std::exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ _peersMutex.unlock();
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+
+ PVariable deviceDescriptions(new Variable(VariableType::tArray));
+ deviceDescriptions->arrayValue = peer->getDeviceDescriptions(clientInfo, true, std::map());
+ raiseRPCNewDevices(deviceDescriptions);
+ GD::out.printMessage("Added peer " + std::to_string(peer->getID()) + ".");
+
+ return PVariable(new Variable((uint32_t)peer->getID()));
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyCentral::deleteDevice(BaseLib::PRpcClientInfo clientInfo, std::string serialNumber, int32_t flags)
+{
+ try
+ {
+ if(serialNumber.empty()) return Variable::createError(-2, "Unknown device.");
+ std::shared_ptr peer = getPeer(serialNumber);
+ if(!peer) return PVariable(new Variable(VariableType::tVoid));
+
+ return deleteDevice(clientInfo, peer->getID(), flags);
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyCentral::deleteDevice(BaseLib::PRpcClientInfo clientInfo, uint64_t peerID, int32_t flags)
+{
+ try
+ {
+ if(peerID == 0) return Variable::createError(-2, "Unknown device.");
+ std::shared_ptr peer = getPeer(peerID);
+ if(!peer) return PVariable(new Variable(VariableType::tVoid));
+ uint64_t id = peer->getID();
+
+ deletePeer(id);
+
+ if(peerExists(id)) return Variable::createError(-1, "Error deleting peer. See log for more details.");
+
+ return PVariable(new Variable(VariableType::tVoid));
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyCentral::getDeviceInfo(BaseLib::PRpcClientInfo clientInfo, uint64_t id, std::map fields)
+{
+ try
+ {
+ if(id > 0)
+ {
+ std::shared_ptr peer(getPeer(id));
+ if(!peer) return Variable::createError(-2, "Unknown device.");
+
+ return peer->getDeviceInfo(clientInfo, fields);
+ }
+ else
+ {
+ PVariable array(new Variable(VariableType::tArray));
+
+ std::vector> peers;
+ //Copy all peers first, because listDevices takes very long and we don't want to lock _peersMutex too long
+ _peersMutex.lock();
+ for(std::map>::iterator i = _peersById.begin(); i != _peersById.end(); ++i)
+ {
+ peers.push_back(std::dynamic_pointer_cast(i->second));
+ }
+ _peersMutex.unlock();
+
+ for(std::vector>::iterator i = peers.begin(); i != peers.end(); ++i)
+ {
+ //listDevices really needs a lot of resources, so wait a little bit after each device
+ std::this_thread::sleep_for(std::chrono::milliseconds(3));
+ PVariable info = (*i)->getDeviceInfo(clientInfo, fields);
+ if(!info) continue;
+ array->arrayValue->push_back(info);
+ }
+
+ return array;
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyCentral::putParamset(BaseLib::PRpcClientInfo clientInfo, std::string serialNumber, int32_t channel, ParameterGroup::Type::Enum type, std::string remoteSerialNumber, int32_t remoteChannel, PVariable paramset)
+{
+ try
+ {
+ std::shared_ptr peer(getPeer(serialNumber));
+ uint64_t remoteID = 0;
+ if(!remoteSerialNumber.empty())
+ {
+ std::shared_ptr remotePeer(getPeer(remoteSerialNumber));
+ if(!remotePeer) return Variable::createError(-3, "Remote peer is unknown.");
+ remoteID = remotePeer->getID();
+ }
+ if(peer) return peer->putParamset(clientInfo, channel, type, remoteID, remoteChannel, paramset);
+ return Variable::createError(-2, "Unknown device.");
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyCentral::putParamset(BaseLib::PRpcClientInfo clientInfo, uint64_t peerID, int32_t channel, ParameterGroup::Type::Enum type, uint64_t remoteID, int32_t remoteChannel, PVariable paramset)
+{
+ try
+ {
+ std::shared_ptr peer(getPeer(peerID));
+ if(peer) return peer->putParamset(clientInfo, channel, type, remoteID, remoteChannel, paramset);
+ return Variable::createError(-2, "Unknown device.");
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyCentral::setInterface(BaseLib::PRpcClientInfo clientInfo, uint64_t peerId, std::string interfaceId)
+{
+ try
+ {
+ std::shared_ptr peer(getPeer(peerId));
+ if(!peer) return Variable::createError(-2, "Unknown device.");
+ return peer->setInterface(clientInfo, interfaceId);
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+}
diff --git a/src/MyCentral.h b/src/MyCentral.h
new file mode 100644
index 0000000..b0de51a
--- /dev/null
+++ b/src/MyCentral.h
@@ -0,0 +1,78 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef MYCENTRAL_H_
+#define MYCENTRAL_H_
+
+#include "MyPeer.h"
+#include "MyPacket.h"
+#include
+
+#include
+#include
+#include
+
+namespace MyFamily
+{
+
+class MyCentral : public BaseLib::Systems::ICentral
+{
+public:
+ MyCentral(ICentralEventSink* eventHandler);
+ MyCentral(uint32_t deviceType, std::string serialNumber, ICentralEventSink* eventHandler);
+ virtual ~MyCentral();
+ virtual void dispose(bool wait = true);
+
+ std::string handleCliCommand(std::string command);
+ virtual bool onPacketReceived(std::string& senderId, std::shared_ptr packet);
+
+ std::shared_ptr getPeer(uint64_t id);
+ std::shared_ptr getPeer(int32_t address);
+ std::shared_ptr getPeer(std::string serialNumber);
+
+ virtual PVariable createDevice(BaseLib::PRpcClientInfo clientInfo, int32_t deviceType, std::string serialNumber, int32_t address, int32_t firmwareVersion, std::string interfaceId);
+ virtual PVariable deleteDevice(BaseLib::PRpcClientInfo clientInfo, std::string serialNumber, int32_t flags);
+ virtual PVariable deleteDevice(BaseLib::PRpcClientInfo clientInfo, uint64_t peerId, int32_t flags);
+ virtual PVariable getDeviceInfo(BaseLib::PRpcClientInfo clientInfo, uint64_t id, std::map fields);
+ virtual PVariable putParamset(BaseLib::PRpcClientInfo clientInfo, std::string serialNumber, int32_t channel, ParameterGroup::Type::Enum type, std::string remoteSerialNumber, int32_t remoteChannel, PVariable paramset);
+ virtual PVariable putParamset(BaseLib::PRpcClientInfo clientInfo, uint64_t peerId, int32_t channel, ParameterGroup::Type::Enum type, uint64_t remoteId, int32_t remoteChannel, PVariable paramset);
+ virtual PVariable setInterface(BaseLib::PRpcClientInfo clientInfo, uint64_t peerId, std::string interfaceId);
+protected:
+ virtual void init();
+ virtual void loadPeers();
+ virtual void savePeers(bool full);
+ virtual void loadVariables() {}
+ virtual void saveVariables() {}
+ std::shared_ptr createPeer(uint32_t deviceType, int32_t address, std::string serialNumber, bool save = true);
+ void deletePeer(uint64_t id);
+};
+
+}
+
+#endif
diff --git a/src/MyFamily.cpp b/src/MyFamily.cpp
new file mode 100644
index 0000000..66f0771
--- /dev/null
+++ b/src/MyFamily.cpp
@@ -0,0 +1,110 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "GD.h"
+#include "Interfaces.h"
+#include "MyFamily.h"
+#include "MyCentral.h"
+
+namespace MyFamily
+{
+
+MyFamily::MyFamily(BaseLib::Obj* bl, BaseLib::Systems::DeviceFamily::IFamilyEventSink* eventHandler) : BaseLib::Systems::DeviceFamily(bl, eventHandler, MY_FAMILY_ID, MY_FAMILY_NAME)
+{
+ GD::bl = bl;
+ GD::family = this;
+ GD::out.init(bl);
+ GD::out.setPrefix(std::string("Module ") + MY_FAMILY_NAME + ": ");
+ GD::out.printDebug("Debug: Loading module...");
+ _physicalInterfaces.reset(new Interfaces(bl, _settings->getPhysicalInterfaceSettings()));
+}
+
+MyFamily::~MyFamily()
+{
+
+}
+
+void MyFamily::dispose()
+{
+ if(_disposed) return;
+ DeviceFamily::dispose();
+
+ _central.reset();
+}
+
+void MyFamily::createCentral()
+{
+ try
+ {
+ _central.reset(new MyCentral(0, "VIT0000001", this));
+ GD::out.printMessage("Created central with id " + std::to_string(_central->getId()) + ".");
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+std::shared_ptr MyFamily::initializeCentral(uint32_t deviceId, int32_t address, std::string serialNumber)
+{
+ return std::shared_ptr(new MyCentral(deviceId, serialNumber, this));
+}
+
+PVariable MyFamily::getPairingMethods()
+{
+ try
+ {
+ if(!_central) return PVariable(new Variable(VariableType::tArray));
+ PVariable array(new Variable(VariableType::tArray));
+ array->arrayValue->push_back(PVariable(new Variable(std::string("createDevice"))));
+ return array;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+}
diff --git a/src/MyFamily.h b/src/MyFamily.h
new file mode 100644
index 0000000..653a5cd
--- /dev/null
+++ b/src/MyFamily.h
@@ -0,0 +1,57 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef MYFAMILY_H_
+#define MYFAMILY_H_
+
+#include
+
+using namespace BaseLib;
+
+namespace MyFamily
+{
+class MyCentral;
+
+class MyFamily : public BaseLib::Systems::DeviceFamily
+{
+public:
+ MyFamily(BaseLib::Obj* bl, BaseLib::Systems::DeviceFamily::IFamilyEventSink* eventHandler);
+ virtual ~MyFamily();
+ virtual void dispose();
+
+ virtual bool hasPhysicalInterface() { return true; }
+ virtual PVariable getPairingMethods();
+protected:
+ virtual std::shared_ptr initializeCentral(uint32_t deviceId, int32_t address, std::string serialNumber);
+ virtual void createCentral();
+};
+
+}
+
+#endif
diff --git a/src/MyPacket.cpp b/src/MyPacket.cpp
new file mode 100644
index 0000000..7a4f847
--- /dev/null
+++ b/src/MyPacket.cpp
@@ -0,0 +1,94 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "MyPacket.h"
+
+#include "GD.h"
+
+namespace MyFamily
+{
+MyPacket::MyPacket()
+{
+}
+
+MyPacket::MyPacket(int32_t senderAddress, std::string& payload) : _payload(payload)
+{
+ _senderAddress = senderAddress;
+}
+
+MyPacket::~MyPacket()
+{
+ _payload.clear();
+}
+
+std::string MyPacket::hexString()
+{
+ try
+ {
+ if(!_packet.empty()) return _packet;
+ if(_senderAddress & 0xFFFFFC00)
+ {
+ std::cerr << "Moin" << std::hex << _senderAddress << std::dec << std::endl;
+ _packet.reserve(32);
+ for(int32_t i = 29; i >= 4; i--)
+ {
+ _packet.push_back(_senderAddress & (1 << i) ? '1' : '0');
+ }
+ _packet.insert(_packet.end(), _payload.begin(), _payload.end());
+ for(int32_t i = 3; i >= 0; i--)
+ {
+ _packet.push_back(_senderAddress & (1 << i) ? '1' : '0');
+ }
+ }
+ else
+ {
+ _packet.reserve(12);
+ for(int32_t i = 9; i >= 0; i--)
+ {
+ _packet.push_back(_senderAddress & (1 << i) ? '1' : '0');
+ }
+ _packet.insert(_packet.end(), _payload.begin(), _payload.end());
+ }
+ return _packet;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return "";
+}
+}
diff --git a/src/MyPacket.h b/src/MyPacket.h
new file mode 100644
index 0000000..abcd6ac
--- /dev/null
+++ b/src/MyPacket.h
@@ -0,0 +1,54 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef MYPACKET_H_
+#define MYPACKET_H_
+
+#include
+
+namespace MyFamily
+{
+
+class MyPacket : public BaseLib::Systems::Packet
+{
+ public:
+ MyPacket();
+ MyPacket(int32_t senderAddress, std::string& payload);
+ virtual ~MyPacket();
+
+ std::string hexString();
+ protected:
+ std::string _packet;
+ std::string _payload;
+};
+
+typedef std::shared_ptr PMyPacket;
+
+}
+#endif
diff --git a/src/MyPeer.cpp b/src/MyPeer.cpp
new file mode 100644
index 0000000..6e57b36
--- /dev/null
+++ b/src/MyPeer.cpp
@@ -0,0 +1,704 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "MyPeer.h"
+
+#include "GD.h"
+#include "MyPacket.h"
+#include "MyCentral.h"
+
+namespace MyFamily
+{
+std::shared_ptr MyPeer::getCentral()
+{
+ try
+ {
+ if(_central) return _central;
+ _central = GD::family->getCentral();
+ return _central;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return std::shared_ptr();
+}
+
+MyPeer::MyPeer(uint32_t parentID, IPeerEventSink* eventHandler) : BaseLib::Systems::Peer(GD::bl, parentID, eventHandler)
+{
+ init();
+}
+
+MyPeer::MyPeer(int32_t id, int32_t address, std::string serialNumber, uint32_t parentID, IPeerEventSink* eventHandler) : BaseLib::Systems::Peer(GD::bl, id, address, serialNumber, parentID, eventHandler)
+{
+ init();
+}
+
+MyPeer::~MyPeer()
+{
+ try
+ {
+ dispose();
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyPeer::init()
+{
+ try
+ {
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyPeer::dispose()
+{
+ if(_disposing) return;
+ Peer::dispose();
+}
+
+void MyPeer::homegearStarted()
+{
+ try
+ {
+ Peer::homegearStarted();
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyPeer::homegearShuttingDown()
+{
+ try
+ {
+ _shuttingDown = true;
+ Peer::homegearShuttingDown();
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+std::string MyPeer::handleCliCommand(std::string command)
+{
+ try
+ {
+ std::ostringstream stringStream;
+
+ if(command == "help")
+ {
+ stringStream << "List of commands:" << std::endl << std::endl;
+ stringStream << "For more information about the individual command type: COMMAND help" << std::endl << std::endl;
+ stringStream << "unselect\t\tUnselect this peer" << std::endl;
+ stringStream << "channel count\t\tPrint the number of channels of this peer" << std::endl;
+ stringStream << "config print\t\tPrints all configuration parameters and their values" << std::endl;
+ return stringStream.str();
+ }
+ if(command.compare(0, 13, "channel count") == 0)
+ {
+ std::stringstream stream(command);
+ std::string element;
+ int32_t index = 0;
+ while(std::getline(stream, element, ' '))
+ {
+ if(index < 2)
+ {
+ index++;
+ continue;
+ }
+ else if(index == 2)
+ {
+ if(element == "help")
+ {
+ stringStream << "Description: This command prints this peer's number of channels." << std::endl;
+ stringStream << "Usage: channel count" << std::endl << std::endl;
+ stringStream << "Parameters:" << std::endl;
+ stringStream << " There are no parameters." << std::endl;
+ return stringStream.str();
+ }
+ }
+ index++;
+ }
+
+ stringStream << "Peer has " << _rpcDevice->functions.size() << " channels." << std::endl;
+ return stringStream.str();
+ }
+ else if(command.compare(0, 12, "config print") == 0)
+ {
+ std::stringstream stream(command);
+ std::string element;
+ int32_t index = 0;
+ while(std::getline(stream, element, ' '))
+ {
+ if(index < 2)
+ {
+ index++;
+ continue;
+ }
+ else if(index == 2)
+ {
+ if(element == "help")
+ {
+ stringStream << "Description: This command prints all configuration parameters of this peer. The values are in BidCoS packet format." << std::endl;
+ stringStream << "Usage: config print" << std::endl << std::endl;
+ stringStream << "Parameters:" << std::endl;
+ stringStream << " There are no parameters." << std::endl;
+ return stringStream.str();
+ }
+ }
+ index++;
+ }
+
+ return printConfig();
+ }
+ else return "Unknown command.\n";
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return "Error executing command. See log file for more details.\n";
+}
+
+std::string MyPeer::printConfig()
+{
+ try
+ {
+ std::ostringstream stringStream;
+ stringStream << "MASTER" << std::endl;
+ stringStream << "{" << std::endl;
+ for(std::unordered_map>::const_iterator i = configCentral.begin(); i != configCentral.end(); ++i)
+ {
+ stringStream << "\t" << "Channel: " << std::dec << i->first << std::endl;
+ stringStream << "\t{" << std::endl;
+ for(std::unordered_map::const_iterator j = i->second.begin(); j != i->second.end(); ++j)
+ {
+ stringStream << "\t\t[" << j->first << "]: ";
+ if(!j->second.rpcParameter) stringStream << "(No RPC parameter) ";
+ for(std::vector::const_iterator k = j->second.data.begin(); k != j->second.data.end(); ++k)
+ {
+ stringStream << std::hex << std::setfill('0') << std::setw(2) << (int32_t)*k << " ";
+ }
+ stringStream << std::endl;
+ }
+ stringStream << "\t}" << std::endl;
+ }
+ stringStream << "}" << std::endl << std::endl;
+
+ stringStream << "VALUES" << std::endl;
+ stringStream << "{" << std::endl;
+ for(std::unordered_map>::const_iterator i = valuesCentral.begin(); i != valuesCentral.end(); ++i)
+ {
+ stringStream << "\t" << "Channel: " << std::dec << i->first << std::endl;
+ stringStream << "\t{" << std::endl;
+ for(std::unordered_map::const_iterator j = i->second.begin(); j != i->second.end(); ++j)
+ {
+ stringStream << "\t\t[" << j->first << "]: ";
+ if(!j->second.rpcParameter) stringStream << "(No RPC parameter) ";
+ for(std::vector::const_iterator k = j->second.data.begin(); k != j->second.data.end(); ++k)
+ {
+ stringStream << std::hex << std::setfill('0') << std::setw(2) << (int32_t)*k << " ";
+ }
+ stringStream << std::endl;
+ }
+ stringStream << "\t}" << std::endl;
+ }
+ stringStream << "}" << std::endl << std::endl;
+
+ return stringStream.str();
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return "";
+}
+
+void MyPeer::setPhysicalInterfaceId(std::string id)
+{
+ if(id.empty() || (GD::physicalInterfaces.find(id) != GD::physicalInterfaces.end() && GD::physicalInterfaces.at(id)))
+ {
+ _physicalInterfaceId = id;
+ setPhysicalInterface(id.empty() ? GD::defaultPhysicalInterface : GD::physicalInterfaces.at(_physicalInterfaceId));
+ saveVariable(19, _physicalInterfaceId);
+ }
+}
+
+void MyPeer::setPhysicalInterface(std::shared_ptr interface)
+{
+ try
+ {
+ if(!interface) return;
+ _physicalInterface = interface;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyPeer::loadVariables(BaseLib::Systems::ICentral* central, std::shared_ptr& rows)
+{
+ try
+ {
+ if(!rows) rows = _bl->db->getPeerVariables(_peerID);
+ Peer::loadVariables(central, rows);
+
+ _rpcDevice = GD::family->getRpcDevices()->find(_deviceType, _firmwareVersion, -1);
+ if(!_rpcDevice) return;
+
+ for(BaseLib::Database::DataTable::iterator row = rows->begin(); row != rows->end(); ++row)
+ {
+ switch(row->second.at(2)->intValue)
+ {
+ case 19:
+ _physicalInterfaceId = row->second.at(4)->textValue;
+ if(!_physicalInterfaceId.empty() && GD::physicalInterfaces.find(_physicalInterfaceId) != GD::physicalInterfaces.end()) setPhysicalInterface(GD::physicalInterfaces.at(_physicalInterfaceId));
+ break;
+ }
+ }
+ if(!_physicalInterface) _physicalInterface = GD::defaultPhysicalInterface;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyPeer::saveVariables()
+{
+ try
+ {
+ if(_peerID == 0) return;
+ Peer::saveVariables();
+ saveVariable(19, _physicalInterfaceId);
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+bool MyPeer::load(BaseLib::Systems::ICentral* central)
+{
+ try
+ {
+ std::shared_ptr rows;
+ loadVariables(central, rows);
+ if(!_rpcDevice)
+ {
+ GD::out.printError("Error loading peer " + std::to_string(_peerID) + ": Device type not found: 0x" + BaseLib::HelperFunctions::getHexString(_deviceType) + " Firmware version: " + std::to_string(_firmwareVersion));
+ return false;
+ }
+
+ initializeTypeString();
+ std::string entry;
+ loadConfig();
+ initializeCentralConfig();
+
+ serviceMessages.reset(new BaseLib::Systems::ServiceMessages(_bl, _peerID, _serialNumber, this));
+ serviceMessages->load();
+
+ std::unordered_map>::iterator channelIterator = configCentral.find(0);
+ if(channelIterator != configCentral.end())
+ {
+ std::unordered_map::iterator parameterIterator = channelIterator->second.find("ADDRESS");
+ if(parameterIterator != channelIterator->second.end() && parameterIterator->second.rpcParameter)
+ {
+ _address = parameterIterator->second.rpcParameter->convertFromPacket(parameterIterator->second.data)->booleanValue;
+ }
+ }
+
+ return true;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return false;
+}
+
+void MyPeer::packetReceived(PMyPacket& packet)
+{
+}
+
+PParameterGroup MyPeer::getParameterSet(int32_t channel, ParameterGroup::Type::Enum type)
+{
+ try
+ {
+ PFunction rpcChannel = _rpcDevice->functions.at(channel);
+ if(type == ParameterGroup::Type::Enum::variables) return rpcChannel->variables;
+ else if(type == ParameterGroup::Type::Enum::config) return rpcChannel->configParameters;
+ else if(type == ParameterGroup::Type::Enum::link) return rpcChannel->linkParameters;
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return PParameterGroup();
+}
+
+bool MyPeer::getAllValuesHook2(PRpcClientInfo clientInfo, PParameter parameter, uint32_t channel, PVariable parameters)
+{
+ try
+ {
+ if(channel == 1)
+ {
+ if(parameter->id == "PEER_ID") parameter->convertToPacket(PVariable(new Variable((int32_t)_peerID)), valuesCentral[channel][parameter->id].data);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return false;
+}
+
+bool MyPeer::getParamsetHook2(PRpcClientInfo clientInfo, PParameter parameter, uint32_t channel, PVariable parameters)
+{
+ try
+ {
+ if(channel == 1)
+ {
+ if(parameter->id == "PEER_ID") parameter->convertToPacket(PVariable(new Variable((int32_t)_peerID)), valuesCentral[channel][parameter->id].data);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return false;
+}
+
+PVariable MyPeer::putParamset(BaseLib::PRpcClientInfo clientInfo, int32_t channel, ParameterGroup::Type::Enum type, uint64_t remoteID, int32_t remoteChannel, PVariable variables, bool onlyPushing)
+{
+ try
+ {
+ if(_disposing) return Variable::createError(-32500, "Peer is disposing.");
+ if(channel < 0) channel = 0;
+ if(remoteChannel < 0) remoteChannel = 0;
+ Functions::iterator functionIterator = _rpcDevice->functions.find(channel);
+ if(functionIterator == _rpcDevice->functions.end()) return Variable::createError(-2, "Unknown channel.");
+ if(type == ParameterGroup::Type::none) type = ParameterGroup::Type::link;
+ PParameterGroup parameterGroup = functionIterator->second->getParameterGroup(type);
+ if(!parameterGroup) return Variable::createError(-3, "Unknown parameter set.");
+ if(variables->structValue->empty()) return PVariable(new Variable(VariableType::tVoid));
+
+ if(type == ParameterGroup::Type::Enum::config)
+ {
+ bool parameterChanged = false;
+ for(Struct::iterator i = variables->structValue->begin(); i != variables->structValue->end(); ++i)
+ {
+ if(i->first.empty() || !i->second) continue;
+ if(configCentral[channel].find(i->first) == configCentral[channel].end()) continue;
+ BaseLib::Systems::RPCConfigurationParameter& parameter = configCentral[channel][i->first];
+ if(!parameter.rpcParameter) continue;
+ if(parameter.rpcParameter->password && i->second->stringValue.empty()) continue; //Don't safe password if empty
+ parameter.rpcParameter->convertToPacket(i->second, parameter.data);
+ if(parameter.databaseID > 0) saveParameter(parameter.databaseID, parameter.data);
+ else saveParameter(0, ParameterGroup::Type::Enum::config, channel, i->first, parameter.data);
+
+ parameterChanged = true;
+ GD::out.printInfo("Info: Parameter " + i->first + " of peer " + std::to_string(_peerID) + " and channel " + std::to_string(channel) + " was set to 0x" + BaseLib::HelperFunctions::getHexString(parameter.data) + ".");
+ }
+
+ if(parameterChanged) raiseRPCUpdateDevice(_peerID, channel, _serialNumber + ":" + std::to_string(channel), 0);
+ }
+ else if(type == ParameterGroup::Type::Enum::variables)
+ {
+ for(Struct::iterator i = variables->structValue->begin(); i != variables->structValue->end(); ++i)
+ {
+ if(i->first.empty() || !i->second) continue;
+ setValue(clientInfo, channel, i->first, i->second, false);
+ }
+ }
+ else
+ {
+ return Variable::createError(-3, "Parameter set type is not supported.");
+ }
+ return PVariable(new Variable(VariableType::tVoid));
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyPeer::setInterface(BaseLib::PRpcClientInfo clientInfo, std::string interfaceId)
+{
+ try
+ {
+ if(!interfaceId.empty() && GD::physicalInterfaces.find(interfaceId) == GD::physicalInterfaces.end())
+ {
+ return Variable::createError(-5, "Unknown physical interface.");
+ }
+ std::shared_ptr interface(GD::physicalInterfaces.at(interfaceId));
+ setPhysicalInterfaceId(interfaceId);
+ return PVariable(new Variable(VariableType::tVoid));
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error.");
+}
+
+PVariable MyPeer::setValue(BaseLib::PRpcClientInfo clientInfo, uint32_t channel, std::string valueKey, PVariable value, bool wait)
+{
+ try
+ {
+ Peer::setValue(clientInfo, channel, valueKey, value, wait); //Ignore result, otherwise setHomegerValue might not be executed
+ if(_disposing) return Variable::createError(-32500, "Peer is disposing.");
+ std::shared_ptr central = std::dynamic_pointer_cast(getCentral());
+ if(!central) return Variable::createError(-32500, "Could not get central object.");;
+ if(valueKey.empty()) return Variable::createError(-5, "Value key is empty.");
+ if(channel == 0 && serviceMessages->set(valueKey, value->booleanValue)) return PVariable(new Variable(VariableType::tVoid));
+ std::unordered_map>::iterator channelIterator = valuesCentral.find(channel);
+ if(channelIterator == valuesCentral.end()) return Variable::createError(-2, "Unknown channel.");
+ std::unordered_map::iterator parameterIterator = channelIterator->second.find(valueKey);
+ if(parameterIterator == valuesCentral[channel].end()) return Variable::createError(-5, "Unknown parameter.");
+ PParameter rpcParameter = parameterIterator->second.rpcParameter;
+ if(!rpcParameter) return Variable::createError(-5, "Unknown parameter.");
+ BaseLib::Systems::RPCConfigurationParameter& parameter = valuesCentral[channel][valueKey];
+ std::shared_ptr> valueKeys(new std::vector());
+ std::shared_ptr> values(new std::vector());
+ if(rpcParameter->readable)
+ {
+ valueKeys->push_back(valueKey);
+ values->push_back(value);
+ }
+ if(rpcParameter->physical->operationType == IPhysical::OperationType::Enum::store)
+ {
+ rpcParameter->convertToPacket(value, parameter.data);
+ if(parameter.databaseID > 0) saveParameter(parameter.databaseID, parameter.data);
+ else saveParameter(0, ParameterGroup::Type::Enum::variables, channel, valueKey, parameter.data);
+ if(!valueKeys->empty())
+ {
+ raiseEvent(_peerID, channel, valueKeys, values);
+ raiseRPCEvent(_peerID, channel, _serialNumber + ":" + std::to_string(channel), valueKeys, values);
+ }
+ return PVariable(new Variable(VariableType::tVoid));
+ }
+ else if(rpcParameter->physical->operationType != IPhysical::OperationType::Enum::command) return Variable::createError(-6, "Parameter is not settable.");
+
+ rpcParameter->convertToPacket(value, parameter.data);
+ if(parameter.databaseID > 0) saveParameter(parameter.databaseID, parameter.data);
+ else saveParameter(0, ParameterGroup::Type::Enum::variables, channel, valueKey, parameter.data);
+ if(_bl->debugLevel >= 4) GD::out.printInfo("Info: " + valueKey + " of peer " + std::to_string(_peerID) + " with serial number " + _serialNumber + ":" + std::to_string(channel) + " was set to 0x" + BaseLib::HelperFunctions::getHexString(parameter.data) + ".");
+
+ PMyPacket packet;
+ if(valueKey == "STATE")
+ {
+ std::string payload;
+ if(value->booleanValue) payload = (_address & 0xFFFFFC00) ? "01" : "FF";
+ else payload = (_address & 0xFFFFFC00) ? "00" : "F0";
+ packet.reset(new MyPacket(_address, payload));
+ }
+ if(valueKey == "GROUP_STATE")
+ {
+ std::string payload;
+ if(value->booleanValue) payload = (_address & 0xFFFFFC00) ? "11" : "FF";
+ else payload = (_address & 0xFFFFFC00) ? "10" : "F0";
+ packet.reset(new MyPacket(_address, payload));
+ }
+ else if(valueKey == "PAIRING")
+ {
+ std::string payload = (_address & 0xFFFFFC00) ? "01" : "FF";
+ packet.reset(new MyPacket(_address, payload));
+ }
+ else if(valueKey == "UNPAIRING")
+ {
+ std::string payload = (_address & 0xFFFFFC00) ? "00" : "F0";
+ packet.reset(new MyPacket(_address, payload));
+ }
+
+ if(packet) _physicalInterface->sendPacket(packet);
+
+ if(!valueKeys->empty())
+ {
+ raiseEvent(_peerID, channel, valueKeys, values);
+ raiseRPCEvent(_peerID, channel, _serialNumber + ":" + std::to_string(channel), valueKeys, values);
+ }
+
+ return PVariable(new Variable(VariableType::tVoid));
+ }
+ catch(const std::exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ GD::out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return Variable::createError(-32500, "Unknown application error. See error log for more details.");
+}
+
+}
diff --git a/src/MyPeer.h b/src/MyPeer.h
new file mode 100644
index 0000000..e14e6bc
--- /dev/null
+++ b/src/MyPeer.h
@@ -0,0 +1,126 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef MYPEER_H_
+#define MYPEER_H_
+
+#include "MyPacket.h"
+#include
+#include "PhysicalInterfaces/IIntertechnoInterface.h"
+
+using namespace BaseLib;
+using namespace BaseLib::DeviceDescription;
+
+namespace MyFamily
+{
+class MyCentral;
+
+class MyPeer : public BaseLib::Systems::Peer, public BaseLib::Rpc::IWebserverEventSink
+{
+public:
+ MyPeer(uint32_t parentID, IPeerEventSink* eventHandler);
+ MyPeer(int32_t id, int32_t address, std::string serialNumber, uint32_t parentID, IPeerEventSink* eventHandler);
+ virtual ~MyPeer();
+ void init();
+ void dispose();
+
+ //Features
+ virtual bool wireless() { return true; }
+ //End features
+
+ //{{{ In table variables
+ std::string getPhysicalInterfaceId() { return _physicalInterfaceId; }
+ void setPhysicalInterfaceId(std::string);
+ //}}}
+
+ std::shared_ptr& getPhysicalInterface() { return _physicalInterface; }
+
+ virtual std::string handleCliCommand(std::string command);
+ void packetReceived(PMyPacket& packet);
+
+ virtual bool load(BaseLib::Systems::ICentral* central);
+ virtual void savePeers() {}
+
+ virtual int32_t getChannelGroupedWith(int32_t channel) { return -1; }
+ virtual int32_t getNewFirmwareVersion() { return 0; }
+ virtual std::string getFirmwareVersionString(int32_t firmwareVersion) { return "1.0"; }
+ virtual bool firmwareUpdateAvailable() { return false; }
+
+ std::string printConfig();
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual void homegearStarted();
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual void homegearShuttingDown();
+
+ //RPC methods
+ virtual PVariable putParamset(BaseLib::PRpcClientInfo clientInfo, int32_t channel, ParameterGroup::Type::Enum type, uint64_t remoteID, int32_t remoteChannel, PVariable variables, bool onlyPushing = false);
+ PVariable setInterface(BaseLib::PRpcClientInfo clientInfo, std::string interfaceId);
+ virtual PVariable setValue(BaseLib::PRpcClientInfo clientInfo, uint32_t channel, std::string valueKey, PVariable value, bool wait);
+ //End RPC methods
+protected:
+ //In table variables:
+ std::string _physicalInterfaceId;
+ //End
+
+ bool _shuttingDown = false;
+ std::shared_ptr _physicalInterface;
+
+ virtual void loadVariables(BaseLib::Systems::ICentral* central, std::shared_ptr& rows);
+ virtual void saveVariables();
+
+ virtual void setPhysicalInterface(std::shared_ptr interface);
+
+ virtual std::shared_ptr getCentral();
+
+ virtual PParameterGroup getParameterSet(int32_t channel, ParameterGroup::Type::Enum type);
+
+ // {{{ Hooks
+ /**
+ * {@inheritDoc}
+ */
+ virtual bool getAllValuesHook2(PRpcClientInfo clientInfo, PParameter parameter, uint32_t channel, PVariable parameters);
+
+ /**
+ * {@inheritDoc}
+ */
+ virtual bool getParamsetHook2(PRpcClientInfo clientInfo, PParameter parameter, uint32_t channel, PVariable parameters);
+ // }}}
+};
+
+typedef std::shared_ptr PMyPeer;
+
+}
+
+#endif
diff --git a/src/PhysicalInterfaces/Cul.cpp b/src/PhysicalInterfaces/Cul.cpp
new file mode 100644
index 0000000..97f7394
--- /dev/null
+++ b/src/PhysicalInterfaces/Cul.cpp
@@ -0,0 +1,158 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "../GD.h"
+#include "Cul.h"
+
+namespace MyFamily
+{
+
+Cul::Cul(std::shared_ptr settings) : IIntertechnoInterface(settings)
+{
+ _settings = settings;
+ _out.init(GD::bl);
+ _out.setPrefix(GD::out.getPrefix() + "Intertechno CUL \"" + settings->id + "\": ");
+
+ signal(SIGPIPE, SIG_IGN);
+}
+
+Cul::~Cul()
+{
+ stopListening();
+}
+
+void Cul::startListening()
+{
+ try
+ {
+ stopListening();
+
+ if(_settings->device.empty())
+ {
+ _out.printError("Error: No device defined for CUL. Please specify it in \"intertechno.conf\".");
+ return;
+ }
+
+ _serial.reset(new BaseLib::SerialReaderWriter(_bl, _settings->device, 57600, 0, true, -1));
+ _serial->openDevice(false, false, false);
+ if(!_serial->isOpen())
+ {
+ _out.printError("Error: Could not open device.");
+ return;
+ }
+
+ _stopCallbackThread = false;
+ _stopped = false;
+ IPhysicalInterface::startListening();
+ }
+ catch(const std::exception& ex)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void Cul::stopListening()
+{
+ try
+ {
+ _stopCallbackThread = true;
+ _bl->threadManager.join(_listenThread);
+ _stopped = true;
+ if(_serial) _serial->closeDevice();
+ IPhysicalInterface::stopListening();
+ }
+ catch(const std::exception& ex)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void Cul::sendPacket(std::shared_ptr packet)
+{
+ try
+ {
+ std::shared_ptr myPacket(std::dynamic_pointer_cast(packet));
+ if(!myPacket) return;
+
+ if(_stopped || !_serial)
+ {
+ _out.printWarning("Warning: !!!Not!!! sending packet " + myPacket->hexString() + ", because device is not open.");
+ return;
+ }
+
+ if(!_serial->isOpen())
+ {
+ _serial->closeDevice();
+ _serial->openDevice(false, false, false);
+ if(!_serial->isOpen())
+ {
+ _out.printError("Error: Could not open device.");
+ return;
+ }
+ }
+
+ std::string hexString = "is" + myPacket->hexString() + "\n";
+ std::vector data;
+ data.insert(data.end(), hexString.begin(), hexString.end());
+
+ _out.printInfo("Info: Sending (" + _settings->id + "): " + packet->hexString());
+
+ _serial->writeData(data);
+ }
+ catch(const std::exception& ex)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(BaseLib::Exception& ex)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ _out.printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+}
diff --git a/src/PhysicalInterfaces/Cul.h b/src/PhysicalInterfaces/Cul.h
new file mode 100644
index 0000000..d8cf133
--- /dev/null
+++ b/src/PhysicalInterfaces/Cul.h
@@ -0,0 +1,58 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef CUL_H_
+#define CUL_H_
+
+#include "../MyPacket.h"
+#include
+#include "IIntertechnoInterface.h"
+
+namespace MyFamily
+{
+
+class Cul : public IIntertechnoInterface
+{
+public:
+ Cul(std::shared_ptr settings);
+ virtual ~Cul();
+
+ virtual void startListening();
+ virtual void stopListening();
+
+ virtual bool isOpen() { return _serial && _serial->isOpen() && !_stopped; }
+
+ virtual void sendPacket(std::shared_ptr packet);
+protected:
+ std::unique_ptr _serial;
+};
+
+}
+
+#endif
diff --git a/src/PhysicalInterfaces/IIntertechnoInterface.cpp b/src/PhysicalInterfaces/IIntertechnoInterface.cpp
new file mode 100644
index 0000000..0b6ae55
--- /dev/null
+++ b/src/PhysicalInterfaces/IIntertechnoInterface.cpp
@@ -0,0 +1,54 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "../GD.h"
+#include "../MyPacket.h"
+#include "IIntertechnoInterface.h"
+
+namespace MyFamily
+{
+
+IIntertechnoInterface::IIntertechnoInterface(std::shared_ptr settings) : IPhysicalInterface(GD::bl, GD::family->getFamily(), settings)
+{
+ _bl = GD::bl;
+
+ if(settings->listenThreadPriority == -1)
+ {
+ settings->listenThreadPriority = 0;
+ settings->listenThreadPolicy = SCHED_OTHER;
+ }
+}
+
+IIntertechnoInterface::~IIntertechnoInterface()
+{
+
+}
+
+
+}
diff --git a/src/PhysicalInterfaces/IIntertechnoInterface.h b/src/PhysicalInterfaces/IIntertechnoInterface.h
new file mode 100644
index 0000000..b5f6775
--- /dev/null
+++ b/src/PhysicalInterfaces/IIntertechnoInterface.h
@@ -0,0 +1,55 @@
+/* Copyright 2013-2016 Sathya Laufer
+ *
+ * Homegear 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.
+ *
+ * Homegear 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 Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef IINTERTECHNOINTERFACE_H_
+#define IINTERTECHNOINTERFACE_H_
+
+#include
+
+namespace MyFamily
+{
+
+class IIntertechnoInterface : public BaseLib::Systems::IPhysicalInterface
+{
+public:
+ IIntertechnoInterface(std::shared_ptr settings);
+ virtual ~IIntertechnoInterface();
+
+ virtual void startListening() {}
+ virtual void stopListening() {}
+
+ virtual void sendPacket(std::shared_ptr packet) {}
+protected:
+ BaseLib::Obj* _bl = nullptr;
+ BaseLib::Output _out;
+};
+
+}
+
+#endif