]> rtime.felk.cvut.cz Git - hydro.git/commitdiff
Added monitoring web system. Minor changes in regulator and in control.
authorstefic User <stefic@ubuntu.ubuntu-domain>
Fri, 6 Feb 2009 12:55:03 +0000 (13:55 +0100)
committerstefic User <stefic@ubuntu.ubuntu-domain>
Fri, 6 Feb 2009 12:55:03 +0000 (13:55 +0100)
77 files changed:
app-bohyn/Makefile [new file with mode: 0644]
app-bohyn/Makefile.omk [new file with mode: 0644]
app-bohyn/Makefile.rules [new file with mode: 0644]
app-bohyn/_build/kern/ul_drv/ul_drv/ul_drv_config.h [new file with mode: 0644]
app-bohyn/_build/kern/ul_drv/ul_drv/ul_drv_config.h.stamp [new file with mode: 0644]
app-bohyn/_build/kern/ul_drv/ul_drv_config.h [new file with mode: 0644]
app-bohyn/_build/kern/ul_drv/ul_drv_config.h.stamp [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_drv/ul_drv_config.h [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_drv/ul_drv_config.h.stamp [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_drv_config.h [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_drv_config.h.stamp [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_drv.o [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_drv.o.d [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_log.o [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_log.o.d [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_msg.o [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_msg.o.d [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_oi.o [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_l_oi.o.d [new file with mode: 0644]
app-bohyn/_build/user/ul_drv/ul_lib/ul_lib_config.h.stamp [new file with mode: 0644]
app-bohyn/_compiled/include/ul_l_drv_eth.h [new file with mode: 0644]
app-bohyn/_compiled/include/ul_lib/ul_drvdef.h [new file with mode: 0644]
app-bohyn/_compiled/include/ul_lib/ul_fd.h [new file with mode: 0644]
app-bohyn/_compiled/include/ul_lib/ul_fddir.h [new file with mode: 0644]
app-bohyn/_compiled/include/ul_lib/ul_l_log.h [new file with mode: 0644]
app-bohyn/_compiled/include/ul_lib/ul_lib_config.h [new file with mode: 0644]
app-bohyn/_compiled/include/ul_lib/ulan.h [new file with mode: 0644]
app-bohyn/_compiled/include/ul_msg_buf.h [new file with mode: 0644]
app-bohyn/_compiled/lib/libulan.a [new file with mode: 0644]
app-bohyn/lighttpd_conf/lighttpd.conf [new file with mode: 0644]
app-bohyn/media/arrow_refresh.png [new file with mode: 0644]
app-bohyn/media/js/jquery.js [new file with mode: 0644]
app-bohyn/media/js/nodevar.js [new file with mode: 0644]
app-bohyn/media/styles/main.css [new file with mode: 0644]
app-bohyn/src/Makefile [new file with mode: 0644]
app-bohyn/src/Makefile.omk.bck [new file with mode: 0644]
app-bohyn/src/address_parser.cc [new file with mode: 0644]
app-bohyn/src/address_parser.h [new file with mode: 0644]
app-bohyn/src/address_parser.o [new file with mode: 0644]
app-bohyn/src/defines.h [new file with mode: 0644]
app-bohyn/src/fcgi.cc [new file with mode: 0644]
app-bohyn/src/forms.cc [new file with mode: 0644]
app-bohyn/src/forms.h [new file with mode: 0644]
app-bohyn/src/graph_painter.cc [new file with mode: 0644]
app-bohyn/src/graph_painter.h [new file with mode: 0644]
app-bohyn/src/graph_painter.o [new file with mode: 0644]
app-bohyn/src/html_layer.cc [new file with mode: 0644]
app-bohyn/src/html_layer.h [new file with mode: 0644]
app-bohyn/src/html_layer.o [new file with mode: 0644]
app-bohyn/src/http.cc [new file with mode: 0644]
app-bohyn/src/http.h [new file with mode: 0644]
app-bohyn/src/moc_forms.cpp [new file with mode: 0644]
app-bohyn/src/node.cc [new file with mode: 0644]
app-bohyn/src/node.h [new file with mode: 0644]
app-bohyn/src/node.o [new file with mode: 0644]
app-bohyn/src/src.pro [new file with mode: 0644]
app-bohyn/src/uldy_server.cc [new file with mode: 0644]
app-bohyn/src/uldy_server.h [new file with mode: 0644]
app-bohyn/src/uldy_server.o [new file with mode: 0644]
app-bohyn/src/utils.cc [new file with mode: 0644]
app-bohyn/src/utils.h [new file with mode: 0644]
app-bohyn/src/value_cache.cc [new file with mode: 0644]
app-bohyn/src/value_cache.h [new file with mode: 0644]
app-bohyn/src/value_cache.o [new file with mode: 0644]
app-bohyn/ul_drv [new symlink]
app-bohyn/xml_def/relax_ng_schema.xml [new file with mode: 0644]
app-stefic/control/board.c
app-stefic/control/hydroponieoi.c
app-stefic/regulator/board.c
app-stefic/regulator/board.h
app-stefic/regulator/hydroponieoi.c
app-stefic/sensor/board.c
app-stefic/sensor/board.h
app-stefic/sensor/definitions.c
app-stefic/sensor/definitions.h
app-stefic/sensor/hydroponie.c
app-stefic/sensor/hydroponie.h

diff --git a/app-bohyn/Makefile b/app-bohyn/Makefile
new file mode 100644 (file)
index 0000000..b22a357
--- /dev/null
@@ -0,0 +1,14 @@
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ;  while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd`  ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+       @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
diff --git a/app-bohyn/Makefile.omk b/app-bohyn/Makefile.omk
new file mode 100644 (file)
index 0000000..6d1dc90
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS = ul_drv
+
+QT_SUBDIRS = src
+
diff --git a/app-bohyn/Makefile.rules b/app-bohyn/Makefile.rules
new file mode 100644 (file)
index 0000000..2382ed7
--- /dev/null
@@ -0,0 +1,1325 @@
+#                   Version for Linux/RTLinux builds.        #OMK@linux
+#
+#  Makefile.rules - OCERA make framework common project rules -*- makefile -*- #OMK@base
+#
+#  (C) Copyright 2003 by Pavel Pisa - OCERA team member
+#  (C) Copyright 2006 by Michal Sojka - Czech Technical University, FEE, DCE
+#
+#  Homepage: http://rtime.felk.cvut.cz/omk/
+#
+# The OMK build system is distributed under the GNU General Public
+# License.  See file COPYING for details.
+#
+# input variables
+# V                .. if set to 1, full command text is shown else short form is used
+# W                .. whole tree - if set to 1, make is always called from the top-level directory
+# SUBDIRS          .. list of subdirectories intended for make from actual directory
+# default_CONFIG   .. list of default config assignments CONFIG_XXX=y/n ...
+# LN_HEADERS       .. if "y", header files are symbolicaly linked instead of copied. #OMK@include
+#                                                            #OMK@linux
+# input variables
+# lib_LIBRARIES    .. list of the user-space libraries
+# shared_LIBRARIES .. list of the user-space shared libraries
+# kernel_LIBRARIES .. list of the kernel-space libraries
+# rtlinux_LIBRARIES.. list of the RT-Linux kernel-space libraries
+# include_HEADERS  .. list of the user-space public header files
+# nobase_include_HEADERS .. public headers copied even with directory part
+# renamed_include_HEADERS .. public headers copied to the different target name
+# kernel_HEADERS   .. list of the kernel-space public header files
+# rtlinux_HEADERS  .. list of the RT-Linux kernel-space public header files
+# bin_PROGRAMS     .. list of the require binary programs
+# utils_PROGRAMS   .. list of the development utility programs
+# test_PROGRAMS    .. list of the testing programs
+# kernel_MODULES   .. list of the kernel side modules/applications
+# rtlinux_MODULES  .. list of RT-Linux the kernel side modules/applications
+# xxx_SOURCES      .. list of specific target sources
+# xxx_LIBS         .. list of specific target libraries
+# INCLUDES         .. additional include directories and defines for user-space
+# kernel_INCLUDES  .. additional include directories and defines for kernel-space
+# rtlinux_INCLUDES .. additional include directories and defines for RT-Linux
+# OMIT_KERNEL_PASSES  if defined, all kernel passes are omited
+#
+# LINUX_DIR        .. location of Linux kernel sources
+# RTL_DIR          .. location of RT-Linux sources
+# CFLAGS           .. C compiler flags
+# CXXFLAGS         .. C++ compiler flags
+# CPPFLAGS        .. C preprocessor flags
+# LDFLAGS         .. linker flags for programs linking
+# LOCAL_CONFIG_H   .. name of local config.h file generated from values #OMK@config_h
+#                     of options defined in the current directory
+# config_include_HEADERS .. names of global config files (possibly
+#                     with subdirectories)
+# xxx_DEFINES      .. list of config directives to be included in
+#                     config header file of the name <somedir>/xxx.h
+# DOXYGEN          .. if non-empty, generated headers includes Doxygen's @file
+#                    command, so it is possible to document config
+#                    variables.
+# QT_SUBDIRS       .. subdirectories where to build QT applications using qmake #OMK@qt
+# QTDIR                   .. where QT resides
+OMK_RULES_TYPE=linux                                         #OMK@__type
+                                                             #OMK@base
+# We need to ensure definition of sources directory first
+ifndef SOURCES_DIR
+# Only shell built-in pwd understands -L
+SOURCES_DIR := $(shell ( pwd -L ) )
+endif
+
+# If we are not called by OMK leaf Makefile...
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(abspath $(dir $(filter %Makefile.rules,$(MAKEFILE_LIST))))
+endif
+
+# OUTPUT_DIR is the place where _compiled, _build and possible other
+# files/directories are created. By default is the same as
+# $(MAKERULES_DIR).
+ifndef OUTPUT_DIR
+OUTPUT_DIR := $(MAKERULES_DIR)
+endif
+
+.PHONY: all default check-make-ver omkize
+
+ifdef W
+  ifeq ("$(origin W)", "command line")
+    OMK_WHOLE_TREE:=$(W)
+  endif
+endif
+ifndef OMK_WHOLE_TREE
+  OMK_WHOLE_TREE:=0
+endif
+
+ifneq ($(OMK_WHOLE_TREE),1)
+all: check-make-ver default
+       @echo "Compilation finished"
+else
+# Run make in the top-level directory
+all:
+       @$(MAKE) -C $(MAKERULES_DIR) OMK_SERIALIZE_INCLUDED=n SOURCES_DIR=$(MAKERULES_DIR) RELATIVE_DIR="" $(MAKECMDGOALS) W=0
+endif
+
+ifdef OMK_TESTSROOT
+# Usage: $(call canttest,<error message>)
+define canttest
+       ( echo "$(1)" > $(OUTPUT_DIR)/_canttest; echo "$(1)"; exit 1 )
+endef
+else
+define canttest
+       echo "$(1)"
+endef
+endif
+
+#=========================
+# Include the config file
+
+# FIXME: I think CONFIG_FILE_OK variable is useless. We have three
+# config files and it is not clearly defined to which file is this
+# variable related.
+ifneq ($(CONFIG_FILE_OK),y)
+ifndef CONFIG_FILE
+CONFIG_FILE      := $(OUTPUT_DIR)/config.omk
+endif
+ifneq ($(wildcard $(CONFIG_FILE)-default),)
+-include $(CONFIG_FILE)-default
+else
+ifneq ($(MAKECMDGOALS),default-config)
+$(warning Please, run "make default-config" first)
+endif
+endif
+
+-include $(OUTPUT_DIR)/config.target
+
+ifneq ($(wildcard $(CONFIG_FILE)),)
+-include $(CONFIG_FILE)
+CONFIG_FILE_OK = y
+endif
+endif #$(CONFIG_FILE_OK)
+
+
+CONFIG_FILES ?= $(wildcard $(CONFIG_FILE)-default) $(wildcard $(OUTPUT_DIR)/config.target) $(wildcard $(CONFIG_FILE))
+
+
+export SOURCES_DIR MAKERULES_DIR RELATIVE_DIR
+export CONFIG_FILE CONFIG_FILES OMK_SERIALIZE_INCLUDED OMK_VERBOSE OMK_SILENT
+# OMK_SERIALIZE_INCLUDED has to be exported to submakes because passes
+# must to be serialized only in the toplevel make.
+
+ifndef RELATIVE_DIR
+RELATIVE_DIR := $(SOURCES_DIR:$(OUTPUT_DIR)%=%)
+endif
+#$(warning  === RELATIVE_DIR = "$(RELATIVE_DIR)" ===)
+override RELATIVE_DIR := $(RELATIVE_DIR:/%=%)
+override RELATIVE_DIR := $(RELATIVE_DIR:\\%=%)
+#$(warning  RELATIVE_DIR = "$(RELATIVE_DIR)")
+override BACK2TOP_DIR := $(shell echo $(RELATIVE_DIR)/ | sed -e 's_//_/_g' -e 's_/\./_/_g' -e 's_^\./__g'  -e 's_\([^/][^/]*\)_.._g' -e 's_/$$__')
+#$(warning  BACK2TOP_DIR = "$(BACK2TOP_DIR)")
+
+#$(warning SOURCES_DIR = "$(SOURCES_DIR)")
+#$(warning MAKERULES_DIR = "$(OUTPUT_DIR)")
+#$(warning RELATIVE_DIR = "$(RELATIVE_DIR)")
+
+# We have to use RELATIVE_PREFIX because of mingw
+override RELATIVE_PREFIX := $(RELATIVE_DIR)/
+override RELATIVE_PREFIX := $(RELATIVE_PREFIX:/%=%)
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+# Define srcdir for Automake compatibility
+srcdir = $(SOURCES_DIR)
+
+# Defines for quiet compilation
+ifdef V
+  ifeq ("$(origin V)", "command line")
+    OMK_VERBOSE = $(V)
+  endif
+endif
+ifndef OMK_VERBOSE
+  OMK_VERBOSE = 0
+endif
+ifneq ($(OMK_VERBOSE),0)
+  Q =
+else
+  Q = @
+endif
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  QUIET_CMD_ECHO = true
+  OMK_SILENT = 1
+else
+  QUIET_CMD_ECHO = echo
+endif
+
+MAKEFILE_OMK=Makefile.omk
+# All subdirectories (even linked ones) containing Makefile.omk
+# Usage in Makefile.omk: SUBDIRS = $(ALL_OMK_SUBDIRS)
+ALL_OMK_SUBDIRS = $(patsubst %/$(MAKEFILE_OMK),%,$(patsubst $(SOURCES_DIR)/%,%,$(wildcard $(SOURCES_DIR)/*/$(MAKEFILE_OMK))))
+
+# ===================================================================
+# We have set up all important variables, so we can check and include
+# real OCERA style Makefile.omk now
+ifndef OMK_INCLUDED
+include $(SOURCES_DIR)/$(MAKEFILE_OMK)
+ifeq ($(AUTOMATIC_SUBDIRS),y)
+SUBDIRS?=$(ALL_OMK_SUBDIRS)
+endif
+OMK_INCLUDED := 1
+endif
+
+check-make-ver:
+       @GOOD_MAKE_VERSION=`echo $(MAKE_VERSION) | sed -n -e 's/^[4-9]\..*\|^3\.9[0-9].*\|^3\.8[1-9].*/y/p'` ; \
+       if [ x$$GOOD_MAKE_VERSION != xy ] ; then \
+               echo "Your make program version is too old and does not support OMK system." ; \
+               echo "Please update to make program 3.81beta1 or newer." ; exit 1 ; \
+       fi
+
+distclean dist-clean:
+       @$(QUIET_CMD_ECHO) "  RM      $(COMPILED_DIR_NAME) $(BUILD_DIR_NAME)"
+       @rm -fr $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)  $(OUTPUT_DIR)/$(BUILD_DIR_NAME)
+
+# Common OMK templates
+# ====================
+
+# Syntax: $(call mkdir,<dir name>)
+define mkdir_def
+       [ -d $(1) ] || mkdir -p $(1) || exit 1
+endef
+
+ifneq ($(OMK_VERBOSE),2)
+NO_PRINT_DIRECTORY := --no-print-directory
+endif
+
+ifeq ($(USE_LEAF_MAKEFILES),n)
+export USE_LEAF_MAKEFILES
+SUBDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+SOURCESDIR_MAKEFILE=$(MAKERULES_DIR)/Makefile.rules
+else
+SUBDIR_MAKEFILE=$(SOURCES_DIR)/$(3)/Makefile
+SOURCESDIR_MAKEFILE=$(SOURCES_DIR)/Makefile
+endif
+
+pass = $(strip $(1))
+
+# Call a pass in a subdirectory
+# Usage: $(call omk_pass_subdir_template,<pass name>,<build dir>,<subdir>)
+define omk_pass_subdir_template
+.PHONY: $(pass)-$(3)-subdir
+$(pass)-submakes: $(pass)-$(3)-subdir
+$(pass)-$(3)-subdir:
+       @$(call mkdir_def,$(2)/$(3))
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(3) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(3) -C $(2)/$(3) \
+               -f $(SUBDIR_MAKEFILE) $(pass)-submakes
+# In subdirectories we can call submakes directly since passes are
+# already searialized on the toplevel make.
+endef
+
+ifdef OMK_TESTSROOT
+check-target = $(1:%=%-check)
+endif
+
+# Call a pass in a subdirectory
+# Usage: $(call extra_rules_subdir_template,<subdir>)
+define extra_rules_subdir_template
+extra-rules-subdirs: extra-rules-$(1)
+extra-rules-$(1):
+       +@$(MAKE) OMK_SERIALIZE_INCLUDED=n MAKERULES_DIR=$(SOURCES_DIR)/$(1) OUTPUT_DIR=$(OUTPUT_DIR) \
+               SOURCES_DIR=$(SOURCES_DIR)/$(1) RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) -C $(SOURCES_DIR)/$(1)
+endef
+
+.PHONY: extra-rules-subdirs
+extra-rules-subdirs:
+
+$(foreach subdir,$(EXTRA_RULES_SUBDIRS),$(eval $(call extra_rules_subdir_template,$(subdir))))
+
+# Usage: $(call omk_pass_template,<pass name>,<build dir>,[<local make flags>],[<local enable condition>])
+define omk_pass_template
+.PHONY: $(pass) $(pass)-local $(pass)-check $(pass)-submakes
+$(foreach subdir,$(SUBDIRS),$(eval $(call omk_pass_subdir_template,$(pass),$(2),$(subdir))))
+$(pass):
+# Submakes have to be called this way and not as dependecies for pass
+# serialization to work
+       +@$(MAKE) SOURCES_DIR=$(SOURCES_DIR) $(NO_PRINT_DIRECTORY) \
+               RELATIVE_DIR=$(RELATIVE_DIR) \
+               -f $(SOURCESDIR_MAKEFILE) $(pass)-submakes
+$(pass)-submakes:
+       @true                   # Do not emit "nothing to be done" messages
+
+ifneq ($(4)$($(pass)_HOOKS),)
+$(pass)-submakes: $(pass)-this-dir
+$(pass)-this-dir: $(foreach subdir,$(SUBDIRS),$(pass)-$(subdir)-subdir)
+       +@echo "make[omk]: $(pass) in $(RELATIVE_DIR)"
+       @$(call mkdir_def,$(2))
+       +@$(MAKE) $(NO_PRINT_DIRECTORY) SOURCES_DIR=$(SOURCES_DIR) RELATIVE_DIR=$(RELATIVE_DIR) -C $(2) \
+               -f $(SOURCESDIR_MAKEFILE) $(3) $(check-target) $(1:%=%-local)
+$(pass)-local: $($(pass)_HOOKS)
+endif
+endef
+
+# =======================
+# DEFAULT CONFIG PASS
+
+default-config:
+       @echo "# Start of OMK config file" > "$(CONFIG_FILE)-default"
+       @echo "# This file should not be altered manually" >> "$(CONFIG_FILE)-default"
+       @echo "# Overrides should be stored in file $(notdir $(CONFIG_FILE))" >> "$(CONFIG_FILE)-default"
+       @echo >> "$(CONFIG_FILE)-default"
+       @$(MAKE) $(NO_PRINT_DIRECTORY) -C $(OUTPUT_DIR) \
+               RELATIVE_DIR="" SOURCES_DIR=$(OUTPUT_DIR) \
+               -f $(OUTPUT_DIR)/Makefile default-config-pass
+
+$(eval $(call omk_pass_template,default-config-pass,$$(LOCAL_BUILD_DIR),,always))
+
+default-config-pass-local:
+#      @echo Default config for $(RELATIVE_DIR)
+       @echo "# Config for $(RELATIVE_DIR)" >> "$(CONFIG_FILE)-default"
+       @$(foreach x, $(default_CONFIG), echo '$(x)' | \
+               sed -e 's/^[^=]*=x$$/#\0/' >> "$(CONFIG_FILE)-default" ; )
+
+
+omkize:
+       $(Q)if ! grep -q MAKERULES_DIR Makefile; then \
+          echo "Makefile is not OMK leaf makefile!" >&2; exit 1; \
+       fi
+       $(Q)for i in `find -L . -name Makefile.omk` ; do \
+          d=`dirname $${i}`; \
+          if ! test -f "$${d}/Makefile.rules" && ( ! test -f "$${d}/Makefile" || ! cmp --silent Makefile "$${d}/Makefile" ); then \
+             rm -f "$${d}/Makefile"; \
+             cp -v Makefile "$${d}/Makefile"; \
+          fi \
+       done
+ifeq ($(OMK_VERBOSE),1)                                      #OMK@include
+CPHEADER_FLAGS += -v
+LNHEADER_FLAGS += -v
+endif
+
+ifneq ($(LN_HEADERS),y)
+define cp_cmd
+( echo "  CP      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; cp $(CPHEADER_FLAGS) $(1) $(2) )
+endef
+else
+define cp_cmd
+( echo "  LN      $(1:$(OUTPUT_DIR)/%=%) -> $(2:$(OUTPUT_DIR)/%=%)"; [ -f $(1) ] && ln -sf $(LNHEADER_FLAGS) $(1) $(2) )
+endef
+endif
+
+# TODO: Check modification date of changed header files. If it is
+# newer that in source dir, show a warning.
+
+# Syntax: $(call include-pass-template,<include dir>,<keyword>)
+define include-pass-template
+include-pass-local: include-pass-local-$(2)
+include-pass-local-$(2): $$($(2)_GEN_HEADERS) $$(foreach f,$$(renamed_$(2)_GEN_HEADERS),$$(shell echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'))
+       @$$(foreach f, $$($(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; )
+       @$$(foreach f, $$($(2)_GEN_HEADERS), cmp --quiet $$(f) $(1)/$$(notdir $$(f)) \
+          || $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$(f),$(1)/$$(notdir $$(f))) || exit 1 ; ) # FIXME: Use correct build dir, then document it
+       @$$(foreach f, $$(nobase_$(2)_HEADERS), cmp --quiet $$(SOURCES_DIR)/$$(f) $(1)/$$(f) \
+          || ( mkdir -p $(1)/$$(dir $$(f)) && $$(call cp_cmd,$$(SOURCES_DIR)/$$(f),$(1)/$$(f)) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$(SOURCES_DIR)/$$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(SOURCES_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+       @$$(foreach f, $$(renamed_$(2)_GEN_HEADERS), \
+          srcfname=`echo '$$(f)' | sed -e 's/^\(.*\)->.*$$$$/\1/'` ; destfname=`echo '$$(f)' | sed -e 's/^.*->\(.*\)$$$$/\1/'` ; \
+          cmp --quiet $$$${srcfname} $(1)/$$$${destfname} \
+          || ( mkdir -p `dirname $(1)/$$$${destfname}` && $$(call cp_cmd,$$(LOCAL_BUILD_DIR)/$$$${srcfname},$(1)/$$$${destfname}) ) || exit 1 ; )
+endef
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@linux
+# Hack to check RT-Linux rules
+#LINUX_DIR := /home/cvs/ocera/ocera-build/kernel/linux
+#RTL_DIR := /home/cvs/ocera/ocera-build/kernel/rtlinux
+#CONFIG_RTLINUX = y
+#OCERA_DIR := $(shell ( cd -L $(OUTPUT_DIR)/../../.. ; pwd -L ) )
+
+-include $(OUTPUT_DIR)/OCERA_TOP_DIR
+
+BUILD_DIR_NAME = _build
+COMPILED_DIR_NAME = _compiled
+ifndef GROUP_DIR_NAME
+GROUP_DIR_NAME = nogroup
+endif
+
+ifdef OCERA_DIR
+ifeq ($(wildcard $(OCERA_DIR)/ocera.mk),)
+$(warning "ocera.mk" file does not exist. Adapt Makefile.rules for standalone compilation)
+$(warning (comment out definition of OCERA_DIR line and optionally select RTL_DIR) )
+$(error or go to the ocera/ directory and do 'make' to generate the "ocera.mk" file first, please)
+endif
+include $(OCERA_DIR)/ocera.mk
+KERN_INCLUDE_DIR := $(OCERA_KERNEL_INCLUDES_DIR)
+KERN_LIB_DIR     := $(OCERA_KERNEL_LIBRARIES_DIR)
+KERN_MODULES_DIR := $(OCERA_MODULES_DIR)
+KERN_BUILD_DIR   := $(BUILD_DIR)/kern/$(GROUP_DIR_NAME)
+KERN_MODPOST_DIR := $(BUILD_DIR)/kern-modpost
+USER_INCLUDE_DIR := $(OCERA_USER_INCLUDES_DIR)
+USER_LIB_DIR     := $(OCERA_USER_LIBRARIES_DIR)
+USER_UTILS_DIR   := $(TARGET_DIR)/usr/bin
+USER_TESTS_DIR   := $(TARGET_DIR)/usr/bin
+USER_BIN_DIR     := $(TARGET_DIR)/usr/bin
+USER_BUILD_DIR   := $(BUILD_DIR)/user/$(GROUP_DIR_NAME)
+#LINUX_DIR        := $(OCERA_DIR)/kernel/linux
+#RTL_DIR          := $(OCERA_DIR)/kernel/rtlinux
+#CONFIG_FILE      := $(OCERA_DIR)/emdebsys/.config 
+ifneq ($(wildcard $(CONFIG_FILE)),)
+CONFIG_FILE_OK = y
+endif
+else # OCERA_DIR
+KERN_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include-kern
+KERN_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib-kern
+KERN_MODULES_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/modules
+KERN_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern
+KERN_MODPOST_DIR := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/kern-modpost
+USER_INCLUDE_DIR := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/include
+USER_LIB_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/lib
+USER_UTILS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-utils
+USER_TESTS_DIR   := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin-tests
+USER_BIN_DIR     := $(OUTPUT_DIR)/$(COMPILED_DIR_NAME)/bin
+USER_BUILD_DIR   := $(OUTPUT_DIR)/$(BUILD_DIR_NAME)/user
+
+ifndef LINUX_VERSION
+LINUX_VERSION=$(shell uname -r)
+endif
+ifndef LINUX_DIR
+LINUX_DIR=/lib/modules/$(LINUX_VERSION)/build
+endif
+endif # OCERA_DIR
+
+ifeq ($(BUILD_OS),)
+  # Check for target
+  ifeq ($(OS),Windows_NT)
+    BUILD_OS := win32
+  else
+    BUILD_OS := $(shell uname | tr '[A-Z]' '[a-z]' )
+    #$(warning BUILD_OS=$(BUILD_OS))
+  endif
+endif
+
+ifeq ($(TARGET_OS),)
+  TARGET_OS := $(BUILD_OS)
+endif
+
+LOCAL_BUILD_DIR  = $(USER_OBJS_DIR)
+
+# Assign default values to CFLAGS variable. If the variable is defined
+# earlier (i.g. in config.omk), it is not overriden here.
+CFLAGS ?= -O2 -Wall
+CXXFLAGS ?= -O2 -Wall
+
+
+CPPFLAGS  += -I $(USER_INCLUDE_DIR)
+
+LOADLIBES += -L$(USER_LIB_DIR) 
+
+LOADLIBES += $(lib_LOADLIBES:%=-l%)
+
+LIB_CPPFLAGS += $(CPPFLAGS)
+LIB_CFLAGS   += $(CFLAGS)
+
+ifeq ($(TARGET_OS),win32)
+  SOLIB_EXT = dll
+else
+  SOLIB_EXT = so
+  SOLIB_PICFLAGS += -fpic
+endif
+
+#vpath %.c $(SOURCES_DIR)
+#vpath %.cc $(SOURCES_DIR)
+#vpath %.cxx $(SOURCES_DIR)
+
+USER_OBJS_DIR = $(USER_BUILD_DIR)/$(RELATIVE_DIR)
+KERN_OBJS_DIR = $(KERN_BUILD_DIR)/$(RELATIVE_DIR)
+
+.PHONY: dep subdirs clean clean-custom cleandepend check-dir
+
+# Some support to serialize some targets for parallel make
+ifneq ($(OMK_SERIALIZE_INCLUDED),y)
+include-pass: check-dir
+library-pass: include-pass
+binary-pass: library-pass
+kernel-lib-pass: include-pass
+kernel-mod-pass: kernel-lib-pass
+kernel-modpost-pass: kernel-mod-pass
+kernel-pass: kernel-mod-pass kernel-modpost-pass
+
+override OMK_SERIALIZE_INCLUDED = y
+MAKEOVERRIDES := $(filter-out OMK_SERIALIZE_INCLUDED=n,$(MAKEOVERRIDES))
+endif
+
+# Checks for OMK tester
+ifdef OMK_TESTSROOT
+default-config-pass-check include-pass-check:
+library-pass-check binary-pass-check:
+       @[ -x "$(shell which $(CC))" ] || $(call canttest,Cannot find compiler: $(CC))
+endif
+
+#=====================================================================
+# User-space rules and templates to compile programs, libraries etc.
+
+ifdef USER_RULE_TEMPLATES
+
+USER_SOURCES2OBJS = .o/.c .o/.cc .o/.cxx .o/.S .o/.o
+
+USER_SOURCES2OBJSLO = .lo/.c .lo/.cc .lo/.cxx .lo/.S .lo/.lo
+
+#%.lo: %.c
+#      $(CC) -o $@ $(LCFLAGS) -c $<
+
+c_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+cc_o_COMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -DOMK_FOR_USER
+
+S_o_COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(ASFLAGS) -DOMK_FOR_USER
+
+idl_COMPILE = $(IDL_COMPILER)
+
+# Check GCC version for user build
+ifndef CC_MAJOR_VERSION
+CC_MAJOR_VERSION := $(shell $(CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(CC_MAJOR_VERSION),2)
+CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+
+# Syntax: $(call COMPILE_c_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_c_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CC      $$@"
+       $(Q) if $$(c_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_cc_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_cc_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  CXX     $$@"
+       $(Q) if $$(cc_o_COMPILE) $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call COMPILE_S_o_template,<source>,<target>,<additional c-flags>)
+define COMPILE_S_o_template
+$(2): $(1) $$(GEN_HEADERS)
+       @$(QUIET_CMD_ECHO) "  AS      $$@"
+       $(Q) if $$(S_o_COMPILE) -D__ASSEMBLY__ $$(CC_DEPFLAGS) $(3) -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+# Syntax: $(call CMETRIC_o_h_template,<object_file>,<target_header>)
+define CMETRIC_o_h_template
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CMETRIC $$@"
+       $(Q)if [ -n `dirname $$@` ] ; then \
+             if [ ! -e `dirname $$@` ] ; then \
+               mkdir -p `dirname $$@` ; fi ; fi
+       $(Q)echo >$$@ '/* Automatically generated from $$< */'
+       $(Q)echo >>$$@ '/* Conditionals to control compilation */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2cond_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+       $(Q)echo >>$$@ '/* Defines from the values defined to symbols */'
+       $(Q)set -o pipefail ; $(NM) $$< \
+               | sed -n 's/^ *0*\(0[0-9A-Fa-f]*\) *A *_cmetric2def_\([A-Za-z_0-9]*\) */#define \2 0x\1/p' \
+               | sort >>$$@
+endef
+
+
+
+define COMPILE_idl_template
+$(2).c $(2)-stubs.c $(2)-skels.c $(2)-common.c $(2).h: $(1)
+       @$(QUIET_CMD_ECHO) "  IDL     $$@"
+       $(Q) $$(idl_COMPILE) $(1)
+endef
+
+
+# Syntax: $(call PROGRAM_template,<dir>,<executable-name>,<executable-suffix>,<linker-sript>)
+# FIXME: ???????? asi je tu blbej komentar
+define PROGRAM_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(2)/$(1)$(3): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $$(if $$(filter %.cc,$$($(1)_SOURCES:%.cxx=%.cc)),$$(CXX),$$(CC)) \
+         $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) $$(LOADLIBES) $$(LDFLAGS) -Wl,-Map,$(USER_OBJS_DIR)/$(1).exe.map -o $$@
+       @echo "$(2)/$(1)$(3): \\" >$(USER_OBJS_DIR)/$(1).exe.d
+       @sed -n -e 's|^LOAD \(.*\)$$$$|  \1  \&|p' $(USER_OBJS_DIR)/$(1).exe.map|tr '&' '\134'  >>$(USER_OBJS_DIR)/$(1).exe.d
+       @echo >>$(USER_OBJS_DIR)/$(1).exe.d
+endef
+
+
+# Syntax: $(call LIBRARY_template,<library-name>)
+define LIBRARY_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+USER_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJS),
+$(1)_OBJS += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJS := $$(sort $$($(1)_OBJS:%/=%))
+
+USER_OBJS  += $$($(1)_OBJS)
+USER_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR      $$@"
+       $(Q) $(AR) rcs $$@ $$^
+endef
+
+
+# Syntax: $(call SOLIB_template,<library-name>)
+define SOLIB_template
+
+USER_IDLS  += $$($(1)_SERVER_IDL) $$($(1)_CLIENT_IDL) $$($(1)_IDL)
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-skels.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_SERVER_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-stubs.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_CLIENT_IDL:%.idl=%-common.c))
+$(1)_GEN_SOURCES += $$(filter %.c,$$($(1)_IDL:%.idl=%.c))
+SOLIB_GEN_SOURCES += $$($(1)_GEN_SOURCES)
+
+$(foreach x, $(USER_SOURCES2OBJSLO),
+$(1)_OBJSLO += $$(patsubst %$(notdir $(x)),%$(dir $(x)),$$(filter %$(notdir $(x)),\
+               $$($(1)_SOURCES) $$($(1)_GEN_SOURCES)))
+)
+$(1)_OBJSLO := $$(sort $$($(1)_OBJSLO:%/=%))
+
+SOLIB_OBJS  += $$($(1)_OBJSLO)
+SOLIB_SOURCES += $$($(1)_SOURCES)
+
+$(USER_LIB_DIR)/lib$(1).$(SOLIB_EXT): $$($(1)_OBJSLO)
+       @$(QUIET_CMD_ECHO) "  LINK    $$@"
+       $(Q) $(CC) --shared -Xlinker -soname=lib$(1).$(SOLIB_EXT) -o $$@ $$^ $$(LOADLIBES) $$($(1)_LIBS:%=-l%)
+endef
+
+
+
+library-pass-local: $(addprefix $(USER_INCLUDE_DIR)/,$(cmetric_include_HEADERS)) \
+                   $(lib_LIBRARIES:%=$(USER_LIB_DIR)/lib%.a) $(shared_LIBRARIES:%=$(USER_LIB_DIR)/lib%.$(SOLIB_EXT))
+
+binary-pass-local: $(bin_PROGRAMS:%=$(USER_BIN_DIR)/%$(EXE_SUFFIX)) $(utils_PROGRAMS:%=$(USER_UTILS_DIR)/%$(EXE_SUFFIX)) $(test_PROGRAMS:%=$(USER_TESTS_DIR)/%$(EXE_SUFFIX))
+
+# Special rules for CMETRIC generated headers
+
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call COMPILE_c_o_template,\
+               $(SOURCES_DIR)/$($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES),\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),)))
+$(foreach cmetrh,$(cmetric_include_HEADERS),$(eval $(call CMETRIC_o_h_template,\
+               $($(basename $(notdir $(cmetrh)))_CMETRIC_SOURCES:%.c=%.o),\
+               $(addprefix $(USER_INCLUDE_DIR)/,$(cmetrh)))))
+
+GEN_HEADERS+=$(cmetric_include_HEADERS:%=$(USER_INCLUDE_DIR)/%)
+
+GEN_HEADERS+=$(filter %.h,$(USER_IDLS:%.idl=%.h))
+
+# Generate rules for compilation of programs and libraries
+
+$(foreach prog,$(utils_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_UTILS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(test_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_TESTS_DIR),$(EXE_SUFFIX))))
+
+$(foreach prog,$(bin_PROGRAMS),$(eval $(call PROGRAM_template,$(prog),$(USER_BIN_DIR),$(EXE_SUFFIX))))
+
+$(foreach lib,$(lib_LIBRARIES),$(eval $(call LIBRARY_template,$(lib))))
+
+$(foreach lib,$(shared_LIBRARIES),$(eval $(call SOLIB_template,$(lib))))
+
+-include $(USER_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+# Kernel-space rules and templates to compile modules, libraries etc.
+
+ifdef KERN_RULE_TEMPLATES
+
+$(KERN_LIB_DIR)/kernel.mk: $(LINUX_DIR)/.config $(MAKERULES_DIR)/kernelcfg2mk
+       @$(QUIET_CMD_ECHO) "  KCFG2MK $$@"
+       $(Q) $(MAKERULES_DIR)/kernelcfg2mk $(LINUX_DIR) $(KERN_LIB_DIR)
+
+ifeq ($(CONFIG_RTLINUX),y)
+include $(RTL_DIR)/rtl.mk
+
+KERN_CC = $(CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+INCLUDES := -I $(KERN_INCLUDE_DIR) $(INCLUDE) $(rtlinux_INCLUDES) $(kernel_INCLUDES)
+#-DEXPORT_NO_SYMBOLS
+c_o_kern_COMPILE = $(KERN_CC) -idirafter $(kern_GCCLIB_DIR)/include $(INCLUDES)  $(CFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(CXX) $(INCLUDES) $(CXXFLAGS) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := .o
+KERN_ARCH = $(ARCH)
+KERN_LD = $(LD)
+KERN_AR = $(AR)
+
+else # CONFIG_RTLINUX
+
+include $(KERN_LIB_DIR)/kernel.mk
+
+ifeq ($(LINUX_SRC),)
+LINUX_SRC = $(LINUX_DIR)
+endif
+kernel_INCLUDES += -I $(LINUX_DIR) -idirafter $(LINUX_SRC)/include/linux
+
+ifdef LINUX_CC
+KERN_CC = $(LINUX_CC)
+kern_GCCLIB_DIR=$(shell LANG=C LC_ALL=C LC_MESSAGES=C $(LINUX_CC) -print-search-dirs | sed -n -e 's/^install: \(.*\)$$/\1/p' )
+else
+KERN_CC = echo KERN_CC not defined - compilation skipped
+endif
+c_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB -nostdinc
+cc_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_CFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+S_o_kern_COMPILE = $(KERN_CC) $(kernel_INCLUDES) -idirafter $(kern_GCCLIB_DIR)/include $(LINUX_CPPFLAGS) $(LINUX_AFLAGS) $(LINUX_CFLAGS_MODULE) -DOMK_FOR_KERNEL -DEXPORT_SYMTAB
+KERN_EXE_SUFFIX := $(LINUX_MODULE_EXT)
+KERN_LDFLAGS = $(LINUX_LDFLAGS)
+ifdef LINUX_ARCH
+KERN_ARCH = $(LINUX_ARCH)
+else
+KERN_ARCH = echo KERN_ARCH not defined - skipped
+endif
+ifdef LINUX_LD
+KERN_LD = $(LINUX_LD)
+else
+KERN_LD = echo KERN_LD  not defined - skipped
+endif
+ifneq ($(LINUX_AR),)
+KERN_AR = $(LINUX_AR)
+else
+KERN_AR = $(AR)
+endif
+ifeq ($(LINUX_QUOTE_MODNAME),y)
+KERN_MQ=\"
+KERN_KBUILD_MODNAME=-D"KBUILD_MODNAME=((THIS_MODULE)!=NULL?(THIS_MODULE)->name:NULL)"
+endif
+endif # CONFIG_RTLINUX
+
+KERN_LOADLIBES += -L$(KERN_LIB_DIR) 
+
+KERN_LOADLIBES += $(rtlinux_LOADLIBES:%=-l%)
+KERN_LOADLIBES += $(kernel_LOADLIBES:%=-l%)
+
+
+
+# Check GCC version for kernel part of build
+ifndef kern_CC_MAJOR_VERSION
+kern_CC_MAJOR_VERSION := $(shell $(KERN_CC) -dumpversion | sed -e 's/\([^.]\)\..*/\1/')
+endif
+# Prepare suitable define for dependency building
+ifeq ($(kern_CC_MAJOR_VERSION),2)
+kern_CC_DEPFLAGS = -Wp,-MD,"$@.d.tmp"
+else
+kern_CC_DEPFLAGS = -MT $@ -MD -MP -MF "$@.d.tmp"
+endif
+
+ifeq ($(KERN_EXE_SUFFIX),.ko)
+ifeq ($(wildcard $(LINUX_DIR)/scripts/mod/modpost),)
+KERN_MODPOST = $(LINUX_DIR)/scripts/modpost
+else
+KERN_MODPOST = $(LINUX_DIR)/scripts/mod/modpost
+endif
+KERN_MODULES_LINK_DIR = $(KERN_MODPOST_DIR)
+KERN_LINK_SUFFIX = .o
+else
+KERN_MODULES_LINK_DIR = $(KERN_MODULES_DIR)
+KERN_LINK_SUFFIX = $(KERN_EXE_SUFFIX)
+endif
+
+define COMPILE_c_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CC [K]  $$@"
+       $(Q) if $$(c_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_cc_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  CXX [K] $$@"
+       $(Q) if $$(cc_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define COMPILE_S_o_kern_template
+
+$(2): $(1)
+       @$(QUIET_CMD_ECHO) "  AS [K]  $$@"
+       $(Q) if $$(S_o_kern_COMPILE) $$(kern_CC_DEPFLAGS) $(3) $(KERN_KBUILD_MODNAME) \
+       -D"KBUILD_BASENAME=$(KERN_MQ)$(notdir $(basename $(1)))$(KERN_MQ)" \
+       -o $$@ -c $$< ; \
+       then mv -f "$$@.d.tmp" "$$@.d" ; \
+       else rm -f "$$@.d.tmp" ; exit 1; \
+       fi
+endef
+
+
+
+define MODULE_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+# this is hack to build "__this_module" structure for 2.6.x kernels
+# modpost is used for that purpose now
+
+#$(1).mod.c:
+#      echo  "\
+#      #include <linux/version.h>@\
+#      #include <linux/module.h>@\
+#      #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,5))@\
+#      #include <linux/vermagic.h>@\
+#      #include <linux/compiler.h>@\
+#      @\
+#      MODULE_INFO(vermagic, VERMAGIC_STRING);@\
+#      @\
+#      #undef unix@\
+#      struct module __this_module@\
+#      __attribute__((section(\".gnu.linkonce.this_module\"))) = {@\
+#       .name = __stringify(KBUILD_MODNAME),@\
+#       .init = init_module,@\
+#      #ifdef CONFIG_MODULE_UNLOAD@\
+#       .exit = cleanup_module,@\
+#      #endif@\
+#      };@\
+#      #endif@\
+#      " | tr @ \\n >$$@ 
+
+
+#$(eval $(call COMPILE_c_o_kern_template,$(1).mod.c,$(1).mod.o,-DKBUILD_MODNAME=$(1)))
+
+$(2)/$(1)$(KERN_LINK_SUFFIX): $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  LD [K]  $$@"
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) -r $$($(1)_OBJS) -L$$(kern_GCCLIB_DIR) $$($(1)_LIBS:%=-l%) $$(KERN_LOADLIBES) -Map $(KERN_OBJS_DIR)/$(1).mod.map -o $$@
+       @echo "$(2)/$(1)$(KERN_LINK_SUFFIX): \\" >$(KERN_OBJS_DIR)/$(1).mod.d
+       @sed -n -e 's/^LOAD \(.*\)$$$$/  \1  \\/p' $(KERN_OBJS_DIR)/$(1).mod.map  >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @echo >>$(KERN_OBJS_DIR)/$(1).mod.d
+       @if [ "$(KERN_EXE_SUFFIX)" = ".ko" ] ; then \
+         echo $(1) >>$(KERN_MODPOST_DIR)/module-changes ; \
+         echo $(1) >>$(KERN_MODPOST_DIR)/$(1).mod.stamp ; \
+       fi
+
+endef
+
+
+
+define LIBRARY_kern_template
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.c=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cc=%.o))
+$(1)_OBJS += $$(filter %.o,$$($(1)_SOURCES:%.cxx=%.o))
+$(1)_OBJS := $$(sort $$($(1)_OBJS))
+
+KERN_OBJS  += $$($(1)_OBJS)
+KERN_SOURCES += $$($(1)_SOURCES)
+
+$(KERN_LIB_DIR)/lib$(1).a: $$($(1)_OBJS)
+       @$(QUIET_CMD_ECHO) "  AR [K]  $$@"
+       $(Q) $(KERN_AR) rcs $$@ $$^
+endef
+
+
+ifdef LINUX_DIR
+
+kernel-lib-pass-local: $(kernel_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+kernel-mod-pass-local: $(kernel_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+$(foreach module,$(kernel_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(kernel_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+
+ifeq ($(CONFIG_RTLINUX),y)
+
+kernel-mod-pass-local: $(rtlinux_MODULES:%=$(KERN_MODULES_LINK_DIR)/%$(KERN_LINK_SUFFIX))
+
+kernel-lib-pass-local: $(rtlinux_LIBRARIES:%=$(KERN_LIB_DIR)/lib%.a)
+
+$(foreach module,$(rtlinux_MODULES),$(eval $(call MODULE_kern_template,$(module),$(KERN_MODULES_LINK_DIR))))
+
+$(foreach lib,$(rtlinux_LIBRARIES),$(eval $(call LIBRARY_kern_template,$(lib))))
+
+endif
+
+ifeq ($(KERN_MODPOST_PASS),y)
+
+MODULES_LIST :=        $(wildcard *.mod.stamp)
+MODULES_LIST := $(MODULES_LIST:%.mod.stamp=%)
+
+define MODPOST_kern_template
+$(2) : $(1)$(KERN_LINK_SUFFIX) $(1).mod.c
+       @$(QUIET_CMD_ECHO) "  LD [M]  $$@"
+       $(Q) $$(cc_o_kern_COMPILE) -D"KBUILD_BASENAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -D"KBUILD_MODNAME=$(KERN_MQ)$(1)$(KERN_MQ)" \
+               -o $(1).mod.o -c $(1).mod.c
+       $(Q) $$(KERN_LD) $$(KERN_LDFLAGS) $(1)$(KERN_LINK_SUFFIX) $(1).mod.o -r -o $$@
+endef
+
+kernel-modpost-versions: $(wildcard $(LINUX_DIR)/Module.symvers)
+       @$(QUIET_CMD_ECHO) "  MODPOST    $(KERN_MODPOST_DIR)"
+       @echo  >$(KERN_MODPOST_DIR)/modpost-running
+       @rm -f $(KERN_MODPOST_DIR)/module-changes
+       $(Q) $(KERN_MODPOST) $(MODULES_LIST:%=%$(KERN_LINK_SUFFIX)) $(^:%=-i %)
+
+$(MODULES_LIST:%=%.mod.c) : kernel-modpost-versions
+
+kernel-modpost-pass-local: $(MODULES_LIST:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX))
+       @rm -f $(KERN_MODPOST_DIR)/modpost-running
+
+$(foreach module,$(MODULES_LIST),$(eval $(call MODPOST_kern_template,$(module),$(module:%=$(KERN_MODULES_DIR)/%$(KERN_EXE_SUFFIX)))))
+
+endif
+
+-include $(KERN_OBJS_DIR)/*.d
+
+endif
+
+#=====================================================================
+
+# Kernel requires its own set of configuration header-files
+ifneq ($(kernel_LIBRARIES)$(rtlinux_LIBRARIES)$(kernel_MODULES)$(rtlinux_MODULES)$(kernel_HEADERS)$(rtlinux_HEADERS)$(kernel_HEADERS)$(rtlinux_HEADERS)$(nobase_kernel_HEADERS)$(nobase_rtlinux_HEADERS)$(renamed_kernel_HEADERS)$(renamed_rtlinux_HEADERS),)
+KERN_CONFIG_HEADERS_REQUIRED = y
+endif
+
+$(eval $(call omk_pass_template, kernel-lib-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_LIBRARIES)$(rtlinux_LIBRARIES)))
+$(eval $(call omk_pass_template, kernel-mod-pass,$(KERN_OBJS_DIR),KERN_RULE_TEMPLATES=y,$(kernel_MODULES)$(rtlinux_MODULES)))
+
+kernel-modpost-pass:
+       +@if [ -e "$(KERN_MODPOST_DIR)/module-changes" -o -e "$(KERN_MODPOST_DIR)/modpost-running" ] ; \
+       then \
+           $(MAKE) --no-print-directory -C $(KERN_MODPOST_DIR) \
+              -f $(SOURCES_DIR)/Makefile KERN_RULE_TEMPLATES=y KERN_MODPOST_PASS=y $(@:%=%-local) ; \
+       fi
+
+$(eval $(call omk_pass_template, library-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(lib_LIBRARIES)$(shared_LIBRARIES)))
+$(eval $(call omk_pass_template, binary-pass, $(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,$(bin_PROGRAMS)$(utils_PROGRAMS)$(test_PROGRAMS)))
+
+$(eval $(call omk_pass_template,clean,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,install,$(USER_OBJS_DIR),,always))
+$(eval $(call omk_pass_template,include-pass,$(USER_OBJS_DIR),USER_RULE_TEMPLATES=y,always))
+
+check-dir:
+       @$(call mkdir_def,$(USER_BUILD_DIR))
+       @$(call mkdir_def,$(KERN_BUILD_DIR))
+       @$(call mkdir_def,$(USER_INCLUDE_DIR))
+       @$(call mkdir_def,$(KERN_INCLUDE_DIR))
+       @$(call mkdir_def,$(USER_LIB_DIR))
+       @$(call mkdir_def,$(KERN_LIB_DIR))
+       @$(call mkdir_def,$(USER_BIN_DIR))
+       @$(call mkdir_def,$(USER_UTILS_DIR))
+       @$(call mkdir_def,$(USER_TESTS_DIR))
+       @$(call mkdir_def,$(KERN_MODULES_DIR))
+       @$(call mkdir_def,$(KERN_MODPOST_DIR))
+
+install-local:                 # TODO
+
+$(eval $(call include-pass-template,$(USER_INCLUDE_DIR),include))
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),kernel))
+ifeq ($(CONFIG_RTLINUX),y)
+$(eval $(call include-pass-template,$(KERN_INCLUDE_DIR),rtlinux))
+endif
+
+
+ifdef USER_RULE_TEMPLATES
+
+# User-space static libraries and applications object files
+
+USER_SOURCES := $(sort $(USER_SOURCES))
+
+USER_GEN_SOURCES := $(sort $(USER_GEN_SOURCES))
+
+#$(warning USER_SOURCES = $(USER_SOURCES))
+
+$(foreach src,$(filter %.c,$(USER_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(USER_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+
+$(foreach src,$(filter %.c,$(USER_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.o),)))
+
+# User-space shared libraries object files
+
+SOLIB_SOURCES := $(sort $(SOLIB_SOURCES))
+
+SOLIB_GEN_SOURCES := $(sort $(SOLIB_GEN_SOURCES))
+
+#$(warning SOLIB_SOURCES = $(SOLIB_SOURCES))
+#$(warning SOLIB_GEN_SOURCES = $(SOLIB_GEN_SOURCES))
+
+$(foreach src,$(filter %.c,$(SOLIB_SOURCES)),$(eval $(call COMPILE_c_o_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cc,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.cxx,$(SOLIB_SOURCES)),$(eval $(call COMPILE_cc_o_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.S,$(SOLIB_SOURCES)),$(eval $(call COMPILE_S_o_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.lo),$(SOLIB_PICFLAGS))))
+
+$(foreach src,$(filter %.c,$(SOLIB_GEN_SOURCES)),$(eval $(call COMPILE_c_o_template,$(src),$(src:%.c=%.lo),$(SOLIB_PICFLAGS))))
+
+# IDL compilation
+
+USER_IDLS := $(sort $(USER_IDLS))
+
+$(foreach src,$(filter %.idl,$(USER_IDLS)),$(eval $(call COMPILE_idl_template,$(SOURCES_DIR)/$(src),$(src:%.idl=%))))
+
+endif
+
+ifdef KERN_RULE_TEMPLATES
+
+KERN_SOURCES := $(sort $(KERN_SOURCES))
+
+#$(warning KERN_SOURCES = $(KERN_SOURCES))
+
+$(foreach src,$(filter %.c,$(KERN_SOURCES)),$(eval $(call COMPILE_c_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.c=%.o),)))
+
+$(foreach src,$(filter %.cc,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cc=%.o),)))
+
+$(foreach src,$(filter %.cxx,$(KERN_SOURCES)),$(eval $(call COMPILE_cc_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.cxx=%.o),)))
+
+$(foreach src,$(filter %.S,$(USER_SOURCES)),$(eval $(call COMPILE_S_o_kern_template,$(SOURCES_DIR)/$(src),$(src:%.S=%.o),)))
+endif
+
+clean-local: clean-custom
+       @echo Cleaning in $(KERN_OBJS_DIR) and $(USER_OBJS_DIR)
+       @rm -f $(KERN_OBJS_DIR)/*.o $(USER_OBJS_DIR)/*.[och] $(USER_OBJS_DIR)/*.lo\
+              $(KERN_OBJS_DIR)/*.d $(USER_OBJS_DIR)/*.d \
+              $(KERN_OBJS_DIR)/*.map $(USER_OBJS_DIR)/*.map \
+              $(KERN_OBJS_DIR)/*.mod.c \
+              $(kernel_MODULES:%=$(KERN_MODPOST_DIR)/%.*) \
+              $(LOCAL_CONFIG_H:%=$(KERN_OBJS_DIR)/%) \
+              $(LOCAL_CONFIG_H:%=$(USER_OBJS_DIR)/%)
+       @if [ -e $(KERN_LIB_DIR)/kernel.mk ] ; then \
+           touch -t 200001010101 $(KERN_LIB_DIR)/kernel.mk ; \
+       fi
+
+include-pass-submakes: extra-rules-subdirs
+
+# We must go to EXTRA_RULES_SUBDIRS beofre going to any other
+# directory, since the executables compiled in EXTRA_RULES_SUBDIRS
+# might be needed there.
+include-pass-this-dir $(foreach subdir,$(SUBDIRS),include-pass-$(subdir)-subdir): extra-rules-subdirs
+
+default: include-pass library-pass binary-pass
+ifndef OMIT_KERNEL_PASSES
+# Also make kernel passes if not disabled
+default: kernel-lib-pass kernel-pass
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@config_h
+# Syntax: $(call BUILD_CONFIG_H_template,<stamp_dir>,<header_file_path>,<list_of_options_to_export>,<header_barrier>)
+define BUILD_CONFIG_H_template
+
+$(addprefix $(1)/,$(notdir $(addsuffix .stamp,$(2)))) : $(CONFIG_FILES)
+       @$(QUIET_CMD_ECHO) "  CONFGEN $$(@:%.stamp=%)"
+       @if [ ! -d `dirname $(2).tmp` ] ; then \
+               mkdir -p `dirname $(2).tmp` ; fi
+       @echo "/* Automatically generated from */" > "$(2).tmp"
+       @echo "/* config files: $$(^:$(OUTPUT_DIR)/%=%) */" >> "$(2).tmp"
+       $(if $(DOXYGEN),@echo "/** @file */" >> "$(2).tmp")
+       @echo "#ifndef $(4)" >> "$(2).tmp"
+       @echo "#define $(4)" >> "$(2).tmp"
+       @( $(foreach x, $(shell echo '$($(3))' | tr 'x\t ' 'x\n\n' | sed -e 's/^\([^ =]*\)\(=[^ ]\+\|\)$$/\1/' ), \
+               echo '$(x).$($(x))' ; ) echo ; ) | \
+               sed -e '/^[^.]*\.n$$$$/d' -e '/^[^.]*\.$$$$/d' -e 's/^\([^.]*\)\.[ym]$$$$/\1.1/' | \
+               sed -n -e 's/^\([^.]*\)\.\(.*\)$$$$/#define \1 \2/p' \
+                 >> "$(2).tmp"
+       @echo "#endif /*$(4)*/" >> "$(2).tmp"
+       @touch "$$@"
+       @if cmp --quiet "$(2).tmp" "$(2)" ; then rm "$(2).tmp"; \
+       else mv "$(2).tmp" "$(2)" ; \
+       echo "Updated configuration $(2)" ; fi
+
+endef
+
+ifdef LOCAL_CONFIG_H
+
+# This must be declared after the default cflags are assigned!
+# Override is used to override command line assignemnt.
+override CFLAGS += -I $(USER_OBJS_DIR)
+override kernel_INCLUDES += -I $(KERN_OBJS_DIR)
+$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(USER_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+
+endif
+
+# Special rules for configuration exported headers
+
+#FIXME: The directory for headers should not be specified here.
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(USER_OBJS_DIR),$(addprefix $(USER_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+config_h_stamp_files = $(addprefix $(USER_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(config_h_stamp_files)
+
+ifneq ($(KERN_CONFIG_HEADERS_REQUIRED),)
+
+ifdef LOCAL_CONFIG_H
+$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(KERN_OBJS_DIR)/$(LOCAL_CONFIG_H),default_CONFIG,_LOCAL_CONFIG_H) )
+endif
+
+$(foreach confh,$(config_include_HEADERS),$(eval $(call BUILD_CONFIG_H_template,$(KERN_OBJS_DIR),$(addprefix $(KERN_INCLUDE_DIR)/,$(confh)),$(basename $(notdir $(confh)))_DEFINES,\
+_$(basename $(notdir $(confh)))_H \
+)))
+
+kern_config_h_stamp_files = $(addprefix $(KERN_OBJS_DIR)/,$(notdir $(addsuffix .stamp,$(config_include_HEADERS) $(LOCAL_CONFIG_H))))
+
+# Add some hooks to standard passes
+include-pass-local: $(kern_config_h_stamp_files)
+
+endif
+
+clean-local: clean-local-config-h
+
+clean-local-config-h:
+       @$(foreach confh,$(config_h_stamp_files) $(kern_config_h_stamp_files),\
+           if [ -e $(confh) ] ; then rm $(confh) ; fi ; \
+       )
+
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@qt
+ifneq ($(QT_SUBDIRS),)
+
+.PHONY: qt-subpass clean-qt distclean-qt
+
+# Usage: $(call qt_makefile_template,<qt-subdir>)
+define qt_makefile_template
+$(SOURCES_DIR)/$(1)/Makefile: $(wildcard $(SOURCES_DIR)/$(1)/*.pro)
+       cd $(SOURCES_DIR)/$(1); $(QTDIR:%=%/bin/)qmake TOP_DIR=$(OUTPUT_DIR) \
+            RELATIVE_DIR=$(RELATIVE_PREFIX)$(1) $(QTDIR:%=QTDIR=%) CC=$(CC) \
+            CXX=$(CXX) LIBS+="-L$(USER_LIB_DIR)" INCLUDEPATH+="$(USER_INCLUDE_DIR)"
+endef
+$(foreach dir,$(QT_SUBDIRS), $(eval $(call qt_makefile_template,$(dir))))
+
+qt-subpass: $(foreach dir,$(QT_SUBDIRS), $(SOURCES_DIR)/$(dir)/Makefile)
+       $(foreach dir,$(QT_SUBDIRS),\
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile || exit 1 ;)
+
+# Hook to binary pass
+binary-pass-submakes: qt-subpass
+
+# Hook to clean pass
+clean-local: clean-qt
+clean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  CLEAN   $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile clean|| exit 1 ;))
+
+
+# Hook to distclean
+distclean: distclean-qt
+
+# TODO: Add distclean-qt-pass to handle QT_SUBDIRS in the whole
+# tree. This way we only distclean toplevel subdirs.
+distclean-qt:
+       +@$(foreach dir, $(QT_SUBDIRS), \
+               $(if $(wildcard $(SOURCES_DIR)/$(dir)/Makefile), \
+               @$(QUIET_CMD_ECHO) "  DISTCLEAN $(dir)"; \
+               $(MAKE) SOURCES_DIR=$(SOURCES_DIR)/$(dir) \
+               RELATIVE_DIR=$(RELATIVE_PREFIX)$(dir) -C $(SOURCES_DIR)/$(dir) \
+               -f $(SOURCES_DIR)/$(dir)/Makefile distclean|| exit 1 ;))
+endif
+
+# Local Variables:
+# mode:makefile
+# End:
+                                                             #OMK@sources-list
+# Rules that creates the list of files which are used during
+# compilation. The list reflects conditional compilation depending on
+# config.omk and other variables.
+
+SOURCES_LIST_FN=sources.txt
+ifndef SOURCES_LIST
+SOURCES_LIST_DIR:=$(RELATIVE_DIR)
+SOURCES_LIST:=$(OUTPUT_DIR)/$(SOURCES_LIST_DIR)/$(SOURCES_LIST_FN)
+SOURCES_LIST_D := $(LOCAL_BUILD_DIR)/$(SOURCES_LIST_FN).d
+export SOURCES_LIST SOURCES_LIST_DIR SOURCES_LIST_D
+endif
+
+ifeq ($(MAKECMDGOALS),sources-list)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),TAGS)
+NEED_SOURCES_LIST=y
+endif
+ifeq ($(MAKECMDGOALS),tags)
+NEED_SOURCES_LIST=y
+endif
+
+ifeq ($(NEED_SOURCES_LIST),y) # avoid execution of find command bellow if it is not useful
+.PHONY: sources-list
+sources-list: $(SOURCES_LIST)
+
+$(SOURCES_LIST): $(CONFIG_FILES) $(shell find -name $(MAKEFILE_OMK))
+       @$(call mkdir_def,$(dir $(SOURCES_LIST_D)))
+       @echo -n "" > "$(SOURCES_LIST).tmp"
+       @echo -n "" > "$(SOURCES_LIST_D).tmp"
+       @$(MAKE) --no-print-directory sources-list-pass
+       @echo "# Automatically generated list of files in '$(RELATIVE_DIR)' that are used during OMK compilation" > "$(SOURCES_LIST).tmp2"
+       @cat "$(SOURCES_LIST).tmp"|sort|uniq >> "$(SOURCES_LIST).tmp2"
+       @rm "$(SOURCES_LIST).tmp"
+       @mv "$(SOURCES_LIST).tmp2" "$(SOURCES_LIST)"
+       @echo "$(SOURCES_LIST): \\" > "$(SOURCES_LIST_D).tmp2"
+       @cat "$(SOURCES_LIST_D).tmp"|grep -v "$(SOURCES_LIST_D).tmp"|sort|uniq|\
+               sed -e 's/$$/\\/' >> "$(SOURCES_LIST_D).tmp2"
+       @rm "$(SOURCES_LIST_D).tmp"
+       @mv "$(SOURCES_LIST_D).tmp2" "$(SOURCES_LIST_D)"
+endif
+
+$(eval $(call omk_pass_template,sources-list-pass,$$(LOCAL_BUILD_DIR),,always))
+
+sources-list-pass-local:
+       @$(foreach m,$(MAKEFILE_LIST),echo '  $(m)' >> "$(SOURCES_LIST_D).tmp";)
+       @$(foreach h,$(include_HEADERS) $(nobase_include_HEADERS) $(kernel_HEADERS),\
+         echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(h)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach ch,$(config_include_HEADERS), \
+         echo "$(USER_INCLUDE_DIR:$(OUTPUT_DIR)/$(addsuffix /,$(SOURCES_LIST_DIR))%=%)/$(ch)" >> "$(SOURCES_LIST).tmp";)
+       @$(foreach h,$(renamed_include_HEADERS),echo '$(h)'|sed -e 's|\(.*\)->.*|$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))\1|' >> "$(SOURCES_LIST).tmp";)
+       @$(foreach bin,$(lib_LIBRARIES) $(shared_LIBRARIES) $(bin_PROGRAMS) $(test_PROGRAMS) $(utils_PROGRAMS) \
+         $(kernel_LIBRARIES) $(rtlinux_LIBRARIES) $(kernel_MODULES),\
+         $(foreach src,$(filter-out %.o,$($(bin)_SOURCES)),echo "$(addsuffix /,$(RELATIVE_DIR:$(SOURCES_LIST_DIR)/%=%))$(src)" >> "$(SOURCES_LIST).tmp";))
+
+############ TAGS ###########
+
+ifeq ($(MAKECMDGOALS),TAGS)
+ETAGS=etags
+TAGS_CMD = $(ETAGS)
+TAGS: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+ifeq ($(MAKECMDGOALS),tags) 
+CTAGS=ctags -N
+TAGS_CMD = $(CTAGS)
+tags: $(SOURCES_LIST)
+       @$(MAKE) --no-print-directory do-tags
+endif
+export TAGS_CMD
+
+ifeq ($(MAKECMDGOALS),do-tags)
+.PHONY: do-tags
+do-tags: $(shell sed -e '/^\#/d' $(SOURCES_LIST))
+       @$(QUIET_CMD_ECHO) "  TAGS    $(SOURCES_LIST_FN)"
+       $(Q)$(TAGS_CMD) $^
+endif
+
+############ CSCOPE ###########
+
+cscope: $(SOURCES_LIST)
+       @$(QUIET_CMD_ECHO) "  CSCOPE  < $(SOURCES_LIST_FN)"
+       $(Q)sed -e '/^#/d' $(SOURCES_LIST)|cscope -b -i-
+#FIXME: see doc to -i in cscope(1)
+
+# Local Variables:
+# mode:makefile
+# End:
diff --git a/app-bohyn/_build/kern/ul_drv/ul_drv/ul_drv_config.h b/app-bohyn/_build/kern/ul_drv/ul_drv/ul_drv_config.h
new file mode 100644 (file)
index 0000000..ba16194
--- /dev/null
@@ -0,0 +1,7 @@
+/* Automatically generated from */
+/* config files: config.omk-default */
+#ifndef _LOCAL_CONFIG_H
+#define _LOCAL_CONFIG_H
+#define CONFIG_OC_UL_DRV_WITH_USB 1
+#define CONFIG_OC_UL_DRV_WITH_PCI 1
+#endif /*_LOCAL_CONFIG_H*/
diff --git a/app-bohyn/_build/kern/ul_drv/ul_drv/ul_drv_config.h.stamp b/app-bohyn/_build/kern/ul_drv/ul_drv/ul_drv_config.h.stamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/app-bohyn/_build/kern/ul_drv/ul_drv_config.h b/app-bohyn/_build/kern/ul_drv/ul_drv_config.h
new file mode 100644 (file)
index 0000000..ba16194
--- /dev/null
@@ -0,0 +1,7 @@
+/* Automatically generated from */
+/* config files: config.omk-default */
+#ifndef _LOCAL_CONFIG_H
+#define _LOCAL_CONFIG_H
+#define CONFIG_OC_UL_DRV_WITH_USB 1
+#define CONFIG_OC_UL_DRV_WITH_PCI 1
+#endif /*_LOCAL_CONFIG_H*/
diff --git a/app-bohyn/_build/kern/ul_drv/ul_drv_config.h.stamp b/app-bohyn/_build/kern/ul_drv/ul_drv_config.h.stamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/app-bohyn/_build/user/ul_drv/ul_drv/ul_drv_config.h b/app-bohyn/_build/user/ul_drv/ul_drv/ul_drv_config.h
new file mode 100644 (file)
index 0000000..ba16194
--- /dev/null
@@ -0,0 +1,7 @@
+/* Automatically generated from */
+/* config files: config.omk-default */
+#ifndef _LOCAL_CONFIG_H
+#define _LOCAL_CONFIG_H
+#define CONFIG_OC_UL_DRV_WITH_USB 1
+#define CONFIG_OC_UL_DRV_WITH_PCI 1
+#endif /*_LOCAL_CONFIG_H*/
diff --git a/app-bohyn/_build/user/ul_drv/ul_drv/ul_drv_config.h.stamp b/app-bohyn/_build/user/ul_drv/ul_drv/ul_drv_config.h.stamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/app-bohyn/_build/user/ul_drv/ul_drv_config.h b/app-bohyn/_build/user/ul_drv/ul_drv_config.h
new file mode 100644 (file)
index 0000000..ba16194
--- /dev/null
@@ -0,0 +1,7 @@
+/* Automatically generated from */
+/* config files: config.omk-default */
+#ifndef _LOCAL_CONFIG_H
+#define _LOCAL_CONFIG_H
+#define CONFIG_OC_UL_DRV_WITH_USB 1
+#define CONFIG_OC_UL_DRV_WITH_PCI 1
+#endif /*_LOCAL_CONFIG_H*/
diff --git a/app-bohyn/_build/user/ul_drv/ul_drv_config.h.stamp b/app-bohyn/_build/user/ul_drv/ul_drv_config.h.stamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_drv.o b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_drv.o
new file mode 100644 (file)
index 0000000..ffb5760
Binary files /dev/null and b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_drv.o differ
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_drv.o.d b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_drv.o.d
new file mode 100644 (file)
index 0000000..04f9671
--- /dev/null
@@ -0,0 +1,133 @@
+ul_l_drv.o ul_l_drv.o:  \
+ /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/ul_drv/ul_lib/ul_l_drv.c \
+  /usr/include/sys/types.h /usr/include/features.h \
+  /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
+  /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
+  /usr/include/bits/types.h /usr/include/bits/typesizes.h \
+  /usr/include/time.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h \
+  /usr/include/endian.h /usr/include/bits/endian.h \
+  /usr/include/sys/select.h /usr/include/bits/select.h \
+  /usr/include/bits/sigset.h /usr/include/bits/time.h \
+  /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \
+  /usr/include/sys/stat.h /usr/include/bits/stat.h \
+  /usr/include/sys/time.h /usr/include/unistd.h \
+  /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
+  /usr/include/getopt.h /usr/include/fcntl.h /usr/include/bits/fcntl.h \
+  /usr/include/errno.h /usr/include/bits/errno.h \
+  /usr/include/linux/errno.h /usr/include/asm/errno.h \
+  /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \
+  /usr/include/string.h /usr/include/bits/string.h \
+  /usr/include/bits/string2.h /usr/include/stdlib.h /usr/include/alloca.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h \
+  /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+  /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+  /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h \
+  /usr/include/sys/ttydefaults.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h
+
+/usr/include/sys/types.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/time.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/sys/stat.h:
+
+/usr/include/bits/stat.h:
+
+/usr/include/sys/time.h:
+
+/usr/include/unistd.h:
+
+/usr/include/bits/posix_opt.h:
+
+/usr/include/bits/confname.h:
+
+/usr/include/getopt.h:
+
+/usr/include/fcntl.h:
+
+/usr/include/bits/fcntl.h:
+
+/usr/include/errno.h:
+
+/usr/include/bits/errno.h:
+
+/usr/include/linux/errno.h:
+
+/usr/include/asm/errno.h:
+
+/usr/include/asm-generic/errno.h:
+
+/usr/include/asm-generic/errno-base.h:
+
+/usr/include/string.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+/usr/include/stdlib.h:
+
+/usr/include/alloca.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h:
+
+/usr/include/sys/ioctl.h:
+
+/usr/include/bits/ioctls.h:
+
+/usr/include/asm/ioctls.h:
+
+/usr/include/asm/ioctl.h:
+
+/usr/include/asm-generic/ioctl.h:
+
+/usr/include/bits/ioctl-types.h:
+
+/usr/include/sys/ttydefaults.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h:
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_log.o b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_log.o
new file mode 100644 (file)
index 0000000..271e8c5
Binary files /dev/null and b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_log.o differ
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_log.o.d b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_log.o.d
new file mode 100644 (file)
index 0000000..79cda9d
--- /dev/null
@@ -0,0 +1,109 @@
+ul_l_log.o ul_l_log.o:  \
+ /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/ul_drv/ul_lib/ul_l_log.c \
+  /usr/include/stdlib.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h \
+  /usr/include/sys/types.h /usr/include/bits/types.h \
+  /usr/include/bits/typesizes.h /usr/include/time.h /usr/include/endian.h \
+  /usr/include/bits/endian.h /usr/include/sys/select.h \
+  /usr/include/bits/select.h /usr/include/bits/sigset.h \
+  /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
+  /usr/include/bits/pthreadtypes.h /usr/include/alloca.h \
+  /usr/include/stdio.h /usr/include/libio.h /usr/include/_G_config.h \
+  /usr/include/wchar.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h \
+  /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \
+  /usr/include/bits/stdio.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h \
+  /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+  /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+  /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h \
+  /usr/include/sys/ttydefaults.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_l_log.h
+
+/usr/include/stdlib.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/time.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/alloca.h:
+
+/usr/include/stdio.h:
+
+/usr/include/libio.h:
+
+/usr/include/_G_config.h:
+
+/usr/include/wchar.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h:
+
+/usr/include/bits/stdio_lim.h:
+
+/usr/include/bits/sys_errlist.h:
+
+/usr/include/bits/stdio.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h:
+
+/usr/include/sys/ioctl.h:
+
+/usr/include/bits/ioctls.h:
+
+/usr/include/asm/ioctls.h:
+
+/usr/include/asm/ioctl.h:
+
+/usr/include/asm-generic/ioctl.h:
+
+/usr/include/bits/ioctl-types.h:
+
+/usr/include/sys/ttydefaults.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_l_log.h:
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_msg.o b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_msg.o
new file mode 100644 (file)
index 0000000..89acd1c
Binary files /dev/null and b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_msg.o differ
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_msg.o.d b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_msg.o.d
new file mode 100644 (file)
index 0000000..38589fa
--- /dev/null
@@ -0,0 +1,96 @@
+ul_l_msg.o ul_l_msg.o:  \
+ /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/ul_drv/ul_lib/ul_l_msg.c \
+  /usr/include/stdlib.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h \
+  /usr/include/sys/types.h /usr/include/bits/types.h \
+  /usr/include/bits/typesizes.h /usr/include/time.h /usr/include/endian.h \
+  /usr/include/bits/endian.h /usr/include/sys/select.h \
+  /usr/include/bits/select.h /usr/include/bits/sigset.h \
+  /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
+  /usr/include/bits/pthreadtypes.h /usr/include/alloca.h \
+  /usr/include/string.h /usr/include/bits/string.h \
+  /usr/include/bits/string2.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h \
+  /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+  /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+  /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h \
+  /usr/include/sys/ttydefaults.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h
+
+/usr/include/stdlib.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/time.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h:
+
+/usr/include/sys/ioctl.h:
+
+/usr/include/bits/ioctls.h:
+
+/usr/include/asm/ioctls.h:
+
+/usr/include/asm/ioctl.h:
+
+/usr/include/asm-generic/ioctl.h:
+
+/usr/include/bits/ioctl-types.h:
+
+/usr/include/sys/ttydefaults.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h:
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_oi.o b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_oi.o
new file mode 100644 (file)
index 0000000..31e3ced
Binary files /dev/null and b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_oi.o differ
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_oi.o.d b/app-bohyn/_build/user/ul_drv/ul_lib/ul_l_oi.o.d
new file mode 100644 (file)
index 0000000..184abea
--- /dev/null
@@ -0,0 +1,99 @@
+ul_l_oi.o ul_l_oi.o:  \
+ /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/ul_drv/ul_lib/ul_l_oi.c \
+  /usr/include/stdlib.h /usr/include/features.h /usr/include/sys/cdefs.h \
+  /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
+  /usr/include/gnu/stubs-64.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h \
+  /usr/include/sys/types.h /usr/include/bits/types.h \
+  /usr/include/bits/typesizes.h /usr/include/time.h /usr/include/endian.h \
+  /usr/include/bits/endian.h /usr/include/sys/select.h \
+  /usr/include/bits/select.h /usr/include/bits/sigset.h \
+  /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
+  /usr/include/bits/pthreadtypes.h /usr/include/alloca.h \
+  /usr/include/string.h /usr/include/bits/string.h \
+  /usr/include/bits/string2.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h \
+  /usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h \
+  /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+  /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+  /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h \
+  /usr/include/sys/ttydefaults.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h \
+  /home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_l_log.h
+
+/usr/include/stdlib.h:
+
+/usr/include/features.h:
+
+/usr/include/sys/cdefs.h:
+
+/usr/include/bits/wordsize.h:
+
+/usr/include/gnu/stubs.h:
+
+/usr/include/gnu/stubs-64.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stddef.h:
+
+/usr/include/sys/types.h:
+
+/usr/include/bits/types.h:
+
+/usr/include/bits/typesizes.h:
+
+/usr/include/time.h:
+
+/usr/include/endian.h:
+
+/usr/include/bits/endian.h:
+
+/usr/include/sys/select.h:
+
+/usr/include/bits/select.h:
+
+/usr/include/bits/sigset.h:
+
+/usr/include/bits/time.h:
+
+/usr/include/sys/sysmacros.h:
+
+/usr/include/bits/pthreadtypes.h:
+
+/usr/include/alloca.h:
+
+/usr/include/string.h:
+
+/usr/include/bits/string.h:
+
+/usr/include/bits/string2.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ulan.h:
+
+/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include/stdarg.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h:
+
+/usr/include/sys/ioctl.h:
+
+/usr/include/bits/ioctls.h:
+
+/usr/include/asm/ioctls.h:
+
+/usr/include/asm/ioctl.h:
+
+/usr/include/asm-generic/ioctl.h:
+
+/usr/include/bits/ioctl-types.h:
+
+/usr/include/sys/ttydefaults.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fd.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_fddir.h:
+
+/home/stefic/BAP/build_ulan/ulan/embedded/hydro/app-bohyn/_compiled/include/ul_lib/ul_l_log.h:
diff --git a/app-bohyn/_build/user/ul_drv/ul_lib/ul_lib_config.h.stamp b/app-bohyn/_build/user/ul_drv/ul_lib/ul_lib_config.h.stamp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/app-bohyn/_compiled/include/ul_l_drv_eth.h b/app-bohyn/_compiled/include/ul_l_drv_eth.h
new file mode 100644 (file)
index 0000000..f91bfde
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _UL_L_DRV_ETH_H
+#define _UL_L_DRV_ETH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ul_dbuff.h>
+#include <ul_netbase.h>
+
+#define UL_ETH_SOCK_TIMEOUT 10
+
+int ul_eth_recv_msg(int fd,ul_dbuff_t *rcvbuff,int timeout, int *terminated);
+int ul_eth_send_msg(FILE *fd,ul_msg_buf_t *sndbuff);
+int ul_eth_demarshal_stream(ul_msg_buf_t *msg_buf,char *stream,int stream_len);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /*_UL_L_DRV_ETH_H*/
diff --git a/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h b/app-bohyn/_compiled/include/ul_lib/ul_drvdef.h
new file mode 100644 (file)
index 0000000..1b34fe7
--- /dev/null
@@ -0,0 +1,141 @@
+/*******************************************************************
+  uLan Communication - user visible definitions
+
+  ul_drvdef.h  - driver exported definitions and types to userspace
+
+  (C) Copyright 1996,1999 by Pavel Pisa 
+
+  The uLan driver is distributed under the Gnu General Public Licence. 
+  See file COPYING for details.
+ *******************************************************************/
+
+#ifndef _UL_DRVDEF_H
+#define _UL_DRVDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined OMK_FOR_TARGET || defined OMK_FOR_USER || defined OMK_FOR_KERNEL
+  #include <ul_lib/ul_lib_config.h>
+#endif
+
+#ifndef _WIN32
+ #ifndef CONFIG_OC_UL_DRV_SYSLESS
+   #include <sys/ioctl.h>
+ #endif /* CONFIG_OC_UL_DRV_SYSLESS */
+#else /* _WIN32 */
+ #include <windows.h>
+ #include <winioctl.h>
+#endif /* _WIN32 */
+
+#ifndef uchar
+ #define uchar unsigned char
+#endif
+
+/* ul_mess_head flags definition defines proccessing 
+   of message or its frames stored in bll */
+#define UL_BFL_LOCK 0x8000     /* locked message is pointed only once */
+#define UL_BFL_MSST 0x4000      /* Message must be received by some proccess */
+#define UL_BFL_M2IN 0x2000      /* After succesfull proccessing move to proc_bll */
+#define UL_BFL_LNMM 0x1000      /* Length of received frame must match expected len */
+#define UL_BFL_FAIL 0x0800      /* Message cannot be proccessed - error */
+#define UL_BFL_TAIL 0x0400      /* Multiframe message continues by next bll block */
+#define UL_BFL_SND  0x0200      /* Send this frame */
+#define UL_BFL_REC  0x0100      /* Receive answer frame into this bll block */
+#define UL_BFL_VERL 0x0040      /* Verify free space in buffer of destination station */
+#define UL_BFL_NORE 0x0020      /* Do not try to repeat if error occurs */
+#define UL_BFL_REWA 0x0010      /* If error occurs do wait with retry */
+#define UL_BFL_PRQ  0x0002      /* Request imediate proccessing of frame by receiver station */
+#define UL_BFL_ARQ  0x0001      /* Request imediate acknowledge by receiving station */
+
+#define UL_BFL_PROC 0x0000      /* Flag used by ASM code version */
+
+/*******************************************************************/
+/* ioctl definitions */
+
+#ifdef _WIN32
+
+/* 32768-65535 are reserved for use by customers.*/
+#define FILE_DEVICE_ULAN  0x0000A000
+
+/* function codes 2048-4095 are reserved for customers. */
+#define UL_IOCTL_INDEX  0xA00
+
+#define UL_IO(function) \
+       CTL_CODE(FILE_DEVICE_ULAN,UL_IOCTL_INDEX+function,METHOD_BUFFERED,FILE_ANY_ACCESS)
+#define UL_IOR(function,size) \
+       CTL_CODE(FILE_DEVICE_ULAN,UL_IOCTL_INDEX+function,METHOD_BUFFERED,FILE_ANY_ACCESS)
+#define UL_IOW(function,size) \
+       CTL_CODE(FILE_DEVICE_ULAN,UL_IOCTL_INDEX+function,METHOD_BUFFERED,FILE_ANY_ACCESS)
+
+#else /* _WIN32 */
+
+#define        UL_IOCTL        0x75
+
+#define UL_IO(function)        _IO(UL_IOCTL,function)
+#define UL_IOR(function,size)  _IOR(UL_IOCTL,function,size)
+#define UL_IOW(function,size)  _IOW(UL_IOCTL,function,size)
+
+#endif /* _WIN32 */
+
+#define UL_DRV_VER     UL_IO(0x10)
+#define UL_NEWMSG      UL_IOW(0x11,ul_msginfo)
+#define UL_TAILMSG     UL_IOW(0x12,ul_msginfo)
+#define UL_FREEMSG     UL_IO(0x13)
+#define UL_ACCEPTMSG   UL_IOR(0x14,ul_msginfo)
+#define UL_ACTAILMSG   UL_IOR(0x15,ul_msginfo)
+#define UL_ADDFILT     UL_IOW(0x16,ul_msginfo)
+#define UL_ABORTMSG    UL_IO(0x17)
+#define UL_REWMSG      UL_IO(0x18)
+#define UL_INEPOLL     UL_IO(0x19)
+#define UL_WAITREC     UL_IO(0x1A)
+#define UL_SETMYADR    UL_IO(0x1B)  /* arg = new station address */
+#define UL_SETIDSTR    UL_IO(0x1C)  /* arg = "C" string */
+#define UL_SETBAUDRATE UL_IO(0x1D)  /* arg = new baudrate */
+#define UL_KLOGBLL     UL_IO(0x41)
+#define UL_STROKE      UL_IO(0x42)
+#define UL_DEBFLG      UL_IO(0x43)  /* arg = new debug mask */
+#define UL_HWTEST      UL_IO(0x44)  /* arg = test subcommand */
+
+typedef struct ul_msginfo {
+       int     dadr;           /* destignation address */
+       int     sadr;           /* source address */
+       int     cmd;            /* command/socket number */
+       int     flg;            /* message flags */
+       int     len;            /* length of frame */
+       unsigned stamp;         /* unigue message number */
+} ul_msginfo;
+
+/*******************************************************************/
+/* command definitions */
+
+/* standard command codes 
+   00H .. 3FH    store to buffer 
+   40H .. 7FH    store to buffer without ACK
+   80H .. 9FH    proccess at onece
+   A0H .. BFH    process with additional receive
+   C0H .. FFH    process with additional send
+*/
+
+#define UL_CMD_RES     0x80    /* Reinitialize RS485 or connected module */
+#define UL_CMD_SFT     0x81    /* Test free space in input buffer */
+#define UL_CMD_SID     0xF0    /* Send identification */
+#define UL_CMD_SFI     0xF1    /* Send amount of free space in IB */
+#define UL_CMD_TF0     0x98    /* End of stepping */
+#define UL_CMD_TF1     0x99    /* Begin of stepping */
+#define UL_CMD_STP     0x9A    /* Do step */
+#define UL_CMD_DEB     0x9B    /* Additional debug commands */
+#define UL_CMD_SPC     0xDA    /* Send state - for 8051 PCL PCH PSW ACC */
+
+#define UL_CMD_RDM     0xF8    /* Read memory   T T B B L L */
+#define UL_CMD_WRM     0xB8    /* Write mamory  T T B B L L */
+#define UL_CMD_ERM      0x88    /* Erase memory T T B B L L */
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /* _UL_DRVDEF_H */
+
+
diff --git a/app-bohyn/_compiled/include/ul_lib/ul_fd.h b/app-bohyn/_compiled/include/ul_lib/ul_fd.h
new file mode 100644 (file)
index 0000000..5d50e01
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef _UL_FD_H
+#define _UL_FD_H
+
+/* The applications calls directly functions based above uLan driver API */
+
+#include <ul_lib/ul_fddir.h>
+
+#undef WITH_UL_FD_INDIRECT
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef ul_fd_direct_t ul_fd_t;
+#define UL_FD_INVALID UL_FD_DIRECT_INVALID
+
+static inline ul_fd_direct_t ul_fd2sys_fd(ul_fd_t fd)
+{
+  return fd;
+}
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /*_UL_FD_H*/
diff --git a/app-bohyn/_compiled/include/ul_lib/ul_fddir.h b/app-bohyn/_compiled/include/ul_lib/ul_fddir.h
new file mode 100644 (file)
index 0000000..bb643c9
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef _UL_FDDIR_H
+#define _UL_FDDIR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _WIN32
+
+ #define UL_DEV_NAME "\\\\.\\UL_DRV"
+
+ typedef HANDLE ul_fd_direct_t;
+
+ #define UL_FD_DIRECT_INVALID INVALID_HANDLE_VALUE
+ typedef long ssize_t;
+
+ #define WITHOUT_SYS_SELECT
+ #define HAS_GETOPT_LONG
+
+ #ifdef WITH_UL_FD_INDIRECT
+ #define WIN32_FILE_OVERLAPPED
+ #endif /* WITH_UL_FD_INDIRECT */
+ #if defined(WIN32_FILE_OVERLAPPED)&&!defined(WITH_UL_FD_INDIRECT)
+   #error to enable WIN32_FILE_OVERLAPPED operation is neccessary compile sources with flag WITH_UL_FD_INDIRECT
+ #endif
+
+#elif defined(__DJGPP__) || defined(CONFIG_OC_UL_DRV_SYSLESS) || defined(CONFIG_OC_UL_DRV_USLIB)
+
+ #ifdef(__DJGPP__)
+   #define UL_DEV_NAME "1"
+ #else /* !__DJGPP__ */
+   #define UL_DEV_NAME "/dev/ulan"
+ #endif  /* !__DJGPP__ */
+
+ struct ul_opdata;
+ typedef struct ul_opdata *ul_fd_direct_t;
+ #define UL_FD_DIRECT_INVALID (NULL)
+
+ #define WITHOUT_SYS_SELECT
+ #define UL_DRV_IN_LIB
+
+#else /* !_WIN32 && !__DJGPP__ */
+
+ #define UL_DEV_NAME "/dev/ulan"
+
+ typedef int ul_fd_direct_t;
+
+ #define UL_FD_DIRECT_INVALID (-1)
+
+ #define HAS_GETDELIM
+ #define HAS_GETOPT_LONG
+
+#endif /* _WIN32 */
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /*_UL_FDDIR_H*/
diff --git a/app-bohyn/_compiled/include/ul_lib/ul_l_log.h b/app-bohyn/_compiled/include/ul_lib/ul_l_log.h
new file mode 100644 (file)
index 0000000..e2305a7
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef _UL_L_LOG_H
+#define _UL_L_LOG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* debugging support routines */
+int uloi_debug_flg;
+
+#ifndef UL_LOGL_FATAL
+
+#define UL_LOGL_MASK (0xff)
+#define UL_LOGL_CONT (0x1000)
+
+#define UL_LOGL_FATAL   1
+#define UL_LOGL_ERR     2
+#define UL_LOGL_MSG     3
+#define UL_LOGL_INF     4
+#define UL_LOGL_DEB     5
+#define UL_LOGL_TRASH   6
+
+#endif /*UL_LOGL_FATAL*/
+
+struct ul_log_domain;
+
+typedef void (ul_log_fnc_t)(struct ul_log_domain *domain, int level,
+       const char *format, va_list ap);
+
+void ul_log(struct ul_log_domain *domain, int level,
+       const char *format, ...) UL_ATTR_PRINTF (3, 4);
+
+void ul_log_redir(ul_log_fnc_t *log_fnc, int add_flags);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /* _UL_L_LOG_H */
+
diff --git a/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h b/app-bohyn/_compiled/include/ul_lib/ul_lib_config.h
new file mode 100644 (file)
index 0000000..867ef2f
--- /dev/null
@@ -0,0 +1,5 @@
+/* Automatically generated from */
+/* config files: config.omk-default */
+#ifndef  _ul_lib_config_H 
+#define  _ul_lib_config_H 
+#endif /* _ul_lib_config_H */
diff --git a/app-bohyn/_compiled/include/ul_lib/ulan.h b/app-bohyn/_compiled/include/ul_lib/ulan.h
new file mode 100644 (file)
index 0000000..a18f06f
--- /dev/null
@@ -0,0 +1,157 @@
+#ifndef _ULAN_H
+#define _ULAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <ul_lib/ul_drvdef.h>
+#include <ul_lib/ul_fd.h>
+
+/* GNUC neat features */
+
+#ifdef __GNUC__
+#ifndef UL_ATTR_UNUSED
+#define UL_ATTR_PRINTF( format_idx, arg_idx )  \
+  __attribute__((format (printf, format_idx, arg_idx)))
+#define UL_ATTR_SCANF( format_idx, arg_idx )   \
+  __attribute__((format (scanf, format_idx, arg_idx)))
+#define UL_ATTR_FORMAT( arg_idx )              \
+  __attribute__((format_arg (arg_idx)))
+#define UL_ATTR_NORETURN                       \
+  __attribute__((noreturn))
+#define UL_ATTR_CONST                          \
+  __attribute__((const))
+#define        UL_ATTR_UNUSED                          \
+  __attribute__((unused))
+#endif  /*UL_ATTR_UNUSED*/
+#else  /* !__GNUC__ */
+#ifndef UL_ATTR_UNUSED
+#define UL_ATTR_PRINTF( format_idx, arg_idx )
+#define UL_ATTR_SCANF( format_idx, arg_idx )
+#define UL_ATTR_FORMAT( arg_idx )
+#define UL_ATTR_NORETURN
+#define UL_ATTR_CONST
+#define        UL_ATTR_UNUSED
+#endif  /*UL_ATTR_UNUSED*/
+#endif /* !__GNUC__ */
+
+/* driver interface */
+
+ul_fd_t        ul_open(const char *dev_name, const char *options);
+int    ul_close(ul_fd_t ul_fd);
+int    ul_drv_version(ul_fd_t ul_fd);
+ssize_t        ul_read(ul_fd_t ul_fd, void *buffer, size_t size);
+ssize_t        ul_write(ul_fd_t ul_fd, const void *buffer, size_t size);
+int    ul_newmsg(ul_fd_t ul_fd,const ul_msginfo *msginfo);
+int    ul_tailmsg(ul_fd_t ul_fd,const ul_msginfo *msginfo);
+int    ul_freemsg(ul_fd_t ul_fd);
+int    ul_acceptmsg(ul_fd_t ul_fd,ul_msginfo *msginfo);
+int    ul_actailmsg(ul_fd_t ul_fd,ul_msginfo *msginfo);
+int    ul_addfilt(ul_fd_t ul_fd,const ul_msginfo *msginfo);
+int    ul_abortmsg(ul_fd_t ul_fd);
+int    ul_rewmsg(ul_fd_t ul_fd);
+int    ul_inepoll(ul_fd_t ul_fd);
+int    ul_drv_debflg(ul_fd_t ul_fd,int debug_msk);
+int    ul_fd_wait(ul_fd_t ul_fd, int wait_sec);
+int    ul_setmyadr(ul_fd_t ul_fd, int newadr);
+int    ul_setidstr(ul_fd_t ul_fd, const char *idstr);
+int    ul_setbaudrate(ul_fd_t ul_fd, int baudrate);
+int    ul_stroke(ul_fd_t ul_fd);
+
+/* simple message operations */
+
+int ul_send_command(ul_fd_t ul_fd,int dadr,int cmd,int flg,
+                    const void *buf,int len);
+int ul_send_command_wait(ul_fd_t ul_fd,int dadr,int cmd,int flg,
+                         const void *buf,int len);
+int ul_send_query(ul_fd_t ul_fd,int dadr,int cmd,int flg,
+                  const void *buf,int len);
+int ul_send_query_wait(ul_fd_t ul_fd,int dadr,int cmd,int flg,
+                      const void *bufin,int lenin,void **bufout,int *lenout);
+
+/* basic uLan commands/services */
+
+#define UL_CMD_OISV    0x10    /* Object Interface Service */
+#define UL_CMD_LCDABS  0x4f    /* Absorbance data block */
+#define UL_CMD_LCDMRK  0x4e    /* Mark */
+#define UL_CMD_NCS     0x7f    /* Network Control Service */
+#define UL_CMD_GST     0xc1    /* Fast module get status */
+#define UL_CMD_PDO     0xc2    /* Asynchronous service */
+
+/* definitions of basic uLan OI commands */
+
+#define ULOI_AOID   10 /* name is defined in ASCII for DOIx */
+#define ULOI_DOII   12 /* description of input objects */
+#define ULOI_DOIO   14 /* description of output objects */
+#define ULOI_QOII   16 /* ID numbers of recognized input objects */
+#define ULOI_QOIO   18 /* ID numbers of recognized output objects */
+#define ULOI_RDRQ   20 /* object values read request */
+#define ULOI_STATUS 30 /* read instrument status */
+#define ULOI_ERRCLR 31 /* clear error status */
+
+typedef struct uloi_coninfo_t {
+  int adr;     /* address of target module */
+  int cmd;     /* service/cmd number for uLOI on target */
+  int bcmd;    /* service/cmd number for returned messages */
+  int sn;      /* sequence counter */
+  int bsn;     /* sequence counter of target module */
+  int outflg;  /* flags used for outgoing messages */
+  ul_fd_t ul_fd;/* handle for ul_drv */
+  ul_fd_t ul_fd1;/* the auxiliary handle for ULOI direct reply */
+  int timeout; /* timeout */
+  int error;   /* error condition occurred */
+  int state;   /* internal state */
+} uloi_coninfo_t;
+
+/* definitions of basic uLan OI functions */
+
+uloi_coninfo_t* uloi_open(char *ul_dev_name,int adr,int cmd,
+                       int bcmd, int timeout);
+void uloi_close(uloi_coninfo_t *coninfo);
+int uloi_transfer(uloi_coninfo_t *coninfo,
+                 uchar *bufin,int lenin,uchar **bufout,int *lenout);
+int uloi_set_var(uloi_coninfo_t *coninfo,int oid, void *val, int size);
+int uloi_get_var(uloi_coninfo_t *coninfo,int oid, void *val, int size);
+int uloi_set_var_u2(uloi_coninfo_t *coninfo,int oid,unsigned val);
+int uloi_get_var_u2(uloi_coninfo_t *coninfo,int oid,unsigned *val);
+int uloi_send_cmd(uloi_coninfo_t *coninfo,int oid);
+int uloi_get_oids(uloi_coninfo_t *coninfo,int list,int **oids_list);
+int uloi_get_oiddes(uloi_coninfo_t *coninfo,int list, int oid, uchar **poiddespack);
+int uloi_get_aoiddes(uloi_coninfo_t *coninfo,int list,char *aoid, uchar **poiddespack);
+uchar *uloi_oiddespack_getloc(uchar *despack, int strindex);
+char *uloi_oiddespack_strdup(uchar *despack, int strindex);
+
+/* UL_CMD_NCS  Network Control Service */
+
+#define ULNCS_ADR_RQ   0xC0    /* SN0 SN1 SN2 SN3 */
+#define ULNCS_SET_ADDR 0xC1    /* SN0 SN1 SN2 SN3 NEW_ADR */
+#define ULNCS_SID_RQ   0xC2    /* send serial num and ID string request */
+#define ULNCS_SID_RPLY 0xC3    /* SN0 SN1 SN2 SN3 ID ... */
+#define ULNCS_ADDR_NVSV        0xC4    /* SN0 SN1 SN2 SN3 - save addres to EEPROM */
+#define ULNCS_BOOT_ACT  0xC5    /* SN0 SN1 SN2 SN3 */
+#define ULNCS_BOOT_ACK  0xC6    /* SN0 SN1 SN2 SN3 */
+#define ULNCS_SET_SN    0xE0    /* SN0 SN1 SN2 SN3 */
+
+/* UL_CMD_RES  Reinitialize RS485 or connected module */
+
+#define ULRES_LINK      0x10
+#define ULRES_BAUD      0x12
+#define ULRES_CPU       0x21    /* password - default 0x55 0xAA */
+
+#if 0
+  #define  read                error_to_use_read
+  #define  write       error_to_use_write
+  #define  open                error_to_use_open
+  #define  close       error_to_use_close
+  #define  ioctl       error_to_use_ioctl
+#endif
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /* _ULAN_H */
+
diff --git a/app-bohyn/_compiled/include/ul_msg_buf.h b/app-bohyn/_compiled/include/ul_msg_buf.h
new file mode 100644 (file)
index 0000000..9d73b0e
--- /dev/null
@@ -0,0 +1,54 @@
+/*******************************************************************
+  uLan Communication - C interface library
+
+  ul_netbase.c - basic network and module constructions
+
+  (C) Copyright 2001 by Pavel Pisa - Originator
+
+  (C) Copyright 2002-2004 by Pavel Pisa - Originator
+
+  The uLan C interface library can be used, copied and modified
+  under next licenses
+    - GPL - GNU General Public License
+    - LGPL - GNU Lesser General Public License
+    - MPL - Mozilla Public License
+    - and other licenses added by project originators
+  Code can be modified and re-distributed under any combination
+  of the above listed licenses. If contributor does not agree with
+  some of the licenses, he/she can delete appropriate line.
+  Warning, if you delete all lines, you are not allowed to
+  distribute source code and/or binaries utilizing code.
+  
+  See files COPYING and README for details.
+
+ *******************************************************************/
+
+#ifndef _UL_MSG_BUF_H
+#define _UL_MSG_BUF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <ul_lib/ulan.h>
+#include <ul_dbuff.h>
+
+
+typedef struct ul_msg_buf{     /* buffer to hold full message taken from driver */
+  ul_msginfo msginfo;          /* dadr, sadr, cmd, flg, len, stamp */
+  ul_dbuff_t  data;            /* message data */
+  struct ul_msg_buf *tail;     /* optional tail message */
+} ul_msg_buf_t;
+
+
+int ul_msg_buf_init(ul_msg_buf_t *buf);
+void ul_msg_buf_destroy(ul_msg_buf_t *buf);
+int ul_msg_buf_rd_data(ul_msg_buf_t *buf, ul_fd_t ul_fd);
+int ul_msg_buf_rd_rest(ul_msg_buf_t *buf, ul_fd_t ul_fd);
+int ul_msg_buf_wr(ul_msg_buf_t *buf, ul_fd_t ul_fd);
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /* _UL_MSG_BUF_H */
diff --git a/app-bohyn/_compiled/lib/libulan.a b/app-bohyn/_compiled/lib/libulan.a
new file mode 100644 (file)
index 0000000..4d0e652
Binary files /dev/null and b/app-bohyn/_compiled/lib/libulan.a differ
diff --git a/app-bohyn/lighttpd_conf/lighttpd.conf b/app-bohyn/lighttpd_conf/lighttpd.conf
new file mode 100644 (file)
index 0000000..8e2c53c
--- /dev/null
@@ -0,0 +1,201 @@
+# Debian lighttpd configuration file
+#
+
+############ Options you really have to take care of ####################
+
+## modules to load
+# mod_access, mod_accesslog and mod_alias are loaded by default
+# all other module should only be loaded if neccesary
+# - saves some time
+# - saves memory
+
+server.modules              = (
+            "mod_access",
+            "mod_alias",
+            "mod_accesslog",
+            "mod_compress",
+#           "mod_fastcgi",
+#           "mod_rewrite",
+#           "mod_redirect",
+#           "mod_evhost",
+#           "mod_usertrack",
+#           "mod_rrdtool",
+#           "mod_webdav",
+#           "mod_expire",
+#           "mod_flv_streaming",
+#           "mod_evasive"
+)
+
+## a static document-root, for virtual-hosting take look at the
+## server.virtual-* options
+server.document-root       = "/var/www/"
+
+## where to upload files to, purged daily.
+server.upload-dirs = ( "/var/cache/lighttpd/uploads" )
+
+## where to send error-messages to
+server.errorlog            = "/var/log/lighttpd/error.log"
+
+## files to check for if .../ is requested
+index-file.names           = ( "index.php", "index.html",
+                               "index.htm", "default.htm",
+                               "index.lighttpd.html" )
+
+
+## Use the "Content-Type" extended attribute to obtain mime type if possible
+# mimetype.use-xattr = "enable"
+
+#### accesslog module
+accesslog.filename         = "/var/log/lighttpd/access.log"
+
+## deny access the file-extensions
+#
+# ~    is for backupfiles from vi, emacs, joe, ...
+# .inc is often used for code includes which should in general not be part
+#      of the document-root
+url.access-deny            = ( "~", ".inc" )
+
+##
+# which extensions should not be handle via static-file transfer
+#
+# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
+static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
+
+
+######### Options that are good to be but not neccesary to be changed #######
+
+## Use ipv6 only if available.
+include_shell "/usr/share/lighttpd/use-ipv6.pl"
+
+## bind to port (default: 80)
+server.port               = 81
+
+## bind to localhost only (default: all interfaces)
+## server.bind                = "localhost"
+
+## error-handler for status 404
+#server.error-handler-404  = "/error-handler.html"
+#server.error-handler-404  = "/error-handler.php"
+
+## to help the rc.scripts
+server.pid-file            = "/var/run/lighttpd.pid"
+
+##
+## Format: <errorfile-prefix><status>.html
+## -> ..../status-404.html for 'File not found'
+#server.errorfile-prefix    = "/var/www/"
+
+## virtual directory listings
+dir-listing.encoding        = "utf-8"
+server.dir-listing          = "enable"
+
+## send unhandled HTTP-header headers to error-log
+#debug.dump-unknown-headers  = "enable"
+
+### only root can use these options
+#
+# chroot() to directory (default: no chroot() )
+#server.chroot            = "/"
+
+## change uid to <uid> (default: don't care)
+server.username            = "www-data"
+
+## change uid to <uid> (default: don't care)
+server.groupname           = "www-data"
+
+#### compress module
+compress.cache-dir          = "/var/cache/lighttpd/compress/"
+compress.filetype           = ("text/plain", "text/html", "application/x-javascript", "text/css")
+
+
+#### url handling modules (rewrite, redirect, access)
+# url.rewrite                 = ( "^/$"             => "/server-status" )
+# url.redirect                = ( "^/wishlist/(.+)" => "http://www.123.org/$1" )
+
+#
+# define a pattern for the host url finding
+# %% => % sign
+# %0 => domain name + tld
+# %1 => tld
+# %2 => domain name without tld
+# %3 => subdomain 1 name
+# %4 => subdomain 2 name
+#
+# evhost.path-pattern = "/home/storage/dev/www/%3/htdocs/"
+
+#### expire module
+# expire.url                  = ( "/buggy/" => "access 2 hours", "/asdhas/" => "access plus 1 seconds 2 minutes")
+
+#### rrdtool
+# rrdtool.binary = "/usr/bin/rrdtool"
+# rrdtool.db-name = "/var/www/lighttpd.rrd"
+
+
+#### variable usage:
+## variable name without "." is auto prefixed by "var." and becomes "var.bar"
+#bar = 1
+#var.mystring = "foo"
+
+## integer add
+#bar += 1
+## string concat, with integer cast as string, result: "www.foo1.com"
+#server.name = "www." + mystring + var.bar + ".com"
+## array merge
+#index-file.names = (foo + ".php") + index-file.names
+#index-file.names += (foo + ".php")
+
+
+#### external configuration files
+## mimetype mapping
+include_shell "/usr/share/lighttpd/create-mime.assign.pl"
+
+## load enabled configuration files,
+## read /etc/lighttpd/conf-available/README first
+include_shell "/usr/share/lighttpd/include-conf-enabled.pl"
+
+#### handle Debian Policy Manual, Section 11.5. urls
+## by default allow them only from localhost
+## (This must come last due to #445459)
+## Note: =~ "127.0.0.1" works with ipv6 enabled, whereas == "127.0.0.1" doesn't
+$HTTP["remoteip"] =~ "127.0.0.1" {
+       alias.url += (
+               "/doc/" => "/usr/share/doc/",
+               "/images/" => "/usr/share/images/"
+       )
+       $HTTP["url"] =~ "^/doc/|^/images/" {
+               dir-listing.activate = "enable"
+       }
+}
+
+$HTTP["host"] == "hydroponie" {
+    server.server-root = "/var/www"
+    server.document-root = "/"
+
+    fastcgi.server = ( "/scripts/" =>
+       ((      "bin-path" => "/home/bohacekm/fel/X36BAP/hydroweb/src/hydroponie",
+            "socket" => "/tmp/hydro.socket",
+           "max-procs" => 1,
+            "check-local" => "disable",
+           "docroot" => "/scripts/" # remote server may use
+                            # it's own docroot
+       ))
+    )
+}
+
+
+#$HTTP["host"] == "threads" {
+#    server.server-root = "/var/www"
+#    server.document-root = "/"
+#    
+#    fastcgi.server = ( "/" =>
+#        ((  "bin-path" => "/home/bohacekm/src/qt_lighttpd_test/fcgi_testapp",
+#            "socket" => "/tmp/fcgi_testapp.socket",
+#            "max-procs" => 10,
+#            "check-local" => "disable",
+#            "docroot" => "/" # remote server may use
+#                           # it's own docroot
+#        ))
+#    )
+#}
+                                                                                                             
+                                                                                                             
diff --git a/app-bohyn/media/arrow_refresh.png b/app-bohyn/media/arrow_refresh.png
new file mode 100644 (file)
index 0000000..0de2656
Binary files /dev/null and b/app-bohyn/media/arrow_refresh.png differ
diff --git a/app-bohyn/media/js/jquery.js b/app-bohyn/media/js/jquery.js
new file mode 100644 (file)
index 0000000..d646859
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * jQuery 1.2.1 - New Wave Javascript
+ *
+ * Copyright (c) 2007 John Resig (jquery.com)
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
+ * and GPL (GPL-LICENSE.txt) licenses.
+ *
+ * $Date: 2007-09-16 23:42:06 -0400 (Sun, 16 Sep 2007) $
+ * $Rev: 3353 $
+ */
+eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(G(){9(1m E!="W")H w=E;H E=18.15=G(a,b){I 6 7u E?6.5N(a,b):1u E(a,b)};9(1m $!="W")H D=$;18.$=E;H u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/;E.1b=E.3A={5N:G(c,a){c=c||U;9(1m c=="1M"){H m=u.2S(c);9(m&&(m[1]||!a)){9(m[1])c=E.4D([m[1]],a);J{H b=U.3S(m[3]);9(b)9(b.22!=m[3])I E().1Y(c);J{6[0]=b;6.K=1;I 6}J c=[]}}J I 1u E(a).1Y(c)}J 9(E.1n(c))I 1u E(U)[E.1b.2d?"2d":"39"](c);I 6.6v(c.1c==1B&&c||(c.4c||c.K&&c!=18&&!c.1y&&c[0]!=W&&c[0].1y)&&E.2h(c)||[c])},4c:"1.2.1",7Y:G(){I 6.K},K:0,21:G(a){I a==W?E.2h(6):6[a]},2o:G(a){H b=E(a);b.4Y=6;I b},6v:G(a){6.K=0;1B.3A.1a.16(6,a);I 6},N:G(a,b){I E.N(6,a,b)},4I:G(a){H b=-1;6.N(G(i){9(6==a)b=i});I b},1x:G(f,d,e){H c=f;9(f.1c==3X)9(d==W)I 6.K&&E[e||"1x"](6[0],f)||W;J{c={};c[f]=d}I 6.N(G(a){L(H b 1i c)E.1x(e?6.R:6,b,E.1e(6,c[b],e,a,b))})},17:G(b,a){I 6.1x(b,a,"3C")},2g:G(e){9(1m e!="5i"&&e!=S)I 6.4n().3g(U.6F(e));H t="";E.N(e||6,G(){E.N(6.3j,G(){9(6.1y!=8)t+=6.1y!=1?6.6x:E.1b.2g([6])})});I t},5m:G(b){9(6[0])E(b,6[0].3H).6u().3d(6[0]).1X(G(){H a=6;1W(a.1w)a=a.1w;I a}).3g(6);I 6},8m:G(a){I 6.N(G(){E(6).6q().5m(a)})},8d:G(a){I 6.N(G(){E(6).5m(a)})},3g:G(){I 6.3z(1q,Q,1,G(a){6.58(a)})},6j:G(){I 6.3z(1q,Q,-1,G(a){6.3d(a,6.1w)})},6g:G(){I 6.3z(1q,P,1,G(a){6.12.3d(a,6)})},50:G(){I 6.3z(1q,P,-1,G(a){6.12.3d(a,6.2q)})},2D:G(){I 6.4Y||E([])},1Y:G(t){H b=E.1X(6,G(a){I E.1Y(t,a)});I 6.2o(/[^+>] [^+>]/.14(t)||t.1g("..")>-1?E.4V(b):b)},6u:G(e){H f=6.1X(G(){I 6.67?E(6.67)[0]:6.4R(Q)});H d=f.1Y("*").4O().N(G(){9(6[F]!=W)6[F]=S});9(e===Q)6.1Y("*").4O().N(G(i){H c=E.M(6,"2P");L(H a 1i c)L(H b 1i c[a])E.1j.1f(d[i],a,c[a][b],c[a][b].M)});I f},1E:G(t){I 6.2o(E.1n(t)&&E.2W(6,G(b,a){I t.16(b,[a])})||E.3m(t,6))},5V:G(t){I 6.2o(t.1c==3X&&E.3m(t,6,Q)||E.2W(6,G(a){I(t.1c==1B||t.4c)?E.2A(a,t)<0:a!=t}))},1f:G(t){I 6.2o(E.1R(6.21(),t.1c==3X?E(t).21():t.K!=W&&(!t.11||E.11(t,"2Y"))?t:[t]))},3t:G(a){I a?E.3m(a,6).K>0:P},7c:G(a){I 6.3t("."+a)},3i:G(b){9(b==W){9(6.K){H c=6[0];9(E.11(c,"24")){H e=c.4Z,a=[],Y=c.Y,2G=c.O=="24-2G";9(e<0)I S;L(H i=2G?e:0,33=2G?e+1:Y.K;i<33;i++){H d=Y[i];9(d.26){H b=E.V.1h&&!d.9V["1Q"].9L?d.2g:d.1Q;9(2G)I b;a.1a(b)}}I a}J I 6[0].1Q.1p(/\\r/g,"")}}J I 6.N(G(){9(b.1c==1B&&/4k|5j/.14(6.O))6.2Q=(E.2A(6.1Q,b)>=0||E.2A(6.2H,b)>=0);J 9(E.11(6,"24")){H a=b.1c==1B?b:[b];E("9h",6).N(G(){6.26=(E.2A(6.1Q,a)>=0||E.2A(6.2g,a)>=0)});9(!a.K)6.4Z=-1}J 6.1Q=b})},4o:G(a){I a==W?(6.K?6[0].3O:S):6.4n().3g(a)},6H:G(a){I 6.50(a).28()},6E:G(i){I 6.2J(i,i+1)},2J:G(){I 6.2o(1B.3A.2J.16(6,1q))},1X:G(b){I 6.2o(E.1X(6,G(a,i){I b.2O(a,i,a)}))},4O:G(){I 6.1f(6.4Y)},3z:G(f,d,g,e){H c=6.K>1,a;I 6.N(G(){9(!a){a=E.4D(f,6.3H);9(g<0)a.8U()}H b=6;9(d&&E.11(6,"1I")&&E.11(a[0],"4m"))b=6.4l("1K")[0]||6.58(U.5B("1K"));E.N(a,G(){H a=c?6.4R(Q):6;9(!5A(0,a))e.2O(b,a)})})}};G 5A(i,b){H a=E.11(b,"1J");9(a){9(b.3k)E.3G({1d:b.3k,3e:P,1V:"1J"});J E.5f(b.2g||b.6s||b.3O||"");9(b.12)b.12.3b(b)}J 9(b.1y==1)E("1J",b).N(5A);I a}E.1k=E.1b.1k=G(){H c=1q[0]||{},a=1,2c=1q.K,5e=P;9(c.1c==8o){5e=c;c=1q[1]||{}}9(2c==1){c=6;a=0}H b;L(;a<2c;a++)9((b=1q[a])!=S)L(H i 1i b){9(c==b[i])6r;9(5e&&1m b[i]==\'5i\'&&c[i])E.1k(c[i],b[i]);J 9(b[i]!=W)c[i]=b[i]}I c};H F="15"+(1u 3D()).3B(),6p=0,5c={};E.1k({8a:G(a){18.$=D;9(a)18.15=w;I E},1n:G(a){I!!a&&1m a!="1M"&&!a.11&&a.1c!=1B&&/G/i.14(a+"")},4a:G(a){I a.2V&&!a.1G||a.37&&a.3H&&!a.3H.1G},5f:G(a){a=E.36(a);9(a){9(18.6l)18.6l(a);J 9(E.V.1N)18.56(a,0);J 3w.2O(18,a)}},11:G(b,a){I b.11&&b.11.27()==a.27()},1L:{},M:G(c,d,b){c=c==18?5c:c;H a=c[F];9(!a)a=c[F]=++6p;9(d&&!E.1L[a])E.1L[a]={};9(b!=W)E.1L[a][d]=b;I d?E.1L[a][d]:a},30:G(c,b){c=c==18?5c:c;H a=c[F];9(b){9(E.1L[a]){2E E.1L[a][b];b="";L(b 1i E.1L[a])1T;9(!b)E.30(c)}}J{2a{2E c[F]}29(e){9(c.53)c.53(F)}2E E.1L[a]}},N:G(a,b,c){9(c){9(a.K==W)L(H i 1i a)b.16(a[i],c);J L(H i=0,48=a.K;i<48;i++)9(b.16(a[i],c)===P)1T}J{9(a.K==W)L(H i 1i a)b.2O(a[i],i,a[i]);J L(H i=0,48=a.K,3i=a[0];i<48&&b.2O(3i,i,3i)!==P;3i=a[++i]){}}I a},1e:G(c,b,d,e,a){9(E.1n(b))b=b.2O(c,[e]);H f=/z-?4I|7T-?7Q|1r|69|7P-?1H/i;I b&&b.1c==4W&&d=="3C"&&!f.14(a)?b+"2T":b},1o:{1f:G(b,c){E.N((c||"").2l(/\\s+/),G(i,a){9(!E.1o.3K(b.1o,a))b.1o+=(b.1o?" ":"")+a})},28:G(b,c){b.1o=c!=W?E.2W(b.1o.2l(/\\s+/),G(a){I!E.1o.3K(c,a)}).66(" "):""},3K:G(t,c){I E.2A(c,(t.1o||t).3s().2l(/\\s+/))>-1}},2k:G(e,o,f){L(H i 1i o){e.R["3r"+i]=e.R[i];e.R[i]=o[i]}f.16(e,[]);L(H i 1i o)e.R[i]=e.R["3r"+i]},17:G(e,p){9(p=="1H"||p=="2N"){H b={},42,41,d=["7J","7I","7G","7F"];E.N(d,G(){b["7C"+6]=0;b["7B"+6+"5Z"]=0});E.2k(e,b,G(){9(E(e).3t(\':3R\')){42=e.7A;41=e.7w}J{e=E(e.4R(Q)).1Y(":4k").5W("2Q").2D().17({4C:"1P",2X:"4F",19:"2Z",7o:"0",1S:"0"}).5R(e.12)[0];H a=E.17(e.12,"2X")||"3V";9(a=="3V")e.12.R.2X="7g";42=e.7e;41=e.7b;9(a=="3V")e.12.R.2X="3V";e.12.3b(e)}});I p=="1H"?42:41}I E.3C(e,p)},3C:G(h,j,i){H g,2w=[],2k=[];G 3n(a){9(!E.V.1N)I P;H b=U.3o.3Z(a,S);I!b||b.4y("3n")==""}9(j=="1r"&&E.V.1h){g=E.1x(h.R,"1r");I g==""?"1":g}9(j.1t(/4u/i))j=y;9(!i&&h.R[j])g=h.R[j];J 9(U.3o&&U.3o.3Z){9(j.1t(/4u/i))j="4u";j=j.1p(/([A-Z])/g,"-$1").2p();H d=U.3o.3Z(h,S);9(d&&!3n(h))g=d.4y(j);J{L(H a=h;a&&3n(a);a=a.12)2w.4w(a);L(a=0;a<2w.K;a++)9(3n(2w[a])){2k[a]=2w[a].R.19;2w[a].R.19="2Z"}g=j=="19"&&2k[2w.K-1]!=S?"2s":U.3o.3Z(h,S).4y(j)||"";L(a=0;a<2k.K;a++)9(2k[a]!=S)2w[a].R.19=2k[a]}9(j=="1r"&&g=="")g="1"}J 9(h.3Q){H f=j.1p(/\\-(\\w)/g,G(m,c){I c.27()});g=h.3Q[j]||h.3Q[f];9(!/^\\d+(2T)?$/i.14(g)&&/^\\d/.14(g)){H k=h.R.1S;H e=h.4v.1S;h.4v.1S=h.3Q.1S;h.R.1S=g||0;g=h.R.71+"2T";h.R.1S=k;h.4v.1S=e}}I g},4D:G(a,e){H r=[];e=e||U;E.N(a,G(i,d){9(!d)I;9(d.1c==4W)d=d.3s();9(1m d=="1M"){d=d.1p(/(<(\\w+)[^>]*?)\\/>/g,G(m,a,b){I b.1t(/^(70|6Z|6Y|9Q|4t|9N|9K|3a|9G|9E)$/i)?m:a+"></"+b+">"});H s=E.36(d).2p(),1s=e.5B("1s"),2x=[];H c=!s.1g("<9y")&&[1,"<24>","</24>"]||!s.1g("<9w")&&[1,"<6T>","</6T>"]||s.1t(/^<(9u|1K|9t|9r|9p)/)&&[1,"<1I>","</1I>"]||!s.1g("<4m")&&[2,"<1I><1K>","</1K></1I>"]||(!s.1g("<9m")||!s.1g("<9k"))&&[3,"<1I><1K><4m>","</4m></1K></1I>"]||!s.1g("<6Y")&&[2,"<1I><1K></1K><6L>","</6L></1I>"]||E.V.1h&&[1,"1s<1s>","</1s>"]||[0,"",""];1s.3O=c[1]+d+c[2];1W(c[0]--)1s=1s.5p;9(E.V.1h){9(!s.1g("<1I")&&s.1g("<1K")<0)2x=1s.1w&&1s.1w.3j;J 9(c[1]=="<1I>"&&s.1g("<1K")<0)2x=1s.3j;L(H n=2x.K-1;n>=0;--n)9(E.11(2x[n],"1K")&&!2x[n].3j.K)2x[n].12.3b(2x[n]);9(/^\\s/.14(d))1s.3d(e.6F(d.1t(/^\\s*/)[0]),1s.1w)}d=E.2h(1s.3j)}9(0===d.K&&(!E.11(d,"2Y")&&!E.11(d,"24")))I;9(d[0]==W||E.11(d,"2Y")||d.Y)r.1a(d);J r=E.1R(r,d)});I r},1x:G(c,d,a){H e=E.4a(c)?{}:E.5o;9(d=="26"&&E.V.1N)c.12.4Z;9(e[d]){9(a!=W)c[e[d]]=a;I c[e[d]]}J 9(E.V.1h&&d=="R")I E.1x(c.R,"9e",a);J 9(a==W&&E.V.1h&&E.11(c,"2Y")&&(d=="9d"||d=="9a"))I c.97(d).6x;J 9(c.37){9(a!=W){9(d=="O"&&E.11(c,"4t")&&c.12)6G"O 94 93\'t 92 91";c.90(d,a)}9(E.V.1h&&/6C|3k/.14(d)&&!E.4a(c))I c.4p(d,2);I c.4p(d)}J{9(d=="1r"&&E.V.1h){9(a!=W){c.69=1;c.1E=(c.1E||"").1p(/6O\\([^)]*\\)/,"")+(3I(a).3s()=="8S"?"":"6O(1r="+a*6A+")")}I c.1E?(3I(c.1E.1t(/1r=([^)]*)/)[1])/6A).3s():""}d=d.1p(/-([a-z])/8Q,G(z,b){I b.27()});9(a!=W)c[d]=a;I c[d]}},36:G(t){I(t||"").1p(/^\\s+|\\s+$/g,"")},2h:G(a){H r=[];9(1m a!="8P")L(H i=0,2c=a.K;i<2c;i++)r.1a(a[i]);J r=a.2J(0);I r},2A:G(b,a){L(H i=0,2c=a.K;i<2c;i++)9(a[i]==b)I i;I-1},1R:G(a,b){9(E.V.1h){L(H i=0;b[i];i++)9(b[i].1y!=8)a.1a(b[i])}J L(H i=0;b[i];i++)a.1a(b[i]);I a},4V:G(b){H r=[],2f={};2a{L(H i=0,6y=b.K;i<6y;i++){H a=E.M(b[i]);9(!2f[a]){2f[a]=Q;r.1a(b[i])}}}29(e){r=b}I r},2W:G(b,a,c){9(1m a=="1M")a=3w("P||G(a,i){I "+a+"}");H d=[];L(H i=0,4g=b.K;i<4g;i++)9(!c&&a(b[i],i)||c&&!a(b[i],i))d.1a(b[i]);I d},1X:G(c,b){9(1m b=="1M")b=3w("P||G(a){I "+b+"}");H d=[];L(H i=0,4g=c.K;i<4g;i++){H a=b(c[i],i);9(a!==S&&a!=W){9(a.1c!=1B)a=[a];d=d.8M(a)}}I d}});H v=8K.8I.2p();E.V={4s:(v.1t(/.+(?:8F|8E|8C|8B)[\\/: ]([\\d.]+)/)||[])[1],1N:/6w/.14(v),34:/34/.14(v),1h:/1h/.14(v)&&!/34/.14(v),35:/35/.14(v)&&!/(8z|6w)/.14(v)};H y=E.V.1h?"4h":"5h";E.1k({5g:!E.V.1h||U.8y=="8x",4h:E.V.1h?"4h":"5h",5o:{"L":"8w","8v":"1o","4u":y,5h:y,4h:y,3O:"3O",1o:"1o",1Q:"1Q",3c:"3c",2Q:"2Q",8u:"8t",26:"26",8s:"8r"}});E.N({1D:"a.12",8q:"15.4e(a,\'12\')",8p:"15.2I(a,2,\'2q\')",8n:"15.2I(a,2,\'4d\')",8l:"15.4e(a,\'2q\')",8k:"15.4e(a,\'4d\')",8j:"15.5d(a.12.1w,a)",8i:"15.5d(a.1w)",6q:"15.11(a,\'8h\')?a.8f||a.8e.U:15.2h(a.3j)"},G(i,n){E.1b[i]=G(a){H b=E.1X(6,n);9(a&&1m a=="1M")b=E.3m(a,b);I 6.2o(E.4V(b))}});E.N({5R:"3g",8c:"6j",3d:"6g",8b:"50",89:"6H"},G(i,n){E.1b[i]=G(){H a=1q;I 6.N(G(){L(H j=0,2c=a.K;j<2c;j++)E(a[j])[n](6)})}});E.N({5W:G(a){E.1x(6,a,"");6.53(a)},88:G(c){E.1o.1f(6,c)},87:G(c){E.1o.28(6,c)},86:G(c){E.1o[E.1o.3K(6,c)?"28":"1f"](6,c)},28:G(a){9(!a||E.1E(a,[6]).r.K){E.30(6);6.12.3b(6)}},4n:G(){E("*",6).N(G(){E.30(6)});1W(6.1w)6.3b(6.1w)}},G(i,n){E.1b[i]=G(){I 6.N(n,1q)}});E.N(["85","5Z"],G(i,a){H n=a.2p();E.1b[n]=G(h){I 6[0]==18?E.V.1N&&3y["84"+a]||E.5g&&38.33(U.2V["5a"+a],U.1G["5a"+a])||U.1G["5a"+a]:6[0]==U?38.33(U.1G["6n"+a],U.1G["6m"+a]):h==W?(6.K?E.17(6[0],n):S):6.17(n,h.1c==3X?h:h+"2T")}});H C=E.V.1N&&3x(E.V.4s)<83?"(?:[\\\\w*57-]|\\\\\\\\.)":"(?:[\\\\w\\82-\\81*57-]|\\\\\\\\.)",6k=1u 47("^>\\\\s*("+C+"+)"),6i=1u 47("^("+C+"+)(#)("+C+"+)"),6h=1u 47("^([#.]?)("+C+"*)");E.1k({55:{"":"m[2]==\'*\'||15.11(a,m[2])","#":"a.4p(\'22\')==m[2]",":":{80:"i<m[3]-0",7Z:"i>m[3]-0",2I:"m[3]-0==i",6E:"m[3]-0==i",3v:"i==0",3u:"i==r.K-1",6f:"i%2==0",6e:"i%2","3v-46":"a.12.4l(\'*\')[0]==a","3u-46":"15.2I(a.12.5p,1,\'4d\')==a","7X-46":"!15.2I(a.12.5p,2,\'4d\')",1D:"a.1w",4n:"!a.1w",7W:"(a.6s||a.7V||15(a).2g()||\'\').1g(m[3])>=0",3R:\'"1P"!=a.O&&15.17(a,"19")!="2s"&&15.17(a,"4C")!="1P"\',1P:\'"1P"==a.O||15.17(a,"19")=="2s"||15.17(a,"4C")=="1P"\',7U:"!a.3c",3c:"a.3c",2Q:"a.2Q",26:"a.26||15.1x(a,\'26\')",2g:"\'2g\'==a.O",4k:"\'4k\'==a.O",5j:"\'5j\'==a.O",54:"\'54\'==a.O",52:"\'52\'==a.O",51:"\'51\'==a.O",6d:"\'6d\'==a.O",6c:"\'6c\'==a.O",2r:\'"2r"==a.O||15.11(a,"2r")\',4t:"/4t|24|6b|2r/i.14(a.11)",3K:"15.1Y(m[3],a).K",7S:"/h\\\\d/i.14(a.11)",7R:"15.2W(15.32,G(1b){I a==1b.T;}).K"}},6a:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,1u 47("^([:.#]*)("+C+"+)")],3m:G(a,c,b){H d,2b=[];1W(a&&a!=d){d=a;H f=E.1E(a,c,b);a=f.t.1p(/^\\s*,\\s*/,"");2b=b?c=f.r:E.1R(2b,f.r)}I 2b},1Y:G(t,o){9(1m t!="1M")I[t];9(o&&!o.1y)o=S;o=o||U;H d=[o],2f=[],3u;1W(t&&3u!=t){H r=[];3u=t;t=E.36(t);H l=P;H g=6k;H m=g.2S(t);9(m){H p=m[1].27();L(H i=0;d[i];i++)L(H c=d[i].1w;c;c=c.2q)9(c.1y==1&&(p=="*"||c.11.27()==p.27()))r.1a(c);d=r;t=t.1p(g,"");9(t.1g(" ")==0)6r;l=Q}J{g=/^([>+~])\\s*(\\w*)/i;9((m=g.2S(t))!=S){r=[];H p=m[2],1R={};m=m[1];L(H j=0,31=d.K;j<31;j++){H n=m=="~"||m=="+"?d[j].2q:d[j].1w;L(;n;n=n.2q)9(n.1y==1){H h=E.M(n);9(m=="~"&&1R[h])1T;9(!p||n.11.27()==p.27()){9(m=="~")1R[h]=Q;r.1a(n)}9(m=="+")1T}}d=r;t=E.36(t.1p(g,""));l=Q}}9(t&&!l){9(!t.1g(",")){9(o==d[0])d.44();2f=E.1R(2f,d);r=d=[o];t=" "+t.68(1,t.K)}J{H k=6i;H m=k.2S(t);9(m){m=[0,m[2],m[3],m[1]]}J{k=6h;m=k.2S(t)}m[2]=m[2].1p(/\\\\/g,"");H f=d[d.K-1];9(m[1]=="#"&&f&&f.3S&&!E.4a(f)){H q=f.3S(m[2]);9((E.V.1h||E.V.34)&&q&&1m q.22=="1M"&&q.22!=m[2])q=E(\'[@22="\'+m[2]+\'"]\',f)[0];d=r=q&&(!m[3]||E.11(q,m[3]))?[q]:[]}J{L(H i=0;d[i];i++){H a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];9(a=="*"&&d[i].11.2p()=="5i")a="3a";r=E.1R(r,d[i].4l(a))}9(m[1]==".")r=E.4X(r,m[2]);9(m[1]=="#"){H e=[];L(H i=0;r[i];i++)9(r[i].4p("22")==m[2]){e=[r[i]];1T}r=e}d=r}t=t.1p(k,"")}}9(t){H b=E.1E(t,r);d=r=b.r;t=E.36(b.t)}}9(t)d=[];9(d&&o==d[0])d.44();2f=E.1R(2f,d);I 2f},4X:G(r,m,a){m=" "+m+" ";H c=[];L(H i=0;r[i];i++){H b=(" "+r[i].1o+" ").1g(m)>=0;9(!a&&b||a&&!b)c.1a(r[i])}I c},1E:G(t,r,h){H d;1W(t&&t!=d){d=t;H p=E.6a,m;L(H i=0;p[i];i++){m=p[i].2S(t);9(m){t=t.7O(m[0].K);m[2]=m[2].1p(/\\\\/g,"");1T}}9(!m)1T;9(m[1]==":"&&m[2]=="5V")r=E.1E(m[3],r,Q).r;J 9(m[1]==".")r=E.4X(r,m[2],h);J 9(m[1]=="["){H g=[],O=m[3];L(H i=0,31=r.K;i<31;i++){H a=r[i],z=a[E.5o[m[2]]||m[2]];9(z==S||/6C|3k|26/.14(m[2]))z=E.1x(a,m[2])||\'\';9((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1g(m[5])||O=="$="&&z.68(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1g(m[5])>=0)^h)g.1a(a)}r=g}J 9(m[1]==":"&&m[2]=="2I-46"){H e={},g=[],14=/(\\d*)n\\+?(\\d*)/.2S(m[3]=="6f"&&"2n"||m[3]=="6e"&&"2n+1"||!/\\D/.14(m[3])&&"n+"+m[3]||m[3]),3v=(14[1]||1)-0,d=14[2]-0;L(H i=0,31=r.K;i<31;i++){H j=r[i],12=j.12,22=E.M(12);9(!e[22]){H c=1;L(H n=12.1w;n;n=n.2q)9(n.1y==1)n.4U=c++;e[22]=Q}H b=P;9(3v==1){9(d==0||j.4U==d)b=Q}J 9((j.4U+d)%3v==0)b=Q;9(b^h)g.1a(j)}r=g}J{H f=E.55[m[1]];9(1m f!="1M")f=E.55[m[1]][m[2]];f=3w("P||G(a,i){I "+f+"}");r=E.2W(r,f,h)}}I{r:r,t:t}},4e:G(b,c){H d=[];H a=b[c];1W(a&&a!=U){9(a.1y==1)d.1a(a);a=a[c]}I d},2I:G(a,e,c,b){e=e||1;H d=0;L(;a;a=a[c])9(a.1y==1&&++d==e)1T;I a},5d:G(n,a){H r=[];L(;n;n=n.2q){9(n.1y==1&&(!a||n!=a))r.1a(n)}I r}});E.1j={1f:G(g,e,c,h){9(E.V.1h&&g.4j!=W)g=18;9(!c.2u)c.2u=6.2u++;9(h!=W){H d=c;c=G(){I d.16(6,1q)};c.M=h;c.2u=d.2u}H i=e.2l(".");e=i[0];c.O=i[1];H b=E.M(g,"2P")||E.M(g,"2P",{});H f=E.M(g,"2t",G(){H a;9(1m E=="W"||E.1j.4T)I a;a=E.1j.2t.16(g,1q);I a});H j=b[e];9(!j){j=b[e]={};9(g.4S)g.4S(e,f,P);J g.7N("43"+e,f)}j[c.2u]=c;6.1Z[e]=Q},2u:1,1Z:{},28:G(d,c,b){H e=E.M(d,"2P"),2L,4I;9(1m c=="1M"){H a=c.2l(".");c=a[0]}9(e){9(c&&c.O){b=c.4Q;c=c.O}9(!c){L(c 1i e)6.28(d,c)}J 9(e[c]){9(b)2E e[c][b.2u];J L(b 1i e[c])9(!a[1]||e[c][b].O==a[1])2E e[c][b];L(2L 1i e[c])1T;9(!2L){9(d.4P)d.4P(c,E.M(d,"2t"),P);J d.7M("43"+c,E.M(d,"2t"));2L=S;2E e[c]}}L(2L 1i e)1T;9(!2L){E.30(d,"2P");E.30(d,"2t")}}},1F:G(d,b,e,c,f){b=E.2h(b||[]);9(!e){9(6.1Z[d])E("*").1f([18,U]).1F(d,b)}J{H a,2L,1b=E.1n(e[d]||S),4N=!b[0]||!b[0].2M;9(4N)b.4w(6.4M({O:d,2m:e}));b[0].O=d;9(E.1n(E.M(e,"2t")))a=E.M(e,"2t").16(e,b);9(!1b&&e["43"+d]&&e["43"+d].16(e,b)===P)a=P;9(4N)b.44();9(f&&f.16(e,b)===P)a=P;9(1b&&c!==P&&a!==P&&!(E.11(e,\'a\')&&d=="4L")){6.4T=Q;e[d]()}6.4T=P}I a},2t:G(d){H a;d=E.1j.4M(d||18.1j||{});H b=d.O.2l(".");d.O=b[0];H c=E.M(6,"2P")&&E.M(6,"2P")[d.O],3q=1B.3A.2J.2O(1q,1);3q.4w(d);L(H j 1i c){3q[0].4Q=c[j];3q[0].M=c[j].M;9(!b[1]||c[j].O==b[1]){H e=c[j].16(6,3q);9(a!==P)a=e;9(e===P){d.2M();d.3p()}}}9(E.V.1h)d.2m=d.2M=d.3p=d.4Q=d.M=S;I a},4M:G(c){H a=c;c=E.1k({},a);c.2M=G(){9(a.2M)a.2M();a.7L=P};c.3p=G(){9(a.3p)a.3p();a.7K=Q};9(!c.2m&&c.65)c.2m=c.65;9(E.V.1N&&c.2m.1y==3)c.2m=a.2m.12;9(!c.4K&&c.4J)c.4K=c.4J==c.2m?c.7H:c.4J;9(c.64==S&&c.63!=S){H e=U.2V,b=U.1G;c.64=c.63+(e&&e.2R||b.2R||0);c.7E=c.7D+(e&&e.2B||b.2B||0)}9(!c.3Y&&(c.61||c.60))c.3Y=c.61||c.60;9(!c.5F&&c.5D)c.5F=c.5D;9(!c.3Y&&c.2r)c.3Y=(c.2r&1?1:(c.2r&2?3:(c.2r&4?2:0)));I c}};E.1b.1k({3W:G(c,a,b){I c=="5Y"?6.2G(c,a,b):6.N(G(){E.1j.1f(6,c,b||a,b&&a)})},2G:G(d,b,c){I 6.N(G(){E.1j.1f(6,d,G(a){E(6).5X(a);I(c||b).16(6,1q)},c&&b)})},5X:G(a,b){I 6.N(G(){E.1j.28(6,a,b)})},1F:G(c,a,b){I 6.N(G(){E.1j.1F(c,a,6,Q,b)})},7x:G(c,a,b){9(6[0])I E.1j.1F(c,a,6[0],P,b)},25:G(){H a=1q;I 6.4L(G(e){6.4H=0==6.4H?1:0;e.2M();I a[6.4H].16(6,[e])||P})},7v:G(f,g){G 4G(e){H p=e.4K;1W(p&&p!=6)2a{p=p.12}29(e){p=6};9(p==6)I P;I(e.O=="4x"?f:g).16(6,[e])}I 6.4x(4G).5U(4G)},2d:G(f){5T();9(E.3T)f.16(U,[E]);J E.3l.1a(G(){I f.16(6,[E])});I 6}});E.1k({3T:P,3l:[],2d:G(){9(!E.3T){E.3T=Q;9(E.3l){E.N(E.3l,G(){6.16(U)});E.3l=S}9(E.V.35||E.V.34)U.4P("5S",E.2d,P);9(!18.7t.K)E(18).39(G(){E("#4E").28()})}}});E.N(("7s,7r,39,7q,6n,5Y,4L,7p,"+"7n,7m,7l,4x,5U,7k,24,"+"51,7j,7i,7h,3U").2l(","),G(i,o){E.1b[o]=G(f){I f?6.3W(o,f):6.1F(o)}});H x=P;G 5T(){9(x)I;x=Q;9(E.V.35||E.V.34)U.4S("5S",E.2d,P);J 9(E.V.1h){U.7f("<7d"+"7y 22=4E 7z=Q "+"3k=//:><\\/1J>");H a=U.3S("4E");9(a)a.62=G(){9(6.2C!="1l")I;E.2d()};a=S}J 9(E.V.1N)E.4B=4j(G(){9(U.2C=="5Q"||U.2C=="1l"){4A(E.4B);E.4B=S;E.2d()}},10);E.1j.1f(18,"39",E.2d)}E.1b.1k({39:G(g,d,c){9(E.1n(g))I 6.3W("39",g);H e=g.1g(" ");9(e>=0){H i=g.2J(e,g.K);g=g.2J(0,e)}c=c||G(){};H f="4z";9(d)9(E.1n(d)){c=d;d=S}J{d=E.3a(d);f="5P"}H h=6;E.3G({1d:g,O:f,M:d,1l:G(a,b){9(b=="1C"||b=="5O")h.4o(i?E("<1s/>").3g(a.40.1p(/<1J(.|\\s)*?\\/1J>/g,"")).1Y(i):a.40);56(G(){h.N(c,[a.40,b,a])},13)}});I 6},7a:G(){I E.3a(6.5M())},5M:G(){I 6.1X(G(){I E.11(6,"2Y")?E.2h(6.79):6}).1E(G(){I 6.2H&&!6.3c&&(6.2Q||/24|6b/i.14(6.11)||/2g|1P|52/i.14(6.O))}).1X(G(i,c){H b=E(6).3i();I b==S?S:b.1c==1B?E.1X(b,G(a,i){I{2H:c.2H,1Q:a}}):{2H:c.2H,1Q:b}}).21()}});E.N("5L,5K,6t,5J,5I,5H".2l(","),G(i,o){E.1b[o]=G(f){I 6.3W(o,f)}});H B=(1u 3D).3B();E.1k({21:G(d,b,a,c){9(E.1n(b)){a=b;b=S}I E.3G({O:"4z",1d:d,M:b,1C:a,1V:c})},78:G(b,a){I E.21(b,S,a,"1J")},77:G(c,b,a){I E.21(c,b,a,"45")},76:G(d,b,a,c){9(E.1n(b)){a=b;b={}}I E.3G({O:"5P",1d:d,M:b,1C:a,1V:c})},75:G(a){E.1k(E.59,a)},59:{1Z:Q,O:"4z",2z:0,5G:"74/x-73-2Y-72",6o:Q,3e:Q,M:S},49:{},3G:G(s){H f,2y=/=(\\?|%3F)/g,1v,M;s=E.1k(Q,s,E.1k(Q,{},E.59,s));9(s.M&&s.6o&&1m s.M!="1M")s.M=E.3a(s.M);9(s.1V=="4b"){9(s.O.2p()=="21"){9(!s.1d.1t(2y))s.1d+=(s.1d.1t(/\\?/)?"&":"?")+(s.4b||"5E")+"=?"}J 9(!s.M||!s.M.1t(2y))s.M=(s.M?s.M+"&":"")+(s.4b||"5E")+"=?";s.1V="45"}9(s.1V=="45"&&(s.M&&s.M.1t(2y)||s.1d.1t(2y))){f="4b"+B++;9(s.M)s.M=s.M.1p(2y,"="+f);s.1d=s.1d.1p(2y,"="+f);s.1V="1J";18[f]=G(a){M=a;1C();1l();18[f]=W;2a{2E 18[f]}29(e){}}}9(s.1V=="1J"&&s.1L==S)s.1L=P;9(s.1L===P&&s.O.2p()=="21")s.1d+=(s.1d.1t(/\\?/)?"&":"?")+"57="+(1u 3D()).3B();9(s.M&&s.O.2p()=="21"){s.1d+=(s.1d.1t(/\\?/)?"&":"?")+s.M;s.M=S}9(s.1Z&&!E.5b++)E.1j.1F("5L");9(!s.1d.1g("8g")&&s.1V=="1J"){H h=U.4l("9U")[0];H g=U.5B("1J");g.3k=s.1d;9(!f&&(s.1C||s.1l)){H j=P;g.9R=g.62=G(){9(!j&&(!6.2C||6.2C=="5Q"||6.2C=="1l")){j=Q;1C();1l();h.3b(g)}}}h.58(g);I}H k=P;H i=18.6X?1u 6X("9P.9O"):1u 6W();i.9M(s.O,s.1d,s.3e);9(s.M)i.5C("9J-9I",s.5G);9(s.5y)i.5C("9H-5x-9F",E.49[s.1d]||"9D, 9C 9B 9A 5v:5v:5v 9z");i.5C("X-9x-9v","6W");9(s.6U)s.6U(i);9(s.1Z)E.1j.1F("5H",[i,s]);H c=G(a){9(!k&&i&&(i.2C==4||a=="2z")){k=Q;9(d){4A(d);d=S}1v=a=="2z"&&"2z"||!E.6S(i)&&"3U"||s.5y&&E.6R(i,s.1d)&&"5O"||"1C";9(1v=="1C"){2a{M=E.6Q(i,s.1V)}29(e){1v="5k"}}9(1v=="1C"){H b;2a{b=i.5s("6P-5x")}29(e){}9(s.5y&&b)E.49[s.1d]=b;9(!f)1C()}J E.5r(s,i,1v);1l();9(s.3e)i=S}};9(s.3e){H d=4j(c,13);9(s.2z>0)56(G(){9(i){i.9q();9(!k)c("2z")}},s.2z)}2a{i.9o(s.M)}29(e){E.5r(s,i,S,e)}9(!s.3e)c();I i;G 1C(){9(s.1C)s.1C(M,1v);9(s.1Z)E.1j.1F("5I",[i,s])}G 1l(){9(s.1l)s.1l(i,1v);9(s.1Z)E.1j.1F("6t",[i,s]);9(s.1Z&&!--E.5b)E.1j.1F("5K")}},5r:G(s,a,b,e){9(s.3U)s.3U(a,b,e);9(s.1Z)E.1j.1F("5J",[a,s,e])},5b:0,6S:G(r){2a{I!r.1v&&9n.9l=="54:"||(r.1v>=6N&&r.1v<9j)||r.1v==6M||E.V.1N&&r.1v==W}29(e){}I P},6R:G(a,c){2a{H b=a.5s("6P-5x");I a.1v==6M||b==E.49[c]||E.V.1N&&a.1v==W}29(e){}I P},6Q:G(r,b){H c=r.5s("9i-O");H d=b=="6K"||!b&&c&&c.1g("6K")>=0;H a=d?r.9g:r.40;9(d&&a.2V.37=="5k")6G"5k";9(b=="1J")E.5f(a);9(b=="45")a=3w("("+a+")");I a},3a:G(a){H s=[];9(a.1c==1B||a.4c)E.N(a,G(){s.1a(3f(6.2H)+"="+3f(6.1Q))});J L(H j 1i a)9(a[j]&&a[j].1c==1B)E.N(a[j],G(){s.1a(3f(j)+"="+3f(6))});J s.1a(3f(j)+"="+3f(a[j]));I s.66("&").1p(/%20/g,"+")}});E.1b.1k({1A:G(b,a){I b?6.1U({1H:"1A",2N:"1A",1r:"1A"},b,a):6.1E(":1P").N(G(){6.R.19=6.3h?6.3h:"";9(E.17(6,"19")=="2s")6.R.19="2Z"}).2D()},1z:G(b,a){I b?6.1U({1H:"1z",2N:"1z",1r:"1z"},b,a):6.1E(":3R").N(G(){6.3h=6.3h||E.17(6,"19");9(6.3h=="2s")6.3h="2Z";6.R.19="2s"}).2D()},6J:E.1b.25,25:G(a,b){I E.1n(a)&&E.1n(b)?6.6J(a,b):a?6.1U({1H:"25",2N:"25",1r:"25"},a,b):6.N(G(){E(6)[E(6).3t(":1P")?"1A":"1z"]()})},9c:G(b,a){I 6.1U({1H:"1A"},b,a)},9b:G(b,a){I 6.1U({1H:"1z"},b,a)},99:G(b,a){I 6.1U({1H:"25"},b,a)},98:G(b,a){I 6.1U({1r:"1A"},b,a)},96:G(b,a){I 6.1U({1r:"1z"},b,a)},95:G(c,a,b){I 6.1U({1r:a},c,b)},1U:G(k,i,h,g){H j=E.6D(i,h,g);I 6[j.3L===P?"N":"3L"](G(){j=E.1k({},j);H f=E(6).3t(":1P"),3y=6;L(H p 1i k){9(k[p]=="1z"&&f||k[p]=="1A"&&!f)I E.1n(j.1l)&&j.1l.16(6);9(p=="1H"||p=="2N"){j.19=E.17(6,"19");j.2U=6.R.2U}}9(j.2U!=S)6.R.2U="1P";j.3M=E.1k({},k);E.N(k,G(c,a){H e=1u E.2j(3y,j,c);9(/25|1A|1z/.14(a))e[a=="25"?f?"1A":"1z":a](k);J{H b=a.3s().1t(/^([+-]=)?([\\d+-.]+)(.*)$/),1O=e.2b(Q)||0;9(b){H d=3I(b[2]),2i=b[3]||"2T";9(2i!="2T"){3y.R[c]=(d||1)+2i;1O=((d||1)/e.2b(Q))*1O;3y.R[c]=1O+2i}9(b[1])d=((b[1]=="-="?-1:1)*d)+1O;e.3N(1O,d,2i)}J e.3N(1O,a,"")}});I Q})},3L:G(a,b){9(E.1n(a)){b=a;a="2j"}9(!a||(1m a=="1M"&&!b))I A(6[0],a);I 6.N(G(){9(b.1c==1B)A(6,a,b);J{A(6,a).1a(b);9(A(6,a).K==1)b.16(6)}})},9f:G(){H a=E.32;I 6.N(G(){L(H i=0;i<a.K;i++)9(a[i].T==6)a.6I(i--,1)}).5n()}});H A=G(b,c,a){9(!b)I;H q=E.M(b,c+"3L");9(!q||a)q=E.M(b,c+"3L",a?E.2h(a):[]);I q};E.1b.5n=G(a){a=a||"2j";I 6.N(G(){H q=A(6,a);q.44();9(q.K)q[0].16(6)})};E.1k({6D:G(b,a,c){H d=b&&b.1c==8Z?b:{1l:c||!c&&a||E.1n(b)&&b,2e:b,3J:c&&a||a&&a.1c!=8Y&&a};d.2e=(d.2e&&d.2e.1c==4W?d.2e:{8X:8W,8V:6N}[d.2e])||8T;d.3r=d.1l;d.1l=G(){E(6).5n();9(E.1n(d.3r))d.3r.16(6)};I d},3J:{6B:G(p,n,b,a){I b+a*p},5q:G(p,n,b,a){I((-38.9s(p*38.8R)/2)+0.5)*a+b}},32:[],2j:G(b,c,a){6.Y=c;6.T=b;6.1e=a;9(!c.3P)c.3P={}}});E.2j.3A={4r:G(){9(6.Y.2F)6.Y.2F.16(6.T,[6.2v,6]);(E.2j.2F[6.1e]||E.2j.2F.6z)(6);9(6.1e=="1H"||6.1e=="2N")6.T.R.19="2Z"},2b:G(a){9(6.T[6.1e]!=S&&6.T.R[6.1e]==S)I 6.T[6.1e];H r=3I(E.3C(6.T,6.1e,a));I r&&r>-8O?r:3I(E.17(6.T,6.1e))||0},3N:G(c,b,e){6.5u=(1u 3D()).3B();6.1O=c;6.2D=b;6.2i=e||6.2i||"2T";6.2v=6.1O;6.4q=6.4i=0;6.4r();H f=6;G t(){I f.2F()}t.T=6.T;E.32.1a(t);9(E.32.K==1){H d=4j(G(){H a=E.32;L(H i=0;i<a.K;i++)9(!a[i]())a.6I(i--,1);9(!a.K)4A(d)},13)}},1A:G(){6.Y.3P[6.1e]=E.1x(6.T.R,6.1e);6.Y.1A=Q;6.3N(0,6.2b());9(6.1e=="2N"||6.1e=="1H")6.T.R[6.1e]="8N";E(6.T).1A()},1z:G(){6.Y.3P[6.1e]=E.1x(6.T.R,6.1e);6.Y.1z=Q;6.3N(6.2b(),0)},2F:G(){H t=(1u 3D()).3B();9(t>6.Y.2e+6.5u){6.2v=6.2D;6.4q=6.4i=1;6.4r();6.Y.3M[6.1e]=Q;H a=Q;L(H i 1i 6.Y.3M)9(6.Y.3M[i]!==Q)a=P;9(a){9(6.Y.19!=S){6.T.R.2U=6.Y.2U;6.T.R.19=6.Y.19;9(E.17(6.T,"19")=="2s")6.T.R.19="2Z"}9(6.Y.1z)6.T.R.19="2s";9(6.Y.1z||6.Y.1A)L(H p 1i 6.Y.3M)E.1x(6.T.R,p,6.Y.3P[p])}9(a&&E.1n(6.Y.1l))6.Y.1l.16(6.T);I P}J{H n=t-6.5u;6.4i=n/6.Y.2e;6.4q=E.3J[6.Y.3J||(E.3J.5q?"5q":"6B")](6.4i,n,0,1,6.Y.2e);6.2v=6.1O+((6.2D-6.1O)*6.4q);6.4r()}I Q}};E.2j.2F={2R:G(a){a.T.2R=a.2v},2B:G(a){a.T.2B=a.2v},1r:G(a){E.1x(a.T.R,"1r",a.2v)},6z:G(a){a.T.R[a.1e]=a.2v+a.2i}};E.1b.6m=G(){H c=0,3E=0,T=6[0],5t;9(T)8L(E.V){H b=E.17(T,"2X")=="4F",1D=T.12,23=T.23,2K=T.3H,4f=1N&&3x(4s)<8J;9(T.6V){5w=T.6V();1f(5w.1S+38.33(2K.2V.2R,2K.1G.2R),5w.3E+38.33(2K.2V.2B,2K.1G.2B));9(1h){H d=E("4o").17("8H");d=(d=="8G"||E.5g&&3x(4s)>=7)&&2||d;1f(-d,-d)}}J{1f(T.5l,T.5z);1W(23){1f(23.5l,23.5z);9(35&&/^t[d|h]$/i.14(1D.37)||!4f)d(23);9(4f&&!b&&E.17(23,"2X")=="4F")b=Q;23=23.23}1W(1D.37&&!/^1G|4o$/i.14(1D.37)){9(!/^8D|1I-9S.*$/i.14(E.17(1D,"19")))1f(-1D.2R,-1D.2B);9(35&&E.17(1D,"2U")!="3R")d(1D);1D=1D.12}9(4f&&b)1f(-2K.1G.5l,-2K.1G.5z)}5t={3E:3E,1S:c}}I 5t;G d(a){1f(E.17(a,"9T"),E.17(a,"8A"))}G 1f(l,t){c+=3x(l)||0;3E+=3x(t)||0}}})();',62,616,'||||||this|||if|||||||||||||||||||||||||||||||||function|var|return|else|length|for|data|each|type|false|true|style|null|elem|document|browser|undefined||options|||nodeName|parentNode||test|jQuery|apply|css|window|display|push|fn|constructor|url|prop|add|indexOf|msie|in|event|extend|complete|typeof|isFunction|className|replace|arguments|opacity|div|match|new|status|firstChild|attr|nodeType|hide|show|Array|success|parent|filter|trigger|body|height|table|script|tbody|cache|string|safari|start|hidden|value|merge|left|break|animate|dataType|while|map|find|global||get|id|offsetParent|select|toggle|selected|toUpperCase|remove|catch|try|cur|al|ready|duration|done|text|makeArray|unit|fx|swap|split|target||pushStack|toLowerCase|nextSibling|button|none|handle|guid|now|stack|tb|jsre|timeout|inArray|scrollTop|readyState|end|delete|step|one|name|nth|slice|doc|ret|preventDefault|width|call|events|checked|scrollLeft|exec|px|overflow|documentElement|grep|position|form|block|removeData|rl|timers|max|opera|mozilla|trim|tagName|Math|load|param|removeChild|disabled|insertBefore|async|encodeURIComponent|append|oldblock|val|childNodes|src|readyList|multiFilter|color|defaultView|stopPropagation|args|old|toString|is|last|first|eval|parseInt|self|domManip|prototype|getTime|curCSS|Date|top||ajax|ownerDocument|parseFloat|easing|has|queue|curAnim|custom|innerHTML|orig|currentStyle|visible|getElementById|isReady|error|static|bind|String|which|getComputedStyle|responseText|oWidth|oHeight|on|shift|json|child|RegExp|ol|lastModified|isXMLDoc|jsonp|jquery|previousSibling|dir|safari2|el|styleFloat|state|setInterval|radio|getElementsByTagName|tr|empty|html|getAttribute|pos|update|version|input|float|runtimeStyle|unshift|mouseover|getPropertyValue|GET|clearInterval|safariTimer|visibility|clean|__ie_init|absolute|handleHover|lastToggle|index|fromElement|relatedTarget|click|fix|evt|andSelf|removeEventListener|handler|cloneNode|addEventListener|triggered|nodeIndex|unique|Number|classFilter|prevObject|selectedIndex|after|submit|password|removeAttribute|file|expr|setTimeout|_|appendChild|ajaxSettings|client|active|win|sibling|deep|globalEval|boxModel|cssFloat|object|checkbox|parsererror|offsetLeft|wrapAll|dequeue|props|lastChild|swing|handleError|getResponseHeader|results|startTime|00|box|Modified|ifModified|offsetTop|evalScript|createElement|setRequestHeader|ctrlKey|callback|metaKey|contentType|ajaxSend|ajaxSuccess|ajaxError|ajaxStop|ajaxStart|serializeArray|init|notmodified|POST|loaded|appendTo|DOMContentLoaded|bindReady|mouseout|not|removeAttr|unbind|unload|Width|keyCode|charCode|onreadystatechange|clientX|pageX|srcElement|join|outerHTML|substr|zoom|parse|textarea|reset|image|odd|even|before|quickClass|quickID|prepend|quickChild|execScript|offset|scroll|processData|uuid|contents|continue|textContent|ajaxComplete|clone|setArray|webkit|nodeValue|fl|_default|100|linear|href|speed|eq|createTextNode|throw|replaceWith|splice|_toggle|xml|colgroup|304|200|alpha|Last|httpData|httpNotModified|httpSuccess|fieldset|beforeSend|getBoundingClientRect|XMLHttpRequest|ActiveXObject|col|br|abbr|pixelLeft|urlencoded|www|application|ajaxSetup|post|getJSON|getScript|elements|serialize|clientWidth|hasClass|scr|clientHeight|write|relative|keyup|keypress|keydown|change|mousemove|mouseup|mousedown|right|dblclick|resize|focus|blur|frames|instanceof|hover|offsetWidth|triggerHandler|ipt|defer|offsetHeight|border|padding|clientY|pageY|Left|Right|toElement|Bottom|Top|cancelBubble|returnValue|detachEvent|attachEvent|substring|line|weight|animated|header|font|enabled|innerText|contains|only|size|gt|lt|uFFFF|u0128|417|inner|Height|toggleClass|removeClass|addClass|replaceAll|noConflict|insertAfter|prependTo|wrap|contentWindow|contentDocument|http|iframe|children|siblings|prevAll|nextAll|wrapInner|prev|Boolean|next|parents|maxLength|maxlength|readOnly|readonly|class|htmlFor|CSS1Compat|compatMode|compatible|borderTopWidth|ie|ra|inline|it|rv|medium|borderWidth|userAgent|522|navigator|with|concat|1px|10000|array|ig|PI|NaN|400|reverse|fast|600|slow|Function|Object|setAttribute|changed|be|can|property|fadeTo|fadeOut|getAttributeNode|fadeIn|slideToggle|method|slideUp|slideDown|action|cssText|stop|responseXML|option|content|300|th|protocol|td|location|send|cap|abort|colg|cos|tfoot|thead|With|leg|Requested|opt|GMT|1970|Jan|01|Thu|area|Since|hr|If|Type|Content|meta|specified|open|link|XMLHTTP|Microsoft|img|onload|row|borderLeftWidth|head|attributes'.split('|'),0,{}))
\ No newline at end of file
diff --git a/app-bohyn/media/js/nodevar.js b/app-bohyn/media/js/nodevar.js
new file mode 100644 (file)
index 0000000..eb7ed27
--- /dev/null
@@ -0,0 +1,10 @@
+
+function refreshVarValue(url, target_id) {
+    $.ajax({
+        url: url,
+        success: function(response) {
+            $('#'+target_id).html(response);
+        }
+    });
+}
+
diff --git a/app-bohyn/media/styles/main.css b/app-bohyn/media/styles/main.css
new file mode 100644 (file)
index 0000000..bfa733a
--- /dev/null
@@ -0,0 +1,131 @@
+
+* {
+    margin: 0px;
+    padding: 0px;
+}
+
+body {
+    font-size: 13px;
+    font-family: Tahoma, Arial;
+}
+
+a {
+    text-decoration: none;
+    color: #007700;
+    font-weight: bold;
+}
+
+a:hover {
+    text-decoration: underline;
+}
+
+h1 {
+    margin: 10px 30px;
+    font-style: italic;
+    float: left;
+}
+
+.cleaner {
+    clear: both;
+    visibility: hidden;
+    border: 0px none;
+}
+
+.spacer {
+    width: 100%;
+    height: 10px;
+}
+
+#body {
+    width: 1140px;
+}
+
+#crumbs {
+    clear: both;
+    border: 1px solid black;
+    margin: 5px;
+    width: 1122px;
+}
+
+#crumbs span {
+    display: block;
+    padding: 5px 10px 5px 10px;
+}
+
+#nodes {
+    border: 1px solid black;
+    margin: 5px;
+    width: 200px;
+    float: left;
+}
+
+#nodes ul {
+    margin: 10px;
+}
+
+#nodes ul li {
+    list-style-type: none;
+    margin: 10px 0px;
+}
+
+.title {
+    border-bottom: 1px solid black;
+/*     background-color: silver; */
+    background-color: black;
+    color: white;
+    font-weight: bold;
+}
+
+.title span {
+    display: block;
+    height: 1.3em;
+    padding: 5px 10px 5px 10px;
+}
+
+#main {
+    border: 1px solid black;
+    margin: 5px;
+    width: 910px;
+    float: left;
+}
+
+#main #mainInner {
+    margin: 10px;
+}
+
+#main #mainInner .title {
+    margin: -10px -10px 10px -10px;
+}
+
+#configLink {
+    margin-top: 25px;
+    margin-right: 40px;
+    float: right;
+}
+
+ul.nodeVars {
+    margin-top: 20px;
+}
+
+ul.nodeVars li {
+    list-style-type: none;
+}
+
+table.configTable {
+    border: 1px solid black;
+    border-spacing: 1px;
+    padding: 0px;
+}
+
+table.configTable th {
+    padding: 10px;
+}
+
+table.configTable td {
+    border: 1px solid black;
+    padding: 7px;
+}
+
+.errors {
+    color: red;
+}
diff --git a/app-bohyn/src/Makefile b/app-bohyn/src/Makefile
new file mode 100644 (file)
index 0000000..31e3c77
--- /dev/null
@@ -0,0 +1,277 @@
+#############################################################################
+# Makefile for building: hydroponie
+# Generated by qmake (2.01a) (Qt 4.3.4) on: pá úno 6 12:49:29 2009
+# Project:  src.pro
+# Template: app
+# Command: /usr/bin/qmake -unix -o Makefile src.pro
+#############################################################################
+
+####### Compiler, tools and options
+
+CC            = gcc
+CXX           = g++
+DEFINES       = -DQT_SHARED -DQT_SQL_LIB -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB
+CFLAGS        = -pipe -g -D_REENTRANT -Wall -W $(DEFINES)
+CXXFLAGS      = -pipe -fpermissive -g -D_REENTRANT -Wall -W $(DEFINES)
+INCPATH       = -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtXml -I/usr/include/qt4/QtXml -I/usr/include/qt4/QtSql -I/usr/include/qt4/QtSql -I/usr/include/qt4 -I../_compiled/include -I. -I.
+LINK          = g++
+LFLAGS        = -Wl,--no-undefined
+LIBS          = $(SUBLIBS)  -L/usr/lib -L../_compiled/lib -lfcgi -lulan -lQtSql -lQtXml -lQtGui -lQtCore -lpthread
+AR            = ar cqs
+RANLIB        = 
+QMAKE         = /usr/bin/qmake
+TAR           = tar -cf
+COMPRESS      = gzip -9f
+COPY          = cp -f
+SED           = sed
+COPY_FILE     = $(COPY)
+COPY_DIR      = $(COPY) -r
+INSTALL_FILE  = install -m 644 -p
+INSTALL_DIR   = $(COPY_DIR)
+INSTALL_PROGRAM = install -m 755 -p
+DEL_FILE      = rm -f
+SYMLINK       = ln -sf
+DEL_DIR       = rmdir
+MOVE          = mv -f
+CHK_DIR_EXISTS= test -d
+MKDIR         = mkdir -p
+
+####### Output directory
+
+OBJECTS_DIR   = ./
+
+####### Files
+
+SOURCES       = node.cc \
+               uldy_server.cc \
+               html_layer.cc \
+               address_parser.cc \
+               value_cache.cc \
+               graph_painter.cc \
+               http.cc \
+               utils.cc \
+               fcgi.cc \
+               forms.cc moc_forms.cpp
+OBJECTS       = node.o \
+               uldy_server.o \
+               html_layer.o \
+               address_parser.o \
+               value_cache.o \
+               graph_painter.o \
+               http.o \
+               utils.o \
+               fcgi.o \
+               forms.o \
+               moc_forms.o
+DIST          = /usr/share/qt4/mkspecs/common/g++.conf \
+               /usr/share/qt4/mkspecs/common/unix.conf \
+               /usr/share/qt4/mkspecs/common/linux.conf \
+               /usr/share/qt4/mkspecs/qconfig.pri \
+               /usr/share/qt4/mkspecs/features/qt_functions.prf \
+               /usr/share/qt4/mkspecs/features/qt_config.prf \
+               /usr/share/qt4/mkspecs/features/exclusive_builds.prf \
+               /usr/share/qt4/mkspecs/features/default_pre.prf \
+               /usr/share/qt4/mkspecs/features/debug.prf \
+               /usr/share/qt4/mkspecs/features/default_post.prf \
+               /usr/share/qt4/mkspecs/features/qt.prf \
+               /usr/share/qt4/mkspecs/features/unix/thread.prf \
+               /usr/share/qt4/mkspecs/features/moc.prf \
+               /usr/share/qt4/mkspecs/features/warn_on.prf \
+               /usr/share/qt4/mkspecs/features/resources.prf \
+               /usr/share/qt4/mkspecs/features/uic.prf \
+               /usr/share/qt4/mkspecs/features/yacc.prf \
+               /usr/share/qt4/mkspecs/features/lex.prf \
+               src.pro
+QMAKE_TARGET  = hydroponie
+DESTDIR       = 
+TARGET        = hydroponie
+
+first: all
+####### Implicit rules
+
+.SUFFIXES: .o .c .cpp .cc .cxx .C
+
+.cpp.o:
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cc.o:
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.cxx.o:
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.C.o:
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"
+
+.c.o:
+       $(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"
+
+####### Build rules
+
+all: Makefile $(TARGET)
+
+$(TARGET):  $(OBJECTS)  
+       $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)
+
+Makefile: src.pro  /usr/share/qt4/mkspecs/linux-g++/qmake.conf /usr/share/qt4/mkspecs/common/g++.conf \
+               /usr/share/qt4/mkspecs/common/unix.conf \
+               /usr/share/qt4/mkspecs/common/linux.conf \
+               /usr/share/qt4/mkspecs/qconfig.pri \
+               /usr/share/qt4/mkspecs/features/qt_functions.prf \
+               /usr/share/qt4/mkspecs/features/qt_config.prf \
+               /usr/share/qt4/mkspecs/features/exclusive_builds.prf \
+               /usr/share/qt4/mkspecs/features/default_pre.prf \
+               /usr/share/qt4/mkspecs/features/debug.prf \
+               /usr/share/qt4/mkspecs/features/default_post.prf \
+               /usr/share/qt4/mkspecs/features/qt.prf \
+               /usr/share/qt4/mkspecs/features/unix/thread.prf \
+               /usr/share/qt4/mkspecs/features/moc.prf \
+               /usr/share/qt4/mkspecs/features/warn_on.prf \
+               /usr/share/qt4/mkspecs/features/resources.prf \
+               /usr/share/qt4/mkspecs/features/uic.prf \
+               /usr/share/qt4/mkspecs/features/yacc.prf \
+               /usr/share/qt4/mkspecs/features/lex.prf
+       $(QMAKE) -unix -o Makefile src.pro
+/usr/share/qt4/mkspecs/common/g++.conf:
+/usr/share/qt4/mkspecs/common/unix.conf:
+/usr/share/qt4/mkspecs/common/linux.conf:
+/usr/share/qt4/mkspecs/qconfig.pri:
+/usr/share/qt4/mkspecs/features/qt_functions.prf:
+/usr/share/qt4/mkspecs/features/qt_config.prf:
+/usr/share/qt4/mkspecs/features/exclusive_builds.prf:
+/usr/share/qt4/mkspecs/features/default_pre.prf:
+/usr/share/qt4/mkspecs/features/debug.prf:
+/usr/share/qt4/mkspecs/features/default_post.prf:
+/usr/share/qt4/mkspecs/features/qt.prf:
+/usr/share/qt4/mkspecs/features/unix/thread.prf:
+/usr/share/qt4/mkspecs/features/moc.prf:
+/usr/share/qt4/mkspecs/features/warn_on.prf:
+/usr/share/qt4/mkspecs/features/resources.prf:
+/usr/share/qt4/mkspecs/features/uic.prf:
+/usr/share/qt4/mkspecs/features/yacc.prf:
+/usr/share/qt4/mkspecs/features/lex.prf:
+qmake:  FORCE
+       @$(QMAKE) -unix -o Makefile src.pro
+
+dist: 
+       @$(CHK_DIR_EXISTS) .tmp/hydroponie1.0.0 || $(MKDIR) .tmp/hydroponie1.0.0 
+       $(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/hydroponie1.0.0/ && $(COPY_FILE) --parents node.h uldy_server.h html_layer.h address_parser.h value_cache.h graph_painter.h http.h utils.h defines.h forms.h .tmp/hydroponie1.0.0/ && $(COPY_FILE) --parents node.cc uldy_server.cc html_layer.cc address_parser.cc value_cache.cc graph_painter.cc http.cc utils.cc fcgi.cc forms.cc .tmp/hydroponie1.0.0/ && (cd `dirname .tmp/hydroponie1.0.0` && $(TAR) hydroponie1.0.0.tar hydroponie1.0.0 && $(COMPRESS) hydroponie1.0.0.tar) && $(MOVE) `dirname .tmp/hydroponie1.0.0`/hydroponie1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/hydroponie1.0.0
+
+
+clean:compiler_clean 
+       -$(DEL_FILE) $(OBJECTS)
+       -$(DEL_FILE) *~ core *.core
+
+
+####### Sub-libraries
+
+distclean: clean
+       -$(DEL_FILE) $(TARGET) 
+       -$(DEL_FILE) Makefile
+
+
+mocclean: compiler_moc_header_clean compiler_moc_source_clean
+
+mocables: compiler_moc_header_make_all compiler_moc_source_make_all
+
+compiler_moc_header_make_all: moc_forms.cpp
+compiler_moc_header_clean:
+       -$(DEL_FILE) moc_forms.cpp
+moc_forms.cpp: http.h \
+               utils.h \
+               defines.h \
+               forms.h
+       /usr/bin/moc-qt4 $(DEFINES) $(INCPATH) forms.h -o moc_forms.cpp
+
+compiler_rcc_make_all:
+compiler_rcc_clean:
+compiler_image_collection_make_all: qmake_image_collection.cpp
+compiler_image_collection_clean:
+       -$(DEL_FILE) qmake_image_collection.cpp
+compiler_moc_source_make_all:
+compiler_moc_source_clean:
+compiler_uic_make_all:
+compiler_uic_clean:
+compiler_yacc_decl_make_all:
+compiler_yacc_decl_clean:
+compiler_yacc_impl_make_all:
+compiler_yacc_impl_clean:
+compiler_lex_make_all:
+compiler_lex_clean:
+compiler_clean: compiler_moc_header_clean 
+
+####### Compile
+
+node.o: node.cc node.h \
+               defines.h \
+               utils.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o node.o node.cc
+
+uldy_server.o: uldy_server.cc uldy_server.h \
+               node.h \
+               defines.h \
+               utils.h \
+               value_cache.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o uldy_server.o uldy_server.cc
+
+html_layer.o: html_layer.cc html_layer.h \
+               defines.h \
+               utils.h \
+               node.h \
+               value_cache.h \
+               graph_painter.h \
+               http.h \
+               forms.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o html_layer.o html_layer.cc
+
+address_parser.o: address_parser.cc address_parser.h \
+               utils.h \
+               defines.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o address_parser.o address_parser.cc
+
+value_cache.o: value_cache.cc value_cache.h \
+               defines.h \
+               utils.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o value_cache.o value_cache.cc
+
+graph_painter.o: graph_painter.cc graph_painter.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o graph_painter.o graph_painter.cc
+
+http.o: http.cc http.h \
+               utils.h \
+               defines.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o http.o http.cc
+
+utils.o: utils.cc utils.h \
+               defines.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o utils.o utils.cc
+
+fcgi.o: fcgi.cc defines.h \
+               utils.h \
+               http.h \
+               uldy_server.h \
+               node.h \
+               value_cache.h \
+               address_parser.h \
+               html_layer.h \
+               graph_painter.h \
+               forms.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o fcgi.o fcgi.cc
+
+forms.o: forms.cc forms.h \
+               http.h \
+               utils.h \
+               defines.h
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o forms.o forms.cc
+
+moc_forms.o: moc_forms.cpp 
+       $(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_forms.o moc_forms.cpp
+
+####### Install
+
+install:   FORCE
+
+uninstall:   FORCE
+
+FORCE:
+
diff --git a/app-bohyn/src/Makefile.omk.bck b/app-bohyn/src/Makefile.omk.bck
new file mode 100644 (file)
index 0000000..bf1b038
--- /dev/null
@@ -0,0 +1,8 @@
+
+lib_LOADLIBES = fcgi ulan QtCore
+
+INCLUDES = -I/usr/include/qt4
+
+bin_PROGRAMS = hydroponie
+hydroponie_HEADERS = node.h
+hydroponie_SOURCES = node.cc fcgi.cc
diff --git a/app-bohyn/src/address_parser.cc b/app-bohyn/src/address_parser.cc
new file mode 100644 (file)
index 0000000..42f400c
--- /dev/null
@@ -0,0 +1,24 @@
+
+#include "address_parser.h"
+
+AddressParser::AddressParser(QString path) {
+    docRoot = QString(getenv("DOCUMENT_ROOT"));
+    url = path;
+}
+
+QString AddressParser::getUrlPart(int position) const {
+    return url.path().split("/").value(docRoot.split("/").size() - 2 + position, "");
+}
+
+int AddressParser::getCurrentAddr() const {
+//     int addr = url.path().split("/").value(docRoot.split("/").size() - 2 + 1, "").toInt();
+    int addr = getUrlPart(1).toInt();
+    if (addr < 0) addr = 0;
+    return addr;
+}
+
+QString AddressParser::getCurrentVarName() const {
+//     QString varName = url.path().split("/").value(docRoot.split("/").size() - 2 + 2, "");
+//     return varName;
+    return getUrlPart(2);
+}
diff --git a/app-bohyn/src/address_parser.h b/app-bohyn/src/address_parser.h
new file mode 100644 (file)
index 0000000..bf1a315
--- /dev/null
@@ -0,0 +1,28 @@
+# ifndef _ADDRESS_PARSER_H
+# define _ADDRESS_PARSER_H
+
+#include <stdlib.h>
+
+#include <QString>
+#include <QStringList>
+#include <QUrl>
+
+#include "utils.h"
+
+class AddressParser {
+  private:
+    QString docRoot;
+    QUrl url;
+
+  public:
+    AddressParser(QString path);
+
+    QString getUrlPart(int position) const;
+
+    int getCurrentAddr() const;
+
+    QString getCurrentVarName() const;
+    
+};
+
+# endif
diff --git a/app-bohyn/src/address_parser.o b/app-bohyn/src/address_parser.o
new file mode 100644 (file)
index 0000000..2501847
Binary files /dev/null and b/app-bohyn/src/address_parser.o differ
diff --git a/app-bohyn/src/defines.h b/app-bohyn/src/defines.h
new file mode 100644 (file)
index 0000000..2cb3144
--- /dev/null
@@ -0,0 +1,32 @@
+# ifndef _DEFINES_H
+# define _DEFINES_H
+
+#define MAX_ADDR 60
+
+#define NOT_ASSIGNED_ADDR 99
+
+#define LOG_FILENAME "/home/bohacekm/fel/bap/hydroweb/src/log.txt"
+
+#define NODE_CLEANER_PERIOD_SECS 4
+#define HEARTBEAT_CID 1023
+#define PDO_SKIP_BYTES 3
+
+#define SQLITE_DB_FILE "/home/bohacekm/fel/bap/hydroweb/db/db.sqlite"
+#define SQLITE_CACHE_TABLE_NAME "history"
+#define SQLITE_CACHE_SIZE 20
+
+#define VAR_IMG_WIDTH 700
+#define VAR_IMG_HEIGHT 400
+#define VAR_IMG_BORDER_TOP 30
+#define VAR_IMG_BORDER_RIGHT 30
+#define VAR_IMG_BORDER_BOTTOM 30
+#define VAR_IMG_BORDER_LEFT 50
+#define VAR_CACHE_AGE 3600 * 24 * 7
+#define VAR_IMG_FILE_PATH "/var/www/hydroponie/media/"
+#define VAR_IMG_URL_BASE "/media/"
+
+#define HISTORY_LEN 60
+
+// #define TEST_RUN 1
+
+# endif
diff --git a/app-bohyn/src/fcgi.cc b/app-bohyn/src/fcgi.cc
new file mode 100644 (file)
index 0000000..8d6d795
--- /dev/null
@@ -0,0 +1,168 @@
+// #include <stdlib.h>
+#include <iostream>
+#include <string>
+#include <string.h>
+
+#include <QApplication>
+#include <QString>
+#include <QTextCodec>
+
+#include <fcgi_config.h>
+#include <fcgi_stdio.h>
+#include <ul_lib/ulan.h>
+
+#include "defines.h"
+#include "utils.h"
+
+#include "http.h"
+#include "uldy_server.h"
+// #include "node_cleaner.h"
+#include "node.h"
+#include "address_parser.h"
+#include "html_layer.h"
+// #include "forms.h"
+#include "graph_painter.h"
+
+using namespace std;
+
+extern CidPool cidPool;
+
+void myMessageOutput(QtMsgType type, const char *msg)
+ {
+     switch (type) {
+     case QtDebugMsg:
+         logToFile(QString("Debug: %1").arg(msg));
+         break;
+     case QtWarningMsg:
+         logToFile(QString("Warning: %1").arg(msg));
+         break;
+     case QtCriticalMsg:
+         logToFile(QString("Critical: %1").arg(msg));
+         break;
+     case QtFatalMsg:
+         logToFile(QString("Fatal: %1").arg(msg));
+//          abort();
+     }
+}
+
+int main(int argc, char *argv[]) {
+    logToFile("START SERVERU");
+    qInstallMsgHandler(myMessageOutput);
+    QApplication app(argc, argv, false);
+    QTime timer;
+    QByteArray ba;
+
+    /* globalni aktivace utf-8 */
+    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+
+    int currentNodeAddr = 0;
+    QString currentVarName = "";
+    
+    ULDYServer uldySrv;
+    uldySrv.start();
+
+    while (FCGI_Accept() >= 0) {
+        HttpRequest request;
+        HtmlLayer html(request);
+//         logToFile(QString("request %1").arg(request.method()));
+
+        html.startBuffering();
+
+        AddressParser parser(request.path());
+        currentNodeAddr = parser.getCurrentAddr();
+        currentVarName = parser.getCurrentVarName();
+
+        NodeMap &nodes = uldySrv.getNodesRef();
+        ValueCache &valueCache = uldySrv.getValueCacheRef();
+#ifndef TEST_RUN
+        uldySrv.tryRemoveNodes();
+#endif
+        bool printRefreshHeader = false;
+        try {
+            if (parser.getUrlPart(1) == "xml_config") {
+                
+                if (parser.getUrlPart(2) == "download") {
+                    html.stopBuffering();
+                    html.printXMLDownload(nodes);
+                    continue;
+                }
+
+                html.addCrumb(QString("%1xml_config/").arg(html.documentRoot()), "Správa konfigurace");
+                html.printNodesConfig(nodes);
+
+            } else if (currentNodeAddr == 0) {
+
+                printRefreshHeader = true;
+                html.home(nodes, valueCache);
+
+            } else {
+                Node &selectedNode = nodes.getNodeRef(currentNodeAddr);
+                html.addCrumb(QString("%1%2/").arg(html.documentRoot()).arg(currentNodeAddr), selectedNode.getCustomName());
+
+                if (currentVarName == "configure_vars") {
+                    /* konfigurace promennych nodu */
+                    html.addCrumb("./", "Konfigurace zařízení");
+                    html.printVarsConfig(nodes, selectedNode, cidPool);
+                } else if (currentVarName != "") {
+                    /* detail promenne */
+                    NodeVar selectedVar = selectedNode.getVar(currentVarName);
+                    if (parser.getUrlPart(3) == "refresh_value") {
+                        html.stopBuffering();
+                        html.printHTTPHeaders();
+                        html.printVarValueAjaxRespose(selectedNode, selectedVar);
+                        continue;
+                    } else {
+                        html.addCrumb("./", selectedVar.getCustomDescription());
+                        html.printVar(selectedVar, valueCache);
+                        printRefreshHeader = true;
+                    }
+                } else {
+                    /* detail nodu */
+                    html.printNode(selectedNode);
+                }
+
+            }
+        
+        } catch (NodeError err) {
+            html.stopBuffering();
+            html.printHTTP404Headers();
+            html.print404Error();
+            continue;
+        } catch (NodeVarError err) {
+            html.stopBuffering();
+            html.printHTTP404Headers();
+            html.print404Error();
+            continue;
+        } catch (HttpRedirect redir) {
+            html.stopBuffering();
+            html.printHTTPRedirectHeaders(redir.getUrl());
+            continue;
+        }
+        
+        html.stopBuffering();
+        
+        if (printRefreshHeader)
+            html.printHTTPRefreshHeaders(10);
+        else
+            html.printHTTPHeaders();
+        html.printDocumentStart();
+        html.printCrumbs();
+        html.printNodes(nodes);
+        html.printContentStart();
+        html.printBuffer();
+        html.printContentEnd();
+//         html.printEnvVars();
+        html.print("<hr />");
+//         html.print(cidPool.cidsToStr());
+        html.printDocumentEnd();
+
+    } /* while */
+
+//     nodeClenaer.stopCleaner();
+//     nodeClenaer.wait(3000);
+    
+    uldySrv.stopServer();
+    uldySrv.wait(3000);
+
+    return 0;
+}
diff --git a/app-bohyn/src/forms.cc b/app-bohyn/src/forms.cc
new file mode 100644 (file)
index 0000000..420b4e2
--- /dev/null
@@ -0,0 +1,228 @@
+
+#include "forms.h"
+
+/* Widgets */
+/* TextInput */
+QString TextInput::render(QString name, QVariant value) const {
+    return QString("<input type=\"text\" id=\"id_%1\" name=\"%1\" value=\"%2\" />").arg(name, value.toString());
+}
+
+/* Select */
+QString Select::render(QString name, QVariant value) const {
+    QString output = QString("<select id=\"id_%1\" name=\"%1\">\n").arg(name);
+    if (show_empty_row)
+        output.append("\t<option value=\"\">------</option>\n");
+    SelectOption option;
+    QString selected_str = "";
+    QListIterator<SelectOption> it(choices);
+    while (it.hasNext()) {
+        option = it.next();
+        if (option.first == value.toString())
+            selected_str = " selected=\"selected\"";
+        else
+            selected_str = "";
+        output.append(QString("\t<option%1 value=\"%2\">%3</option>\n").arg(selected_str, option.first, option.second));
+    }
+    output.append("</select>\n");
+    return output;
+}
+
+/* CheckboxInput */
+QString CheckboxInput::render(QString name, QVariant value) const {
+    QString checked_str = "";
+    if (value.toBool())
+        checked_str = " checked=\"checked\"";
+    return QString("<input type=\"checkbox\" id=\"id_%1\" name=\"%1\" value=\"true\"%2>").arg(name, checked_str);
+}
+
+QVariant CheckboxInput::valueFromDatadict(const QueryDict &data, const FilesDict &, QString name) const {
+    return QVariant(data.value(name, "")).toBool();
+}
+
+/* FileInput */
+QString FileInput::render(QString name, QVariant) const {
+    return QString("<input type=\"file\" id=\"id_%1\" name=\"%1\">").arg(name);
+}
+
+QVariant FileInput::valueFromDatadict(const QueryDict &, const FilesDict &files, QString name) const {
+    QVariant value;
+    value.setValue(files.value(name, UploadedFile()));
+    return value;
+}
+
+/* Fields */
+/* Field - abstract */
+QVariant Field::clean(QVariant value) const {
+    QString strval = value.toString().trimmed();
+    if (isRequired() && strval == "")
+        throw ValidationError("Pole je povinné");
+    return strval;
+}
+
+QString Field::render(const QueryDict &data, QString field_template) const {
+    Form *form = (Form*)parent();
+    QVariant value;
+    if (form->isBound())
+        value = data.value(objectName(), "");
+    else
+        value = getInitial();
+    return field_template.arg(widget->render(objectName(), value));
+}
+
+/* CharField */
+CharField::CharField(QString _label, bool _required, QVariant _initial, QObject *parent)
+    : Field(_label, _required, _initial, parent) {
+    widget = new TextInput(this);
+}
+
+/* IntegerField */
+IntegerField::IntegerField(QString _label, bool _required, QVariant _initial, QObject *parent) 
+    : Field(_label, _required, _initial, parent) {
+    widget = new TextInput(this);
+}
+
+QVariant IntegerField::clean(QVariant value) const {
+    bool success;
+    int retval;
+    QString strval = Field::clean(value).toString();
+    retval = strval.toInt(&success);
+    if (!success) {
+        if (!isRequired() && value.toString() == "")
+            return "";
+        throw ValidationError("Hodnotu nelze převést na celé číslo");
+    }
+    return retval;
+}
+
+/* DoubleField */
+FloatField::FloatField(QString _label, bool _required, QVariant _initial, QObject *parent) 
+    : Field(_label, _required, _initial, parent) {
+    widget = new TextInput(this);
+}
+
+QVariant FloatField::clean(QVariant value) const {
+    bool success;
+    float retval;
+    QString strval = Field::clean(value).toString();
+    retval = strval.toFloat(&success);
+    if (!success) {
+        if (!isRequired() && value.toString() == "")
+            return "";
+        throw ValidationError("Hodnotu nelze převést na desetinné číslo");
+    }
+    return retval;
+}
+
+/* ChoiceField */
+ChoiceField::ChoiceField(QString _label, const QList<SelectOption> &_choices, bool _required, QVariant _initial, QObject *parent)
+    : Field(_label, _required, _initial, parent), choices(_choices) {
+    widget = new Select(_choices, true, this);
+}
+
+QVariant ChoiceField::clean(QVariant value) const {
+    QString strval = Field::clean(value).toString();
+    QListIterator<SelectOption> it(choices);
+    SelectOption option;
+    while (it.hasNext()) {
+        option = it.next();
+        if (option.first == value.toString())
+            return value;
+    }
+    if (!isRequired() && value.toString() == "")
+        return "";
+    throw ValidationError("Neplatná hodnota");
+}
+
+/* BooleanField */
+BooleanField::BooleanField(QString _label, bool _required, QVariant _initial, QObject *parent)
+    : Field(_label, _required, _initial, parent) {
+    widget = new CheckboxInput();
+}
+    
+QVariant BooleanField::clean(QVariant value) const {
+    bool boolval = value.toBool();
+    if (!boolval)
+        QString strval = Field::clean("").toString();
+    return boolval;
+}
+
+/* FielField */
+FileField::FileField(QString _label, bool _required, QObject *parent)
+    : Field(_label, _required, "", parent) {
+    widget = new FileInput();
+}
+
+QVariant FileField::clean(QVariant value) const {
+    UploadedFile file = value.value<UploadedFile>();
+    logToFile(QString("file: povinne: %1, null: %2").arg(isRequired()).arg(file.isNull()));
+    if (isRequired() && file.isNull())
+        throw ValidationError("Pole je povinné");
+    return value;
+}
+
+
+/* Form */
+void Form::addField(QString name, Field *field) {
+    field->setObjectName(name);
+    field->setParent(this);
+}
+
+void Form::setError(QString field_name, QString msg) {
+    errors.insert(field_name, msg);
+}
+
+void Form::fullClean() {
+    Field *field;
+    QListIterator<Field*> it(this->findChildren<Field*>());
+    while (it.hasNext()) {
+        field = it.next();
+        try {
+//             cleaned_data.insert(field->objectName(), field->clean(data.value(field->objectName(), "")));
+//             logToFile(QString("cistim %1").arg(field->objectName()));
+            QVariant value = field->getWidgetPtr()->valueFromDatadict(data, files, field->objectName());
+//             logToFile(QString("vycisteno %1").arg(field->objectName()));
+            cleaned_data.insert(field->objectName(), field->clean(value));
+        } catch (ValidationError err) {
+//             logToFile(QString("nevycisteno %1").arg(field->objectName()));
+            errors.insert(field->objectName(), err.getMsg());
+        }
+    }
+}
+
+bool Form::isValid() {
+    fullClean();
+    return isBound() && !(errors.size() > 0);
+}
+
+QString Form::renderField(QString field_name, QString field_template, QString label_template, QString error_template) const {
+    /* 
+        field template: <p>%1 %2 %3</p>
+        label template: <label for="%1">%2</label>
+        error template: <span class="errors">%1</span>
+    */
+    Field *field = findChild<Field*>(field_name);
+    QString label_str = "";
+    QString error_str = "";
+    if (field) {
+        if (label_template != "")
+            label_str = label_template.arg(QString("id_%1").arg(field->objectName()), field->getLabel());
+        if (errors.contains(field_name) && error_template != "")
+            error_str = error_template.arg(errors.value(field_name));
+        return field_template.arg(label_str, field->render(data), error_str);
+    } else {
+        return "";
+    }
+}
+
+QList<QString> Form::fieldNames() const {
+    QList<QString> names;
+    QListIterator<Field*> it(this->findChildren<Field*>());
+    while (it.hasNext()) {
+        names.append(it.next()->objectName());
+    }
+    return names;
+}
+
+Field *Form::operator[](QString field_name) const {
+    return findChild<Field*>(field_name);
+}
diff --git a/app-bohyn/src/forms.h b/app-bohyn/src/forms.h
new file mode 100644 (file)
index 0000000..205b848
--- /dev/null
@@ -0,0 +1,205 @@
+# ifndef FORMS_H
+# define FORMS_H
+
+#include <QPair>
+#include <QString>
+#include <QVariant>
+#include <QVariantMap>
+
+#include "http.h"
+#include "utils.h"
+
+/* Form Errors */
+typedef QMap<QString, QString> ErrorDict;
+class ValidationError {
+  private:
+    QString msg;
+
+  public:
+    ValidationError(QString _msg): msg(_msg) {}
+
+    QString getMsg() { return msg; }
+};
+
+
+/* Widgets */
+class Widget : public QObject {
+  Q_OBJECT;
+  public:
+    Widget(QObject *parent=0): QObject(parent) {}
+
+    virtual ~Widget() {};
+    
+    virtual QString render(QString name, QVariant value) const = 0;
+
+    virtual QVariant valueFromDatadict(const QueryDict &data, const FilesDict &, QString name) const {
+        return QVariant(data.value(name, ""));
+    }
+};
+
+class TextInput : public Widget {
+  public:
+    TextInput(QObject *parent=0): Widget(parent) {}
+
+    virtual QString render(QString name, QVariant value) const;
+
+};
+
+typedef QPair<QString, QString> SelectOption;
+class Select : public Widget {
+  private:
+    QList<SelectOption> choices;
+    bool show_empty_row;
+
+  public:
+    Select(bool _show_empty_row=true, QObject *parent=0): Widget(parent), show_empty_row(_show_empty_row) {}
+
+    Select(const QList<SelectOption> &_choices, bool _show_empty_row=true, QObject *parent=0): Widget(parent), choices(_choices), show_empty_row(_show_empty_row) {}
+
+    void addOption(const SelectOption &option) {
+        choices.append(option);
+    }
+
+    virtual QString render(QString name, QVariant value) const;
+
+    virtual const QList<SelectOption> &getChoicesRef() const { return choices; }
+};
+
+class CheckboxInput : public Widget {
+  public:
+    CheckboxInput(QObject *parent=0): Widget(parent) {}
+
+    virtual QString render(QString name, QVariant value) const;
+
+    virtual QVariant valueFromDatadict(const QueryDict &data, const FilesDict &files, QString name) const;
+};
+
+class FileInput : public Widget {
+  public:
+    FileInput(QObject *parent=0): Widget(parent) {}
+
+    virtual QString render(QString name, QVariant value) const;
+
+    virtual QVariant valueFromDatadict(const QueryDict &data, const FilesDict &files, QString name) const;
+};
+
+
+/* Fields */
+class Field : public QObject {
+  Q_OBJECT;
+  protected:
+    QString label;
+    bool required;
+    QVariant initial;
+    Widget *widget;
+
+  public:
+    Field(QString _label, bool _required, QVariant _initial, QObject *parent=0)
+        : QObject(parent), label(_label), required(_required), initial(_initial) {}
+
+    virtual ~Field() {};
+
+    virtual QString render(const QueryDict &data, QString field_template="%1") const;
+
+    virtual QVariant clean(QVariant value) const;
+
+    virtual QString getLabel() const { return label; }
+
+    virtual bool isRequired() const { return required; }
+
+    virtual QVariant getInitial() const { return initial; }
+
+    virtual Widget *getWidgetPtr() { return widget; }
+};
+
+class CharField : public Field {
+  public:
+    CharField(QString _label, bool _required, QVariant _initial="", QObject *parent=0);
+
+};
+
+class IntegerField : public Field {
+  public:
+    IntegerField(QString _label, bool _required, QVariant _initial="", QObject *parent=0);
+    
+    virtual QVariant clean(QVariant value) const;
+};
+
+class FloatField : public Field {
+  public:
+    FloatField(QString _label, bool _required, QVariant _initial="", QObject *parent=0);
+    
+    virtual QVariant clean(QVariant value) const;
+};
+
+class ChoiceField : public Field {
+  private:
+    const QList<SelectOption> &choices;
+
+  public:
+    ChoiceField(QString _label, const QList<SelectOption> &_choices, bool _required, QVariant _initial="", QObject *parent=0);
+
+    virtual QVariant clean(QVariant value) const;
+};
+
+class BooleanField : public Field {
+  public:
+    BooleanField(QString _label, bool _required, QVariant _initial=false, QObject *parent=0);
+    
+    virtual QVariant clean(QVariant value) const;
+};
+
+class FileField : public Field {
+  public:
+    FileField(QString _label, bool _required, QObject *parent=0);
+
+    virtual QVariant clean(QVariant value) const;
+};
+
+
+/* Form */
+class Form : public QObject {
+  Q_OBJECT;
+  private:
+    bool is_bound;
+    QueryDict data;
+    FilesDict files;
+    ErrorDict errors;
+    QVariantMap cleaned_data;
+
+  public:
+    Form(QObject *parent=0): QObject(parent), is_bound(false) {}
+
+    virtual ~Form() {}
+
+    void bindData(const QueryDict &_data) {
+        is_bound = true;
+        data = _data;
+    }
+
+    void bindFiles(const FilesDict &_files) {
+        is_bound = true;
+        files = _files;
+    }
+
+    bool isBound() const { return is_bound; }
+
+    void addField(QString name, Field *field);
+
+    void setError(QString field_name, QString msg);
+
+    void fullClean();
+
+    bool isValid();
+
+    QString renderField(QString field_name, QString field_template="<p>\n\t%1\n\t%2\n\t%3\n</p>\n", QString label_template="<label for=\"%1\">%2</label>\n", QString error_template="<span class=\"errors\">%1</span>\n") const;
+
+    QList<QString> fieldNames() const;
+
+    const QVariantMap &getCleanedDataRef() const { return cleaned_data; }
+
+    Field *operator[](QString field_name) const;
+};
+
+
+# endif
diff --git a/app-bohyn/src/graph_painter.cc b/app-bohyn/src/graph_painter.cc
new file mode 100644 (file)
index 0000000..1157d90
--- /dev/null
@@ -0,0 +1,242 @@
+
+# include "graph_painter.h"
+
+#define SHRINK_FACTOR 1.2
+
+double Graph::maxVal() const {
+    if (this->data.size() == 0) return 0.0;
+    double maxval = this->data[0].y();
+    for (int i = 1; i < this->data.size(); i++)
+        if (this->data[i].y() > maxval) maxval = this->data[i].y();
+    return maxval;
+}
+
+double Graph::minVal() const {
+    if (this->data.size() == 0) return 0.0;
+    double minval = this->data[0].y();
+    for (int i = 1; i < this->data.size(); i++)
+        if (this->data[i].y() < minval) minval = this->data[i].y();
+    return minval;
+}
+
+QPen Graph::getLinePen() const {
+    QPen linePen(this->color);
+    linePen.setStyle(this->penStyle);
+    linePen.setWidth(1);
+    return linePen;
+}
+
+QPen Graph::getPointPen() const {
+    QPen pointPen(this->color);
+    pointPen.setWidth(4);
+    return pointPen;
+}
+
+QPen Graph::getValuesPen() const {
+    QPen valuesPen(Qt::darkRed);
+    valuesPen.setWidth(1);
+    return valuesPen;
+}
+
+
+/* class GraphPainter */
+QPen GraphPainter::getAxisPen() const {
+    QPen axisPen(Qt::black);
+    axisPen.setWidth(1);
+    return axisPen;
+}
+
+double GraphPainter::getStep() const {
+    return ((double)(image.width() - borderLeft - borderRight)) / (maxValuesCount - 1);
+}
+
+/* prepocet Y-hodnoty z kartezskeho systemu do souradnic QPainteru + posunuti o definovany okraj */
+double GraphPainter::_correctYvalue(double val) const {
+    return image.height() - borderBottom - val;
+}
+
+double GraphPainter::_countXvalue(double val) const {
+    return x_size / (x_max - x_min) * (val - x_min) + borderLeft;
+}
+
+double GraphPainter::totalMaxVal() const {
+    if (graphs.size() == 0) return 0.0;
+    double maxval = graphs[0].maxVal();
+    double tmpmax;
+    for (int i = 1; i < graphs.size(); i++) {
+        tmpmax = graphs[i].maxVal();
+        if (tmpmax > maxval) maxval = tmpmax;
+    }
+    return maxval;
+}
+
+double GraphPainter::totalMinVal() const {
+    if (graphs.size() == 0) return 0.0;
+    double minval = graphs[0].minVal();
+    double tmpmin;
+    for (int i = 1; i < graphs.size(); i++) {
+        tmpmin = graphs[i].minVal();
+        if (tmpmin < minval) minval = tmpmin;
+    }
+    return minval;
+}
+
+void GraphPainter::drawAxes(double zero_level, const AxisLabelList &x_labels, double y_axis_minval, double y_axis_maxval, double scale, double lift) {
+    painter.setPen(getAxisPen());
+    painter.drawLine(borderLeft, _correctYvalue(zero_level), image.width() - borderRight, _correctYvalue(zero_level));
+    painter.drawLine(borderLeft, borderTop, borderLeft, _correctYvalue(0.0));
+    painter.drawText(0, _correctYvalue(zero_level) - 7, borderLeft - 10, 20, Qt::AlignRight, "0");
+    
+    AxisLabel label;
+    double x_value;
+    for (int i = 0; i < x_labels.size(); i++) {
+        label = x_labels[i];
+        if (label.first >= x_min && label.first <= x_max) {
+            x_value = _countXvalue(label.first);
+            painter.drawLine(x_value, _correctYvalue(zero_level), x_value, _correctYvalue(zero_level - 5));
+            painter.drawText(x_value, _correctYvalue(zero_level - 18), label.second);
+        }
+    }
+
+    double y_range = y_axis_maxval - y_axis_minval;
+    if (y_range > 0.0) {
+        double y_step;
+        double y_pos;
+        if (y_range <= 1)
+            y_step = y_range / 10.0;
+        else if (y_range <= 10)
+            y_step = ((int)y_range / 10.0);
+        else
+            y_step = (int)(y_range / 10.0);
+
+        y_pos = y_step;
+        while (y_pos <= (y_axis_maxval)) {
+            painter.drawText(0, _correctYvalue(scale * y_pos + lift) - 7, borderLeft - 10, 20, Qt::AlignRight, QString("%1").arg(y_pos));
+            painter.drawLine(borderLeft - 5, _correctYvalue(scale * y_pos + lift), borderLeft, _correctYvalue(scale * y_pos + lift));
+            y_pos += y_step;
+        }
+        y_pos = -y_step;
+        while (y_pos >= (y_axis_minval)) {
+            painter.drawText(0, _correctYvalue(scale * y_pos + lift) - 7, borderLeft - 10, 20, Qt::AlignRight, QString("%1").arg(y_pos));
+            painter.drawLine(borderLeft - 5, _correctYvalue(scale * y_pos + lift), borderLeft, _correctYvalue(scale * y_pos + lift));
+            y_pos -= y_step;
+        }
+    }
+}
+
+QPolygonF GraphPainter::data2Polygon(const GraphData &data, double scale, double lift) const {
+    double x_coord, y_coord, x_val;
+//     double step = getStep();
+    QPolygonF polygon;
+    for (int i = 0; i < data.size(); i++) {
+//         x_coord = borderLeft + qRound(i * step);
+        x_val = data[i].x();
+        if (x_val < x_min || x_val > x_max)
+            continue;
+        x_coord = _countXvalue(x_val);
+        y_coord = _correctYvalue(scale * data[i].y() + lift);
+        polygon.append(QPointF(x_coord, y_coord));
+    }
+    return polygon;
+}
+
+bool GraphPainter::existsNonEmptyGraph() const {
+    for (int i = 0; i < graphs.size(); i++)
+        if (graphs[i].getDataConstRef().size() > 0) return true;
+    return false;
+}
+
+GraphPainter::GraphPainter(QSize _size, int _borderTop, int _borderRight, int _borderBottom, int _borderLeft) {
+//     this->maxValuesCount = _maxValuesCount;
+    this->borderTop = _borderTop; this->borderRight = _borderRight; this->borderBottom = _borderBottom; this->borderLeft = _borderLeft;
+    this->x_min = 0.0;
+    this->x_max = 1.0;
+    this->x_size = _size.width() - _borderLeft - _borderRight;
+    image = QImage(_size, QImage::Format_RGB16);
+    painter.begin(&image);
+    painter.fillRect(image.rect(), Qt::white);
+}
+
+/* pridani grafu pro vykresleni */
+void GraphPainter::addGraph(const Graph &graph) {
+    graphs.append(graph);
+}
+
+/* kresleni grafu - maxValuesCount udava max. pocet hodnot v datove rade */
+void GraphPainter::drawGraphs(double x_min, double x_max) {
+    AxisLabelList empty_list;
+    drawGraphs(x_min, x_max, empty_list);
+}
+
+void GraphPainter::drawGraphs(double _x_min, double _x_max, const AxisLabelList &x_labels) {
+    x_min = _x_min;
+    x_max = _x_max;
+
+    /* pokud nejsou k dispozici hodnoty, jsou nakresleny pozue souradne osy */
+    if (existsNonEmptyGraph()) {
+        double minval = totalMinVal();
+        double maxval = totalMaxVal();
+        int box_height = image.height() - borderTop - borderBottom;
+        double range = maxval - minval;
+        double x_coord, y_coord;
+        double y_axis_minval, y_axis_maxval;
+        int y_shift;
+
+        /* vypocet umisteni nuly na ose Y, meritka a posunuti grafu po ose Y */
+        double zero_level, scale, lift;
+        if (maxval >= 0.0 && minval >= 0.0) {
+            zero_level = 0.0;
+            scale = box_height / maxval / SHRINK_FACTOR;
+            lift = 0.0;
+            y_axis_minval = 0.0;
+            y_axis_maxval = maxval * (SHRINK_FACTOR - (SHRINK_FACTOR - 1) / 2.0);
+        } else if (maxval <= 0.0 && minval <= 0.0) {
+            zero_level = box_height;
+            scale = box_height / qAbs(minval) / SHRINK_FACTOR;
+            lift = qAbs(minval) * scale * SHRINK_FACTOR;
+            y_axis_minval = minval * (SHRINK_FACTOR - (SHRINK_FACTOR - 1) / 2.0);
+            y_axis_maxval = 0.0;
+        } else {
+            zero_level = box_height * (range - maxval) / range;
+            scale = qMin( (box_height - zero_level) / maxval , zero_level / qAbs(minval) ) / SHRINK_FACTOR;
+            lift = qAbs(minval) * scale * SHRINK_FACTOR;
+            y_axis_minval = minval;
+            y_axis_maxval = maxval;
+        }
+
+        drawAxes(zero_level, x_labels, y_axis_minval, y_axis_maxval, scale, lift);
+
+        for (int i = 0; i < graphs.size(); i++) {
+            Graph &graph = graphs[i];
+            QPolygonF polygon = data2Polygon(graph.getDataConstRef(), scale, lift);
+
+            /* kresleni uzlu a hran */
+            painter.setPen(graph.getPointPen());
+            painter.drawPoints(polygon);
+            painter.setPen(graph.getLinePen());
+            painter.drawPolyline(polygon);
+
+            if (graph.withValues()) {
+                /* kresleni ciselnych hodnot */
+                painter.setPen(graph.getValuesPen());
+                painter.setFont(QFont(painter.font().family(), 10));
+                for (int j = 0; j < polygon.size(); j++) {
+                    x_coord = polygon[j].x();
+                    y_coord = polygon[j].y();
+                    if (graph.getDataConstRef()[j].y() >= 0.0) y_shift = -20;
+                    else y_shift = 4;
+                    painter.translate(x_coord + 1, y_coord + y_shift);
+                    painter.rotate(30);
+                    painter.drawText(0, 0, 40, 20, Qt::AlignLeft, QString("%1").arg(graph.getDataConstRef()[j].y(), 0, 'f', 1));
+                    painter.resetTransform();
+                }
+            }
+        }
+    } else
+        drawAxes(0.0, x_labels, 0.0, 0.0);
+}
+
+/* ulozeni grafu do souboru */
+bool GraphPainter::saveGraphs(QString filename) const {
+    return image.save(filename, "PNG", 40);
+}
diff --git a/app-bohyn/src/graph_painter.h b/app-bohyn/src/graph_painter.h
new file mode 100644 (file)
index 0000000..00733a2
--- /dev/null
@@ -0,0 +1,98 @@
+# ifndef _GRAPH_PAINTER_H
+# define _GRAPH_PAINTER_H
+
+#include <cmath>
+#include <QtSql>
+#include <QImage>
+#include <QPainter>
+#include <QPen>
+#include <QPointF>
+#include <QPolygonF>
+#include <QList>
+#include <QPair>
+
+// #include "defines.h"
+// #include "utils.h"
+
+typedef QVector<QPointF> GraphData;
+class Graph {
+  private:
+    GraphData data;
+    QColor color;
+    Qt::PenStyle penStyle;
+    bool drawValues;
+
+  public:
+    Graph(GraphData _data, QColor _color, Qt::PenStyle _penStyle=Qt::SolidLine, bool _drawValues=true): data(_data), color(_color), penStyle(_penStyle), drawValues(_drawValues) {}
+
+    double maxVal() const;
+
+    double minVal() const;
+
+    bool withValues() {
+        return this->drawValues;
+    }
+
+    QColor getColor() const {
+        return this->color;
+    }
+
+    Qt::PenStyle getPenStyle() const {
+        return this->penStyle;
+    }
+
+    QPen getLinePen() const;
+
+    QPen getPointPen() const;
+
+    QPen getValuesPen() const;
+
+    const GraphData &getDataConstRef() const {
+        return this->data;
+    }
+};
+
+typedef QPair<double, QString> AxisLabel;
+typedef QList<AxisLabel> AxisLabelList;
+class GraphPainter {
+  private:
+    QImage image;
+    QPainter painter;
+    QList<Graph> graphs;
+    int borderTop, borderRight, borderBottom, borderLeft;
+    int maxValuesCount;
+    int x_size;
+    double x_min;
+    double x_max;
+
+    QPen getAxisPen() const;
+
+    double getStep() const;
+
+    double _correctYvalue(double val) const;
+
+    double _countXvalue(double val) const;
+
+    double totalMaxVal() const;
+
+    double totalMinVal() const;
+
+    void drawAxes(double zero_level, const AxisLabelList &x_labels, double y_axis_minval, double y_axis_maxval, double scale=1.0, double lift=0.0);
+
+    QPolygonF data2Polygon(const GraphData &data, double scale=1.0, double lift=0.0) const;
+
+    bool existsNonEmptyGraph() const;
+
+  public:
+    GraphPainter(QSize _size, int _borderTop, int _borderRight, int _borderBottom, int _borderLeft);
+
+    void addGraph(const Graph &graph);
+
+    void drawGraphs(double x_min, double x_max);
+    
+    void drawGraphs(double x_min, double x_max, const AxisLabelList &x_labels);
+
+    bool saveGraphs(QString filename) const;
+};
+
+# endif
diff --git a/app-bohyn/src/graph_painter.o b/app-bohyn/src/graph_painter.o
new file mode 100644 (file)
index 0000000..3817b7c
Binary files /dev/null and b/app-bohyn/src/graph_painter.o differ
diff --git a/app-bohyn/src/html_layer.cc b/app-bohyn/src/html_layer.cc
new file mode 100644 (file)
index 0000000..3fb3c7b
--- /dev/null
@@ -0,0 +1,520 @@
+
+#include "html_layer.h"
+
+extern char** environ;
+
+using namespace std;
+
+void HtmlLayer::_print(const QString &msg) {
+    if (this->buffering) {
+        this->buffer.append(msg);
+    } else {
+        QByteArray ba = msg.toUtf8();
+        printf("%s", ba.constData());
+    }
+}
+
+HtmlLayer::HtmlLayer(HttpRequest &request) {
+    this->addCrumb(documentRoot(), "Home");
+    this->buffering = false;
+    this->request = request;
+}
+
+/* buffer funkce */
+void HtmlLayer::startBuffering() {
+    this->buffering = true;
+    this->buffer = "";
+}
+
+void HtmlLayer::stopBuffering() { this->buffering = false; }
+
+void HtmlLayer::printBuffer() const {
+    QByteArray ba = this->buffer.toUtf8();
+    printf("%s", ba.constData());
+}
+
+/* drobky */
+void HtmlLayer::addCrumb(QString url, QString link) {
+    QStringList crumb;
+    crumb.append(url);
+    crumb.append(link);
+    crumbs.append(crumb);
+}
+
+void HtmlLayer::printCrumbs() {
+    CrumbsIterator it(crumbs);
+    QByteArray url;
+    QByteArray link;
+    _print("<div id=\"crumbs\"><span>");
+    while (it.hasNext()) {
+        QStringList crumb = it.next();
+        _print(QString("<a href=\"%1\">%2</a>").arg(crumb[0]).arg(crumb[1]));
+        if (it.hasNext()) _print(" &gt;&gt; ");
+    }
+    _print("</span></div>\n");
+}
+
+/* zakladni html funkce */
+QString HtmlLayer::documentRoot() const {
+    return QString(getenv("DOCUMENT_ROOT"));
+}
+
+void HtmlLayer::printHTTPHeaders() {
+    _print("Status: 200 OK\r\n");
+    _print("Pragma: no-cache\r\n");
+    _print("Content-Type: text/html; charset=UTF-8\r\n\r\n");
+}
+
+void HtmlLayer::printHTTPRefreshHeaders(int seconds) {
+    _print("Status: 200 OK\r\n");
+    _print(QString("Refresh: %1\r\n").arg(seconds));
+    _print("Pragma: no-cache\r\n");
+    _print("Content-Type: text/html; charset=UTF-8\r\n\r\n");
+}
+
+void HtmlLayer::printHTTPRedirectHeaders(QString location) {
+    _print("Status: 302 Found\r\n");
+    _print(QString("Location: %1\r\n").arg(location));
+    _print("Connection: close\r\n\r\n");
+}
+
+void HtmlLayer::printHTTP404Headers() {
+    _print("Status: 404 Not Found\r\n");
+    _print("Pragma: no-cache\r\n");
+    _print("Content-Type: text/html; charset=UTF-8\r\n\r\n");
+}
+
+void HtmlLayer::print404Error() {
+    _print("<html>\r\n\t<head>\r\n\t\t<title>404 - Not Found</title>\r\n\t<body>\r\n\t\t<h1>404 - Not Found</h1>\r\n\t</body>\r\n</html>\r\n");
+}
+
+void HtmlLayer::printDocumentStart() {
+    _print(
+        "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\r\n"
+        "<html>\r\n"
+        "<head>\n"
+        "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n"
+        "\t<script type=\"text/javascript\" src=\"" VAR_IMG_URL_BASE "js/jquery.js\"></script>\r\n"
+        "\t<script type=\"text/javascript\" src=\"" VAR_IMG_URL_BASE "js/nodevar.js\"></script>\r\n"
+        "\t<link rel=\"stylesheet\" type=\"text/css\" href=\"" VAR_IMG_URL_BASE "styles/main.css\" media=\"screen\" />\r\n"
+        "\t<title>Hydroponie FastCGI echo</title>\r\n"
+        "</head>\n"
+        "<body><div id=\"body\">\r\n\t<h1>Hydroponie web interface</h1>\r\n"
+    );
+    _print(QString("<a id=\"configLink\" href=\"%1xml_config/\">Správa konfigurace</a>").arg(documentRoot()));
+}
+
+void HtmlLayer::printDocumentEnd() {
+    _print("</div></body></html>\r\n");
+}
+
+void HtmlLayer::printContentStart() {
+    _print("<div id=\"main\"><div id=\"mainInner\">\n");
+}
+
+void HtmlLayer::printContentEnd() {
+    _print("</div></div><div class=\"cleaner\"></div>\n");
+}
+
+void HtmlLayer::printEnvVars() {
+    int i;
+    _print("<hr />\n"
+           "<div id=\"envVars\" style=\"color: grey;\">\n");
+    for(i = 0; environ[i] != NULL; i++)
+        _print(QString("%1<br />\n").arg(environ[i]));
+    _print("</div>\n");
+}
+
+/* funkce pro prezentaci nodu */
+void HtmlLayer::home(NodeMap &nodes, ValueCache &valueCache) {
+    _print(QString("<div class=\"title\"><span>Vyberte zařízení...</span></div>\n"));
+
+    QString filename("common_graph.png");
+    GraphPainter gp(QSize(VAR_IMG_WIDTH, VAR_IMG_HEIGHT), VAR_IMG_BORDER_TOP, VAR_IMG_BORDER_RIGHT, VAR_IMG_BORDER_BOTTOM, VAR_IMG_BORDER_LEFT);
+    NodeMapIterator itm(nodes);
+    while (itm.hasNext()) {
+        itm.next();
+        NodeVarIterator itv = itm.value()->getIterator();
+        while (itv.hasNext()) {
+            itv.next();
+            if (itv.value().getCommonGraphDisplay()) {
+                GraphData gdata = valueCache.getValues(itv.value().getNodeSN(), itv.value().getId(), HISTORY_LEN).first;
+                gp.addGraph(Graph(gdata, itv.value().getGraphColor(), Qt::SolidLine, false));
+            }
+        }
+    }
+    QDateTime current_datetime = currentDateTime();
+    gp.drawGraphs(current_datetime.toTime_t() - HISTORY_LEN, current_datetime.toTime_t(), getTimeLabels(HISTORY_LEN));
+    gp.saveGraphs(QString(VAR_IMG_FILE_PATH).append(filename));
+
+    _print(QString("<img src=\"" VAR_IMG_URL_BASE "%1\" />\n").arg(filename));
+
+}
+
+void HtmlLayer::printNodes(NodeMap &nodes) {
+    QByteArray ba;
+    NodeMapKeysIterator it(nodes.keys());
+    _print("<div id=\"nodes\"><div class=\"title\"><span>Dostupná zařízení</span></div><ul>\n");
+    while (it.hasNext()) {
+        int addr = it.next();
+        if (nodes.contains(addr)) {
+            Node &tmpNode = nodes.getNodeRef(addr);
+            _print(QString("\t<li><a href=\"%1%2/\" title=\"%3\">%4</a></li>\n").arg(documentRoot()).arg(tmpNode.getAddr()).arg(tmpNode.getIdStr()).arg(tmpNode.getCustomName()));
+        }
+    }
+    _print("</ul></div>\n");
+}
+
+void HtmlLayer::printNodesConfig(NodeMap &nodes) {
+    Form conf_form;
+    conf_form.addField("config_file", new FileField("Konfigurace", true));
+
+    if (request.method() == "POST") {
+        conf_form.bindFiles(request.FILES());
+
+        if (conf_form.isValid()) {
+            bool parseErr = false;
+            UploadedFile config_file = conf_form.getCleanedDataRef()["config_file"].value<UploadedFile>();
+            if (!config_file.isNull()) {
+                QDomDocument config;
+                if (config.setContent(config_file.contentRef())) {
+                    QDomElement confElem = config.documentElement();
+                    if (confElem.tagName() != "configuration") {
+                        parseErr = true;
+                    } else {
+                        QDomElement nodesElem = confElem.firstChildElement("nodes");
+                        if (!nodesElem.isNull())
+                            nodes.setXMLConfig(nodesElem);
+                    }    
+                }
+            } else {
+                parseErr = true;
+            }
+
+            if (parseErr) {
+                conf_form.setError("config_file", "Chyba při parsování konfiguračního souboru");
+            } else {
+                throw HttpRedirect("./");
+            }
+
+        }
+    }
+
+    _print("<div class=\"title\"><span>Nahrání konfigurace</span></div>");
+    _print("<form action=\"./\" method=\"post\" enctype=\"multipart/form-data\"><table class=\"configTable\">\n");
+    _print(conf_form.renderField("config_file", "<tr><td>%1</td><td>%2 %3</td></tr>\n"));
+    _print("\t<tr><td colspan=\"2\"><input type=\"submit\" value=\"Uložit\" /></td></tr>\n</table></form>\n");
+    _print("<div class=\"spacer\"></div><p><a href=\"./download/\">Stáhnout aktuální konfguraci</a></p>\n");
+}
+
+void HtmlLayer::printNode(Node node) {
+//     addCrumb("./", node.getIdStr());
+    NodeVarIterator it = node.getIterator();
+    _print(QString("<div class=\"title\"><span>%1</span></div>").arg(node.getCustomName()));
+    _print(QString("<a href=\"%1%2/configure_vars/\">Konfigurace zařízení</a>").arg(documentRoot()).arg(node.getAddr()));
+    _print("<ul class=\"nodeVars\">\n");
+    while (it.hasNext()) {
+        it.next();
+        NodeVar tmpVar = it.value();
+//         if (!tmpVar.isVisible()) continue;
+        if (tmpVar.isSystemVar()) continue;
+        _print(QString("\t<li><a href=\"./%1/\">%2</a></li>\n").arg(tmpVar.getName()).arg(tmpVar.getCustomDescription()));
+    }
+    _print("</ul>\n");
+}
+
+void HtmlLayer::printVarsConfig(NodeMap &nodes, Node &node, CidPool &cidPool) {
+    Form vars_form, node_form;
+    processVarsConfig(nodes, node, vars_form, cidPool);
+    processNodeConfig(node, node_form);
+            
+    _print(QString("<div class=\"title\"><span>%1 (konfigurace zařízení)</span></div>").arg(node.getCustomName()));
+
+    /* formular pro konfiguraci nodu */
+    _print("<form action=\"./\" method=\"post\"><table class=\"configTable\">\n");
+    _print(node_form.renderField("node_name", "<tr><td>%1</td><td>%2 %3</td></tr>\n"));
+//     _print(node_form.renderField("config_file", "<tr><td>%1</td><td>%2 %3</td></tr>\n"));
+    _print("\t<tr><td colspan=\"2\"><input type=\"submit\" value=\"Uložit\" name=\"configure_node\" /></td></tr>\n</table></form>\n");
+
+    _print("<div class=\"spacer cleaner\"></div>");
+
+    /* formular pro konfiguraci promennych */
+    _print("<form action=\"./\" method=\"post\"><table class=\"configTable\">\n"
+           "\t<tr>"
+           "<th>Systémový název</th>"
+           "<th>Uživatelský název</th>"
+           "<th>Nastavit hodnotu</th>"
+           "<th>Aktuální hodnota</th>"
+           "<th>Barva</th>"
+           "<th>Spol. graf</th>"
+           "<th>Detail</th>"
+           "</tr>\n");
+
+    QString descr_field("%1_description");
+    QString value_field("%1_value");
+    QString color_field("%1_color");
+    QString displ_field("%1_display");
+
+    ULOIConnection conn(node.getAddr());
+
+    NodeVarIterator it = node.getIterator();
+    while (it.hasNext()) {
+        it.next();
+        NodeVar tmpVar = it.value();
+        QString name = tmpVar.getName();
+        QString tdTemplate("<td>%1%2%3</td>");
+        QString errTemplate("<span class=\"errors\">%1</td>");
+        if (!tmpVar.isVisible()) continue;
+
+        _print("\t<tr>");
+//         _print(QString("<td>%1 (W:%2 R:%3)</td>").arg(name).arg(tmpVar.isWriteable()).arg(tmpVar.isReadable()));
+        _print(QString("<td>%1</td>").arg(name));
+
+        /* field pro popis */
+        _print(vars_form.renderField(descr_field.arg(name), tdTemplate, "", errTemplate));
+
+        /* field pro hodnotu */
+        if (vars_form[value_field.arg(name)])
+            _print(vars_form.renderField(value_field.arg(name), tdTemplate, "", errTemplate));
+        else
+            _print("<td></td>");
+        
+        /* odkaz pro aktualizaci hodnoty */
+        if (tmpVar.isReadable())
+            _print(QString("<td><span id=\"%5\">%1</span> <a onclick=\"refreshVarValue(this.href, '%5'); return false;\" href=\"%2%3/%4/refresh_value/\"><img border=\"0\" style=\"margin-bottom: -3px;\" src=\"" VAR_IMG_URL_BASE "arrow_refresh.png\" /></a></td>").arg(tmpVar.getFloatValue(conn)).arg(documentRoot()).arg(node.getAddr()).arg(name).arg(tmpVar.getId()));
+        else
+            _print("<td></td>");
+
+        /* field pro barvu a pro zobrazeni ve spolecnem grafu, odkaz na detail */
+        if (vars_form[color_field.arg(name)] && vars_form[displ_field.arg(name)]) {
+            _print(vars_form.renderField(color_field.arg(name), tdTemplate, "", errTemplate));
+            _print(vars_form.renderField(displ_field.arg(name), tdTemplate, "", errTemplate));
+            _print(QString("<td><a href=\"%1%2/%3/\">Detail</a></td>").arg(documentRoot()).arg(node.getAddr()).arg(name));
+        } else
+            _print("<td></td><td></td><td></td>");
+
+        _print("</tr>\n");
+    }
+
+    _print("\t<tr><td colspan=\"7\"><input type=\"submit\" name =\"configure_vars\" value=\"Uložit\"></td></tr>\n"
+           "</table></form>\n");
+}
+
+void HtmlLayer::printVar(NodeVar &var, ValueCache &valueCache) {
+    
+    _print(QString("<div class=\"title\"><span>%1 (historie hodnot)</span></div>").arg(var.getCustomDescription()));
+    QString filename = QString("%1-%2.png").arg(var.getNodeSN()).arg(var.getId());
+
+    QPair<GraphData, GraphData> values = valueCache.getValues(var.getNodeSN(), var.getId(), HISTORY_LEN);
+    Graph g1(values.first, var.getGraphColor(), Qt::SolidLine, false);
+    Graph g2(values.second, var.getGraphColor(), Qt::DashLine, false);
+    
+    GraphPainter gp(QSize(VAR_IMG_WIDTH, VAR_IMG_HEIGHT), VAR_IMG_BORDER_TOP, VAR_IMG_BORDER_RIGHT, VAR_IMG_BORDER_BOTTOM, VAR_IMG_BORDER_LEFT);
+    gp.addGraph(g1);
+    gp.addGraph(g2);
+    
+    QDateTime current_datetime = currentDateTime();
+    gp.drawGraphs(current_datetime.toTime_t() - HISTORY_LEN, current_datetime.toTime_t(), getTimeLabels(HISTORY_LEN));
+    gp.saveGraphs(QString(VAR_IMG_FILE_PATH).append(filename));
+
+    _print(QString("<img src=\"" VAR_IMG_URL_BASE "%1\" />\n").arg(filename));
+    if (values.first.size() > 0) {
+        _print("<table border=\"1\"><tr>\n");
+        for (int i = 0; i < values.first.size(); i++) {
+            _print(QString("\t<td width=\"30\">%1</td>\n").arg(values.first[i].y()));
+        }
+        _print("</tr></table>\n");
+    }
+}
+
+/* AJAX odezva */
+void HtmlLayer::printVarValueAjaxRespose(Node &node, NodeVar &var) {
+    if (var.isVisible() && var.isReadable()) {
+#ifndef TEST_RUN
+        ULOIConnection conn(node.getAddr());
+        _print(QString("%1").arg(var.getFloatValue(conn)));
+#else
+        _print(QString("%1").arg(getRandom()));
+#endif
+    }
+}
+
+/* XML download a upload */
+void HtmlLayer::printXMLDownload(NodeMap &nodes) {
+    QDomDocument doc;
+    QDomElement configElem = doc.createElement("configuration");
+
+    doc.appendChild(configElem);
+    configElem.appendChild(nodes.getXMLConfig(doc));
+    
+    _print("Status: 200 OK\r\n");
+    _print("Pragma: no-cache\r\n");
+    _print("Content-Type: text/html; charset=UTF-8\r\n");
+    _print("Content-Disposition: attachment; filename=config.xml\r\n\r\n");
+    _print(doc.toString(4));
+}
+
+/* zpracovani dat od uzivatele */
+void HtmlLayer::processVarsConfig(NodeMap &nodes, Node &node, Form &form, CidPool &cidPool) {
+    QList<SelectOption> colorOptions = getColorOptions();
+    QList<SelectOption> onOffOptions = getOnOffOptions();
+    QList<SelectOption> slotOptions = nodes.getSlotOptions(node.getAddr());
+
+    QString descr_field("%1_description");
+    QString value_field("%1_value");
+    QString color_field("%1_color");
+    QString displ_field("%1_display");
+
+    /*******************************/
+    /*
+    Form form;
+
+    form.addField("first_name", new CharField("Jméno", true, "...vyplňte jméno..."));
+    form.addField("surname", new CharField("Příjmení", true, "...vyplňte příjmení..."));
+    form.addField("age", new CharInteger("Věk", true, 18));
+    
+    if (request.method() == "POST") {
+        
+        form.bindData(request.POST());
+        if (form.isValid()) {
+
+            QVariantMap cleaned_data = form.getCleanedDataRef();
+
+        }
+
+    }
+    */
+    /*******************************/
+
+    CidPool localCidCache;
+    ULOIConnection conn(node.getAddr());
+
+    /* vytvoreni formulare */
+    NodeVarIterator it = node.getIterator();
+    while (it.hasNext()) {
+        it.next();
+        NodeVar tmpVar = it.value();
+        QString name = tmpVar.getName();
+        if (!tmpVar.isVisible()) continue;
+        
+        /* field pro popis */
+        form.addField(descr_field.arg(name), new CharField("", true, tmpVar.getCustomDescription()));
+
+        /* field pro hodnotu */
+        if (tmpVar.isWriteable()) {
+            if (tmpVar.getUserType() == "cid")
+                form.addField(value_field.arg(name), new CidField("", true, cidPool, localCidCache, tmpVar.getFloatValue(conn)));
+            else if (tmpVar.getUserType() == "bool")
+                form.addField(value_field.arg(name), new ChoiceField("", onOffOptions, true, QVariant(tmpVar.getFloatValue(conn)).toString()));
+            else if (tmpVar.getUserType() == "slot")
+                form.addField(value_field.arg(name), new ChoiceField("", slotOptions, false, QVariant(tmpVar.getFloatValue(conn)).toString()));
+            else if (tmpVar.getDecimalPlaces() > 0)
+                form.addField(value_field.arg(name), new FloatField("", true, tmpVar.getFloatValue(conn)));
+            else
+                form.addField(value_field.arg(name), new IntegerField("", true, tmpVar.getFloatValue(conn)));
+        }
+
+        /* field pro barvu a pro zobrazeni ve spolecnem grafu */
+        if (!tmpVar.isSystemVar() && tmpVar.isReadable()) {
+            form.addField(color_field.arg(name), new ChoiceField("", colorOptions, true, tmpVar.getGraphColor().name()));
+            form.addField(displ_field.arg(name), new BooleanField("", false, tmpVar.getCommonGraphDisplay()));
+        }
+    }
+
+    if (request.method() == "POST" && request.POST().contains("configure_vars")) {
+        form.bindData(request.POST());
+
+        if (form.isValid()) {
+            QVariantMap cleaned_data = form.getCleanedDataRef();
+            NodeVarMutableIterator it = node.getMutableIterator();
+            QByteArray qItemVal;
+            node.resetUsedCids();
+            while (it.hasNext()) {
+                it.next();
+                NodeVar &tmpVar = it.value();
+                QString name = tmpVar.getName();
+                if (!tmpVar.isVisible()) continue;
+                
+                /* nastaveni popisu */
+                tmpVar.setCustomDescription(cleaned_data[descr_field.arg(name)].toString());
+
+                /* nastaveni hodnoty */
+//                 node.resetUsedCids();
+                if (cleaned_data.contains(value_field.arg(name))) {
+                    float val = cleaned_data.value(value_field.arg(name)).toDouble();
+                    if (tmpVar.getUserType() == "cid") {
+                        if ((val == form[value_field.arg(name)]->getInitial().toDouble()) || tmpVar.setFloatValue(val, conn)) {
+                            node.addUsedCid((int)val);
+                            cidPool.freeCid(form[value_field.arg(name)]->getInitial().toInt());
+                            cidPool.blockCid((int)val);
+                            logToFile("CID nastaven");
+//                         } else if (tmpVar.setFloatValue(val, conn)) {
+//                             node.addUsedCid(val);
+//                             cidPool.freeCid(form[value_field.arg(name)]->getInitial().toInt());
+//                             cidPool.blockCid(val);
+//                             logToFile("CID nastaven");
+                        } else
+                            logToFile("chyba pri nastavovani CIDu");
+                    } else if (val != form[value_field.arg(name)]->getInitial().toDouble())
+                        tmpVar.setFloatValue(val, conn);
+                }
+
+                /* nastaveni barvy a zobrazeni ve spolecnem grafu */
+                if (cleaned_data.contains(color_field.arg(name)) && cleaned_data.contains(displ_field.arg(name))) {
+                    tmpVar.setGraphColor(QColor(cleaned_data.value(color_field.arg(name)).toString()));
+                    tmpVar.setCommonGraphDisplay(cleaned_data.value(displ_field.arg(name)).toBool());
+                }
+                
+                it.setValue(tmpVar);
+            }
+            throw HttpRedirect("./");
+        }
+
+    }
+}
+
+void HtmlLayer::processNodeConfig(Node &node, Form &form) {
+    form.addField("node_name", new CharField("Název zařízení", true, node.getCustomName()));
+    
+    if (request.method() == "POST" && request.POST().contains("configure_node")) {
+        form.bindData(request.POST());
+        if (form.isValid()) {
+            node.setCustomName(form.getCleanedDataRef()["node_name"].toString());
+            throw HttpRedirect("./");   
+        }
+    }
+}
+
+/* chybova hlaseni */
+void HtmlLayer::invalidNode(NodeError err, int/* nodeAddr*/) {
+    _print(QString("<h2 class=\"error\">%1</h2>\n").arg(err.getErrorMsg()));
+}
+
+void HtmlLayer::invalidNodeVar(NodeVarError err, QString/* nodeVarName*/) {
+    _print(QString("<h2 class=\"error\">%1</h2>\n").arg(err.getErrorMsg()));
+}
+
+/* obecne funkce */
+void HtmlLayer::print(const QString &msg) {
+    _print(msg);
+}
+
+
+/* na miru udelany form field kvuli validaci unikatnosti CIDu */
+CidField::CidField(QString _label, bool _required, CidPool &_cidPool, CidPool &_localCidCache, QVariant _initial, QObject *parent) 
+    : IntegerField(_label, _required, _initial, parent), cidPool(_cidPool), localCidCache(_localCidCache) {}
+
+QVariant CidField::clean(QVariant value) const {
+    QVariant retval = IntegerField::clean(value);
+    if (retval == initial)
+        return retval;
+    int tmp_cid_val = retval.toInt();
+    if (tmp_cid_val == 0)
+        return 0;
+    if (!cidPool.isFreeCid(tmp_cid_val))
+        throw ValidationError("Tento CID je již používán");
+    if (!localCidCache.isFreeCid(tmp_cid_val))
+        throw ValidationError("CID musí být unikátní");
+    localCidCache.blockCid(tmp_cid_val);
+    return retval;
+}
diff --git a/app-bohyn/src/html_layer.h b/app-bohyn/src/html_layer.h
new file mode 100644 (file)
index 0000000..b23f886
--- /dev/null
@@ -0,0 +1,123 @@
+# ifndef _HTML_LAYER_H
+# define _HTML_LAYER_H
+
+#include <stdlib.h>
+
+#include <QByteArray>
+#include <QPair>
+#include <QString>
+#include <QStringList>
+#include <QList>
+#include <QListIterator>
+#include <QDateTime>
+#include <QDomDocument>
+
+#include <fcgi_config.h>
+#include <fcgi_stdio.h>
+
+#include "defines.h"
+#include "utils.h"
+
+#include "node.h"
+#include "value_cache.h"
+#include "graph_painter.h"
+#include "http.h"
+#include "forms.h"
+
+typedef QList<QStringList> Crumbs;
+typedef QListIterator<QStringList> CrumbsIterator;
+
+class HtmlLayer {
+  private:
+    Crumbs crumbs;
+    QString buffer;
+    bool buffering;
+    HttpRequest request;
+
+    void _print(const QString &msg);
+
+  public:
+    HtmlLayer(HttpRequest &request);
+
+    /* buffer funkce */
+    void startBuffering();
+
+    void stopBuffering();
+
+    void printBuffer() const;
+
+    /* drobky */
+    void addCrumb(QString url, QString name);
+
+    void printCrumbs();
+
+    /* zakladni html funkce */
+    QString documentRoot() const;
+
+    void printHTTPHeaders();
+
+    void printHTTPRefreshHeaders(int seconds);
+
+    void printHTTPRedirectHeaders(QString location);
+
+    void printHTTP404Headers();
+
+    void print404Error();
+
+    void printDocumentStart();
+
+    void printDocumentEnd();
+
+    void printContentStart();
+
+    void printContentEnd();
+
+    void printEnvVars();
+
+    /* funkce pro prezentaci nodu */
+    void home(NodeMap &nodes, ValueCache &valueCache);
+
+    void printNodes(NodeMap &nodes);
+
+    void printNodesConfig(NodeMap &nodes);
+
+    void printNode(Node node);
+
+    void printVarsConfig(NodeMap &nodes, Node &node, CidPool &cidPool);
+
+    void printVar(NodeVar &var, ValueCache &valueCache);
+
+    /* AJAX odezva */
+    void printVarValueAjaxRespose(Node &node, NodeVar &var);
+
+    /* XML download a upload */
+    void printXMLDownload(NodeMap &nodes);
+
+    /* zpracovani dat od uzivatele */
+    void processVarsConfig(NodeMap &nodes, Node &node, Form &form, CidPool &cidPool);
+
+    void processNodeConfig(Node &node, Form &form);
+
+    /* chybova hlaseni */
+    void invalidNode(NodeError err, int nodeAddr);
+
+    void invalidNodeVar(NodeVarError err, QString nodeVarName);
+
+    /* obecne funkce */
+    void print(const QString &msg);
+};
+
+
+/* na miru udelany form field kvuli validaci unikatnosti CIDu */
+class CidField : public IntegerField {
+  private:
+    CidPool &cidPool;
+    CidPool &localCidCache;
+
+  public:
+    CidField(QString _label, bool _required, CidPool &_cidPool, CidPool &_localCidCache, QVariant _initial, QObject *parent=0);
+
+    virtual QVariant clean(QVariant value) const;
+};  
+
+# endif
diff --git a/app-bohyn/src/html_layer.o b/app-bohyn/src/html_layer.o
new file mode 100644 (file)
index 0000000..bdc1083
Binary files /dev/null and b/app-bohyn/src/html_layer.o differ
diff --git a/app-bohyn/src/http.cc b/app-bohyn/src/http.cc
new file mode 100644 (file)
index 0000000..73e2157
--- /dev/null
@@ -0,0 +1,126 @@
+
+#include "http.h"
+
+QString CRLF("\r\n");
+
+/* class UploadedFile */
+const UploadedFile &UploadedFile::sharedNull() {
+    static UploadedFile uf = UploadedFile(DUMMY_TYPE());
+    return uf;
+}
+
+UploadedFile::UploadedFile() {
+    *this = sharedNull();
+}
+
+UploadedFile::UploadedFile(QString _file_name, QString _content_type, int _file_size, const QByteArray &_content) {
+    d = new Data;
+    d->null = false;
+    d->file_name = _file_name;
+    d->content_type = _content_type;
+    d->file_size = _file_size;
+    d->content = _content;
+}
+
+
+/* class HttpRequest */
+void HttpRequest::parsePostData() {
+    QList<QPair<QByteArray, QByteArray> > queryItems;
+    QString content_type(getenv("CONTENT_TYPE"));
+    int content_length = QString(getenv("CONTENT_LENGTH")).toInt();
+    if (content_type.startsWith("multipart/form-data")) {
+        parseMultipartData(content_length, content_type);
+    } else {
+        if (content_length > 0) {
+            QByteArray buf_in;
+            buf_in.resize(content_length);
+            fread(buf_in.data(), 1, buf_in.size(), FCGI_stdin);
+            QUrl pseudoUrl(QString("/?").append(buf_in));
+            queryItems = pseudoUrl.encodedQueryItems();
+            for (int i = 0; i < queryItems.size(); i++) {
+                QString first = QUrl::fromPercentEncoding(queryItems[i].first).replace("+", "%20");
+                QString second = QUrl::fromPercentEncoding(queryItems[i].second).replace("+", "%20");
+                post_data.insert(QUrl::fromPercentEncoding(first.toUtf8()), QUrl::fromPercentEncoding(second.toUtf8()));
+            }
+        }
+    }
+}
+
+void HttpRequest::parseMultipartData(int content_length, QString content_type) {
+    QByteArray buf_in;
+    buf_in.resize(content_length);
+    if (fread(buf_in.data(), 1, buf_in.size(), FCGI_stdin) != (uint)content_length)
+        return;
+    QByteArray boundary_str = QString(content_type).mid(QString("multipart/form-data").size() + QString("; boundary=").size()).prepend("--").toAscii();
+    buf_in = buf_in.mid(boundary_str.size() + CRLF.size());
+    QList<QByteArray> content_parts;
+    int boundary_index;
+    while (true) {
+        boundary_index = buf_in.indexOf(boundary_str);
+        if (boundary_index == -1)
+            break;
+        content_parts.append(buf_in.left(boundary_index - CRLF.size()));
+        buf_in = buf_in.mid(boundary_index + boundary_str.size() + CRLF.size());
+    }
+    buf_in.clear();
+    
+    for (int i = 0; i < content_parts.size(); i++)
+        parseContentPart(content_parts[i]);
+}
+
+void HttpRequest::parseContentPart(QByteArray &content_part) {
+    int crlf_pos = content_part.indexOf(CRLF);
+    QRegExp file_reg("^Content-Disposition: form-data; name=\"(.+)\"; filename=\"(.*)\"$");
+    QRegExp field_reg("^Content-Disposition: form-data; name=\"(.+)\"$");
+    if (file_reg.exactMatch(content_part.left(crlf_pos))) {
+        parseFileContent(file_reg.cap(1), file_reg.cap(2), content_part, crlf_pos + CRLF.size());
+    } else if (field_reg.exactMatch(content_part.left(crlf_pos))) {
+        parseFieldContent(field_reg.cap(1), content_part, crlf_pos + CRLF.size());
+    } else
+        return;
+}
+
+void HttpRequest::parseFileContent(QString field_name, QString file_name, QByteArray &content_part, int start_pos) {
+    int crlf_pos = content_part.indexOf(CRLF, start_pos);
+    QRegExp content_type_reg("^Content-Type: (.+)$");
+    if (!content_type_reg.exactMatch(content_part.mid(start_pos, crlf_pos - start_pos)))
+        return;
+    QString content_type = content_type_reg.cap(1);
+    content_part = content_part.mid(crlf_pos + 2 * CRLF.size(), content_part.size() - crlf_pos - 2 * CRLF.size());
+    if (file_name != "") {
+//         logToFile(QString("vytvarim soubor %1, size %2").arg(file_name).arg(content_part.size()));
+        files_data.insert(field_name, UploadedFile(file_name, content_type, content_part.size(), content_part));
+//         logToFile(QString("vytvoren soubor %1").arg(file_name));
+    }
+}
+
+void HttpRequest::parseFieldContent(QString field_name, QByteArray &content_part, int start_pos) {
+    QString content = content_part.mid(start_pos + CRLF.size(), content_part.size() - start_pos - CRLF.size());
+    post_data.insert(field_name, content);
+}
+
+
+HttpRequest::HttpRequest() {
+    QUrl requestUrl(getenv("REQUEST_URI"));
+    _path = requestUrl.path();
+    _method = getenv("REQUEST_METHOD");
+    QList<QPair<QByteArray, QByteArray> > queryItems = requestUrl.encodedQueryItems();
+    for (int i = 0; i < queryItems.size(); i++) {
+        QString first = QUrl::fromPercentEncoding(queryItems[i].first);
+        QString second = QUrl::fromPercentEncoding(queryItems[i].second);
+        get_data.insert(QUrl::fromPercentEncoding(first.toUtf8()), QUrl::fromPercentEncoding(second.toUtf8()));
+    }
+    parsePostData();
+
+//     QMapIterator<QString, QString> it(post_data);
+//     while (it.hasNext()) {
+//         it.next();
+//         logToFile(QString("POST --- KEY: %1, VAL %2").arg(it.key(), it.value()));
+//     }
+//     QMapIterator<QString, UploadedFile> itf(files_data);
+//     while (itf.hasNext()) {
+//         itf.next();
+//         logToFile(QString("FILES --- KEY: %1, VAL %2, SIZE %3").arg(itf.key(), itf.value().fileName()).arg(itf.value().size()));
+//         logToFile(QString("CCCCCCC\n%1").arg(QString(itf.value().contentRef())));
+//     }
+}
diff --git a/app-bohyn/src/http.h b/app-bohyn/src/http.h
new file mode 100644 (file)
index 0000000..a284ded
--- /dev/null
@@ -0,0 +1,118 @@
+
+# ifndef _HTTP_H
+# define _HTTP_H
+
+#include <stdlib.h>
+
+#include <QSharedData>
+#include <QSharedDataPointer>
+#include <QVariant>
+#include <QUrl>
+#include <QString>
+#include <QByteArray>
+#include <QMap>
+#include <QRegExp>
+
+#include <fcgi_config.h>
+#include <fcgi_stdio.h>
+
+#include "utils.h"
+
+class UploadedFile : public QVariant {
+  private:
+    struct Data : public QSharedData {
+        bool null;
+        QString file_name;
+        QString content_type;
+        int file_size;
+        QByteArray content;
+        Data(): null(true), file_name(""), content_type(""), file_size(0), content("") {};
+    };
+    QSharedDataPointer<Data> d;
+
+    class DUMMY_TYPE {};
+    
+    static const UploadedFile& sharedNull();
+    
+    UploadedFile(DUMMY_TYPE) { d = new Data; };
+
+  public:
+    UploadedFile();
+
+    UploadedFile(QString _file_name, QString _content_type, int _file_size, const QByteArray &_content);
+
+    QString fileName() const { return d->file_name; }
+
+    QString contentType() const { return d->content_type; }
+
+    int size() const { return d->file_size; }
+
+    const QByteArray &contentRef() const { return d->content; }
+
+    bool isNull() { return d->null; }
+};
+Q_DECLARE_METATYPE(UploadedFile)
+
+
+typedef QMap<QString, QString> QueryDict;
+typedef QMap<QString, UploadedFile> FilesDict;
+
+class HttpRedirect {
+  private:
+    QString url;
+
+  public:
+    HttpRedirect(QString _url): url(_url) {}
+    
+    QString getUrl() const {
+        return url;
+    }
+};
+
+class HttpRequest {
+  private:
+    QString _path;
+    QString _method;
+    QueryDict post_data;
+    QueryDict get_data;
+    FilesDict files_data;
+
+    void parsePostData();
+
+    void parseMultipartData(int content_length, QString content_type);
+
+    void parseContentPart(QByteArray &content_part);
+
+    void parseFileContent(QString field_name, QString file_name, QByteArray &content_part, int start_pos);
+
+    void parseFieldContent(QString field_name, QByteArray &content_part, int start_pos);
+
+  public:
+    HttpRequest();
+
+    QString path() const {
+        return this->_path;
+    }
+
+    QString method() const {
+        return this->_method;
+    }
+
+    const QueryDict &GET() const {
+        return this->get_data;
+    }
+
+    const QueryDict &POST() const {
+        return this->post_data;
+    }
+
+    const FilesDict &FILES() const {
+        return this->files_data;
+    }
+};
+
+// class HttpResponse() {
+//     
+// };
+
+# endif
diff --git a/app-bohyn/src/moc_forms.cpp b/app-bohyn/src/moc_forms.cpp
new file mode 100644 (file)
index 0000000..d9a22ac
--- /dev/null
@@ -0,0 +1,146 @@
+/****************************************************************************
+** Meta object code from reading C++ file 'forms.h'
+**
+** Created: Wed Feb 4 01:02:31 2009
+**      by: The Qt Meta Object Compiler version 59 (Qt 4.4.3)
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#include "forms.h"
+#if !defined(Q_MOC_OUTPUT_REVISION)
+#error "The header file 'forms.h' doesn't include <QObject>."
+#elif Q_MOC_OUTPUT_REVISION != 59
+#error "This file was generated using the moc from 4.4.3. It"
+#error "cannot be used with the include files from this version of Qt."
+#error "(The moc has changed too much.)"
+#endif
+
+QT_BEGIN_MOC_NAMESPACE
+static const uint qt_meta_data_Widget[] = {
+
+ // content:
+       1,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       0,    0, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_Widget[] = {
+    "Widget\0"
+};
+
+const QMetaObject Widget::staticMetaObject = {
+    { &QObject::staticMetaObject, qt_meta_stringdata_Widget,
+      qt_meta_data_Widget, 0 }
+};
+
+const QMetaObject *Widget::metaObject() const
+{
+    return &staticMetaObject;
+}
+
+void *Widget::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_Widget))
+        return static_cast<void*>(const_cast< Widget*>(this));
+    return QObject::qt_metacast(_clname);
+}
+
+int Widget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QObject::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    return _id;
+}
+static const uint qt_meta_data_Field[] = {
+
+ // content:
+       1,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       0,    0, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_Field[] = {
+    "Field\0"
+};
+
+const QMetaObject Field::staticMetaObject = {
+    { &QObject::staticMetaObject, qt_meta_stringdata_Field,
+      qt_meta_data_Field, 0 }
+};
+
+const QMetaObject *Field::metaObject() const
+{
+    return &staticMetaObject;
+}
+
+void *Field::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_Field))
+        return static_cast<void*>(const_cast< Field*>(this));
+    return QObject::qt_metacast(_clname);
+}
+
+int Field::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QObject::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    return _id;
+}
+static const uint qt_meta_data_Form[] = {
+
+ // content:
+       1,       // revision
+       0,       // classname
+       0,    0, // classinfo
+       0,    0, // methods
+       0,    0, // properties
+       0,    0, // enums/sets
+
+       0        // eod
+};
+
+static const char qt_meta_stringdata_Form[] = {
+    "Form\0"
+};
+
+const QMetaObject Form::staticMetaObject = {
+    { &QObject::staticMetaObject, qt_meta_stringdata_Form,
+      qt_meta_data_Form, 0 }
+};
+
+const QMetaObject *Form::metaObject() const
+{
+    return &staticMetaObject;
+}
+
+void *Form::qt_metacast(const char *_clname)
+{
+    if (!_clname) return 0;
+    if (!strcmp(_clname, qt_meta_stringdata_Form))
+        return static_cast<void*>(const_cast< Form*>(this));
+    return QObject::qt_metacast(_clname);
+}
+
+int Form::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
+{
+    _id = QObject::qt_metacall(_c, _id, _a);
+    if (_id < 0)
+        return _id;
+    return _id;
+}
+QT_END_MOC_NAMESPACE
diff --git a/app-bohyn/src/node.cc b/app-bohyn/src/node.cc
new file mode 100644 (file)
index 0000000..7a99edf
--- /dev/null
@@ -0,0 +1,510 @@
+
+#include "node.h"
+
+using namespace std;
+
+/*class CidPool */
+void CidPool::blockCid(int cid) {
+    assignedCids.insert(cid);
+}
+
+void CidPool::freeCid(int cid) {
+    assignedCids.remove(cid);
+}
+
+void CidPool::freeCids(const QSet<int> &cids) {
+    assignedCids.subtract(cids);
+}
+
+bool CidPool::isFreeCid(int cid) const {
+    return (!assignedCids.contains(cid) || cid == 0);
+}
+
+QString CidPool::cidsToStr() const {
+    QString ret(" -- ");
+    QSetIterator<int> it(assignedCids);
+    while (it.hasNext()) {
+        ret.append(QString("%1 -- ").arg(it.next()));
+    }
+    return ret;
+}
+
+/* instance CidPoolu */
+CidPool cidPool;
+
+
+/* ULOIConnection */
+ULOIConnection::ULOIConnection(int addr) {
+//     if (_coninfo != NULL)
+//         uloi_close(_coninfo);
+    
+    int num_tries = 1;
+    while (num_tries < 4) {
+        _coninfo = uloi_open((char*)UL_DEV_NAME, addr, 0x10, 0, 50);
+        if (!_coninfo) {
+            logToFile(QString("[WW] - Chyba pri otevirani objektoveho rozhrani nodu %1..., try %2").arg(addr).arg(num_tries));
+            _coninfo = NULL;
+        } else
+            break;
+        num_tries++;
+    }
+}
+
+ULOIConnection::~ULOIConnection() {
+    if (_coninfo)
+        uloi_close(_coninfo);
+    _coninfo = NULL;
+}
+
+uloi_coninfo_t *ULOIConnection::coninfo() const {
+    return _coninfo;
+}
+
+
+/* class NodeVar */
+const NodeVar &NodeVar::sharedNull() {
+    static NodeVar nv = NodeVar(DUMMY_TYPE());
+    return nv;
+}
+
+bool NodeVar::setFloatValue(float val, const ULOIConnection &conn) const {
+#ifndef TEST_RUN
+    int retval, vallen, ival;
+    logToFile(QString("nastavuji hodnotu %1   konverze na %2").arg(val).arg((int)(val * pow(10.0, (double)getDecimalPlaces()))));
+    if (!conn.coninfo()) {
+        logToFile("neni coninfo");
+        return false;
+    }
+    ival = (int)(val * pow(10.0, (double)getDecimalPlaces()));
+    vallen = 2;
+    logToFile(QString("nastavuji var ID %1, VAL %2, iVAL %3").arg(getId()).arg(val).arg(ival));
+    retval = uloi_set_var(conn.coninfo(), getId(), &ival, vallen);
+    logToFile(QString("nastavena var, ret = %1").arg(retval));
+//     usleep(10);
+    return (retval<0)?false:true;
+#else
+    return true;
+#endif
+}
+
+float NodeVar::getFloatValue(const ULOIConnection &conn) const {
+#ifndef TEST_RUN
+    if (!conn.coninfo())
+        return 0.0;
+    int retval = 0, vallen, state;
+    vallen = 2;
+    state = uloi_get_var(conn.coninfo(), getId(), &retval, vallen);
+    if (state < 0) {
+        return 0.0;
+    }
+    if (retval & 0x8000) retval |= ~0xffff; else retval &= 0xffff;
+    return ((float)retval) / pow(10.0, (double)getDecimalPlaces());
+#else
+    return 666.0;
+#endif
+}
+
+NodeVar::NodeVar() {
+    *this = sharedNull();
+}
+
+NodeVar::NodeVar(int varId, int nodeAddr, long node_sn, QString const &name, QString const &typeStr, bool readable, bool writeable) {
+    d = new Data;
+    d->varId = varId;
+    d->nodeAddr = nodeAddr;
+    d->node_sn = node_sn;
+    d->name = name;
+    QList<QString> parsedType = typeStr.split("/");
+    d->type = parsedType[0];
+    
+    if (parsedType.size() > 1 && parsedType[1].startsWith("."))
+        d->decimalPlaces = parsedType[1].mid(1).toInt();
+    else
+        d->decimalPlaces = 0;
+    
+    if (parsedType.size() > 1 && !parsedType.last().startsWith("."))
+        d->userType = parsedType.last();
+    else
+        d->userType = "";
+
+    d->readable = readable;
+    d->writeable = writeable;
+}
+
+bool NodeVar::isSystemVar() const {
+    if (this->getUserType() == "cid") return true;
+    if (this->getUserType() == "slot") return true;
+    if (this->getName() == "PERIOD") return true;
+    return !(this->isVisible());
+}
+
+bool NodeVar::isVisible() const {
+    if (this->getName() == "STATUS" || this->getName() == "ERRCLR") return false;
+    return true;
+}
+
+QDomElement NodeVar::getXMLConfig(QDomDocument &doc, const ULOIConnection &conn) const {
+    QDomElement varElem = doc.createElement("var");
+    varElem.setAttribute("oid", QVariant(getId()).toString());
+    
+    QDomElement customDescrElem = doc.createElement("customDescription");
+    QDomElement colorElem = doc.createElement("color");
+    QDomElement commonGraphElem = doc.createElement("commonGraphDisplay");
+
+    customDescrElem.appendChild(doc.createTextNode(getCustomDescription()));
+    colorElem.appendChild(doc.createTextNode(getGraphColor().name()));
+    commonGraphElem.appendChild(doc.createTextNode(QVariant(getCommonGraphDisplay()).toString()));
+
+    varElem.appendChild(customDescrElem);
+    varElem.appendChild(colorElem);
+    varElem.appendChild(commonGraphElem);
+#ifndef TEST_RUN
+    if (isReadable() && isWriteable()) {
+        QDomElement valueElem = doc.createElement("value");
+        valueElem.appendChild(doc.createTextNode(QVariant(getFloatValue(conn)).toString()));
+        varElem.appendChild(valueElem);
+    }
+#endif
+    return varElem;
+}
+    
+void NodeVar::setXMLConfig(const QDomElement &conf, const ULOIConnection &conn, QSet<int> &usedCids) {
+    QDomElement customDescrElem = conf.firstChildElement("customDescription");
+    if (!customDescrElem.isNull()) {
+        setCustomDescription(customDescrElem.text());
+    }
+    
+    QDomElement colorElem = conf.firstChildElement("color");
+    if (!colorElem.isNull()) {
+        QColor color(colorElem.text());
+        if (color.isValid())
+            setGraphColor(color);
+    }
+    
+    QDomElement commonGraphElem = conf.firstChildElement("commonGraphDisplay");
+    if (!commonGraphElem.isNull()) {
+        bool commonGraphDisplay = QVariant(commonGraphElem.text()).toBool();
+        setCommonGraphDisplay(commonGraphDisplay);
+    }
+#ifndef TEST_RUN
+    if (isReadable() && isWriteable()) {
+        QDomElement valueElem = conf.firstChildElement("value");
+        if (!valueElem.isNull()) {
+            bool succ;
+            float value = valueElem.text().toFloat(&succ);
+            if (succ) {
+                if (getUserType() == "cid") {
+                    int actual_cid = getFloatValue(conn);
+                    if (cidPool.isFreeCid((int)value) && setFloatValue(value, conn)) {
+                        cidPool.freeCid(actual_cid);
+                        cidPool.blockCid((int)value);
+                        usedCids.remove(actual_cid);
+                        usedCids.insert((int)value);
+                    }
+                } else {
+                    setFloatValue(value, conn);
+                }
+            }
+        }
+    }
+#endif
+}
+
+
+/* class Node */
+// const Node& Node::sharedNull() {
+//     static Node n = Node(DUMMY_TYPE());
+//     return n;
+// }
+
+// Node::Node() {
+//     *this = sharedNull();
+// }
+
+Node::Node(int addr, long sn) {
+//     d = new Data;
+    d = &_d;
+    refreshLastUpdate();
+    d->addr = addr;
+    d->sn = sn;
+    d->idStr = QString("zarizeni %1").arg(sn);
+
+    logToFile(QString("[II] zadam o info na adresu %1 a zakladam nod...").arg(addr));
+
+#ifndef TEST_RUN
+    ULOIConnection conn(getAddr());
+    int ret, i, *oids;
+#endif
+    
+#ifdef TEST_RUN
+    registerVar(1, (uchar*)"TEMPERATURE;s2/.2", true);
+    registerVar(2, (uchar*)"TEMPERATURE_CID;u2/cid", true);
+    registerVar(2, (uchar*)"TEMPERATURE_CID;u2/cid", false);
+    registerVar(3, (uchar*)"PERIOD;u2", true);
+    registerVar(3, (uchar*)"PERIOD;u2", false);
+    registerVar(4, (uchar*)"STATUS;u2", true);
+    registerVar(5, (uchar*)"FAN;u2/bool", true);
+    registerVar(5, (uchar*)"FAN;u2/bool", false);
+    registerVar(6, (uchar*)"FAN_SLOT;u2/slot", true);
+    registerVar(6, (uchar*)"FAN_SLOT;u2/slot", false);
+#else
+    do {
+        if (!conn.coninfo()) {
+            logToFile("[WW] - Chyba pri otevirani objektoveho rozhrani...");
+            break;
+        }
+        ret = uloi_get_oids(conn.coninfo(), ULOI_QOIO, &oids);
+        if (ret < 0) {
+            logToFile("[WW] - Chyba pri ziskavani promennych pro cteni...");
+            break;
+        }
+        for (i = 0; i < ret; i++) {     // nacteni promennych pro cteni
+            uchar *despack = NULL;
+            if (uloi_get_oiddes(conn.coninfo(), ULOI_DOIO, oids[i], &despack) >= 0) {
+                registerVar(oids[i], despack, true);
+                if (despack) free(despack);
+            }
+        }
+        free(oids);
+        ret = uloi_get_oids(conn.coninfo(), ULOI_QOII, &oids);
+        if (ret < 0) {
+            logToFile("[WW] - Chyba pri ziskavani promennych pro zapis...");
+            break;
+        }
+        for (i=0; i < ret; i++) {       // nacteni promennych pro zapis
+            uchar *despack=NULL;
+            if (uloi_get_oiddes(conn.coninfo(), ULOI_DOII, oids[i], &despack) >= 0) {
+                registerVar(oids[i], despack, false);
+                if (despack) free(despack);
+            }
+        }
+        free(oids);
+    } while (0);
+#endif
+    logToFile(QString("[II] zalozen nod na adrese %1...").arg(addr));
+}
+
+NodeVar Node::getVar(QString name) const {
+    if (d->vars.contains(name)) {
+        return d->vars[name];
+    } else {
+        logToFile("hazim neex. promennou");
+        throw NodeVarError("Neplatny nazev promenne");
+    }
+}
+
+NodeVar &Node::getVarRef(QString name) {
+    if (d->vars.contains(name)) {
+        return d->vars[name];
+    } else {
+        logToFile("hazim neex. promennou ref");
+        throw NodeVarError("Neplatny nazev promenne");
+    }
+}
+
+void Node::registerVar(int oid, uchar *despack, bool isReadVar) {
+#ifdef TEST_RUN
+    QString pack((char*)despack);
+    QStringList parsed_pack = pack.split(";");
+    QByteArray ba_name = parsed_pack[0].toUtf8();
+    QByteArray ba_type = parsed_pack[1].toUtf8();
+    char *desname = ba_name.data();
+    char *destype = ba_type.data();
+#else
+    char *desname = uloi_oiddespack_strdup(despack,0);
+    char *destype = uloi_oiddespack_strdup(despack,1);
+#endif
+    if (desname){
+        if (isReadVar) {
+            if (d->vars.contains(desname)) {
+                NodeVar tmp = d->vars.value(desname);
+                tmp.setReadable(true);
+                d->vars.insert(desname, tmp);
+            } else {
+                d->vars.insert(desname, NodeVar(oid, getAddr(), getSN(), desname, destype, true, false));
+            }
+        } else {
+            if (d->vars.contains(desname)) {
+                NodeVar tmp = (d->vars.value(desname));
+                tmp.setWriteable(true);
+                d->vars.insert(desname, tmp);
+            } else {
+                d->vars.insert(desname, NodeVar(oid, getAddr(), getSN(), desname, destype, false, true));
+            }
+        }
+#ifndef TEST_RUN
+        free(desname);
+#endif
+    }
+#ifndef TEST_RUN
+    if (destype) free(destype);
+#endif
+}
+
+NodeVar Node::hasCid(int cid) const {
+    NodeVarIterator it = getIterator();
+    ULOIConnection conn(getAddr());
+    while (it.hasNext()) {
+        it.next();
+        NodeVar tmpVar = it.value();
+        if (tmpVar.getUserType() != "cid") continue;
+#ifndef TEST_RUN
+        if ((int)tmpVar.getFloatValue(conn) != cid) continue;
+#endif
+        QString trgtVarName = tmpVar.getName().left(tmpVar.getName().size() - 4);
+        if (this->hasVar(trgtVarName)) {
+//             return this->getVar(trgtVarName).getId();
+            return this->getVar(trgtVarName);
+        }
+    }
+    throw NodeVarError("promenna neexistuje");
+}
+
+NodeVarIterator Node::getIterator() const {
+    return NodeVarIterator(d->vars);
+}
+
+NodeVarMutableIterator Node::getMutableIterator() {
+    return NodeVarMutableIterator(d->vars);
+}
+
+QDomElement Node::getXMLConfig(QDomDocument &doc) const {
+    ULOIConnection conn(getAddr());
+
+    QDomElement nodeElem = doc.createElement("node");
+    nodeElem.setAttribute("sn", QVariant((qlonglong)getSN()).toString());
+
+    QDomElement customNameElem = doc.createElement("customName");
+    QDomElement varsElem = doc.createElement("vars");
+
+    customNameElem.appendChild(doc.createTextNode(getCustomName()));
+    NodeVarIterator it = getIterator();
+    while (it.hasNext()) {
+        it.next();
+        varsElem.appendChild(it.value().getXMLConfig(doc, conn));
+    }
+
+    nodeElem.appendChild(customNameElem);
+    nodeElem.appendChild(varsElem);
+
+    return nodeElem;
+}
+    
+void Node::setXMLConfig(const QDomElement &conf) {
+    ULOIConnection conn(getAddr());
+
+    QDomElement customNameElem = conf.firstChildElement("customName");
+    if (!customNameElem.isNull())
+        setCustomName(customNameElem.text());
+
+    QDomElement varsElem = conf.firstChildElement("vars");
+    if (varsElem.isNull())
+        return;
+    QDomElement varElem = varsElem.firstChildElement("var");
+    bool succ;
+    while (!varElem.isNull()) {
+        int oid = varElem.attribute("oid").toInt(&succ);
+        if (succ) {
+            NodeVarMutableIterator it = getMutableIterator();
+            while (it.hasNext()) {
+                it.next();
+                if (it.value().getId() == oid) {
+                    it.value().setXMLConfig(varElem, conn, d->usedCids);
+                    break;
+                }
+            }
+        }
+        varElem = varElem.nextSiblingElement("var");
+    }
+}
+
+
+/* class NodeMap */
+// ::Node NodeMap::getNode(int addr) const {
+//     if (this->contains(addr)) {
+//         return this->value(addr);
+//     } else {
+//         logToFile("hazim neex. node");
+//         throw NodeError("Neplatne zarizeni");
+//     }
+// }
+
+::Node &NodeMap::getNodeRef(int addr) {
+//     static QMutex m;
+    if (this->contains(addr)) {
+//         logToFile("chci to zamknout");
+//         m.lock();
+//         logToFile("je to zamceny");
+        ::Node *tmpNode = (*this)[addr];
+//         logToFile("chci to odemknout");
+//         m.unlock();
+        return *tmpNode;
+//         return nd;
+    } else {
+        logToFile("hazim neex. node ref");
+        throw NodeError("Neplatne zarizeni");
+    }
+}
+
+// const NodeMapIterator NodeMap::getIterator() const {
+//     return NodeMapIterator(*this);
+// }
+
+// const NodeMapMutableIterator NodeMap::getMutableIterator() {
+//     return NodeMapMutableIterator(*this);
+// }
+
+QList< QPair<QString, QString> > NodeMap::getSlotOptions(int excludeAddr) const {
+    QList< QPair<QString, QString> > slotOptions;
+    NodeMapIterator it(*this);
+    while (it.hasNext()) {
+        it.next();
+        if (it.key() == excludeAddr) 
+            continue;
+        const ::Node &tmpNode = *it.value();
+        NodeVarIterator itv = tmpNode.getIterator();
+        ULOIConnection conn(tmpNode.getAddr());
+        while (itv.hasNext()) {
+            itv.next();
+            const NodeVar &tmpVar = itv.value();
+            if (tmpVar.getUserType() == "cid" && tmpVar.isReadable()) {
+                int cid_val = tmpVar.getFloatValue(conn);
+                if (cid_val != 0) {
+                    QString optLabel = QString("%1 - %2").arg(tmpNode.getCustomName(), tmpVar.getCustomDescription());
+                    slotOptions.append(QPair<QString, QString>(QVariant(cid_val).toString(), optLabel));
+                }
+            }
+        }
+    }
+    return slotOptions;
+}
+
+QDomElement NodeMap::getXMLConfig(QDomDocument &doc) const {
+    QDomElement nodesElem = doc.createElement("nodes");
+    NodeMapIterator it(*this);
+    while (it.hasNext()) {
+        it.next();
+        nodesElem.appendChild(it.value()->getXMLConfig(doc));
+    }
+    return nodesElem;
+}
+    
+void NodeMap::setXMLConfig(const QDomElement &conf) {
+    QDomElement nodeElem = conf.firstChildElement("node");
+    bool succ;
+    while (!nodeElem.isNull()) {
+        long sn = nodeElem.attribute("sn").toLong(&succ);
+        if (succ) {
+            NodeMapMutableIterator it(*this);
+            while (it.hasNext()) {
+                it.next();
+                if (sn == it.value()->getSN()) {
+                    it.value()->setXMLConfig(nodeElem);
+                    break;
+                }
+            }
+        }
+        nodeElem = nodeElem.nextSiblingElement("node");
+    }
+}
+
diff --git a/app-bohyn/src/node.h b/app-bohyn/src/node.h
new file mode 100644 (file)
index 0000000..4aa5494
--- /dev/null
@@ -0,0 +1,327 @@
+# ifndef _NODE_H
+# define _NODE_H
+
+#include <stdlib.h>
+#include <cmath>
+
+#include <QString>
+#include <QStringList>
+#include <QUrl>
+#include <QListIterator>
+#include <QMap>
+#include <QMapIterator>
+#include <QMutableMapIterator>
+#include <QMutex>
+#include <QSharedDataPointer>
+#include <QTime>
+#include <QDateTime>
+#include <QSet>
+#include <QMutableSetIterator>
+#include <QColor>
+#include <QDomDocument>
+
+#include <QtSql>
+
+#include <fcgi_stdio.h>
+
+#include <ul_lib/ulan.h>
+#include "defines.h"
+#include "utils.h"
+
+class CidPool {
+  private:
+    QSet<int> assignedCids;
+
+  public:
+    CidPool(int reserve=50) {
+        assignedCids.reserve(reserve);
+    }
+    
+    void blockCid(int cid);
+
+    void freeCid(int cid);
+
+    void freeCids(const QSet<int> &cids);
+
+    bool isFreeCid(int cid) const;
+
+    QString cidsToStr() const;
+};
+
+class ULOIConnection {
+  private:
+    uloi_coninfo_t *_coninfo;
+  
+  public:
+    ULOIConnection(int addr);
+
+    ~ULOIConnection();
+
+    uloi_coninfo_t *coninfo() const;
+};
+
+class NodeVar {
+  private:
+    struct Data : public QSharedData {
+        int varId;
+        int nodeAddr;
+        long node_sn;
+        QString name;
+        QString type;
+        int decimalPlaces;
+        QString userType;
+        bool readable;
+        bool writeable;
+        QString customDescription;
+        QColor graphColor;
+        bool commonGraphDisplay;
+        Data(): nodeAddr(0), node_sn(0), readable(true), writeable(false), customDescription(""), graphColor(Qt::red), commonGraphDisplay(false) {};
+    };
+    QSharedDataPointer<Data> d;
+
+    class DUMMY_TYPE {};
+
+    static const NodeVar& sharedNull();
+  
+    NodeVar(DUMMY_TYPE) { d = new Data; };
+
+  public:
+    NodeVar();
+
+    NodeVar(int varId, int nodeAddr, long node_sn, QString const &name, QString const &typeStr, bool readable=true, bool writeable=false);
+
+    int getId() const {
+        return d->varId;
+    }
+
+    QString getName() const {
+        return d->name;
+    }
+
+    QString getType() const {
+        return d->type;
+    }
+
+    int getDecimalPlaces() const {
+        return d->decimalPlaces;
+    }
+
+    QString getUserType() const {
+        return d->userType;
+    }
+
+    long getNodeSN() const {
+        return d->node_sn;
+    }
+
+    bool isReadable() const {
+        return d->readable;
+    }
+
+    bool isWriteable() const {
+        return d->writeable;
+    }
+
+    QColor getGraphColor() const {
+        return d->graphColor;
+    }
+
+    bool getCommonGraphDisplay() const {
+        return d->commonGraphDisplay;
+    }
+
+    void setReadable(bool state) {
+        d->readable = state;
+    }
+    
+    void setWriteable(bool state) {
+        d->writeable = state;
+    }
+
+    bool setFloatValue(float val, const ULOIConnection &conn) const;
+
+    float getFloatValue(const ULOIConnection &conn) const;
+
+    QString getCustomDescription() const {
+        if (d->customDescription == "")
+            return d->name;
+        return d->customDescription;
+    }
+
+    void setCustomDescription(QString descr) {
+        d->customDescription = descr;
+    }
+
+    void setGraphColor(QColor color) {
+        d->graphColor = color;
+    }
+
+    void setCommonGraphDisplay(bool display) {
+        d->commonGraphDisplay = display;
+    }
+
+    bool isSystemVar() const;
+
+    bool isVisible() const;
+
+    QDomElement getXMLConfig(QDomDocument &doc, const ULOIConnection &conn) const;
+    
+    void setXMLConfig(const QDomElement &conf, const ULOIConnection &conn, QSet<int> &usedCids);
+
+};
+// Q_DECLARE_METATYPE(NodeVar);
+
+typedef QMapIterator<QString, NodeVar> NodeVarIterator;
+typedef QMutableMapIterator<QString, NodeVar> NodeVarMutableIterator;
+
+class Node {
+  private:
+//     struct Data : public QSharedData {
+    struct Data {
+        int addr;
+        long sn;
+        QString idStr;
+        QString customName;
+        QMap<QString, NodeVar> vars;
+        QDateTime lastUpdate;
+        QSet<int> usedCids;
+        Data(): addr(0), sn(0), lastUpdate(currentDateTime()) {};
+    };
+//     QSharedDataPointer<Data> d;
+    Data _d, *d;
+
+//     class DUMMY_TYPE {};
+
+//     static const Node& sharedNull();
+  
+//     Node(DUMMY_TYPE) { d = new Data; };
+
+  public:
+    Node();
+    
+    Node(int addr, long sn);
+
+    NodeVar getVar(QString name) const;
+
+    NodeVar &getVarRef(QString name);
+
+    /* nastavi promennou varName_PER na hodnotu period */
+    void setVarPeriod(QString varName, int period);
+
+    /* nastavi promennou varName_CID na hodnotu cid */
+    void setVarCid(QString varName, int cid);
+
+    /* zaregistruje novou promennou k tomuto nodu */
+    void registerVar(int oid, uchar *despack, bool isReadVar);
+
+    int getAddr() const {
+        return d->addr;
+    }
+
+    long getSN() const {
+        return d->sn;
+    }
+
+    QString getIdStr() const {
+        return d->idStr;
+    }
+
+    QString getCustomName() const {
+        if (d->customName == "")
+            return d->idStr;
+        return d->customName;
+    }
+
+    void setCustomName(QString name) {
+        d->customName = name;
+    }
+
+    /* vraci true, pokud tomto nodu existuje promenna varName */
+    bool hasVar(QString varName) const {
+        return d->vars.contains(varName);
+    }
+
+    /* pokud v tomto nodu existuje promenna s nastavenym CID == cid, vraci OID teto promenne, jinak vraci 0 */
+    NodeVar hasCid(int cid) const;
+
+    NodeVarIterator getIterator() const;
+
+    NodeVarMutableIterator getMutableIterator();
+
+    QDateTime getLastUpdate() const {
+        return d->lastUpdate;
+    }
+
+    void refreshLastUpdate() {
+        d->lastUpdate = currentDateTime();
+    }
+
+    void resetUsedCids() {
+        d->usedCids.clear();
+    }
+
+    void addUsedCid(int cid) {
+        d->usedCids.insert(cid);
+    }
+
+    const QSet<int> &getUsedCidsRef() const {
+        return d->usedCids;
+    }
+
+    QDomElement getXMLConfig(QDomDocument &doc) const;
+    
+    void setXMLConfig(const QDomElement &conf);
+
+};
+// Q_DECLARE_METATYPE(Node);
+
+
+class NodeError {
+  private:
+    QString msg;
+  public:
+    NodeError(const QString &msg) { this->msg = msg; };
+
+    QString getErrorMsg() const {
+        return this->msg;
+    }
+};
+
+class NodeVarError {
+  private:
+    QString msg;
+  public:
+    NodeVarError(const QString &msg) { this->msg = msg; };
+
+    QString getErrorMsg() const {
+        return this->msg;
+    }
+};
+
+typedef QMapIterator<int, Node*> NodeMapIterator;
+typedef QMutableMapIterator<int, Node*> NodeMapMutableIterator;
+typedef QListIterator<int> NodeMapKeysIterator;
+
+class NodeMap : public QMap<int, Node*> {
+  public:
+    ~NodeMap() {
+        qDeleteAll(this->values());
+    }
+
+//     ::Node getNode(int addr) const;
+
+    ::Node &getNodeRef(int addr);
+
+//     const NodeMapIterator getIterator() const;
+
+//     const NodeMapMutableIterator getMutableIterator();
+
+    QList< QPair<QString, QString> > getSlotOptions(int excludeAddr=0) const;
+
+    QDomElement getXMLConfig(QDomDocument &doc) const;
+    
+    void setXMLConfig(const QDomElement &conf);
+
+};
+
+# endif
diff --git a/app-bohyn/src/node.o b/app-bohyn/src/node.o
new file mode 100644 (file)
index 0000000..a159ba9
Binary files /dev/null and b/app-bohyn/src/node.o differ
diff --git a/app-bohyn/src/src.pro b/app-bohyn/src/src.pro
new file mode 100644 (file)
index 0000000..1d8afed
--- /dev/null
@@ -0,0 +1,12 @@
+CONFIG += qt
+
+QT += sql xml
+
+HEADERS += node.h uldy_server.h html_layer.h address_parser.h value_cache.h graph_painter.h http.h utils.h defines.h forms.h
+SOURCES += node.cc uldy_server.cc html_layer.cc address_parser.cc value_cache.cc graph_painter.cc http.cc utils.cc fcgi.cc forms.cc
+
+TARGET = hydroponie
+TEMPLATE = app
+
+INCLUDEPATH += ../_compiled/include/
+LIBS += -L../_compiled/lib -lfcgi -lulan
diff --git a/app-bohyn/src/uldy_server.cc b/app-bohyn/src/uldy_server.cc
new file mode 100644 (file)
index 0000000..7f16daf
--- /dev/null
@@ -0,0 +1,275 @@
+#include "uldy_server.h"
+
+using namespace std;
+
+extern CidPool cidPool;
+
+bool AddressPool::blockAddress(long sn, int addr) {
+    if (!assignedAddrs.contains(sn) && !assignedAddrs.values().contains(addr)) {
+        assignedAddrs.insert(sn, addr);
+        holes.remove(addr);
+    }
+    return false;
+}
+
+int AddressPool::getFreeAddress(long sn) {
+//     return 60;  // DOCASNE
+    if (assignedAddrs.size() == MAX_ADDR) return 0;
+    int retval;
+    if (holes.size() == 0) {
+        retval = assignedAddrs.size() + 1;
+    } else {
+        QMutableSetIterator<int> it(holes);
+        it.next();
+        retval = it.value();
+        it.remove();
+    }
+    assignedAddrs.insert(sn, retval);
+    return retval;
+}
+
+void AddressPool::freeAddress(long sn) {
+//     return;     // DOCASNE
+    if (assignedAddrs.contains(sn)) {
+        int addr = assignedAddrs.value(sn);
+        if (addr != assignedAddrs.size())
+            holes.insert(addr);
+        assignedAddrs.remove(sn);
+    }
+}
+AddressPool addressPool;
+
+
+void ULDYServer::sendNewAddress(int addr, long sn) const {
+    int ret;
+    QByteArray buf_out;
+    ul_fd_t ul_fd = ul_open(UL_DEV_NAME, NULL);
+    if (ul_fd == UL_FD_INVALID) {
+        logToFile("[EE] ULDYSRV - chyba pri zasilani adresy: neplatny deskriptor...");
+        return;
+    }
+    buf_out.append(ULNCS_SET_ADDR);    /* SN0 SN1 SN2 SN3 NEW_ADR */
+    buf_out += sn2buf(sn);
+    buf_out.append(addr);
+    ret = ul_send_command(ul_fd, 0, UL_CMD_NCS, UL_BFL_NORE, (uchar*)buf_out.constData(), buf_out.size()); //UL_BFL_ARQ
+//     logToFile(QString("[II] odeslana zprava, status: %1, len: %2 data %3").arg(ret).arg(buf_out.size()).arg(buf_out.toHex().constData()));
+    ul_close(ul_fd);
+}
+
+void ULDYServer::requestIdentification(int addr) const {
+    int ret;
+    QByteArray buf_out;
+    ul_fd_t ul_fd = ul_open(UL_DEV_NAME, NULL);
+    if (ul_fd == UL_FD_INVALID) {
+        logToFile("[EE] ULDYSRV - chyba pri dotazu na identifikaci: neplatny deskriptor...");
+        return;
+    }
+    buf_out.append(ULNCS_SID_RQ);
+    ret = ul_send_command(ul_fd, addr, UL_CMD_NCS, UL_BFL_NORE, (uchar*)buf_out.constData(), buf_out.size()); //UL_BFL_ARQ
+    logToFile(QString("[II] odeslana zadost o identifikaci na adresu %1").arg(addr));
+    ul_close(ul_fd);
+}
+
+void ULDYServer::processPDOMessage(int saddr, int cid, int data) {
+//     logToFile(QString("PDO msg: CID = %1, DATA = %2").arg(cid).arg(data));
+    if (nodes.contains(saddr)) {
+        Node &node = nodes.getNodeRef(saddr);
+        if (cid == HEARTBEAT_CID) {
+            
+            logToFile(QString("[II] - HEARTBEAT from address %1").arg(saddr));
+            node.refreshLastUpdate();
+
+        } else {
+
+            try {
+                NodeVar tmpVar = node.hasCid(cid);
+                float fdata = ((float)data) / pow(10.0, (double)tmpVar.getDecimalPlaces());
+                valueCache.insertValue(node.getSN(), tmpVar.getId(), fdata);
+            } catch (NodeVarError) { }
+            node.refreshLastUpdate();
+
+        }
+    } else if (saddr != NOT_ASSIGNED_ADDR) {
+
+        requestIdentification(saddr);
+
+    }
+//     logToFile(QString("PDO zpracovana %1").arg((unsigned long)QThread::currentThreadId()));
+}
+
+void ULDYServer::stopServer(void) {
+    logToFile("[II] ULDYSRV - stopping uldy server...");
+    this->running = false;
+}
+
+void ULDYServer::run() {
+    int ret;
+    int addr, saddr, msg_len;
+    long sn;
+    QByteArray buf_in;
+    ul_msginfo msginfo;
+    
+    QTime timer;
+    timer.start();
+#ifdef TEST_RUN
+    Node *newNode = new Node(30, 102);
+    this->nodes.insert(30, newNode);
+
+    while (this->running) {
+        sleep(5);
+        int data = getRandom();
+        int cid = 16;
+        processPDOMessage(30, cid, data);
+    }
+#else
+    ul_fd_t ul_fd = ul_open(UL_DEV_NAME, NULL);
+    if (ul_fd == UL_FD_INVALID) {
+        logToFile("[EE] ULDYSRV - neplatny deskriptor");
+        return;
+    }
+
+    memset(&msginfo, 0, sizeof(ul_msginfo));
+    ul_addfilt(ul_fd, &msginfo);
+
+    logToFile("[II] ULDYSRV - cekam na zpravu...");
+
+    while (this->running) {     // main loop
+
+        while ((ul_fd_wait(ul_fd, 1) <= 0) && this->running) ;
+
+        if ((ul_inepoll(ul_fd) > 0) && (ul_acceptmsg(ul_fd, &msginfo)) >= 0) {
+            if (msginfo.cmd == UL_CMD_NCS) {
+                msg_len = msginfo.len;
+                saddr = msginfo.sadr;
+                buf_in.resize(msg_len);
+                ret = ul_read(ul_fd, buf_in.data(), msg_len);        // nacteni SN do bufferu
+//                 logToFile(QString("[II] prijata zprava, sadr: %1, dadr: %2, len: %3 data %4").arg(msginfo.sadr).arg(msginfo.dadr).arg(msginfo.len).arg(buf_in.toHex().constData()));
+                ul_freemsg(ul_fd);
+                switch ((uchar)buf_in[0]) {
+                    case ULNCS_ADR_RQ:
+                        sn = buf2sn(buf_in);
+                        if (sn == -1) {
+                            logToFile(QString("[WW] ULDYSRV - neplatna zadost o adresu, ocekavam delku minimalne 5").arg(msg_len));
+                            break;
+                        }
+//                         logToFile(QString("[II] prijmam zadost o adresu, SN %1").arg(sn));
+                        if ((addr = addressPool.getFreeAddress(sn)) != 0) {
+                            logToFile(QString("[II] ULDYSRV - sending new address \"%1\" to SN \"%2\"...").arg(addr).arg(sn));
+                            if (!(this->nodes.contains(addr))) {
+                                sendNewAddress(addr, sn);
+                                Node *newNode = new Node(addr, sn);
+                                this->nodes.insert(addr, newNode);
+                                logToFile(QString("[II] mapa nodu nyni obsahuje %1 polozek...").arg(this->nodes.size()));
+                            } else { logToFile("nod uz tam je"); }
+                        } else {
+                            logToFile("[WW] ULDYSRV - address pool is full, try again later, please...");
+                        }
+                        break;
+                    case ULNCS_SID_RPLY:
+                        sn = buf2sn(buf_in);
+                        logToFile(QString("[II] - received identification from unknown node, addr %1").arg(saddr));
+                        if (!(this->nodes.contains(saddr))) {
+                            Node *newNode = new Node(saddr, sn);
+                            addressPool.blockAddress(sn, saddr);
+                            this->nodes.insert(saddr, newNode);
+                            logToFile(QString("[II] mapa nodu nyni obsahuje %1 polozek...").arg(this->nodes.size()));
+                        } else { logToFile("nod uz tam je"); }
+                        break;
+
+                    default:
+                        break;
+                } /* switch */
+
+            } else if (msginfo.cmd == UL_CMD_PDO) {
+                msg_len = msginfo.len;
+                saddr = msginfo.sadr;
+                buf_in.resize(msg_len);
+                ret = ul_read(ul_fd, buf_in.data(), msg_len);
+                ul_freemsg(ul_fd);
+                
+                buf_in = buf_in.mid(PDO_SKIP_BYTES);
+
+                while (1) {
+                    bool success = true;
+
+                    int cid = takeCid(buf_in, &success);
+                    if (!success) break;
+
+                    int len = takeLen(buf_in, &success);
+                    if (!success) break;
+
+                    int data = takeData(buf_in, len, &success);
+                    if (!success) break;
+
+                    processPDOMessage(saddr, cid, data);
+                }
+            } else
+                ul_freemsg(ul_fd);
+
+        } /* ul_inepool && ul_acceptmsg */
+
+    } /* while(running) */
+#endif
+}
+
+int ULDYServer::takeCid(QByteArray &buf, bool *success) const {
+    if (buf.size() < 2) { *success = false; /*logToFile("nedostatecna delka CID");*/ return 0; }
+    int ret = buf2uint16(buf);
+    buf = buf.mid(2);
+    *success = true;
+    return ret;
+}
+
+int ULDYServer::takeLen(QByteArray &buf, bool *success) const {
+//     return takeCid(buf, success);
+    if (buf.size() < 2) { *success = false; /*logToFile("nedostatecna delka LEN");*/ return 0; }
+//     int ret = buf[0];
+    int ret = buf2uint16(buf);
+    buf = buf.mid(2);
+    *success = true;
+    return ret;
+}
+
+int ULDYServer::takeData(QByteArray &buf, int len, bool *success) const {
+    if (buf.size() < len) { *success = false; return 0; }
+    int ret = 0;
+    for (int i = 0; i < len; i++) {
+        ret += (uchar)buf[i]<<(i * 8);
+    }
+    buf = buf.mid(len);
+    *success = true;
+    return ret;
+}
+
+const NodeMap &ULDYServer::getNodes() const {
+    return this->nodes;
+}
+
+NodeMap &ULDYServer::getNodesRef() {
+    return this->nodes;
+}
+
+ValueCache &ULDYServer::getValueCacheRef() {
+    return this->valueCache;
+}
+
+void ULDYServer::tryRemoveNodes() {
+    NodeMapMutableIterator it(this->nodes);
+    QDateTime curr, last;
+    while (it.hasNext()) {
+        it.next();
+        int addr = it.key();
+        curr = currentDateTime();
+        last = this->nodes.getNodeRef(addr).getLastUpdate();
+        last.setTimeSpec(Qt::UTC);
+        if ((curr.toTime_t() - last.toTime_t()) > NODE_CLEANER_PERIOD_SECS) {
+            logToFile(QString("[II] - Removing node SN %1...").arg(this->nodes.getNodeRef(addr).getSN()));
+            addressPool.freeAddress(this->nodes.getNodeRef(addr).getSN());
+            cidPool.freeCids(this->nodes.getNodeRef(addr).getUsedCidsRef());
+            Node *tmpNode = this->nodes.value(addr);
+            this->nodes.remove(addr);
+            delete tmpNode;
+        }
+    }
+}
+
diff --git a/app-bohyn/src/uldy_server.h b/app-bohyn/src/uldy_server.h
new file mode 100644 (file)
index 0000000..8adbf7e
--- /dev/null
@@ -0,0 +1,73 @@
+# ifndef _ULDY_SERVER_H
+# define _ULDY_SERVER_H
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <QByteArray>
+#include <QThread>
+
+#include <ul_lib/ulan.h>
+
+#include "node.h"
+#include "value_cache.h"
+#include "utils.h"
+#include "defines.h"
+
+// typedef QMap<long, uchar> AddressPool;
+// typedef QMutableMapIterator<long, uchar> AddressPoolMutableIterator;
+
+class AddressPool {
+  private:
+    QMap<long, int> assignedAddrs;
+    QSet<int> holes;
+
+  public:
+    AddressPool() {
+//         assignedAddrs.reserve(MAX_ADDR);
+        holes.reserve(20);
+    }
+
+    bool blockAddress(long sn, int addr);
+
+    int getFreeAddress(long sn);
+
+    void freeAddress(long sn);
+};
+
+
+class ULDYServer : public QThread {
+  private:
+    bool running;
+    NodeMap nodes;
+    ValueCache valueCache;
+
+    void sendNewAddress(int addr, long sn) const;
+
+    void requestIdentification(int addr) const;
+
+    void processPDOMessage(int saddr, int cid, int data);
+
+  public:
+    ULDYServer(): running(true) {};
+
+    void stopServer();
+
+    void run();
+
+    int takeCid(QByteArray &buf, bool *success) const;
+
+    int takeLen(QByteArray &buf, bool *success) const;
+
+    int takeData(QByteArray &buf, int len, bool *success) const;
+
+    const NodeMap &getNodes() const;
+
+    NodeMap &getNodesRef();
+
+    ValueCache &getValueCacheRef();
+
+    void tryRemoveNodes();
+};
+
+# endif
diff --git a/app-bohyn/src/uldy_server.o b/app-bohyn/src/uldy_server.o
new file mode 100644 (file)
index 0000000..ba7b98c
Binary files /dev/null and b/app-bohyn/src/uldy_server.o differ
diff --git a/app-bohyn/src/utils.cc b/app-bohyn/src/utils.cc
new file mode 100644 (file)
index 0000000..16794ea
--- /dev/null
@@ -0,0 +1,133 @@
+#include "utils.h"
+
+using namespace std;
+
+unsigned long buf2sn(const QByteArray &_buf) {
+    if (_buf.size() < 5) return -1;
+    const uchar *buf = (const uchar*)(_buf.constData()+1);
+    unsigned long l;
+    l = (unsigned long)buf[0];
+    l += (unsigned long)buf[1]<<8;
+    l += (unsigned long)buf[2]<<16;
+    l += (unsigned long)buf[3]<<24;
+    return l;
+}
+
+QByteArray sn2buf(unsigned long mod_sn) {
+    QByteArray ret_val;
+    ret_val.resize(4);
+    uchar *buf = (uchar*)(ret_val.data());
+    buf[0] = mod_sn>>0;
+    buf[1] = mod_sn>>8;
+    buf[2] = mod_sn>>16;
+    buf[3] = mod_sn>>24;
+    return ret_val;
+}
+
+int16_t buf2int16(const QByteArray &_buf) {
+    int i;
+    i = (uchar)_buf[0];
+//     i += (int)_buf[1]<<8;
+    i = ((uchar)_buf[1]<<8) | i;
+    return (int16_t)i;
+}
+
+uint16_t buf2uint16(const QByteArray &_buf) {
+    return (uint16_t)buf2int16(_buf);
+}
+
+void logToFile(const QString &msg, bool end_new_line) {
+    FILE *log = fopen(LOG_FILENAME, "a");
+    int write;
+    if (log) {
+        QString now = currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
+        now.append(" - ");
+        QByteArray ba;
+        ba = now.toUtf8();
+        write = fwrite(ba.constData(), 1, now.length(), log);
+        ba = msg.toUtf8();
+        write = fwrite(ba.constData(), 1, msg.length(), log);
+        if (end_new_line)
+            write = fwrite("\n", 1, 1, log);
+        fclose(log);
+    }
+}
+
+void logDebug(const QByteArray &buf) {
+    FILE *debug_log = fopen("/home/bohacekm/fel/bap/hydroweb/src/log_debug.txt", "a");
+    int write;
+    write = fwrite(buf.constData(), 1, buf.size(), debug_log);
+    fclose(debug_log);
+}
+
+QDateTime currentDateTime() {
+    QDateTime curr_dtime = QDateTime::currentDateTime();
+//     QDateTime curr_dtime;
+    curr_dtime.setTimeSpec(Qt::UTC);
+    return curr_dtime;
+}
+
+int getRandom() {
+    
+    return sin(currentDateTime().toTime_t()) + log(qRound(RAND_MAX / (qrand() / 2.0)) * 5 + 1);
+}
+
+QList< QPair<QString, QString> > getColorOptions() {
+    QList< QPair<QString, QString> > colorOptions;
+    colorOptions.append(QPair<QString, QString>("#ff0000", "Červená"));
+    colorOptions.append(QPair<QString, QString>("#800000", "Tmavě červená"));
+    colorOptions.append(QPair<QString, QString>("#00ff00", "Zelená"));
+    colorOptions.append(QPair<QString, QString>("#008000", "Tmavě zelená"));
+    colorOptions.append(QPair<QString, QString>("#0000ff", "Modrá"));
+    colorOptions.append(QPair<QString, QString>("#000080", "Tmavě modrá"));
+    return colorOptions;
+}
+
+QList< QPair<QString, QString> > getOnOffOptions() {
+    QList< QPair<QString, QString> > onOffOptions;
+    onOffOptions.append(QPair<QString, QString>("0", "Vypnuto"));
+    onOffOptions.append(QPair<QString, QString>("1", "Zapnuto"));
+    return onOffOptions;
+}
+
+QList< QPair<double, QString> > getTimeLabels(int secs_ago) {
+    QDateTime ago_dtime = currentDateTime().addSecs(-secs_ago);
+    ago_dtime.setTimeSpec(Qt::UTC);
+    QDateTime start_dtime;
+    QString format_str;
+    int step;
+    if (secs_ago < 240) {   /* po 10 sekundach */
+        format_str = "h:mm:ss";
+        step = 10;
+        start_dtime = ago_dtime.addSecs((60 - ago_dtime.time().second()) % 10);
+    } else if (secs_ago < 720) {   /* po 1 minute */
+        format_str = "h:mm";
+        step = 60;
+        start_dtime = ago_dtime.addSecs((60 - ago_dtime.time().second()) % 60);
+    } else if (secs_ago < 7200) {   /* po 10 minutach */
+        format_str = "h:mm";
+        step = 600;
+        start_dtime = ago_dtime.addSecs((60 - ago_dtime.time().second()) % 60);
+        start_dtime = start_dtime.addSecs(((60 - start_dtime.time().minute()) % 10) * 60);
+    } else if (secs_ago < 48 * 3600) {  /* po 1 hodine */
+        format_str = "h:mm";
+        step = 3600;
+        start_dtime = ago_dtime.addSecs((60 - ago_dtime.time().second()) % 60);
+        start_dtime = start_dtime.addSecs(((60 - start_dtime.time().minute()) % 60) * 60);
+    } else {    /* po 1 dni */
+        format_str = "d.M.";
+        step = 24 * 3600;
+        start_dtime = QDateTime(ago_dtime.date());
+        if (ago_dtime.time().second() || ago_dtime.time().minute() || ago_dtime.time().hour())
+            start_dtime = start_dtime.addDays(1);
+    }
+    start_dtime.setTimeSpec(Qt::UTC);
+    QList< QPair<double, QString> > ret_value;
+    int elapsed_secs = 0;
+    while (elapsed_secs <= (secs_ago - step)) {
+        ret_value.append(QPair<double, QString>(start_dtime.toTime_t(), start_dtime.toString(format_str)));
+        start_dtime = start_dtime.addSecs(step);
+        elapsed_secs += step;
+    }
+    return ret_value;
+}
diff --git a/app-bohyn/src/utils.h b/app-bohyn/src/utils.h
new file mode 100644 (file)
index 0000000..df5a26e
--- /dev/null
@@ -0,0 +1,46 @@
+# ifndef _UTILS_H
+# define _UTILS_H
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <cmath>
+
+#include <QPair>
+#include <QByteArray>
+#include <QString>
+#include <QDateTime>
+
+#include <ul_lib/ulan.h>
+
+#include "defines.h"
+
+unsigned long buf2sn(const QByteArray &_buf);
+
+QByteArray sn2buf(unsigned long mod_sn);
+
+int16_t buf2int16(const QByteArray &_buf);
+
+uint16_t buf2uint16(const QByteArray &_buf);
+
+int takeCid(QByteArray &buf);
+
+int takeLen(QByteArray &buf);
+
+int takeData(QByteArray &buf, int len);
+
+void logToFile(const QString &msg, bool end_new_line=true);
+
+void logDebug(const QByteArray &buf);
+
+QDateTime currentDateTime();
+
+int getRandom();
+
+QList< QPair<QString, QString> > getColorOptions();
+
+QList< QPair<QString, QString> > getOnOffOptions();
+
+QList< QPair<double, QString> > getTimeLabels(int secs_ago);
+
+# endif
diff --git a/app-bohyn/src/value_cache.cc b/app-bohyn/src/value_cache.cc
new file mode 100644 (file)
index 0000000..a875089
--- /dev/null
@@ -0,0 +1,159 @@
+
+#include "value_cache.h"
+
+#define SECS_PER_DAY 60*60*24
+
+// static uint toTime_tHelper(const QDate &utcDate, const QTime &utcTime)
+// {
+//     int days = QDate(1970, 1, 1).daysTo(utcDate);
+//     int secs = QTime().secsTo(utcTime);
+//     if (days < 0 || (days == 0 && secs < 0))
+//         return uint(-1);
+// 
+//     qlonglong retval = (qlonglong(days) * SECS_PER_DAY) + secs;
+//     if (retval >= Q_INT64_C(0xFFFFFFFF))
+//         return uint(-1);
+//     return uint(retval);
+// }
+// 
+// /*!
+//     Returns the datetime as the number of seconds that have passed
+//     since 1970-01-01T00:00:00, Coordinated Universal Time (Qt::UTC).
+// 
+//     On systems that do not support time zones, this function will
+//     behave as if local time were Qt::UTC.
+// 
+//     \sa setTime_t()
+// */
+// 
+// static uint myToTime_t(QDateTime d)
+// {
+// //     return 0;
+// //     QDate utcDate = d.toUTC().date();
+// //     QTime utcTime = d.toUTC().time();
+//     QDate utcDate = d.date();
+//     QTime utcTime = d.time();
+// //     d->getUTC(utcDate, utcTime);
+// 
+//     return toTime_tHelper(utcDate, utcTime);
+// }
+
+/* formatuje chybove hlaseni driveru */
+QString ValueCache::getErrorMsg(QSqlQuery &query) const {
+    QSqlError err = query.lastError();
+    return QString("%1: %2 - %3").arg(err.number()).arg(err.driverText()).arg(err.databaseText());
+}
+
+/* spusteni query + log pripadne chyby */
+QSqlQuery &ValueCache::processQuery(QSqlQuery &query) const {
+    if (!query.exec()) {
+        logToFile(QString("[WW] - error when executing query: %1").arg(getErrorMsg(query)));
+        logToFile(QString("[WW]   - query was: %1").arg(query.lastQuery()));
+    }
+    return query;
+}
+
+/* konstruktor - vytvoreni tabulek v DB, pokud je potreba */
+ValueCache::ValueCache() {
+    db = QSqlDatabase::addDatabase("QSQLITE");
+    db.setDatabaseName(SQLITE_DB_FILE);
+    if (!db.open())
+        logToFile("[WW] - error when opening database " SQLITE_DB_FILE);
+    QSqlQuery query(db);
+    query.prepare(
+        "CREATE TABLE IF NOT EXISTS " SQLITE_CACHE_TABLE_NAME " ("
+        "id INTEGER PRIMARY KEY, node_sn NUMERIC, value NUMERIC, var_oid NUMERIC, mov_avg NUMERIC, mov_avg_count NUMERIC, timestamp NUMERIC"
+        ");"
+    );
+    processQuery(query);
+}
+
+/* destruktor */
+ValueCache::~ValueCache() {
+    db.close();
+}
+
+/* vlozeni zaznamu do cache a smazani nadbytecnych radku */
+void ValueCache::insertValue(long node_sn, int var_oid, float value) const {
+    /* zjisteni poctu existujicich zaznamu pro dany nod a promennou */
+    QDateTime current_dtime = currentDateTime();
+    QSqlQuery queryCnt(db);
+    queryCnt.prepare("SELECT id, value, timestamp FROM " SQLITE_CACHE_TABLE_NAME " WHERE node_sn = :node_sn AND var_oid = :var_oid ORDER BY timestamp ASC;");
+    queryCnt.bindValue(":node_sn", (qlonglong)node_sn);
+    queryCnt.bindValue(":var_oid", var_oid);
+    processQuery(queryCnt);
+    QList<int> ids;
+    int new_id, avg_val_count = 1;
+    uint timestamp = 0;
+    float new_avg = value;
+    while (queryCnt.next()) {
+        if (!timestamp)
+            timestamp = queryCnt.value(2).toInt();
+        ids.append(queryCnt.value(0).toInt());
+//         if (timestamp > (current_dtime.toTime_t() - HISTORY_LEN)) {
+            new_avg += queryCnt.value(1).toDouble();
+            avg_val_count++;
+//         }
+    }
+    if (!timestamp)
+        timestamp = current_dtime.toTime_t();
+
+    new_avg /= avg_val_count;
+
+    if (timestamp < (current_dtime.toTime_t() - HISTORY_LEN))
+        new_id = ids[0];
+    else
+        new_id = 0;
+
+    /* vlozeni noveho zaznamu */
+    QSqlQuery queryIns(db);
+    if (new_id == 0)
+        queryIns.prepare("INSERT INTO " SQLITE_CACHE_TABLE_NAME " (node_sn, var_oid, value, mov_avg, timestamp) VALUES (:node_sn, :var_oid, :value, :mov_avg, :timestamp);");
+    else {
+        queryIns.prepare("INSERT OR REPLACE INTO " SQLITE_CACHE_TABLE_NAME " (id, node_sn, var_oid, value, mov_avg, timestamp) VALUES (:id, :node_sn, :var_oid, :value, :mov_avg, :timestamp);");
+        queryIns.bindValue(":id", new_id);
+    }
+    queryIns.bindValue(":node_sn", (qlonglong)node_sn);
+    queryIns.bindValue(":var_oid", var_oid);
+    queryIns.bindValue(":value", value);
+    queryIns.bindValue(":mov_avg", new_avg);
+    QDateTime curr = currentDateTime();
+    curr.setTimeSpec(Qt::UTC);
+    queryIns.bindValue(":timestamp", curr.toTime_t());
+    processQuery(queryIns);
+}
+
+/* zajistuje odstraneni vsech zaznamu navazanych na promennou z cache */
+void ValueCache::removeVar(long node_sn, int var_oid) const {
+    QSqlQuery query(db);
+    query.prepare("DELETE FROM " SQLITE_CACHE_TABLE_NAME " WHERE node_sn = :node_sn AND var_oid = :var_oid ;");
+    query.bindValue(":node_sn", (int)node_sn);
+    query.bindValue(":var_oid", var_oid);
+    processQuery(query);
+}
+
+/* zajistuje odstraneni vsech zaznamu navazanych na nod z cache */
+void ValueCache::removeNode(long node_sn) const {
+    QSqlQuery query(db);
+    query.prepare("DELETE FROM " SQLITE_CACHE_TABLE_NAME " WHERE node_sn = :node_sn;");
+    query.bindValue(":node_sn", (int)node_sn);
+    processQuery(query);
+}
+
+/* vraci QList hodnot pro danou promennou v nodu */
+QPair< QVector<QPointF>, QVector<QPointF> > ValueCache::getValues(long node_sn, int var_oid, int secs_ago) const {
+    QDateTime current_dtime = currentDateTime();
+    QSqlQuery query(db);
+    query.prepare("SELECT value, mov_avg, timestamp FROM " SQLITE_CACHE_TABLE_NAME " WHERE node_sn = :node_sn AND var_oid = :var_oid AND timestamp >= :timestamp ORDER BY timestamp ASC;");
+    query.bindValue(":node_sn", (int)node_sn);
+    query.bindValue(":var_oid", var_oid);
+    query.bindValue(":timestamp", current_dtime.toTime_t() - secs_ago);
+    processQuery(query);
+    QVector<QPointF> values;
+    QVector<QPointF> avgs;
+    while (query.next()) {
+        values.append(QPointF(query.value(2).toDouble(), query.value(0).toDouble()));
+        avgs.append(QPointF(query.value(2).toDouble(), query.value(1).toDouble()));
+    }
+    return QPair< QVector<QPointF>, QVector<QPointF> >(values, avgs);
+}
diff --git a/app-bohyn/src/value_cache.h b/app-bohyn/src/value_cache.h
new file mode 100644 (file)
index 0000000..022d633
--- /dev/null
@@ -0,0 +1,35 @@
+# ifndef _VALUE_CACHE_H
+# define _VALUE_CACHE_H
+
+#include <QChar>
+#include <QList>
+#include <QTextStream>
+
+#include <QtSql>
+
+#include "defines.h"
+#include "utils.h"
+
+class ValueCache {
+  private:
+    QSqlDatabase db;
+
+    QString getErrorMsg(QSqlQuery &query) const;
+
+    QSqlQuery &processQuery(QSqlQuery &query) const;
+
+  public:
+    ValueCache();
+
+    ~ValueCache();
+
+    void insertValue(long node_sn, int var_oid, float value) const;
+
+    void removeVar(long node_sn, int var_oid) const;
+    
+    void removeNode(long node_sn) const;
+
+    QPair< QVector<QPointF>, QVector<QPointF> > getValues(long node_sn, int var_oid, int secs_ago) const;
+};
+
+# endif
diff --git a/app-bohyn/src/value_cache.o b/app-bohyn/src/value_cache.o
new file mode 100644 (file)
index 0000000..2164cd1
Binary files /dev/null and b/app-bohyn/src/value_cache.o differ
diff --git a/app-bohyn/ul_drv b/app-bohyn/ul_drv
new file mode 120000 (symlink)
index 0000000..4774d13
--- /dev/null
@@ -0,0 +1 @@
+/home/stefic/BAP/build_ulan/ulan/host/ul_drv
\ No newline at end of file
diff --git a/app-bohyn/xml_def/relax_ng_schema.xml b/app-bohyn/xml_def/relax_ng_schema.xml
new file mode 100644 (file)
index 0000000..d0bf369
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<grammar xmlns="http://relaxng.org/ns/structure/1.0">
+    <start>
+        <element name="configuration">
+            <element name="nodes">
+                <oneOrMore>
+                    <element name="node">
+                        <attribute name="sn">
+                            <text />
+                        </attribute>
+                        <optional>
+                            <element name="customName">
+                                <text />
+                            </element>
+                        </optional>
+                        <element name="vars">
+                            <oneOrMore>
+                                <element name="var">
+                                    <attribute name="oid">
+                                        <text />
+                                    </attribute>
+                                    <optional>
+                                        <element name="customDescription">
+                                            <text />
+                                        </element>
+                                    </optional>
+                                    <optional>
+                                        <element name="color">
+                                            <text />
+                                        </element>
+                                    </optional>
+                                    <optional>
+                                        <element name="commonGraphDisplay">
+                                            <text />
+                                        </element>
+                                    </optional>
+                                    <optional>
+                                        <element name="value">
+                                            <text />
+                                        </element>
+                                    </optional>
+                                </element>
+                            </oneOrMore>
+                        </element>
+                    </element>
+                </oneOrMore>
+            </element>
+        </element>
+    </start>
+</grammar>
index f8676d4844dd6acde14709e13ad44c8d42eca2d0..f4c09f040a6d7d1efb35b0a3243a35a203c4b9f5 100644 (file)
@@ -55,30 +55,37 @@ int oi_period_wrfnc(ULOI_PARAM_coninfo void *context){
 
 void set_fan_PIN(){
     if (oi_fan == 1) {
-        SET_OUT_PIN(OUT_PORT,P1_29_FAN);
+//         SET_OUT_PIN(OUT_PORT,P1_30_FAN);
+        SET_OUT_PIN(LED_PORT,P0_28_FAN);
         printf("FAN PIN UP\n");
     } else {
-        CLR_OUT_PIN(OUT_PORT,P1_29_FAN);
+//         CLR_OUT_PIN(OUT_PORT,P1_30_FAN);
+        CLR_OUT_PIN(LED_PORT,P0_28_FAN);
         printf("FAN PIN DOWN\n");
     }
 }
 
 void set_humidifier_PIN(){
+    IO0DIR |= 0x40000000;
     if (oi_humidifier == 1) {
-        SET_OUT_PIN(OUT_PORT,P1_30_HUMIDIFIER);
+//         SET_OUT_PIN(OUT_PORT,P1_29_HUMIDIFIER);
+        SET_OUT_PIN(LED_PORT,P0_30_HUMIDIFIER);
         printf("HUM PIN UP\n");
     } else {
-        CLR_OUT_PIN(OUT_PORT,P1_30_HUMIDIFIER);
+//         CLR_OUT_PIN(OUT_PORT,P1_29_HUMIDIFIER);
+        CLR_OUT_PIN(LED_PORT,P0_30_HUMIDIFIER);
         printf("HUM PIN DOWN\n");
     }
 }
 
 void set_light_PIN(){
     if (oi_light == 1) {
-        SET_OUT_PIN(OUT_PORT,P1_31_LIGHT);
+//         SET_OUT_PIN(OUT_PORT,P1_31_LIGHT);
+        SET_OUT_PIN(LED_PORT,P0_25_LIGHT);
         printf("LIGHT PIN UP\n");
     } else {
-        CLR_OUT_PIN(OUT_PORT,P1_31_LIGHT);
+//         CLR_OUT_PIN(OUT_PORT,P1_31_LIGHT);
+        CLR_OUT_PIN(LED_PORT,P0_25_LIGHT);
         printf("LIGHT PIN DOWN\n");
     }
 }
@@ -110,7 +117,7 @@ void send_data() {
     static const int MAX_CID_CNT = 4;
     cid_data_t cids[MAX_CID_CNT];
 
-    if (oi_period == 1){
+    if (oi_period == HEART_PERIOD){
         cids[cid_cnt].cid = HEART_CID;
         cids[cid_cnt].value = status_val;
         cid_cnt++;
@@ -147,7 +154,7 @@ void send_data() {
             buff_len += 2;
         }
 
-        msgsend = ul_send_query(ul_fd, 0, UL_CMD_PDO, UL_BFL_NORE, (void*) buf, buff_len);
+        msgsend = ul_send_command(ul_fd, 0, UL_CMD_PDO, UL_BFL_NORE, (void*) buf, buff_len);
         printf("[I] DATA\n");
         ul_freemsg(ul_fd);
     }
@@ -163,12 +170,11 @@ void oiinit(void){
     oi_light = 0;
     oi_cid_light = 0;
     oi_slot_light = 0;
-    oi_period = 1;
+    oi_period = 2;
     status_val = 5;
 }
 
 void check_PDO(int cid, int data){
-    printf("CID: %i\n", cid);
     if (cid == oi_slot_fan){
         oi_fan = data;
         set_fan_PIN();
@@ -187,7 +193,8 @@ void regulate(void){}
 
 void work_with(void){
 
-    PINSEL1 &= 0xFFFFB3FF;
+//     PINSEL1 &= 0xFFFFB3FF;
+    PINSEL1 &= 0xCCF3FFFF;
 
     // u vetsi karbicky je SET z 0 do 3.3
     // u mensi je SET z -3.3 do 0
@@ -196,9 +203,24 @@ void work_with(void){
 //     IO0SET = P0_21_BIT;
 //     IO0SET = P0_22_BIT;
 
-    SET_OUT_PIN(OUT_PORT, P1_29_FAN);
-    SET_OUT_PIN(OUT_PORT, P1_31_LIGHT);
-    SET_OUT_PIN(OUT_PORT, P1_30_HUMIDIFIER);
+//     CLR_OUT_PIN(OUT_PORT, P1_26_UNUSED_BIT);
+// 
+//     CLR_OUT_PIN(OUT_PORT, P1_30_FAN);
+//     CLR_OUT_PIN(OUT_PORT, P1_31_LIGHT);
+//     CLR_OUT_PIN(OUT_PORT, P1_29_HUMIDIFIER);
+//     CLR_OUT_PIN(OUT_PORT, P1_28_UNUSED_BIT);
+//     SET_OUT_PIN(OUT_PORT, P1_27_UNUSED_BIT);
+
+
+IO0DIR |= 0x40000000;
+
+CLR_OUT_PIN(LED_PORT, P0_25_LIGHT);  //25
+CLR_OUT_PIN(LED_PORT, P0_28_FAN);  //28
+// CLR_OUT_PIN(LED_PORT, P0_30_PIN); //30
+
+// SET_OUT_PIN(LED_PORT, P0_25_PIN);  //25
+// SET_OUT_PIN(LED_PORT, P0_28_PIN);  //28
+SET_OUT_PIN(LED_PORT, P0_30_HUMIDIFIER);
 
 
     IO0SET = LED1_BIT; //vypinani LED
index 1c8b3c876180a78fe962b4f83c8b71186e0f5c2b..7964a8923521f5fc8fad836e5157a0c1ecb9aff8 100644 (file)
@@ -59,7 +59,7 @@ ULOI_GENOBJDES(LIGHT,I_LIGHT,"u2/bool",uloi_uint_rdfnc,&oi_light,oi_light_wrfnc,
 ULOI_GENOBJDES(LIGHT_CID,I_LIGHT_CID,"u2/cid",uloi_uint_rdfnc,&oi_cid_light,oi_cid_light_wrfnc,&oi_cid_light)
 ULOI_GENOBJDES(LIGHT_SLOT,I_LIGHT_SLOT,"u2/slot",uloi_uint_rdfnc,&oi_slot_light,oi_slot_light_wrfnc,&oi_slot_light)
 
-ULOI_GENOBJDES(PERIOD,I_PERIOD,"u2",uloi_uint_rdfnc,&oi_period,NULL_CODE,NULL/*oi_period_wrfnc,&oi_period*/)
+ULOI_GENOBJDES(PERIOD,I_PERIOD,"u2",uloi_uint_rdfnc,&oi_period,oi_period_wrfnc,&oi_period)
 
 const uloi_objdes_t * ULOI_CODE uloi_objdes_main_items[]={
     &uloid_objdes_DOII,
index 373615f6aab6f4822cba0102d8788a863911688d..9711161a1b1b45253be68e542d97092f00a50b11 100644 (file)
@@ -16,16 +16,19 @@ unsigned int oi_period;
 unsigned int oi_want_temp;
 unsigned int oi_want_hum;
 unsigned int oi_want_light;
-unsigned int oi_want_dark;
+unsigned int oi_grow_cykl;
+unsigned int lighting;
+unsigned int last = 0;
+float res = 10;
 
-int hyst_temp = 1;
+float hyst_temp = 0.5;
 int hyst_hum = 10;
 
 unsigned int fan = 0;
 unsigned int hum = 0;
 unsigned int light = 0;
-int temperature;
-int humidity;
+float temperature;
+float humidity;
 
 // OBJECT INTERFACE FUNCTIONS
 int oi_cid_fan_wrfnc(ULOI_PARAM_coninfo void *context){
@@ -68,6 +71,28 @@ int oi_want_hum_wrfnc(ULOI_PARAM_coninfo void *context){
     return 1;
 }
 
+int oi_want_light_wrfnc(ULOI_PARAM_coninfo void *context){
+    uloi_uint_wrfnc(ULOI_ARG_coninfo context);
+
+    if (oi_want_light != 0){
+        if (last != oi_want_light){
+            last = oi_want_light;
+            l3time = current_time();
+        }
+        lighting = 1;
+    } else {
+        lighting = 0;
+        last = 0;
+    }
+
+    return 1;
+}
+
+int oi_grow_cykl_wrfnc(ULOI_PARAM_coninfo void *context){
+    uloi_uint_wrfnc(ULOI_ARG_coninfo context);
+    return 1;
+}
+
 void send_data() {
     int msgsend;
 
@@ -75,7 +100,7 @@ void send_data() {
     static const int MAX_CID_CNT = 4;
     cid_data_t cids[MAX_CID_CNT];
 
-    if (oi_period == 1){
+    if (oi_period == HEART_PERIOD){
         cids[cid_cnt].cid = HEART_CID;
         cids[cid_cnt].value = status_val;
         cid_cnt++;
@@ -112,7 +137,7 @@ void send_data() {
             buff_len += 2;
         }
 
-        msgsend = ul_send_query(ul_fd, 0, UL_CMD_PDO, UL_BFL_NORE, (void*) buf, buff_len);
+        msgsend = ul_send_command(ul_fd, 0, UL_CMD_PDO, UL_BFL_NORE, (void*) buf, buff_len);
         printf("[I] DATA\n");
         ul_freemsg(ul_fd);
     }
@@ -130,35 +155,32 @@ void oiinit(void){
 void check_PDO(int cid, int data){
     printf("CID: %i\n", cid);
     if (cid == oi_slot_temp){
-        temperature = data;
-        printf("temperature: %i\n", temperature);
+        temperature = data/res;
+        printf("temperature: %f\n", temperature);
     }
     if (cid == oi_slot_hum){
-        humidity = data;
-        printf("humidity: %i\n", humidity);
+        humidity = data/res;
+        printf("humidity: %f\n", humidity);
     }
 }
 
 void regulate(void){
 
-    if (((oi_want_temp + hyst_temp) > temperature) && fan != 1) fan = 1; 
-    if (((oi_want_temp - hyst_temp) < temperature) && fan != 0) fan = 0;
+    if (temperature > (oi_want_temp/res + hyst_temp)) fan = 1; 
+    if (temperature < (oi_want_temp/res - hyst_temp)) fan = 0;
 
-    if (((oi_want_hum + hyst_hum) > humidity) && hum != 1) hum = 1; 
-    if (((oi_want_hum - hyst_hum) < humidity) && hum != 0) hum = 0;
+    if (humidity < (oi_want_hum/res + hyst_hum)) hum = 1; 
+    if (humidity > (oi_want_hum/res - hyst_hum)) hum = 0;
 
-    if(((current_time()-l3time) < oi_want_light*3600*1000) && light == 0) {
-        light = 1;
-        l3time = current_time();
-    }
-    if(((current_time()-l3time) < oi_want_dark*3600*1000) && light == 1) {
-        light = 0;
-        l3time = current_time();
+    if (lighting == 1){
+        if((current_time()-l3time) < oi_want_light/res/* *3600*/*1000) {
+            light = 1;
+        } else if((current_time()-l3time) < oi_grow_cykl/res/* *3600*/*1000){
+            light = 0;
+        } else l3time = current_time();
     }
 }
 
 void work_with(void){
 
 }
-
-
index 68b4376698b1dbd5c235c986780630d0a7d75f65..e5b05e958acf9892166688123e1b0ce551e0e8e9 100644 (file)
@@ -9,7 +9,6 @@
 #define DATA_BUF_LEN 15
 #define SN 103
 
-
 // OI
 extern const ULOI_CODE uloi_objdes_array_t uloi_objdes_main;
 extern unsigned int status_val;
@@ -21,6 +20,8 @@ extern unsigned int oi_slot_hum;
 extern unsigned int oi_period;
 extern unsigned int oi_want_temp;
 extern unsigned int oi_want_hum;
+extern unsigned int oi_want_light;
+extern unsigned int oi_grow_cykl;
 
 typedef struct cid_data {
     int cid;
@@ -35,6 +36,8 @@ int oi_slot_hum_wrfnc(ULOI_PARAM_coninfo void *context);
 int oi_period_wrfnc(ULOI_PARAM_coninfo void *context);
 int oi_want_temp_wrfnc(ULOI_PARAM_coninfo void *context);
 int oi_want_hum_wrfnc(ULOI_PARAM_coninfo void *context);
+int oi_want_light_wrfnc(ULOI_PARAM_coninfo void *context);
+int oi_grow_cykl_wrfnc(ULOI_PARAM_coninfo void *context);
 
 void send_data();
 void oiinit(void);
index f6e4f2a3e2a7b3d3345c39b280eb9e1046969a7a..05ee38e767bcd00df1e93a22aa308a050e1aa133 100644 (file)
@@ -13,6 +13,8 @@
 
 #define I_WANT_TEMP 1100
 #define I_WANT_HUM 1200
+#define I_WANT_LIGHT 1300
+#define I_GROW_CYKL 1400
 
 unsigned int status_val;
 
@@ -57,6 +59,8 @@ ULOI_GENOBJDES(PERIOD,I_PERIOD,"u2",uloi_uint_rdfnc,&oi_period,oi_period_wrfnc,&
 
 ULOI_GENOBJDES(WANT_TEMP,I_WANT_TEMP,"u2/.1",uloi_uint_rdfnc,&oi_want_temp,oi_want_temp_wrfnc,&oi_want_temp)
 ULOI_GENOBJDES(WANT_HUM,I_WANT_HUM,"u2/.1",uloi_uint_rdfnc,&oi_want_hum,oi_want_hum_wrfnc,&oi_want_hum)
+ULOI_GENOBJDES(WANT_LIGHT,I_WANT_LIGHT,"u2/.1",uloi_uint_rdfnc,&oi_want_light,oi_want_light_wrfnc,&oi_want_light)
+ULOI_GENOBJDES(GROW_CYKL,I_GROW_CYKL,"u2/.1",uloi_uint_rdfnc,&oi_grow_cykl,oi_grow_cykl_wrfnc,&oi_grow_cykl)
 
 const uloi_objdes_t * ULOI_CODE uloi_objdes_main_items[]={
     &uloid_objdes_DOII,
@@ -74,7 +78,9 @@ const uloi_objdes_t * ULOI_CODE uloi_objdes_main_items[]={
     &uloid_objdes_HUMIDITY_SLOT,
     &uloid_objdes_PERIOD,
     &uloid_objdes_WANT_TEMP,
-    &uloid_objdes_WANT_HUM
+    &uloid_objdes_WANT_HUM,
+    &uloid_objdes_WANT_LIGHT,
+    &uloid_objdes_GROW_CYKL
 };
 
 const ULOI_CODE uloi_objdes_array_t uloi_objdes_main={
index 5ef7f811e0b9b9488db897b8b9951ed9227407a9..7a2159ef1b64b731a4c7d53b131da6db9b79c146 100644 (file)
@@ -3,6 +3,8 @@
 #include <system_def.h>
 #include <cpu_def.h>
 
+#include <math.h>
+
 #include "board.h"
 
 adc_stat_t adcst;
@@ -37,7 +39,7 @@ void send_data() {
     static const int MAX_CID_CNT = 3;
     cid_data_t cids[MAX_CID_CNT];
 
-    if (oi_period == 1){
+    if (oi_period == HEART_PERIOD){
         cids[cid_cnt].cid = HEART_CID; 
         cids[cid_cnt].value = status_val; 
         cid_cnt++;
@@ -72,7 +74,7 @@ void send_data() {
             buff_len += 2;
         }
 
-        msgsend = ul_send_query(ul_fd, 0, UL_CMD_PDO, UL_BFL_NORE, (void*) buf, buff_len);
+        msgsend = ul_send_command(ul_fd, 0, UL_CMD_PDO, UL_BFL_NORE, (void*) buf, buff_len);
         printf("[I] DATA\n");
         ul_freemsg(ul_fd);
     }
@@ -86,10 +88,17 @@ void send_data() {
 // }
 
 void adc2oi(void){
-    oi_temperature = adcst.temp;
-    printf("temperature: %i\n",adcst.temp);
-    oi_humidity = adcst.hum;
-    printf("humidity: %i\n",adcst.hum);
+    double tmp_temp, tmp_hum;
+
+    tmp_temp = (adcst.temp*ADres*100)/Aoz;
+    tmp_temp = ((int)(tmp_temp*10))/10.0;
+
+    tmp_hum = (adcst.hum*ADres)*20;
+
+    oi_temperature = tmp_temp * 10;
+    printf("temperature: %4.1f\n",tmp_temp);
+    oi_humidity = tmp_hum * 10;
+    printf("humidity: %4.1f\n",tmp_hum);
 }
 
 void oiinit(void){
@@ -107,7 +116,7 @@ void work_with(void){
     led1_time = current_time();
     led2_time = current_time();
 //     adcst.read = 0;
-//     adcst.temp = 0;
+    adcst.temp = 498;
 //     adcst.temp_tmp = 0;
 //     adcst.hum = 0;
 //     adcst.hum_tmp = 0;
@@ -115,19 +124,26 @@ void work_with(void){
 
     time = current_time();
 
-    while(1){
-//         blink();
-//         read_ADC(&adcst);
-
-        if((current_time()-time) > 1000){
-            printf("AD0.1 %i\n", adcst.temp);
-//             printf("AD0.2 %i\n", adcst.hum);
-            time = current_time();
-            }
-    }
+    double tmp_temp;
+    tmp_temp = (adcst.temp*ADres*100)/Aoz;
+    printf("temperature: %f\n",tmp_temp);
+
+
+//     while(1){
+// //         blink();
+// //         read_ADC(&adcst);
+// 
+//         if((current_time()-time) > 1000){
+//             printf("AD0.1 %i\n", adcst.temp);
+// //             printf("AD0.2 %i\n", adcst.hum);
+//             time = current_time();
+//             }
+//     }
 }
 
 void init_ADC (int selected){
+    #ifndef OS_POSIX
+
     PINSEL1|= 0x05000000; // P0.28 and P0.29 set for AD0.1 and AD0.2 inputs
     AD0CR &= 0x00000000; // Clear All Bit Control 
     switch (selected){
@@ -143,9 +159,12 @@ void init_ADC (int selected){
 //     AD0CR &= 0xFF3FFFFF; // TEST[1:0] = 00 = Modo normal 
 //     AD0CR &= 0xF7FFFFFF; // EDGE = 0 = Flanco de bajada 
 //     AD0STAT = 0x00000110; 
+    #endif
 }
 
 int read_ADC (adc_stat_t *adcst){
+    #ifndef OS_POSIX
+
     init_ADC(1);
     AD0CR |= 0x01000000; // start conversion
     while (!(AD0GDR & (ADGDR_DONE))); // wait for DONE to go high
@@ -172,5 +191,6 @@ int read_ADC (adc_stat_t *adcst){
         return 1;
     }
 
+    #endif
     return 0;
 }
index 32076535224396f833d6ec78fc0b9ef24186869c..8ffe6c33b77df1512edf745579ad2ecc8314909f 100644 (file)
@@ -9,6 +9,9 @@
 #define DATA_BUF_LEN 15
 #define SN 101
 
+#define ADres 0.0032
+#define Aoz 6.43
+
 #define CNT 10
 
 // OI
index 59da0b836a65527179fdd57b46d1e3ac3a717a01..8c85f75bbcf5378491f841095cf01e12676c47d3 100644 (file)
@@ -53,7 +53,7 @@ mstime_t current_time(){
         if(clock_gettime(CLOCK_REALTIME, &tp) == 0){
             ret = tp.tv_sec*1000;
             ret += tp.tv_nsec/1000000;
-        }
+        }   
     #else
         lt_mstime_update();
         ret = actual_msec;
@@ -145,7 +145,7 @@ void heartbeat(void){
     int2buf(&buf[7],status_val);
 
     msgsend = ul_send_command(ul_fd, ul_dyac->ul_dysa, UL_CMD_PDO, UL_BFL_NORE, (void*) buf, HEART_BUF_LEN);
-    printf("[I] BEAT\n");
+    printf("[I] BEAT %i \n",msgsend);
     free(buf);
 }
 
@@ -155,7 +155,7 @@ void accept_SDO(void) {
             if (msginfo.cmd == UL_CMD_PDO){
                 process_PDO();
                 ul_freemsg(ul_fd);
-                printf("accept PDO msg: sadr: %i, dadr: %i\n", msginfo.sadr, msginfo.dadr);
+//                 printf("accept PDO msg: sadr: %i, dadr: %i\n", msginfo.sadr, msginfo.dadr);
             } else if (msginfo.sadr != 99) {
                 if (!(msginfo.flg&(UL_BFL_PROC | UL_BFL_FAIL))) {
                     //waiting for msg from bus
@@ -206,6 +206,7 @@ int data = 0;
 
         check_PDO(cid, data);
     }
+    free(buf);
 }
 
 uint take_cid(uchar * buf){
index 61cfbf37b1a5ebbcb4b5c94e1c829b4b31e24954..214cb2b2d5ae50d67886b9f9ebe48e1b3b8e3446 100644 (file)
@@ -12,6 +12,7 @@
 
 #define HEART_BUF_LEN 9
 #define HEART_CID 1023
+#define HEART_PERIOD 2
 
 #define UL_DEV "/dev/ulan"
 
index 21865eb14f28937afdab46843aedb77849cc6206..b482ffdb2ad3a9bbc222d93dc82cef51b8248254 100644 (file)
@@ -18,7 +18,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-//#define OS_POSIX
+// #define OS_POSIX
 
 #ifdef HAVE_CONFIG_H
     #include <config.h>
@@ -59,20 +59,19 @@ void loop(void){
 
     ltime  = current_time();
     l2time = current_time();
-    l3time = current_time();
 
     while(1){
         blink();
         ctime = current_time();
 
         if (oi_period != 0){
-            if (oi_period == 1){
-                if((ctime-ltime) > 1000){
+            if (oi_period == HEART_PERIOD){
+                if((ctime-ltime) > 1000*HEART_PERIOD){
                     send_data();
                     ltime = current_time();
                 }
             } else {
-                if((ctime-ltime) > 1000){
+                if((ctime-ltime) > 1000*HEART_PERIOD){
                     heartbeat();
                     ltime = current_time();
                 }
@@ -81,7 +80,12 @@ void loop(void){
                     l2time = current_time();
                 }
             }
-        } else heartbeat();
+        } else {
+            if((ctime-ltime) > 1000*HEART_PERIOD){
+                heartbeat();
+                ltime = current_time();
+            }
+        }
         accept_SDO();
 
         regulate();
index 7b9cba2c4fcf29f1506dd6601d22b2de802d3d1b..c1a8bf0561c5158763a7ac1b9e3d8b1b05ddd9d8 100644 (file)
@@ -7,4 +7,6 @@
 #include "definitions.h"
 #include "ul_idstr.h"
 
+
+
 #endif /* HYDRO */