diff --git a/Makefile b/Makefile index 22a1cca..4f2e804 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ - depcomp install-sh missing + compile depcomp install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -137,10 +137,12 @@ CPPFLAGS = CYGPATH_W = echo DEFS = -DHAVE_CONFIG_H DEPDIR = .deps -DEPS_CFLAGS = -I/usr/include/json -DEPS_LIBS = -ljson -lcurl DEPS_LOCAL_CFLAGS = DEPS_LOCAL_LIBS = +DEPS_SML_CFLAGS = -I/usr/include/sml -I/usr/include/uuid +DEPS_SML_LIBS = -lsml -luuid +DEPS_VZ_CFLAGS = -I/usr/include/json +DEPS_VZ_LIBS = -ljson -lcurl ECHO_C = ECHO_N = -n ECHO_T = @@ -170,6 +172,7 @@ PATH_SEPARATOR = : PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = +RANLIB = ranlib SET_MAKE = SHELL = /bin/bash STRIP = @@ -217,7 +220,7 @@ top_build_prefix = top_builddir = . top_srcdir = . sysconf_DATA = etc/vzlogger.conf -SUBDIRS = src docs +SUBDIRS = src bin/vzlogger all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -725,6 +728,7 @@ uninstall-am: uninstall-sysconfDATA mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am uninstall-sysconfDATA +# bin/reader docs # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/Makefile.am b/Makefile.am index 290818e..e3a536b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,3 +1,4 @@ sysconf_DATA = etc/vzlogger.conf -SUBDIRS = src docs +SUBDIRS = src bin/vzlogger +# bin/reader docs diff --git a/bin/reader/Makefile b/bin/reader/Makefile new file mode 100644 index 0000000..c95b155 --- /dev/null +++ b/bin/reader/Makefile @@ -0,0 +1,484 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# bin/reader/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +pkgdatadir = $(datadir)/vzlogger +pkgincludedir = $(includedir)/vzlogger +pkglibdir = $(libdir)/vzlogger +pkglibexecdir = $(libexecdir)/vzlogger +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +bin_PROGRAMS = smlreader$(EXEEXT) +subdir = bin/reader +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__smlreader_SOURCES_DIST = smlreader.c +am_smlreader_OBJECTS = \ + smlreader-smlreader.$(OBJEXT) +smlreader_OBJECTS = $(am_smlreader_OBJECTS) +am__DEPENDENCIES_1 = +smlreader_DEPENDENCIES = $(am__DEPENDENCIES_1) +smlreader_LINK = $(CCLD) $(smlreader_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(smlreader_SOURCES) +DIST_SOURCES = $(am__smlreader_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run aclocal-1.11 +AMTAR = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run tar +AUTOCONF = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run autoconf +AUTOHEADER = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run autoheader +AUTOMAKE = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run automake-1.11 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CPP = gcc -E +CPPFLAGS = +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DEPS_LOCAL_CFLAGS = +DEPS_LOCAL_LIBS = +DEPS_SML_CFLAGS = -I/usr/include/sml -I/usr/include/uuid +DEPS_SML_LIBS = -lsml -luuid +DEPS_VZ_CFLAGS = -I/usr/include/json +DEPS_VZ_LIBS = -ljson -lcurl +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +GREP = /bin/grep +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LDFLAGS = +LIBOBJS = +LIBS = +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +OBJEXT = o +PACKAGE = vzlogger +PACKAGE_BUGREPORT = http://bugs.volkszaehler.org +PACKAGE_NAME = vzlogger +PACKAGE_STRING = vzlogger 0.2 +PACKAGE_TARNAME = vzlogger +PACKAGE_URL = +PACKAGE_VERSION = 0.2 +PATH_SEPARATOR = : +PKG_CONFIG = /usr/bin/pkg-config +PKG_CONFIG_LIBDIR = +PKG_CONFIG_PATH = +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/bash +STRIP = +VERSION = 0.2 +abs_builddir = /home/stv0g/workspace/volkszaehler.org/vzlogger/bin/reader +abs_srcdir = /home/stv0g/workspace/volkszaehler.org/vzlogger/bin/reader +abs_top_builddir = /home/stv0g/workspace/volkszaehler.org/vzlogger +abs_top_srcdir = /home/stv0g/workspace/volkszaehler.org/vzlogger +ac_ct_CC = gcc +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build_alias = +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host_alias = +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../../ +top_builddir = ../.. +top_srcdir = ../.. + +# what flags you want to pass to the C compiler & linker +AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 $(DEPS_CFLAGS) +AM_LDFLAGS = +smlreader_SOURCES = smlreader.c +smlreader_LDADD = -lm $(DEPS_SML_LIBS) +smlreader_CFLAGS = $(AM_CFLAGS) $(DEPS_SML_CFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bin/reader/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu bin/reader/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +smlreader$(EXEEXT): $(smlreader_OBJECTS) $(smlreader_DEPENDENCIES) + @rm -f smlreader$(EXEEXT) + $(smlreader_LINK) $(smlreader_OBJECTS) $(smlreader_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/smlreader-smlreader.Po + +.c.o: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c `$(CYGPATH_W) '$<'` + +smlreader-smlreader.o: smlreader.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(smlreader_CFLAGS) $(CFLAGS) -MT smlreader-smlreader.o -MD -MP -MF $(DEPDIR)/smlreader-smlreader.Tpo -c -o smlreader-smlreader.o `test -f 'smlreader.c' || echo '$(srcdir)/'`smlreader.c + $(am__mv) $(DEPDIR)/smlreader-smlreader.Tpo $(DEPDIR)/smlreader-smlreader.Po +# source='smlreader.c' object='smlreader-smlreader.o' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(smlreader_CFLAGS) $(CFLAGS) -c -o smlreader-smlreader.o `test -f 'smlreader.c' || echo '$(srcdir)/'`smlreader.c + +smlreader-smlreader.obj: smlreader.c + $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(smlreader_CFLAGS) $(CFLAGS) -MT smlreader-smlreader.obj -MD -MP -MF $(DEPDIR)/smlreader-smlreader.Tpo -c -o smlreader-smlreader.obj `if test -f 'smlreader.c'; then $(CYGPATH_W) 'smlreader.c'; else $(CYGPATH_W) '$(srcdir)/smlreader.c'; fi` + $(am__mv) $(DEPDIR)/smlreader-smlreader.Tpo $(DEPDIR)/smlreader-smlreader.Po +# source='smlreader.c' object='smlreader-smlreader.obj' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(smlreader_CFLAGS) $(CFLAGS) -c -o smlreader-smlreader.obj `if test -f 'smlreader.c'; then $(CYGPATH_W) 'smlreader.c'; else $(CYGPATH_W) '$(srcdir)/smlreader.c'; fi` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/bin/reader/Makefile.am b/bin/reader/Makefile.am new file mode 100644 index 0000000..b0181c5 --- /dev/null +++ b/bin/reader/Makefile.am @@ -0,0 +1,13 @@ +# what flags you want to pass to the C compiler & linker +AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 $(DEPS_CFLAGS) +AM_LDFLAGS = + +# SML +#################################################################### +if SML_SUPPORT +bin_PROGRAMS = smlreader +smlreader_SOURCES = smlreader.c +smlreader_LDADD = -lm $(DEPS_SML_LIBS) +smlreader_CFLAGS = $(AM_CFLAGS) $(DEPS_SML_CFLAGS) +endif + diff --git a/bin/reader/smlreader.c b/bin/reader/smlreader.c new file mode 100644 index 0000000..0e33cf9 --- /dev/null +++ b/bin/reader/smlreader.c @@ -0,0 +1,153 @@ +/** + * SML protocol parsing + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @copyright Copyright (c) 2011, Juri Glass, Mathias Runge, Nadim El Sayed, DAI-Labor, TU-Berlin + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include +#include + +#include "obis.h" +#include "unit.h" + +obis_id_t filter; + +void transport_receiver(unsigned char *buffer, size_t buffer_len) { + /* strip escape sequences */ + sml_file *file = sml_file_parse(buffer + 8, buffer_len - 16); + + for (int i = 0; i < file->messages_len; i++) { + sml_message *message = file->messages[i]; + + if (*message->message_body->tag == SML_MESSAGE_GET_LIST_RESPONSE) { + sml_list *entry; + sml_get_list_response *body; + + body = (sml_get_list_response *) message->message_body->data; + + printf("new message from: %*s\n", body->server_id->len, body->server_id->str); + + for (entry = body->val_list; entry != NULL; entry = entry->next) { /* linked list */ + obis_id_t id = obis_init(entry->obj_name->str); + + if (memcmp(&id, &filter, sizeof(obis_id_t)) == 0) { + struct timeval time; + int unit = (entry->unit) ? *entry->unit : 0; + int scaler = (entry->scaler) ? *entry->scaler : 1; + double value; + + switch (entry->value->type) { + case 0x51: value = *entry->value->data.int8; break; + case 0x52: value = *entry->value->data.int16; break; + case 0x54: value = *entry->value->data.int32; break; + case 0x58: value = *entry->value->data.int64; break; + case 0x61: value = *entry->value->data.uint8; break; + case 0x62: value = *entry->value->data.uint16; break; + case 0x64: value = *entry->value->data.uint32; break; + case 0x68: value = *entry->value->data.uint64; break; + + default: + fprintf(stderr, "Unknown value type: %x", type); + value = 0; + } + + /* apply scaler */ + value *= pow(10, scaler); + + + /* get time */ + if (entry->val_time) { // TODO handle SML_TIME_SEC_INDEX + time.tv_sec = *entry->val_time->data.timestamp; + time.tv_usec = 0; + } + else { + gettimeofday(&time, NULL); + } + + printf("%lu.%lu\t%.2f %s\n", time.tv_sec, time.tv_usec, value, dlms_get_unit(unit)); + } + } + } + } + + // free the malloc'd memory + sml_file_free(file); +} + +int open_socket(char *host, char *port) { + struct sockaddr_in sin; + struct addrinfo *ais; + int fd; + + getaddrinfo(host, port, NULL, &ais); + memcpy(&sin, ais->ai_addr, ais->ai_addrlen); + + printf("Opening socket\n"); + fd = socket(PF_INET, SOCK_STREAM, 0); + + printf("Conntecting to %s:%s\n", host, port); + if (connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) { + perror(host); + exit(EXIT_FAILURE); + } + + return fd; +} + +int main(int argc, char **argv) { + char *host, *port, *obis; + char buffer[16]; + int fd; + + host = (argc >= 2) ? argv[1] : "localhost"; + port = (argc >= 3) ? argv[2] : "7331"; + obis = (argc >= 4) ? argv[3] : "1-0:1.7.0"; /* total power */ + + filter = obis_parse(obis); + + obis_unparse(filter, buffer); + printf("Using OBIS Id: %s\n", buffer); + + fd = open_socket(host, port); + + if (fd > 0) { + sml_transport_listen(fd, &transport_receiver); + close(fd); + } + + return 0; +} diff --git a/bin/vzlogger/Makefile b/bin/vzlogger/Makefile new file mode 100644 index 0000000..2e7cb11 --- /dev/null +++ b/bin/vzlogger/Makefile @@ -0,0 +1,494 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# bin/vzlogger/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +pkgdatadir = $(datadir)/vzlogger +pkgincludedir = $(includedir)/vzlogger +pkglibdir = $(libdir)/vzlogger +pkglibexecdir = $(libexecdir)/vzlogger +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +bin_PROGRAMS = vzlogger$(EXEEXT) + +# local interface support +#################################################################### +#am__append_1 = local.c +#am__append_2 = $(DEPS_LOCAL_LIBS) +#am__append_3 = $(DEPS_LOCAL_CFLAGS) + +# sml support +#################################################################### +am__append_4 = $(DEPS_SML_LIBS) +am__append_5 = $(DEPS_SML_CFLAGS) +subdir = bin/vzlogger +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am__vzlogger_SOURCES_DIST = vzlogger.c channel.c api.c options.c \ + list.c buffer.c local.c +#am__objects_1 = local.$(OBJEXT) +am_vzlogger_OBJECTS = vzlogger.$(OBJEXT) channel.$(OBJEXT) \ + api.$(OBJEXT) options.$(OBJEXT) list.$(OBJEXT) \ + buffer.$(OBJEXT) $(am__objects_1) +vzlogger_OBJECTS = $(am_vzlogger_OBJECTS) +am__DEPENDENCIES_1 = +#am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) +am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) +vzlogger_DEPENDENCIES = ../../src/libmeter.a ../../src/libobis.a \ + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_3) +vzlogger_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(vzlogger_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I. -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(vzlogger_SOURCES) +DIST_SOURCES = $(am__vzlogger_SOURCES_DIST) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run aclocal-1.11 +AMTAR = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run tar +AUTOCONF = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run autoconf +AUTOHEADER = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run autoheader +AUTOMAKE = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run automake-1.11 +AWK = gawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 +CPP = gcc -E +CPPFLAGS = +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +DEPS_LOCAL_CFLAGS = +DEPS_LOCAL_LIBS = +DEPS_SML_CFLAGS = -I/usr/include/sml -I/usr/include/uuid +DEPS_SML_LIBS = -lsml -luuid +DEPS_VZ_CFLAGS = -I/usr/include/json +DEPS_VZ_LIBS = -ljson -lcurl +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +GREP = /bin/grep +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LDFLAGS = +LIBOBJS = +LIBS = +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +OBJEXT = o +PACKAGE = vzlogger +PACKAGE_BUGREPORT = http://bugs.volkszaehler.org +PACKAGE_NAME = vzlogger +PACKAGE_STRING = vzlogger 0.2 +PACKAGE_TARNAME = vzlogger +PACKAGE_URL = +PACKAGE_VERSION = 0.2 +PATH_SEPARATOR = : +PKG_CONFIG = /usr/bin/pkg-config +PKG_CONFIG_LIBDIR = +PKG_CONFIG_PATH = +RANLIB = ranlib +SET_MAKE = +SHELL = /bin/bash +STRIP = +VERSION = 0.2 +abs_builddir = /home/stv0g/workspace/volkszaehler.org/vzlogger/bin/vzlogger +abs_srcdir = /home/stv0g/workspace/volkszaehler.org/vzlogger/bin/vzlogger +abs_top_builddir = /home/stv0g/workspace/volkszaehler.org/vzlogger +abs_top_srcdir = /home/stv0g/workspace/volkszaehler.org/vzlogger +ac_ct_CC = gcc +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build_alias = +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host_alias = +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/stv0g/workspace/volkszaehler.org/vzlogger/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = ../../ +top_builddir = ../.. +top_srcdir = ../.. +AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 $(DEPS_VZ_CFLAGS) \ + $(am__append_3) $(am__append_5) +AM_CPPFLAGS = -I$(top_srcdir)/include +vzlogger_SOURCES = vzlogger.c channel.c api.c options.c list.c \ + buffer.c $(am__append_1) +vzlogger_LDADD = ../../src/libmeter.a ../../src/libobis.a \ + $(am__append_2) $(am__append_4) +vzlogger_LDFLAGS = -lpthread -lm $(DEPS_VZ_LIBS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu bin/vzlogger/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu bin/vzlogger/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +vzlogger$(EXEEXT): $(vzlogger_OBJECTS) $(vzlogger_DEPENDENCIES) + @rm -f vzlogger$(EXEEXT) + $(vzlogger_LINK) $(vzlogger_OBJECTS) $(vzlogger_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/api.Po +include ./$(DEPDIR)/buffer.Po +include ./$(DEPDIR)/channel.Po +include ./$(DEPDIR)/list.Po +include ./$(DEPDIR)/local.Po +include ./$(DEPDIR)/options.Po +include ./$(DEPDIR)/vzlogger.Po + +.c.o: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/bin/vzlogger/Makefile.am b/bin/vzlogger/Makefile.am new file mode 100644 index 0000000..dd056f3 --- /dev/null +++ b/bin/vzlogger/Makefile.am @@ -0,0 +1,22 @@ +AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 $(DEPS_VZ_CFLAGS) +AM_CPPFLAGS = -I$(top_srcdir)/include + +bin_PROGRAMS = vzlogger +vzlogger_SOURCES = vzlogger.c channel.c api.c options.c list.c buffer.c +vzlogger_LDADD = ../../src/libmeter.a ../../src/libobis.a +vzlogger_LDFLAGS = -lpthread -lm $(DEPS_VZ_LIBS) + +# local interface support +#################################################################### +if LOCAL_SUPPORT +vzlogger_SOURCES += local.c +vzlogger_LDADD += $(DEPS_LOCAL_LIBS) +AM_CFLAGS += $(DEPS_LOCAL_CFLAGS) +endif + +# sml support +#################################################################### +if SML_SUPPORT +vzlogger_LDADD += $(DEPS_SML_LIBS) +AM_CFLAGS += $(DEPS_SML_CFLAGS) +endif diff --git a/src/api.c b/bin/vzlogger/api.c similarity index 72% rename from src/api.c rename to bin/vzlogger/api.c index b6dec7e..be451a9 100644 --- a/src/api.c +++ b/bin/vzlogger/api.c @@ -27,16 +27,21 @@ #include #include #include +#include + +#include #include "api.h" -#include "main.h" +#include "vzlogger.h" +#include "options.h" extern options_t opts; /** * Reformat CURLs debugging output */ -int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_t size, void *ch) { +int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_t size, void *arg) { + channel_t *ch = (channel_t *) ch; char *end = strchr(data, '\n'); if (data == end) return 0; /* skip empty line */ @@ -45,17 +50,17 @@ int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_ case CURLINFO_TEXT: case CURLINFO_END: if (end) *end = '\0'; /* terminate without \n */ - print(3, "CURL: %.*s", (channel_t *) ch, (int) size, data); + print(7, "CURL: %.*s", ch, (int) size, data); break; case CURLINFO_SSL_DATA_IN: case CURLINFO_DATA_IN: - print(6, "CURL: Received %lu bytes", (channel_t *) ch, (unsigned long) size); + print(9, "CURL: Received %lu bytes", ch, (unsigned long) size); break; case CURLINFO_SSL_DATA_OUT: case CURLINFO_DATA_OUT: - print(6, "CURL: Sent %lu bytes.. ", (channel_t *) ch, (unsigned long) size); + print(9, "CURL: Sent %lu bytes.. ", ch, (unsigned long) size); break; case CURLINFO_HEADER_IN: @@ -83,33 +88,32 @@ size_t curl_custom_write_callback(void *ptr, size_t size, size_t nmemb, void *da return realsize; } -json_object * api_json_tuples(channel_t *ch, bool_t all) { - reading_t rd; +double api_tvtof(struct timeval tv) { + return round(tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0); +} +/** + * Create JSON object of tuples + * + * @param buf the buffer our readings are stored in (required for mutex) + * @param start the first tuple of our linked list which should be encoded + */ +json_object * api_json_tuples(buffer_t *buf, meter_reading_t *start) { json_object *json_tuples = json_object_new_array(); - size_t index = ch->queue.read_p; - size_t end = (all) ? ch->queue.read_p : ch->queue.write_p; - do { - pthread_mutex_lock(&ch->mutex); - queue_get(&ch->queue, index, &rd); - pthread_mutex_unlock(&ch->mutex); + for (meter_reading_t *rd = start; rd != NULL; rd = rd->next) { + struct json_object *json_tuple = json_object_new_array(); - if (rd.tv.tv_sec) { /* skip empty buffers */ - struct json_object *json_tuple = json_object_new_array(); + pthread_mutex_lock(&buf->mutex); + double timestamp = api_tvtof(rd->tv); // TODO use long int of new json-c version + double value = rd->value; + pthread_mutex_unlock(&buf->mutex); - double timestamp = rd.tv.tv_sec * 1000.0 + rd.tv.tv_usec / 1000.0; + json_object_array_add(json_tuple, json_object_new_double(timestamp)); + json_object_array_add(json_tuple, json_object_new_double(value)); - json_object_array_add(json_tuple, json_object_new_double(timestamp)); - json_object_array_add(json_tuple, json_object_new_double(rd.value)); - - json_object_array_add(json_tuples, json_tuple); - } - - index++; - index %= ch->queue.size; /* increment pointer */ - - } while (index != end); + json_object_array_add(json_tuples, json_tuple); + } return json_tuples; } @@ -119,7 +123,7 @@ CURL * api_curl_init(channel_t *ch) { struct curl_slist *header = NULL; char url[255], agent[255]; - /* prepare header & url */ + /* prepare header, uuid & url */ sprintf(agent, "User-Agent: %s/%s (%s)", PACKAGE, VERSION, curl_version()); /* build user agent */ sprintf(url, "%s/data/%s.json", ch->middleware, ch->uuid); /* build url */ @@ -152,7 +156,7 @@ void api_parse_exception(CURLresponse response, char *err) { json_obj = json_object_object_get(json_obj, "exception"); if (json_obj) { - sprintf(err, "[%s] %s", + sprintf(err, "%s: %s", json_object_get_string(json_object_object_get(json_obj, "type")), json_object_get_string(json_object_object_get(json_obj, "message")) ); @@ -179,30 +183,28 @@ void * api_thread(void *arg) { CURL *curl; channel_t *ch = (channel_t *) arg; /* casting argument */ - print(1, "Started logging thread", ch); - curl = api_curl_init(ch); - do { /* start thread mainloop */ + while (TRUE) { /* start thread mainloop */ CURLresponse response; json_object *json_obj; - char *json_str; + const char *json_str; long int http_code, curl_code; /* initialize response */ response.data = NULL; response.size = 0; - pthread_mutex_lock(&ch->mutex); - while (queue_is_empty(&ch->queue)) { /* detect spurious wakeups */ - pthread_cond_wait(&ch->condition, &ch->mutex); /* sleep until new data has been read */ + pthread_mutex_lock(&ch->buffer.mutex); + while (ch->buffer.sent == NULL) { /* detect spurious wakeups */ + pthread_cond_wait(&ch->condition, &ch->buffer.mutex); /* sleep until new data has been read */ } - pthread_mutex_unlock(&ch->mutex); + pthread_mutex_unlock(&ch->buffer.mutex); - json_obj = api_json_tuples(ch, FALSE); + json_obj = api_json_tuples(&ch->buffer, ch->buffer.sent); json_str = json_object_to_json_string(json_obj); - print(8, "JSON request body: %s", ch, json_str); + print(10, "JSON request body: %s", ch, json_str); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_custom_write_callback); @@ -211,9 +213,10 @@ void * api_thread(void *arg) { curl_code = curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + /* check response */ if (curl_code == CURLE_OK && http_code == 200) { /* everything is ok */ - print(3, "Request succeeded with code: %i", ch, http_code); - queue_clear(&ch->queue); + print(4, "Request succeeded with code: %i", ch, http_code); + ch->buffer.sent = NULL; } else { /* error */ if (curl_code != CURLE_OK) { @@ -222,19 +225,22 @@ void * api_thread(void *arg) { else if (http_code != 200) { char err[255]; api_parse_exception(response, err); - print(-1, "Invalid middlware response: %s", ch, err); + print(-1, "Error from middleware: %s", ch, err); } - - print(2, "Sleeping %i seconds due to previous failure", ch, RETRY_PAUSE); - sleep(RETRY_PAUSE); } - + /* householding */ free(response.data); json_object_put(json_obj); - - pthread_testcancel(); /* test for cancelation request */ - } while (opts.daemon); + + if (!opts.daemon) { + break; + } + else if (curl_code != CURLE_OK || http_code != 200) { + print(2, "Sleeping %i seconds due to previous failure", ch, RETRY_PAUSE); + sleep(RETRY_PAUSE); + } + } curl_easy_cleanup(curl); /* always cleanup */ diff --git a/src/api.h b/bin/vzlogger/api.h similarity index 90% rename from src/api.h rename to bin/vzlogger/api.h index 54b9dce..e4d8789 100644 --- a/src/api.h +++ b/bin/vzlogger/api.h @@ -29,9 +29,9 @@ #include #include #include +#include -#include "main.h" -#include "protocol.h" +#include "buffer.h" typedef struct { char *data; @@ -42,7 +42,8 @@ typedef struct { int curl_custom_debug_callback(CURL *curl, curl_infotype type, char *data, size_t size, void *custom); size_t curl_custom_write_callback(void *ptr, size_t size, size_t nmemb, void *data); -json_object * api_json_tuples(channel_t *ch, bool_t all); +json_object * api_json_tuples(buffer_t *buf, meter_reading_t *start); void * api_thread(void *arg); +double api_tvtof(struct timeval tv); #endif /* _API_H_ */ diff --git a/bin/vzlogger/buffer.c b/bin/vzlogger/buffer.c new file mode 100644 index 0000000..bb04afe --- /dev/null +++ b/bin/vzlogger/buffer.c @@ -0,0 +1,123 @@ +/** + * Circular buffer (double linked) + * + * Used to store recent readings and buffer in case of net inconnectivity + * + * @author Steffen Vogel + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @package vzlogger + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include +#include + +#include "buffer.h" + +void buffer_init(buffer_t *buf, int mem) { + pthread_mutex_init(&buf->mutex, NULL); + + pthread_mutex_lock(&buf->mutex); + buf->last = NULL; + buf->start = NULL; + buf->sent = NULL; + buf->size = 0; + buf->memory = mem; + pthread_mutex_unlock(&buf->mutex); +} + +int buffer_push(buffer_t *buf, meter_reading_t rd) { + meter_reading_t *new = malloc(sizeof(meter_reading_t)); + + if (!new) { + return 0; /* cannot allocate memory */ + } + + memcpy(new, &rd, sizeof(meter_reading_t)); + + pthread_mutex_lock(&buf->mutex); + if (buf->last == NULL) { /* empty buffer */ + buf->start = new; + } + else { + buf->last->next = new; + } + + if (buf->sent == NULL) { /* add reading to send queue */ + buf->sent = new; + } + + new->next = NULL; + buf->last = new; + buf->size++; + pthread_mutex_unlock(&buf->mutex); + + buffer_clean(buf); + + return buf->size; +} + +void buffer_clean(buffer_t *buf) { + pthread_mutex_lock(&buf->mutex); + while(buf->size > buf->memory && buf->start != buf->sent) { + meter_reading_t *pop = buf->start; + + buf->start = buf->start->next; + buf->size--; + + free(pop); + } + pthread_mutex_unlock(&buf->mutex); +} + +char * buffer_dump(buffer_t *buf, char *dump, int len) { + strcpy(dump, "|"); + + for (meter_reading_t *rd = buf->start; rd != NULL; rd = rd->next) { + char tmp[16]; + sprintf(tmp, "%.2f|", rd->value); + + if (strlen(dump)+strlen(tmp) < len) { + if (buf->sent == rd) { /* indicate last sent reading */ + strcat(dump, "!"); + } + + strcat(dump, tmp); + } + else { + return NULL; /* dump buffer is full! */ + } + } + + return dump; +} + +void buffer_free(buffer_t *buf) { + pthread_mutex_destroy(&buf->mutex); + + meter_reading_t *rd = buf->start; + do { + meter_reading_t *tmp = rd; + rd = rd->next; + free(tmp); + } while (rd); + + memset(buf, 0, sizeof(buffer_t)); +} diff --git a/bin/vzlogger/buffer.h b/bin/vzlogger/buffer.h new file mode 100644 index 0000000..3de53c4 --- /dev/null +++ b/bin/vzlogger/buffer.h @@ -0,0 +1,57 @@ +/** + * Circular buffer (double linked, threadsafe) + * + * Used to store recent readings and buffer in case of net inconnectivity + * + * @author Steffen Vogel + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @package vzlogger + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _BUFFER_H_ +#define _BUFFER_H_ + +#include +#include + +#include + +typedef struct { + meter_reading_t *last; + meter_reading_t *start; + meter_reading_t *sent; + + int size; /* number of readings currently in the buffer */ + int memory; /* number of readings to keep in mind for local interface */ + + pthread_mutex_t mutex; +} buffer_t; + +/* Prototypes */ +void buffer_init(buffer_t *buf, int mem); +int buffer_push(buffer_t *buf, meter_reading_t rd); +void buffer_free(buffer_t *buf); +void buffer_clean(buffer_t *buf); +void buffer_clear(buffer_t *buf); +char * buffer_dump(buffer_t *buf, char *dump, int len); + + +#endif /* _BUFFER_H_ */ + diff --git a/bin/vzlogger/channel.c b/bin/vzlogger/channel.c new file mode 100644 index 0000000..d61a77e --- /dev/null +++ b/bin/vzlogger/channel.c @@ -0,0 +1,91 @@ +/** + * Channel class + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include +#include + +#include "vzlogger.h" +#include "api.h" +#include "channel.h" +#include "options.h" + +extern options_t opts; + +void reading_thread(void *arg) { + channel_t *ch = (channel_t *) arg; + + while (1) { + meter_reading_t rd = meter_read(&ch->meter); + print(1, "Value read: %.2f at %.0f", ch, rd.value, api_tvtof(rd.tv)); + + buffer_push(&ch->buffer, rd); + pthread_mutex_lock(&ch->buffer.mutex); + pthread_cond_broadcast(&ch->condition); /* notify webserver and logging thread */ + pthread_mutex_unlock(&ch->buffer.mutex); + + /* Debugging */ + if (opts.verbose >= 10) { + char dump[1024]; + buffer_dump(&ch->buffer, dump, 1024); + print(10, "Buffer dump: %s (size=%i, memory=%i)", ch, dump, ch->buffer.size, ch->buffer.memory); + } + + if (ch->meter.type->periodical) { + print(8, "Next reading in %i seconds", ch, ch->interval); + sleep(ch->interval); + } + } +} + +void channel_init(channel_t *ch, char *uuid, char *middleware, unsigned long interval, char *options, meter_type_t *type) { + static int instances; /* static to generate channel ids */ + + int buffer_size = (type->periodical) ? (BUFFER_DURATION / interval) + 1 : BUFFER_LENGTH; + + ch->id = instances++; + ch->interval = interval; + ch->uuid = strdup(uuid); + ch->middleware = strdup(middleware); + ch->options = strdup(options); + + meter_init(&ch->meter, type, options); + buffer_init(&ch->buffer, buffer_size); /* initialize buffer */ + + pthread_cond_init(&ch->condition, NULL); /* initialize thread syncronization helpers */ +} + +/** + * Free all allocated memory recursivly + */ +void channel_free(channel_t *ch) { + buffer_free(&ch->buffer); + meter_free(&ch->meter); + pthread_cond_destroy(&ch->condition); + + free(ch->uuid); + free(ch->options); + free(ch->middleware); +} diff --git a/bin/vzlogger/channel.h b/bin/vzlogger/channel.h new file mode 100644 index 0000000..0e379ee --- /dev/null +++ b/bin/vzlogger/channel.h @@ -0,0 +1,60 @@ +/** + * Channel handling + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _CHANNEL_H_ +#define _CHANNEL_H_ + +#include +#include + +#include + +#include "buffer.h" + +typedef struct channel { + unsigned int id; /* only for internal usage & debugging */ + char *middleware; /* url to middleware */ + char *options; /* protocols specific configuration */ + char *uuid; /* unique identifier for middleware */ + + unsigned long interval; /* polling interval (for sensors only) */ + + meter_t meter; /* handle to store connection status */ + buffer_t buffer; /* circular queue to buffer readings */ + + pthread_t logging_thread; /* pthread for asynchronus logging */ + pthread_t reading_thread; /* pthread for asynchronus reading */ + pthread_cond_t condition; /* pthread syncronization to notify logging thread and local webserver */ + + struct channel *next; /* pointer for linked list */ +} channel_t; + +/* Prototypes */ +void channel_init(channel_t *ch, char *uuid, char *middleware, unsigned long interval, char *options, meter_type_t *type); +void channel_free(channel_t *ch); + +void reading_thread(void *arg); + +#endif /* _CHANNEL_H_ */ diff --git a/src/queue.h b/bin/vzlogger/list.c similarity index 57% rename from src/queue.h rename to bin/vzlogger/list.c index 3832f22..443f94c 100644 --- a/src/queue.h +++ b/bin/vzlogger/list.c @@ -1,5 +1,5 @@ /** - * Circular queue to buffer readings + * Linked list to manage channels * * @package vzlogger * @copyright Copyright (c) 2011, The volkszaehler.org project @@ -22,38 +22,47 @@ * You should have received a copy of the GNU General Public License * along with volkszaehler.org. If not, see . */ - -#ifndef _QUEUE_H_ -#define _QUEUE_H_ -#include "protocol.h" +#include +#include -#ifndef TRUE -#define TRUE 1 -#endif +#include "list.h" -#ifndef FALSE -#define FALSE 0 -#endif +void list_init(list_t *ls) { + ls->start = NULL; + ls->size = 0; +} -typedef char bool_t; +int list_push(list_t *ls, channel_t ch) { + channel_t *new = malloc(sizeof(channel_t)); -typedef struct { - size_t size; - - size_t read_p; - size_t write_p; - - reading_t *buf; -} queue_t; + if (!new) { + return 0; /* cannot allocate memory */ + } -bool_t queue_init(queue_t *q, size_t size); -bool_t queue_is_empty(queue_t *q); -bool_t queue_get(queue_t *q, size_t index, reading_t *rd); -bool_t queue_push(queue_t *q, reading_t rd); -void queue_clear(queue_t *q); -void queue_free(queue_t *q); -char * queue_print(queue_t *q); + memcpy(new, &ch, sizeof(channel_t)); -#endif /* _QUEUE_H_ */ + if (ls->start == NULL) { /* empty list */ + new->next = NULL; + } + else { + new->next = ls->start; + } + ls->start = new; + ls->size++; + + return ls->size; +} + +void list_free(list_t *ls) { + channel_t *ch = ls->start; + do { + channel_t *tmp = ch; + ch = ch->next; + channel_free(tmp); + } while (ch); + + ls->start = NULL; + ls->size = 0; +} diff --git a/src/protocols/random.h b/bin/vzlogger/list.h similarity index 74% rename from src/protocols/random.h rename to bin/vzlogger/list.h index eea173d..7ba93ab 100644 --- a/src/protocols/random.h +++ b/bin/vzlogger/list.h @@ -1,5 +1,5 @@ /** - * Generate pseudo random data series with a random walk + * Linked list to manage channels * * @package vzlogger * @copyright Copyright (c) 2011, The volkszaehler.org project @@ -23,19 +23,19 @@ * along with volkszaehler.org. If not, see . */ -#ifndef _RANDOM_H_ -#define _RANDOM_H_ +#ifndef _LIST_H_ +#define _LIST_H_ -#include "../protocol.h" +#include "channel.h" typedef struct { - float min, max, last; -} random_state_t; + channel_t *start; + int size; +} list_t; -double ltqnorm(double p); +/* Prototypes */ +void list_init(list_t *ls); +int list_push(list_t *ls, channel_t ch); +void list_free(list_t *ls); -void * random_init(char *port); -void random_close(void *handle); -reading_t random_get(void *handle); - -#endif /* _RANDOM_H_ */ +#endif /* _LIST_H_ */ diff --git a/src/local.c b/bin/vzlogger/local.c similarity index 74% rename from src/local.c rename to bin/vzlogger/local.c index 65b100f..c0a13c7 100644 --- a/src/local.c +++ b/bin/vzlogger/local.c @@ -26,39 +26,50 @@ #include #include #include +#include -#include "main.h" +#include "vzlogger.h" #include "local.h" +#include "options.h" +#include "api.h" -extern channel_t chans[MAX_CHANNELS]; +extern list_t chans; extern options_t opts; int handle_request(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) { - const char * json_str; + int ret; - int num_chans = *(int *) cls; - print(2, "Local request received: %s %s %s", NULL, version, method, url); + const char *json_str; + const char *uuid = url+1; + + struct timespec ts; + struct timeval tp; struct MHD_Response *response; struct json_object *json_obj = json_object_new_object(); struct json_object *json_data = json_object_new_object(); - for (int i = 0; i < num_chans; i++) { - channel_t *ch = &chans[i]; - reading_t rd; + print(2, "Local request received: %s %s %s", NULL, version, method, url); - if (strcmp(url, "/") == 0 || strcmp(ch->uuid, url + 1) == 0) { - pthread_mutex_lock(&ch->mutex); - /* wait for new data comet-like blocking of HTTP response */ - pthread_cond_wait(&ch->condition, &ch->mutex); // TODO use pthread_cond_timedwait() - pthread_mutex_unlock(&ch->mutex); + for (channel_t *ch = chans.start; ch != NULL; ch = ch->next) { + if (strcmp(url, "/") == 0 || strcmp(ch->uuid, uuid) == 0) { + /* convert from timeval to timespec */ + gettimeofday(&tp, NULL); + ts.tv_sec = tp.tv_sec; + ts.tv_nsec = tp.tv_usec * 1000; + ts.tv_sec += COMET_TIMEOUT; - struct json_object *json_tuples = api_json_tuples(ch, TRUE); + /* blocking until new data arrives (comet-like blocking of HTTP response) */ + pthread_mutex_lock(&ch->buffer.mutex); + pthread_cond_timedwait(&ch->condition, &ch->buffer.mutex, &ts); + pthread_mutex_unlock(&ch->buffer.mutex); json_object_object_add(json_data, "uuid", json_object_new_string(ch->uuid)); json_object_object_add(json_data, "interval", json_object_new_int(ch->interval)); + + struct json_object *json_tuples = api_json_tuples(&ch->buffer, ch->buffer.start); json_object_object_add(json_data, "tuples", json_tuples); } } diff --git a/src/local.h b/bin/vzlogger/local.h similarity index 100% rename from src/local.h rename to bin/vzlogger/local.h diff --git a/bin/vzlogger/options.c b/bin/vzlogger/options.c new file mode 100644 index 0000000..b03d578 --- /dev/null +++ b/bin/vzlogger/options.c @@ -0,0 +1,231 @@ +/** + * Parsing commandline options and channel list + * + * @author Steffen Vogel + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @package vzlogger + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../../config.h" + +#include "list.h" +#include "options.h" +#include "channel.h" +#include "vzlogger.h" + +extern meter_type_t meter_types[]; + +options_t opts = { /* setting default options */ + "/etc/vzlogger.conf", /* config file */ + 8080, /* port for local interface */ + 0, /* verbosity level */ + 0, /* daemon mode */ + 0 /* local interface */ +}; + +/** + * Command line options + */ +struct option long_options[] = { + {"config", required_argument, 0, 'c'}, + {"daemon", required_argument, 0, 'd'}, +#ifdef LOCAL_SUPPORT + {"local", no_argument, 0, 'l'}, + {"local-port", required_argument, 0, 'p'}, +#endif /* LOCAL_SUPPORT */ + {"verbose", optional_argument, 0, 'v'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, + {} /* stop condition for iterator */ +}; + +/** + * Descriptions vor command line options + */ +char *long_options_descs[] = { + "config file with channel -> uuid mapping", + "run as daemon", +#ifdef LOCAL_SUPPORT + "activate local interface (tiny webserver)", + "TCP port for local interface", +#endif /* LOCAL_SUPPORT */ + "enable verbose output", + "show this help", + "show version of vzlogger", + "" /* stop condition for iterator */ +}; + +/** + * Parse options from command line + */ +void parse_options(int argc, char * argv[], options_t * opts) { + while (1) { + /* getopt_long stores the option index here. */ + int option_index = 0; + + int c = getopt_long(argc, argv, "i:c:p:lhVdv::", long_options, &option_index); + + /* detect the end of the options. */ + if (c == -1) + break; + + switch (c) { + case 'v': + opts->verbose = (optarg == NULL) ? 1 : atoi(optarg); + break; + +#ifdef LOCAL_SUPPORT + case 'l': + opts->local = 1; + break; + + case 'p': /* port for local interface */ + opts->port = atoi(optarg); + break; +#endif /* LOCAL_SUPPORT */ + + case 'd': + opts->daemon = 1; + break; + + case 'c': /* read config file */ + opts->config = (char *) malloc(strlen(optarg)+1); + strcpy(opts->config, optarg); + break; + + case 'V': + printf("%s\n", VERSION); + exit(EXIT_SUCCESS); + break; + + case 'h': + case '?': + usage(argv); + exit((c == '?') ? EXIT_FAILURE : EXIT_SUCCESS); + } + } +} + +void parse_channels(char *filename, list_t *chans) { + FILE *file = fopen(filename, "r"); /* open configuration */ + + if (!filename) { /* nothing found */ + print(-1, "No config file found! Please specify with --config!\n", NULL); + exit(EXIT_FAILURE); + } + + if (file == NULL) { + perror(filename); /* why didn't the file open? */ + exit(EXIT_FAILURE); + } + else { + print(2, "Start parsing configuration from %s", NULL, filename); + } + + int lineno = 1; + char *buffer = malloc(256); + char *tokens[5]; + char *line; + + /* compile regular expressions */ + regex_t re_uuid, re_middleware; + regcomp(&re_uuid, "^[a-f0-9]{8}-([a-f0-9]{4}-){3,3}[a-f0-9]{12}$", REG_EXTENDED | REG_ICASE | REG_NOSUB); + regcomp(&re_middleware, "^https?://[a-z0-9.-]+\\.[a-z]{2,6}(/\\S*)?$", REG_EXTENDED | REG_ICASE | REG_NOSUB); + + /*regerror(err, &re_uuid, buffer, 256); + printf("Error analyzing regular expression: %s.\n", buffer);*/ + + while ((line = fgets(buffer, 256, file)) != NULL) { /* read a line */ + line[strcspn(line, "\n\r;")] = '\0'; /* strip newline and comments */ + if (strlen(line) == 0) continue; /* skip empty lines */ + + /* channel properties */ + char *middleware, *options, *uuid; + unsigned long interval; + channel_t ch; + meter_type_t *type; + + /* parse tokens (required) */ + memset(tokens, 0, 5); + for (int i = 0; i < 5; i++) { + do { + tokens[i] = strsep(&line, " \t"); + } while (tokens[i] == NULL && line != NULL); + } + + /* protocol (required) */ + for (type = meter_types; type->name != NULL; type++) { /* linear search */ + if (strcmp(type->name, tokens[0]) == 0) break; + } + + if (type->name == NULL) { /* reached end */ + print(-1, "Invalid protocol: %s in %s:%i", NULL, tokens[0], filename, lineno); + exit(EXIT_FAILURE); + } + + /* middleware (required) */ + middleware = tokens[1]; + if (regexec(&re_middleware, middleware, 0, NULL, 0) == 0) { + print(-1, "Invalid interval: %s in %s:%i", NULL, tokens[1], filename, lineno); + exit(EXIT_FAILURE); + } + + /* uuid (required) */ + uuid = tokens[2]; + if (regexec(&re_uuid, uuid, 0, NULL, 0) != 0) { + print(-1, "Invalid uuid: %s in %s:%i", NULL, tokens[2], filename, lineno); + exit(EXIT_FAILURE); + } + + /* interval (only if protocol is sensor) */ + if (type->periodical) { + interval = strtol(tokens[3], (char **) NULL, 10); + if (errno == EINVAL || errno == ERANGE) { + print(-1, "Invalid interval: %s in %s:%i", NULL, tokens[3], filename, lineno); + exit(EXIT_FAILURE); + } + } + else { + interval = 0; + } + + /* options (optional) */ + options = tokens[type->periodical ? 4 : 3]; + + channel_init(&ch, uuid, middleware, interval, options, type); + print(1, "Parsed (protocol=%s interval=%i uuid=%s middleware=%s options=%s)", &ch, type->name, interval, uuid, middleware, options); + + list_push(chans, ch); + lineno++; + } + + fclose(file); + free(buffer); + regfree(&re_middleware); + regfree(&re_uuid); +} diff --git a/bin/vzlogger/options.h b/bin/vzlogger/options.h new file mode 100644 index 0000000..ccb332d --- /dev/null +++ b/bin/vzlogger/options.h @@ -0,0 +1,48 @@ +/** + * Parsing commandline options and channel list + * + * @author Steffen Vogel + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @package vzlogger + * @license http://opensource.org/licenses/gpl-license.php GNU Public License + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _OPTIONS_H_ +#define _OPTIONS_H_ + +#include "list.h" + +/** + * Options from command line + */ +typedef struct { + char *config; /* path to config file */ + unsigned int port; /* tcp port for local interface */ + int verbose; /* verbosity level */ + + /* boolean bitfields, at the end of struct */ + int daemon:1; + int local:1; /* enable local interface */ +} options_t; + +/* Prototypes */ +void parse_options(int argc, char *argv[], options_t *opts); +void parse_channels(char *filename, list_t *chans); + +#endif /* _OPTIONS_H_ */ diff --git a/bin/vzlogger/vzlogger b/bin/vzlogger/vzlogger new file mode 100755 index 0000000..770d4cc Binary files /dev/null and b/bin/vzlogger/vzlogger differ diff --git a/bin/vzlogger/vzlogger.c b/bin/vzlogger/vzlogger.c new file mode 100644 index 0000000..d296bf0 --- /dev/null +++ b/bin/vzlogger/vzlogger.c @@ -0,0 +1,192 @@ +/** + * Main source file + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + + +#include /* for print() */ +#include + +#include +#include +#include + +#include "vzlogger.h" + +#include "list.h" +#include "buffer.h" +#include "channel.h" +#include "api.h" +#include "options.h" + +#ifdef LOCAL_SUPPORT +#include +#include "local.h" +#endif /* LOCAL_SUPPORT */ + +/* global variables */ +list_t chans; +extern options_t opts; +extern char *long_options_descs[]; +extern struct option long_options[]; +extern meter_type_t meter_types[]; + +/** + * Print available options and some other usefull information + */ +void usage(char *argv[]) { + char **desc = long_options_descs; + struct option *op = long_options; + meter_type_t *type = meter_types; + + printf("Usage: %s [options]\n\n", argv[0]); + printf(" following options are available:\n"); + + while (op->name && *desc) { + printf("\t-%c, --%-12s\t%s\n", op->val, op->name, *desc); + op++; desc++; + } + + printf("\n"); + printf(" following protocol types are supported:\n"); + + while (type->name) { + printf("\t%-12s\t%s\n", type->name, type->desc); + type++; + } + + printf("\n%s - volkszaehler.org logging utility\n", PACKAGE_STRING); + printf("by Steffen Vogel \n"); + printf("send bugreports to %s\n", PACKAGE_BUGREPORT); +} + +/** + * Wrapper to log notices and errors + * + * @param ch could be NULL for general messages + * @todo integrate into syslog + */ +void print(int level, char * format, channel_t *ch, ... ) { + va_list args; + + struct timeval now; + struct tm * timeinfo; + char buffer[1024] = "[", *pos = buffer+1; + + if (level <= opts.verbose) { + gettimeofday(&now, NULL); + timeinfo = localtime(&now.tv_sec); + pos += strftime(pos, 16, "%b %d %H:%M:%S", timeinfo); + + pos += sprintf(pos, ".%03lu] ", now.tv_usec / 1000); + + if (ch != NULL) { + pos += sprintf(pos, "[ch#%i] ", ch->id); + } + + va_start(args, ch); + pos += vsprintf(pos, format, args); + va_end(args); + + fprintf((level > 0) ? stdout : stderr, "%s\n", buffer); + } +} + +/** + * Cancel threads + * + * Threads gets joined in main() + */ +void quit(int sig) { + print(2, "Closing connections to terminate", NULL); + for (channel_t *ch = chans.start; ch != NULL; ch = ch->next) { + pthread_cancel(ch->logging_thread); + pthread_cancel(ch->reading_thread); + } +} + +/** + * The main loop + */ +int main(int argc, char *argv[]) { + /* bind signal handler */ + struct sigaction action; + sigemptyset(&action.sa_mask); + action.sa_flags = 0; + action.sa_handler = quit; + sigaction(SIGINT, &action, NULL); + + list_init(&chans); + parse_options(argc, argv, &opts); /* parse command line arguments */ + parse_channels(opts.config, &chans); /* parse channels from configuration */ + + curl_global_init(CURL_GLOBAL_ALL); /* global intialization for all threads */ + + for (channel_t *ch = chans.start; ch != NULL; ch = ch->next) { + print(5, "Opening connection to meter", ch); + meter_open(&ch->meter); + + print(5, "Starting threads", ch); + pthread_create(&ch->logging_thread, NULL, &api_thread, (void *) ch); + pthread_create(&ch->reading_thread, NULL, &reading_thread, (void *) ch); + } + +#ifdef LOCAL_SUPPORT + struct MHD_Daemon *httpd_handle = NULL; + if (opts.local) { /* start webserver for local interface */ + print(5, "Starting local interface HTTPd on port %i", NULL, opts.port); + httpd_handle = MHD_start_daemon( + MHD_USE_THREAD_PER_CONNECTION, + opts.port, + NULL, NULL, + handle_request, + NULL, + MHD_OPTION_END + ); + } +#endif /* LOCAL_SUPPORT */ + + /* wait for all threads to terminate */ + for (channel_t *ch = chans.start; ch != NULL; ch = ch->next) { + pthread_join(ch->logging_thread, NULL); + pthread_join(ch->reading_thread, NULL); + + meter_close(&ch->meter); /* closing connection */ + } + +#ifdef LOCAL_SUPPORT + /* stop webserver */ + if (httpd_handle) { + print(8, "Stopping local interface HTTPd on port %i", NULL, opts.port); + MHD_stop_daemon(httpd_handle); + } +#endif /* LOCAL_SUPPORT */ + + /* householding */ + list_free(&chans); + curl_global_cleanup(); + + print(10, "Bye bye!", NULL); + + return EXIT_SUCCESS; +} diff --git a/bin/vzlogger/vzlogger.h b/bin/vzlogger/vzlogger.h new file mode 100644 index 0000000..6e75cda --- /dev/null +++ b/bin/vzlogger/vzlogger.h @@ -0,0 +1,45 @@ +/** + * Main header file + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _VZLOGGER_H_ +#define _VZLOGGER_H_ + +#include "../../config.h" + +#include + +#include "channel.h" + +/* some hard coded configuration */ +#define RETRY_PAUSE 10 //600 /* seconds to wait after failed request */ +#define BUFFER_DURATION 60 /* in seconds */ +#define BUFFER_LENGTH 256 /* in readings */ +#define COMET_TIMEOUT 30 /* seconds */ + +/* Prototypes */ +void print(int level, char *format, channel_t *ch, ... ); +void usage(char ** argv); + +#endif /* _VZLOGGER_H_ */ diff --git a/config.h.in b/config.h.in index b17f255..f68d49d 100644 --- a/config.h.in +++ b/config.h.in @@ -73,7 +73,10 @@ #undef HAVE_UNISTD_H /* Local interface */ -#undef LOCAL +#undef LOCAL_SUPPORT + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O /* Name of package */ #undef PACKAGE @@ -96,6 +99,9 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* Smart Messaging Language */ +#undef SML_SUPPORT + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff --git a/configure b/configure index c83a134..2971782 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for vzlogger 0.2. +# Generated by GNU Autoconf 2.68 for vzlogger 0.2. # # Report bugs to . # @@ -91,6 +91,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -216,11 +217,18 @@ IFS=$as_save_IFS # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -557,7 +565,7 @@ PACKAGE_STRING='vzlogger 0.2' PACKAGE_BUGREPORT='http://bugs.volkszaehler.org' PACKAGE_URL='' -ac_unique_file="src/main.c" +ac_unique_file="src/meter.c" # Factoring default headers for most tests. ac_includes_default="\ #include @@ -599,17 +607,22 @@ am__EXEEXT_TRUE LTLIBOBJS DEPS_LOCAL_LIBS DEPS_LOCAL_CFLAGS -LOCAL_FALSE -LOCAL_TRUE +LOCAL_SUPPORT_FALSE +LOCAL_SUPPORT_TRUE +DEPS_SML_LIBS +DEPS_SML_CFLAGS +SML_SUPPORT_FALSE +SML_SUPPORT_TRUE LIBOBJS EGREP GREP CPP -DEPS_LIBS -DEPS_CFLAGS +DEPS_VZ_LIBS +DEPS_VZ_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG +RANLIB am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE @@ -691,7 +704,8 @@ ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking -enable_local_interface +enable_sml +enable_local enable_debug ' ac_precious_vars='build_alias @@ -705,9 +719,11 @@ CPPFLAGS PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR -DEPS_CFLAGS -DEPS_LIBS +DEPS_VZ_CFLAGS +DEPS_VZ_LIBS CPP +DEPS_SML_CFLAGS +DEPS_SML_LIBS DEPS_LOCAL_CFLAGS DEPS_LOCAL_LIBS' @@ -1114,7 +1130,7 @@ Try \`$0 --help' for more information" $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -1328,6 +1344,7 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors + --enable-sml enable support for smart messaging language (def=no) --enable-local enable support for local HTTPd (def=no) --enable-debug enable debug data generation (def=no) @@ -1344,9 +1361,15 @@ Some influential environment variables: directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path - DEPS_CFLAGS C compiler flags for DEPS, overriding pkg-config - DEPS_LIBS linker flags for DEPS, overriding pkg-config + DEPS_VZ_CFLAGS + C compiler flags for DEPS_VZ, overriding pkg-config + DEPS_VZ_LIBS + linker flags for DEPS_VZ, overriding pkg-config CPP C preprocessor + DEPS_SML_CFLAGS + C compiler flags for DEPS_SML, overriding pkg-config + DEPS_SML_LIBS + linker flags for DEPS_SML, overriding pkg-config DEPS_LOCAL_CFLAGS C compiler flags for DEPS_LOCAL, overriding pkg-config DEPS_LOCAL_LIBS @@ -1419,7 +1442,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF vzlogger configure 0.2 -generated by GNU Autoconf 2.67 +generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1465,7 +1488,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile @@ -1502,7 +1525,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp @@ -1515,10 +1538,10 @@ fi ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval "test \"\${$3+set}\"" = set; then : + if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 @@ -1585,7 +1608,7 @@ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" @@ -1594,7 +1617,7 @@ eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel @@ -1635,7 +1658,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run @@ -1649,7 +1672,7 @@ ac_fn_c_check_header_compile () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1667,7 +1690,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile @@ -1680,7 +1703,7 @@ ac_fn_c_check_type () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" @@ -1721,7 +1744,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type @@ -1736,7 +1759,7 @@ ac_fn_c_check_decl () as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1767,7 +1790,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl @@ -1812,7 +1835,7 @@ fi # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link @@ -1825,7 +1848,7 @@ ac_fn_c_check_func () as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } -if eval "test \"\${$3+set}\"" = set; then : +if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -1880,7 +1903,7 @@ fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } - eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF @@ -1888,7 +1911,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by vzlogger $as_me 0.2, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2146,7 +2169,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;} || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi done @@ -2283,7 +2306,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then -if test "${ac_cv_path_install+set}" = set; then : +if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2370,11 +2393,11 @@ am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5 ;; + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;; + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; esac # Do `set' in a subshell so we don't clobber the current shell's @@ -2460,7 +2483,7 @@ if test "$cross_compiling" != no; then set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_STRIP+set}" = set; then : +if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then @@ -2500,7 +2523,7 @@ if test -z "$ac_cv_prog_STRIP"; then set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then @@ -2553,7 +2576,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then - if test "${ac_cv_path_mkdir+set}" = set; then : + if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2604,7 +2627,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_AWK+set}" = set; then : +if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then @@ -2644,7 +2667,7 @@ done $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF @@ -2745,7 +2768,7 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers config.h" -ac_config_files="$ac_config_files Makefile src/Makefile docs/Makefile" +ac_config_files="$ac_config_files Makefile docs/Makefile src/Makefile bin/reader/Makefile bin/vzlogger/Makefile" # Checks for programs. @@ -2759,7 +2782,7 @@ if test -n "$ac_tool_prefix"; then set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2799,7 +2822,7 @@ if test -z "$ac_cv_prog_CC"; then set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -2852,7 +2875,7 @@ if test -z "$CC"; then set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2892,7 +2915,7 @@ if test -z "$CC"; then set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2951,7 +2974,7 @@ if test -z "$CC"; then set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_CC+set}" = set; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then @@ -2995,7 +3018,7 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then @@ -3050,7 +3073,7 @@ fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -3165,7 +3188,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -3208,7 +3231,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -3267,7 +3290,7 @@ $as_echo "$ac_try_echo"; } >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi fi fi @@ -3278,7 +3301,7 @@ rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } -if test "${ac_cv_objext+set}" = set; then : +if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3319,7 +3342,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi @@ -3329,7 +3352,7 @@ OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if test "${ac_cv_c_compiler_gnu+set}" = set; then : +if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -3366,7 +3389,7 @@ ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } -if test "${ac_cv_prog_cc_g+set}" = set; then : +if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag @@ -3444,7 +3467,7 @@ else fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if test "${ac_cv_prog_cc_c89+set}" = set; then : +if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no @@ -3605,7 +3628,7 @@ depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } -if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : +if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then @@ -3729,6 +3752,228 @@ fi +# We want to build a lib +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +# We use per target compiler flags +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + + # Checks for libraries. @@ -3736,13 +3981,14 @@ fi + if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in @@ -3785,7 +4031,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in @@ -3851,11 +4097,11 @@ $as_echo "no" >&6; } fi pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS" >&5 -$as_echo_n "checking for DEPS... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_VZ" >&5 +$as_echo_n "checking for DEPS_VZ... " >&6; } -if test -n "$DEPS_CFLAGS"; then - pkg_cv_DEPS_CFLAGS="$DEPS_CFLAGS" +if test -n "$DEPS_VZ_CFLAGS"; then + pkg_cv_DEPS_VZ_CFLAGS="$DEPS_VZ_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json >= 0.9 libcurl >= 7.21.0\""; } >&5 @@ -3863,15 +4109,16 @@ if test -n "$DEPS_CFLAGS"; then ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_DEPS_CFLAGS=`$PKG_CONFIG --cflags "json >= 0.9 libcurl >= 7.21.0" 2>/dev/null` + pkg_cv_DEPS_VZ_CFLAGS=`$PKG_CONFIG --cflags "json >= 0.9 libcurl >= 7.21.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi -if test -n "$DEPS_LIBS"; then - pkg_cv_DEPS_LIBS="$DEPS_LIBS" +if test -n "$DEPS_VZ_LIBS"; then + pkg_cv_DEPS_VZ_LIBS="$DEPS_VZ_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json >= 0.9 libcurl >= 7.21.0\""; } >&5 @@ -3879,7 +4126,8 @@ if test -n "$DEPS_LIBS"; then ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_DEPS_LIBS=`$PKG_CONFIG --libs "json >= 0.9 libcurl >= 7.21.0" 2>/dev/null` + pkg_cv_DEPS_VZ_LIBS=`$PKG_CONFIG --libs "json >= 0.9 libcurl >= 7.21.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -3899,22 +4147,22 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - DEPS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "json >= 0.9 libcurl >= 7.21.0" 2>&1` + DEPS_VZ_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "json >= 0.9 libcurl >= 7.21.0" 2>&1` else - DEPS_PKG_ERRORS=`$PKG_CONFIG --print-errors "json >= 0.9 libcurl >= 7.21.0" 2>&1` + DEPS_VZ_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "json >= 0.9 libcurl >= 7.21.0" 2>&1` fi # Put the nasty error message in config.log where it belongs - echo "$DEPS_PKG_ERRORS" >&5 + echo "$DEPS_VZ_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (json >= 0.9 libcurl >= 7.21.0) were not met: -$DEPS_PKG_ERRORS +$DEPS_VZ_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. -Alternatively, you may set the environment variables DEPS_CFLAGS -and DEPS_LIBS to avoid the need to call pkg-config. +Alternatively, you may set the environment variables DEPS_VZ_CFLAGS +and DEPS_VZ_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -3925,15 +4173,15 @@ as_fn_error $? "The pkg-config script could not be found or is too old. Make su is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. -Alternatively, you may set the environment variables DEPS_CFLAGS -and DEPS_LIBS to avoid the need to call pkg-config. +Alternatively, you may set the environment variables DEPS_VZ_CFLAGS +and DEPS_VZ_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else - DEPS_CFLAGS=$pkg_cv_DEPS_CFLAGS - DEPS_LIBS=$pkg_cv_DEPS_LIBS + DEPS_VZ_CFLAGS=$pkg_cv_DEPS_VZ_CFLAGS + DEPS_VZ_LIBS=$pkg_cv_DEPS_VZ_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -3953,7 +4201,7 @@ if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then : + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded @@ -4069,7 +4317,7 @@ else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c @@ -4081,7 +4329,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if test "${ac_cv_path_GREP+set}" = set; then : +if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then @@ -4144,7 +4392,7 @@ $as_echo "$ac_cv_path_GREP" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } -if test "${ac_cv_path_EGREP+set}" = set; then : +if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 @@ -4211,7 +4459,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } -if test "${ac_cv_header_stdc+set}" = set; then : +if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -4354,7 +4602,7 @@ done # Checks for typedefs, structures, and compiler characteristics. ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" -if test "x$ac_cv_type_mode_t" = x""yes; then : +if test "x$ac_cv_type_mode_t" = xyes; then : else @@ -4365,7 +4613,7 @@ _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = x""yes; then : +if test "x$ac_cv_type_size_t" = xyes; then : else @@ -4380,7 +4628,7 @@ fi for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = x""yes; then : +if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF @@ -4391,7 +4639,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 $as_echo_n "checking for GNU libc compatible malloc... " >&6; } -if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then : +if ${ac_cv_func_malloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -4447,7 +4695,7 @@ fi for ac_header in stdlib.h do : ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = x""yes; then : +if test "x$ac_cv_header_stdlib_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STDLIB_H 1 _ACEOF @@ -4458,7 +4706,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5 $as_echo_n "checking for GNU libc compatible realloc... " >&6; } -if test "${ac_cv_func_realloc_0_nonnull+set}" = set; then : +if ${ac_cv_func_realloc_0_nonnull+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : @@ -4512,7 +4760,7 @@ fi ac_fn_c_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default" -if test "x$ac_cv_have_decl_strerror_r" = x""yes; then : +if test "x$ac_cv_have_decl_strerror_r" = xyes; then : ac_have_decl=1 else ac_have_decl=0 @@ -4525,7 +4773,7 @@ _ACEOF for ac_func in strerror_r do : ac_fn_c_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r" -if test "x$ac_cv_func_strerror_r" = x""yes; then : +if test "x$ac_cv_func_strerror_r" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRERROR_R 1 _ACEOF @@ -4535,7 +4783,7 @@ done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5 $as_echo_n "checking whether strerror_r returns char *... " >&6; } -if test "${ac_cv_func_strerror_r_char_p+set}" = set; then : +if ${ac_cv_func_strerror_r_char_p+:} false; then : $as_echo_n "(cached) " >&6 else @@ -4616,59 +4864,61 @@ fi done -# local interface support -# Check whether --enable-local-interface was given. -if test "${enable_local_interface+set}" = set; then : - enableval=$enable_local_interface; local=true +# SML support +# Check whether --enable-sml was given. +if test "${enable_sml+set}" = set; then : + enableval=$enable_sml; sml=true else - local=false + sml=false fi - if test x$local = xtrue; then - LOCAL_TRUE= - LOCAL_FALSE='#' + if test x"$sml" = x"true"; then + SML_SUPPORT_TRUE= + SML_SUPPORT_FALSE='#' else - LOCAL_TRUE='#' - LOCAL_FALSE= + SML_SUPPORT_TRUE='#' + SML_SUPPORT_FALSE= fi -if test x"$local" = x"true"; then +if test x"$sml" = x"true"; then -$as_echo "#define LOCAL /**/" >>confdefs.h +$as_echo "#define SML_SUPPORT /**/" >>confdefs.h pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_LOCAL" >&5 -$as_echo_n "checking for DEPS_LOCAL... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_SML" >&5 +$as_echo_n "checking for DEPS_SML... " >&6; } -if test -n "$DEPS_LOCAL_CFLAGS"; then - pkg_cv_DEPS_LOCAL_CFLAGS="$DEPS_LOCAL_CFLAGS" +if test -n "$DEPS_SML_CFLAGS"; then + pkg_cv_DEPS_SML_CFLAGS="$DEPS_SML_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.9.3\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.9.3") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sml >= 0.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sml >= 0.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_DEPS_LOCAL_CFLAGS=`$PKG_CONFIG --cflags "libmicrohttpd >= 0.9.3" 2>/dev/null` + pkg_cv_DEPS_SML_CFLAGS=`$PKG_CONFIG --cflags "sml >= 0.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi -if test -n "$DEPS_LOCAL_LIBS"; then - pkg_cv_DEPS_LOCAL_LIBS="$DEPS_LOCAL_LIBS" +if test -n "$DEPS_SML_LIBS"; then + pkg_cv_DEPS_SML_LIBS="$DEPS_SML_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.9.3\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.9.3") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sml >= 0.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "sml >= 0.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_DEPS_LOCAL_LIBS=`$PKG_CONFIG --libs "libmicrohttpd >= 0.9.3" 2>/dev/null` + pkg_cv_DEPS_SML_LIBS=`$PKG_CONFIG --libs "sml >= 0.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi @@ -4688,9 +4938,124 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - DEPS_LOCAL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libmicrohttpd >= 0.9.3" 2>&1` + DEPS_SML_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sml >= 0.1" 2>&1` else - DEPS_LOCAL_PKG_ERRORS=`$PKG_CONFIG --print-errors "libmicrohttpd >= 0.9.3" 2>&1` + DEPS_SML_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sml >= 0.1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$DEPS_SML_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (sml >= 0.1) were not met: + +$DEPS_SML_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables DEPS_SML_CFLAGS +and DEPS_SML_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables DEPS_SML_CFLAGS +and DEPS_SML_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see . +See \`config.log' for more details" "$LINENO" 5; } +else + DEPS_SML_CFLAGS=$pkg_cv_DEPS_SML_CFLAGS + DEPS_SML_LIBS=$pkg_cv_DEPS_SML_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi +fi + +# local interface support +# Check whether --enable-local was given. +if test "${enable_local+set}" = set; then : + enableval=$enable_local; local=true +else + local=false + +fi + + + if test x"$local" = x"true"; then + LOCAL_SUPPORT_TRUE= + LOCAL_SUPPORT_FALSE='#' +else + LOCAL_SUPPORT_TRUE='#' + LOCAL_SUPPORT_FALSE= +fi + +if test x"$local" = x"true"; then + +$as_echo "#define LOCAL_SUPPORT /**/" >>confdefs.h + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_LOCAL" >&5 +$as_echo_n "checking for DEPS_LOCAL... " >&6; } + +if test -n "$DEPS_LOCAL_CFLAGS"; then + pkg_cv_DEPS_LOCAL_CFLAGS="$DEPS_LOCAL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.9.3\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.9.3") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DEPS_LOCAL_CFLAGS=`$PKG_CONFIG --cflags "libmicrohttpd >= 0.9.3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$DEPS_LOCAL_LIBS"; then + pkg_cv_DEPS_LOCAL_LIBS="$DEPS_LOCAL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.9.3\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.9.3") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_DEPS_LOCAL_LIBS=`$PKG_CONFIG --libs "libmicrohttpd >= 0.9.3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + DEPS_LOCAL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libmicrohttpd >= 0.9.3" 2>&1` + else + DEPS_LOCAL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libmicrohttpd >= 0.9.3" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$DEPS_LOCAL_PKG_ERRORS" >&5 @@ -4719,7 +5084,7 @@ and DEPS_LOCAL_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5 ; } +See \`config.log' for more details" "$LINENO" 5; } else DEPS_LOCAL_CFLAGS=$pkg_cv_DEPS_LOCAL_CFLAGS DEPS_LOCAL_LIBS=$pkg_cv_DEPS_LOCAL_LIBS @@ -4812,10 +5177,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then - test "x$cache_file" != "x/dev/null" && + if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} - cat confcache >$cache_file + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} @@ -4862,12 +5238,16 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${LOCAL_TRUE}" && test -z "${LOCAL_FALSE}"; then - as_fn_error $? "conditional \"LOCAL\" was never defined. +if test -z "${SML_SUPPORT_TRUE}" && test -z "${SML_SUPPORT_FALSE}"; then + as_fn_error $? "conditional \"SML_SUPPORT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${LOCAL_SUPPORT_TRUE}" && test -z "${LOCAL_SUPPORT_FALSE}"; then + as_fn_error $? "conditional \"LOCAL_SUPPORT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -: ${CONFIG_STATUS=./config.status} +: "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" @@ -4968,6 +5348,7 @@ fi IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. +as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5275,7 +5656,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by vzlogger $as_me 0.2, which was -generated by GNU Autoconf 2.67. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -5341,7 +5722,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ vzlogger config.status 0.2 -configured by $0, generated by GNU Autoconf 2.67, +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. @@ -5471,11 +5852,13 @@ do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "bin/reader/Makefile") CONFIG_FILES="$CONFIG_FILES bin/reader/Makefile" ;; + "bin/vzlogger/Makefile") CONFIG_FILES="$CONFIG_FILES bin/vzlogger/Makefile" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done @@ -5498,9 +5881,10 @@ fi # after its creation but before its name has been assigned to `$tmp'. $debug || { - tmp= + tmp= ac_tmp= trap 'exit_status=$? - { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } @@ -5508,12 +5892,13 @@ $debug || { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. @@ -5535,7 +5920,7 @@ else ac_cs_awk_cr=$ac_cr fi -echo 'BEGIN {' >"$tmp/subs1.awk" && +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF @@ -5563,7 +5948,7 @@ done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h @@ -5611,7 +5996,7 @@ t delim rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK -cat >>"\$tmp/subs1.awk" <<_ACAWK && +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" @@ -5643,7 +6028,7 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat -fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF @@ -5677,7 +6062,7 @@ fi # test -n "$CONFIG_FILES" # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then -cat >"$tmp/defines.awk" <<\_ACAWK || +cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF @@ -5689,8 +6074,8 @@ _ACEOF # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do - ac_t=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_t"; then + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 @@ -5791,7 +6176,7 @@ do esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -5810,7 +6195,7 @@ do for ac_f do case $ac_f in - -) ac_f="$tmp/stdin";; + -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. @@ -5819,7 +6204,7 @@ do [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" @@ -5845,8 +6230,8 @@ $as_echo "$as_me: creating $ac_file" >&6;} esac case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac @@ -5982,21 +6367,22 @@ s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} - rm -f "$tmp/stdin" + rm -f "$ac_tmp/stdin" case $ac_file in - -) cat "$tmp/out" && rm -f "$tmp/out";; - *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; @@ -6007,20 +6393,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" - } >"$tmp/config.h" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" - mv "$tmp/config.h" "$ac_file" \ + mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. diff --git a/configure.ac b/configure.ac index 110af2d..0da8656 100644 --- a/configure.ac +++ b/configure.ac @@ -4,15 +4,26 @@ AC_PREREQ([2.67]) AC_INIT([vzlogger], [0.2], [http://bugs.volkszaehler.org]) AM_INIT_AUTOMAKE(vzlogger, 0.2) -AC_CONFIG_SRCDIR([src/main.c]) +AC_CONFIG_SRCDIR([src/meter.c]) AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([Makefile src/Makefile docs/Makefile]) +AC_CONFIG_FILES([Makefile + docs/Makefile + src/Makefile + bin/reader/Makefile + bin/vzlogger/Makefile + ]) # Checks for programs. AC_PROG_CC +# We want to build a lib +AC_PROG_RANLIB + +# We use per target compiler flags +AM_PROG_CC_C_O + # Checks for libraries. -PKG_CHECK_MODULES([DEPS], [json >= 0.9 libcurl >= 7.21.0]) +PKG_CHECK_MODULES([DEPS_VZ], [json >= 0.9 libcurl >= 7.21.0]) # Checks for header files. AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h termios.h unistd.h]) @@ -27,17 +38,31 @@ AC_FUNC_REALLOC AC_FUNC_STRERROR_R AC_CHECK_FUNCS([gettimeofday memset sqrt strchr strtol]) +# SML support +AC_ARG_ENABLE( + [sml], + [AS_HELP_STRING([--enable-sml], [enable support for smart messaging language (def=no)])], + [sml=true], + [sml=false] +) + +AM_CONDITIONAL([SML_SUPPORT], [test x"$sml" = x"true"]) +if test x"$sml" = x"true"; then + AC_DEFINE([SML_SUPPORT], [], [Smart Messaging Language]) + PKG_CHECK_MODULES([DEPS_SML], [sml >= 0.1]) +fi + # local interface support AC_ARG_ENABLE( - [local-interface], + [local], [AS_HELP_STRING([--enable-local], [enable support for local HTTPd (def=no)])], [local=true], [local=false] ) -AM_CONDITIONAL([LOCAL], [test x$local = xtrue]) +AM_CONDITIONAL([LOCAL_SUPPORT], [test x"$local" = x"true"]) if test x"$local" = x"true"; then - AC_DEFINE([LOCAL],[],[Local interface]) + AC_DEFINE([LOCAL_SUPPORT], [], [Local interface]) PKG_CHECK_MODULES([DEPS_LOCAL], [libmicrohttpd >= 0.9.3]) fi diff --git a/docs/Makefile b/docs/Makefile index 9a024f1..50d92b5 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -83,10 +83,12 @@ CPPFLAGS = CYGPATH_W = echo DEFS = -DHAVE_CONFIG_H DEPDIR = .deps -DEPS_CFLAGS = -I/usr/include/json -DEPS_LIBS = -ljson -lcurl DEPS_LOCAL_CFLAGS = DEPS_LOCAL_LIBS = +DEPS_SML_CFLAGS = -I/usr/include/sml -I/usr/include/uuid +DEPS_SML_LIBS = -lsml -luuid +DEPS_VZ_CFLAGS = -I/usr/include/json +DEPS_VZ_LIBS = -ljson -lcurl ECHO_C = ECHO_N = -n ECHO_T = @@ -116,6 +118,7 @@ PATH_SEPARATOR = : PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = +RANLIB = ranlib SET_MAKE = SHELL = /bin/bash STRIP = diff --git a/etc/vzlogger.conf b/etc/vzlogger.conf index c228748..7c6f896 100644 --- a/etc/vzlogger.conf +++ b/etc/vzlogger.conf @@ -2,9 +2,13 @@ ; use tabs, spaces as delimiter ; use ; to introduce a comment -;prot intval uuid middleware options -1wire 10 371dd700-beb3-11e0-8dda-b961518a06f4 http://demo.volkszaehler.org/middleware.php /mnt/1wire/10.12E6D3000800/temperature -;obis 10 ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 http://volkszaehler.org/demo/middleware.php /dev/ttyS0 -;rawS0 10 27a1b4c0-8f8a-11e0-ad82-db6efbc4ba2e http://volkszaehler.org/demo/middleware.php /dev/ttyUSB2 -random 5 e4ff8f70-9f79-11e0-b44c-d1ce78df8288 http://localhost/workspace/volkszaehler.org/htdocs/middleware 40 +;prot middleware uuid intval options +;1wire http://demo.volkszaehler.org/middleware.php 371dd700-beb3-11e0-8dda-b961518a06f4 10 /mnt/1wire/10.12E6D3000800/temperature +;obis http://volkszaehler.org/demo/middleware.php ef0e9adf-cd9e-4d9a-92c5-b4fb4c89ff98 10 /dev/ttyS0 +;rawS0 http://volkszaehler.org/demo/middleware.php 27a1b4c0-8f8a-11e0-ad82-db6efbc4ba2e 10 /dev/ttyUSB2 +;random http://localhost/workspace/volkszaehler.org/volkszaehler.org/htdocs/middleware fde8f1d0-c5d0-11e0-856e-f9e4360ced10 5 40 +sml http://localhost/workspace/volkszaehler.org/volkszaehler.org/htdocs/middleware c853d890-daf3-11e0-86c4-875e5bd610cf 76h9vv5835w5.dyndns.info:7331:power +;sml http://localhost/workspace/volkszaehler.org/volkszaehler.org/htdocs/middleware 5584d3e0-daf5-11e0-a1c8-3930962bdbf4 76h9vv5835w5.dyndns.info:7331:power-l1 +;sml http://localhost/workspace/volkszaehler.org/volkszaehler.org/htdocs/middleware 6d17cd80-daf5-11e0-916c-bfb24b4b6f01 76h9vv5835w5.dyndns.info:7331:power-l2 +;sml http://localhost/workspace/volkszaehler.org/volkszaehler.org/htdocs/middleware 78c09290-daf5-11e0-81e9-2f2eb65081d7 76h9vv5835w5.dyndns.info:7331:power-l3 diff --git a/src/protocols/obis.h b/include/d0.h similarity index 72% rename from src/protocols/obis.h rename to include/d0.h index ac511a4..669d0bf 100644 --- a/src/protocols/obis.h +++ b/include/d0.h @@ -1,8 +1,8 @@ /** - * OBIS protocol parser + * Plaintext protocol according to DIN EN 62056-21 * - * This is our example protocol. Use this skeleton to add your own - * protocols and meters. + * This protocol uses OBIS to identify the readout data + * And is also sometimes called "D0" * * @package vzlogger * @copyright Copyright (c) 2011, The volkszaehler.org project @@ -26,20 +26,20 @@ * along with volkszaehler.org. If not, see . */ -#ifndef _OBIS_H_ -#define _OBIS_H_ +#ifndef _D0_H_ +#define _D0_H_ #include -#include "../protocol.h" +#include "reading.h" typedef struct { int fd; /* file descriptor of port */ struct termios oldtio; /* required to reset port */ -} obis_state_t; +} meter_handle_d0_t; -void * obis_init(char *port); -void obis_close(void *handle); -reading_t obis_get(void *handle); +int meter_d0_open(meter_handle_d0_t *handle, char *options); +void meter_d0_close(meter_handle_d0_t *handle); +meter_reading_t meter_d0_read(meter_handle_d0_t *handle); -#endif /* _OBIS_H_ */ +#endif /* _D0_H_ */ diff --git a/include/meter.h b/include/meter.h new file mode 100644 index 0000000..e815a1b --- /dev/null +++ b/include/meter.h @@ -0,0 +1,90 @@ +/** + * Protocol interface + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _METER_H_ +#define _METER_H_ + +/** + * We have 2 diffrent protocol types: + * - SENSOR: a readout is triggered in equidistant intervals by calling + * the read function with an POSIX timer. + * The interval is set in the configuration. + * - METER: the meter itselfs triggers a readout. + * The pointer to the read function shoul be NULL. + * The 'interval' column in the configuration as no meaning. + */ + +#include "../config.h" +#include "reading.h" + +/* meter types */ +#include "random.h" +#include "s0.h" +#include "d0.h" +#include "onewire.h" +#ifdef SML_SUPPORT +#include "sml.h" +#endif /* SML_SUPPORT */ + +typedef enum { + S0, + D0, + ONEWIRE, + RANDOM, +#ifdef SML_SUPPORT + SML +#endif /* SML_SUPPORT */ +} meter_tag_t; + +typedef struct { + meter_tag_t tag; + char *name; /* short identifier for protocol */ + char *desc; /* more detailed description */ + int periodical:1; /* does this meter has be triggered periodically? */ +} meter_type_t; + +typedef struct { + meter_type_t *type; + char *options; + union { + meter_handle_s0_t s0; + meter_handle_d0_t d0; + meter_handle_onewire_t onewire; + meter_handle_random_t random; +#ifdef SML_SUPPORT + meter_handle_sml_t sml; +#endif /* SML_SUPPORT */ + } handle; +} meter_t; + +/* prototypes */ +void meter_init(meter_t *meter, meter_type_t *type, char *options); +void meter_free(meter_t *meter); +meter_reading_t meter_read(meter_t *meter); + +int meter_open(meter_t *meter); +void meter_close(meter_t *meter); + +#endif /* _METER_H_ */ diff --git a/include/obis.h b/include/obis.h new file mode 100644 index 0000000..a044bd8 --- /dev/null +++ b/include/obis.h @@ -0,0 +1,118 @@ +/** + * OBIS IDs as specified in DIN EN 62056-61 + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _OBIS_H_ +#define _OBIS_H_ + +#include + +typedef enum { + ABSTRACT = 0, + ELECTRIC = 1, + HEAT_COST = 4, + COOLING = 5, + HEATING = 6, + GAS = 7, + WATER_COLD = 8, + WATER_HOT = 9 +} obis_media_t; + +typedef union { + enum { + GENERAL_PURPOSE = 0, + ACTIVE_POWER_IN = 1, + ACTIVE_POWER_OUT = 2, + REACTIVE_POWER_IN = 3, + REACTIVE_POWER_OUT = 4, + REACTIVE_POWER_Q1 = 5, + REACTIVE_POWER_Q2 = 6, + REACTIVE_POWER_Q3 = 7, + REACTIVE_POWER_Q4 = 8, + APPARENT_POWER_IN = 9, + APPARENT_POWER_OUT = 10, + CURRENT_ANY = 11, + VOLTAGE_ANY = 12, + POWER_FACTOR_OUT = 13, + SUPPLY_FREQUENCY = 14, + ACTIVE_POWER_Q1 = 17, + ACTIVE_POWER_Q2 = 18, + ACTIVE_POWER_Q3 = 19, + ACTIVE_POWER_Q4 = 20, + + L1_ACTIVE_POWER_INT = 21, + L1_ACTIVE_POWER_OUT = 22, + + ANGLES = 81, + UNITLESS = 82, + LOSS = 83, + + L1_POWER_FACTOR_OUT = 85, + L2_POWER_FACTOR_OUT = 86, + L3_POWER_FACTOR_OUT = 87, + + AMPERE_SQUARE_HOURS = 88, + VOLT_SQUARE_HOURS = 89, + + SERVICE = 96, + ERROR = 97, + LIST = 98, + DATA_PROFILE = 99 + + } electric; + + int gas; /* as defined in DIN EN 13757-1 */ +} obis_indicator_t; + +/* regex: A-BB:CC.DD.EE(*FF)? */ +typedef union { + unsigned char raw[6]; + struct { + unsigned char media; + unsigned char channel; + unsigned char indicator; + unsigned char mode; + unsigned char quantities; + unsigned char storage; /* not used in Germany */ + } groups; +} obis_id_t; + +typedef struct { + obis_id_t id; + char *name; + char *desc; +} obis_alias_t; + +/* prototypes */ +obis_id_t obis_init(unsigned char *raw); +obis_id_t obis_parse(char *str); +int obis_unparse(obis_id_t id, char *buffer); +char obis_is_manufacturer_specific(obis_id_t id); + +/* inline functions */ +inline int obis_compare(obis_id_t a, obis_id_t b) { + return memcmp(&a, &b, sizeof(obis_id_t)); +} + +#endif /* _OBIS_H_ */ diff --git a/include/onewire.h b/include/onewire.h new file mode 100644 index 0000000..7b03585 --- /dev/null +++ b/include/onewire.h @@ -0,0 +1,41 @@ +/** + * Wrapper to read Dallas 1-wire Sensors via the 1-wire Filesystem (owfs) + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _ONEWIRE_H_ +#define _ONEWIRE_H_ + +#include + +#include "reading.h" + +typedef struct { + FILE *file; +} meter_handle_onewire_t; + +int meter_onewire_open(meter_handle_onewire_t *handle, char *options); +void meter_onewire_close(meter_handle_onewire_t *handle); +meter_reading_t meter_onewire_read(meter_handle_onewire_t *handle); + +#endif /* _ONEWIRE_H_ */ diff --git a/include/random.h b/include/random.h new file mode 100644 index 0000000..dab1aa9 --- /dev/null +++ b/include/random.h @@ -0,0 +1,41 @@ +/** + * Generate pseudo random data series by a random walk + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#ifndef _RANDOM_H_ +#define _RANDOM_H_ + +#include "reading.h" + +typedef struct { + double min, max, last; +} meter_handle_random_t; + +double ltqnorm(double p); /* forward declaration */ + +int meter_random_open(meter_handle_random_t *handle, char *options); +void meter_random_close(meter_handle_random_t *handle); +meter_reading_t meter_random_read(meter_handle_random_t *handle); + +#endif /* _RANDOM_H_ */ diff --git a/src/protocols/1wire.h b/include/reading.h similarity index 77% rename from src/protocols/1wire.h rename to include/reading.h index 32749af..b4b75ec 100644 --- a/src/protocols/1wire.h +++ b/include/reading.h @@ -1,5 +1,5 @@ /** - * Wrapper to read Dallas 1-wire Sensors via the 1-wire Filesystem (owfs) + * Meter readings * * @package vzlogger * @copyright Copyright (c) 2011, The volkszaehler.org project @@ -22,14 +22,17 @@ * You should have received a copy of the GNU General Public License * along with volkszaehler.org. If not, see . */ - -#ifndef _1WIRE_H_ -#define _1WIRE_H_ -#include "../protocol.h" +#ifndef _READING_H_ +#define _READING_H_ -void * onewire_init(char *port); -void onewire_close(void *handle); -reading_t onewire_get(void *handle); +#include -#endif /* _1WIRE_H_ */ +typedef struct meter_reading { + float value; + struct timeval tv; + + struct meter_reading *next, *prev; /* pointers for linked list */ +} meter_reading_t; + +#endif /* _READING_H_ */ diff --git a/src/protocols/rawS0.h b/include/s0.h similarity index 80% rename from src/protocols/rawS0.h rename to include/s0.h index fc1f6f5..85eaa06 100644 --- a/src/protocols/rawS0.h +++ b/include/s0.h @@ -23,20 +23,20 @@ * along with volkszaehler.org. If not, see . */ -#ifndef _RAWS0_H_ -#define _RAWS0_H_ +#ifndef _S0_H_ +#define _S0_H_ #include -#include "../protocol.h" +#include "reading.h" typedef struct { int fd; /* file descriptor of port */ struct termios oldtio; /* required to reset port */ -} rawS0_state_t; +} meter_handle_s0_t; -void * rawS0_init(char *port); -void rawS0_close(void *handle); -reading_t rawS0_get(void *handle); +int meter_s0_open(meter_handle_s0_t *handle, char *options); +void meter_s0_close(meter_handle_s0_t *handle); +meter_reading_t meter_s0_read(meter_handle_s0_t *handle); -#endif /* _RAWS0_H_ */ +#endif /* _S0_H_ */ diff --git a/src/protocols/sml.h b/include/sml.h similarity index 68% rename from src/protocols/sml.h rename to include/sml.h index fcfe3dd..d29494a 100644 --- a/src/protocols/sml.h +++ b/include/sml.h @@ -30,17 +30,27 @@ #ifndef _SML_H_ #define _SML_H_ -#include "../protocol.h" +#define SML_BUFFER_LEN 8096 + +#include + +#include "reading.h" +#include "obis.h" typedef struct { int fd; + obis_id_t id; /* which OBIS we want to log */ + float counter; /* Zählerstand */ // termios etc.. -} sml_state_t; +} meter_handle_sml_t; -void * sml_init(char *port); -void sml_close(void *handle); -reading_t sml_get(void *handle); -int sml_open_port(char *device); -void sml_transport_receiver(unsigned char *buffer, size_t buffer_len); +int meter_sml_open(meter_handle_sml_t *handle, char *options); +void meter_sml_close(meter_handle_sml_t *handle); +meter_reading_t meter_sml_read(meter_handle_sml_t *handle); + +meter_reading_t meter_sml_parse(sml_file *file, obis_id_t which); + +int meter_sml_open_port(char *device); +int meter_sml_open_socket(char *node, char *service); #endif /* _SML_H_ */ diff --git a/include/unit.h b/include/unit.h new file mode 100644 index 0000000..16e5f24 --- /dev/null +++ b/include/unit.h @@ -0,0 +1,115 @@ +/** + * DLMS Units as specified in ISO EN 62056-62 and used by SML + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +typedef struct { + char code; + char *unit; +} dlms_unit_t; + +/** + * Static lookup table + */ +dlms_unit_t dlms_units[] = { +// code, unit // Quantity Unit name SI definition (comment) +//===================================================================================================== +{1, "a"}, // time year 52*7*24*60*60 s +{2, "mo"}, // time month 31*24*60*60 s +{3, "wk"}, // time week 7*24*60*60 s +{4, "d"}, // time day 24*60*60 s +{5, "h"}, // time hour 60*60 s +{6, "min."}, // time min 60 s +{7, "s"}, // time (t) second s +{8, "°"}, // (phase) angle degree rad*180/π +{9, "°C"}, // temperature (T) degree celsius K-273.15 +{10, "currency"}, // (local) currency +{11, "m"}, // length (l) metre m +{12, "m/s"}, // speed (v) metre per second m/s +{13, "m³"}, // volume (V) cubic metre m³ +{14, "m³"}, // corrected volume cubic metre m³ +{15, "m³/h"}, // volume flux cubic metre per hour m³/(60*60s) +{16, "m³/h"}, // corrected volume flux cubic metre per hour m³/(60*60s) +{17, "m³/d"}, // volume flux m³/(24*60*60s) +{18, "m³/d"}, // corrected volume flux m³/(24*60*60s) +{19, "l"}, // volume litre 10-3 m³ +{20, "kg"}, // mass (m) kilogram +{21, "N"}, // force (F) newton +{22, "Nm"}, // energy newtonmeter J = Nm = Ws +{23, "Pa"}, // pressure (p) pascal N/m² +{24, "bar"}, // pressure (p) bar 10⁵ N/m² +{25, "J"}, // energy joule J = Nm = Ws +{26, "J/h"}, // thermal power joule per hour J/(60*60s) +{27, "W"}, // active power (P) watt W = J/s +{28, "VA"}, // apparent power (S) volt-ampere +{29, "var"}, // reactive power (Q) var +{30, "Wh"}, // active energy watt-hour W*(60*60s) +{31, "VAh"}, // apparent energy volt-ampere-hour VA*(60*60s) +{32, "varh"}, // reactive energy var-hour var*(60*60s) +{33, "A"}, // current (I) ampere A +{34, "C"}, // electrical charge (Q) coulomb C = As +{35, "V"}, // voltage (U) volt V +{36, "V/m"}, // electr. field strength (E) volt per metre +{37, "F"}, // capacitance (C) farad C/V = As/V +{38, "Ω"}, // resistance (R) ohm Ω = V/A +{39, "Ωm²/m"}, // resistivity (ρ) Ωm +{40, "Wb"}, // magnetic flux (Φ) weber Wb = Vs +{41, "T"}, // magnetic flux density (B) tesla Wb/m2 +{42, "A/m"}, // magnetic field strength (H) ampere per metre A/m +{43, "H"}, // inductance (L) henry H = Wb/A +{44, "Hz"}, // frequency (f, ω) hertz 1/s +{45, "1/(Wh)"}, // R_W (Active energy meter constant or pulse value) +{46, "1/(varh)"}, // R_B (reactive energy meter constant or pulse value) +{47, "1/(VAh)"}, // R_S (apparent energy meter constant or pulse value) +{48, "V²h"}, // volt-squared hour volt-squaredhours V²(60*60s) +{49, "A²h"}, // ampere-squared hour ampere-squaredhours A²(60*60s) +{50, "kg/s"}, // mass flux kilogram per second kg/s +{51, "S, mho"}, // conductance siemens 1/Ω +{52, "K"}, // temperature (T) kelvin +{53, "1/(V²h)"}, // R_U²h (Volt-squared hour meter constant or pulse value) +{54, "1/(A²h)"}, // R_I²h (Ampere-squared hour meter constant or pulse value) +{55, "1/m³"}, // R_V, meter constant or pulse value (volume) +{56, "%"}, // percentage % +{57, "Ah"}, // ampere-hours ampere-hour +{60, "Wh/m³"}, // energy per volume 3,6*103 J/m³ +{61, "J/m³"}, // calorific value, wobbe +{62, "Mol %"}, // molar fraction of mole percent (Basic gas composition unit) + // gas composition +{63, "g/m³"}, // mass density, quantity of material (Gas analysis, accompanying elements) +{64, "Pa s"}, // dynamic viscosity pascal second (Characteristic of gas stream) +{253, "(reserved)"}, // reserved +{254, "(other)"}, // other unit +{255, "(unitless)"}, // no unit, unitless, count +{} // stop condition for iterator +}; + +char * dlms_get_unit(unsigned char code) { + dlms_unit_t *it = dlms_units; + do { /* linear search */ + if (it->code == code) { + return it->unit; + } + } while ((++it)->code); + + return NULL; /* not found */ +} diff --git a/src/Makefile b/src/Makefile index ff15e28..4e3b592 100644 --- a/src/Makefile +++ b/src/Makefile @@ -32,10 +32,12 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -bin_PROGRAMS = vzlogger$(EXEEXT) -#am__append_1 = local.c -#am__append_2 = $(DEPS_LOCAL_LIBS) -#am__append_3 = $(DEPS_LOCAL_CFLAGS) +#libobis_a_HEADERS = obis.h + +# SML support +#################################################################### +am__append_1 = sml.c +am__append_2 = $(DEPS_SML_CFLAGS) subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -46,20 +48,22 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" -PROGRAMS = $(bin_PROGRAMS) -am__vzlogger_SOURCES_DIST = main.c buffer.c api.c channel.c ltqnorm.c \ - options.c protocols/onewire.c protocols/din62056.c \ - protocols/rawS0.c protocols/random.c local.c -#am__objects_1 = local.$(OBJEXT) -am_vzlogger_OBJECTS = main.$(OBJEXT) buffer.$(OBJEXT) api.$(OBJEXT) \ - channel.$(OBJEXT) ltqnorm.$(OBJEXT) options.$(OBJEXT) \ - onewire.$(OBJEXT) din62056.$(OBJEXT) rawS0.$(OBJEXT) \ - random.$(OBJEXT) $(am__objects_1) -vzlogger_OBJECTS = $(am_vzlogger_OBJECTS) -am__DEPENDENCIES_1 = -#am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) -vzlogger_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +LIBRARIES = $(noinst_LIBRARIES) +AR = ar +ARFLAGS = cru +libmeter_a_AR = $(AR) $(ARFLAGS) +libmeter_a_DEPENDENCIES = libobis.a +am__libmeter_a_SOURCES_DIST = meter.c d0.c s0.c random.c onewire.c \ + ltqnorm.c sml.c +am__objects_1 = sml.$(OBJEXT) +am_libmeter_a_OBJECTS = meter.$(OBJEXT) d0.$(OBJEXT) s0.$(OBJEXT) \ + random.$(OBJEXT) onewire.$(OBJEXT) ltqnorm.$(OBJEXT) \ + $(am__objects_1) +libmeter_a_OBJECTS = $(am_libmeter_a_OBJECTS) +libobis_a_AR = $(AR) $(ARFLAGS) +libobis_a_LIBADD = +am_libobis_a_OBJECTS = obis.$(OBJEXT) +libobis_a_OBJECTS = $(am_libobis_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -68,8 +72,8 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(vzlogger_SOURCES) -DIST_SOURCES = $(am__vzlogger_SOURCES_DIST) +SOURCES = $(libmeter_a_SOURCES) $(libobis_a_SOURCES) +DIST_SOURCES = $(am__libmeter_a_SOURCES_DIST) $(libobis_a_SOURCES) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -87,10 +91,12 @@ CPPFLAGS = CYGPATH_W = echo DEFS = -DHAVE_CONFIG_H DEPDIR = .deps -DEPS_CFLAGS = -I/usr/include/json -DEPS_LIBS = -ljson -lcurl DEPS_LOCAL_CFLAGS = DEPS_LOCAL_LIBS = +DEPS_SML_CFLAGS = -I/usr/include/sml -I/usr/include/uuid +DEPS_SML_LIBS = -lsml -luuid +DEPS_VZ_CFLAGS = -I/usr/include/json +DEPS_VZ_LIBS = -ljson -lcurl ECHO_C = ECHO_N = -n ECHO_T = @@ -120,6 +126,7 @@ PATH_SEPARATOR = : PKG_CONFIG = /usr/bin/pkg-config PKG_CONFIG_LIBDIR = PKG_CONFIG_PATH = +RANLIB = ranlib SET_MAKE = SHELL = /bin/bash STRIP = @@ -166,15 +173,15 @@ target_alias = top_build_prefix = ../ top_builddir = .. top_srcdir = .. - -# what flags you want to pass to the C compiler & linker -AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 $(DEPS_CFLAGS) \ - $(am__append_3) +AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 $(am__append_2) +AM_CPPFLAGS = -I$(top_srcdir)/include AM_LDFLAGS = -vzlogger_SOURCES = main.c buffer.c api.c channel.c ltqnorm.c options.c \ - protocols/onewire.c protocols/din62056.c protocols/rawS0.c \ - protocols/random.c $(am__append_1) -vzlogger_LDADD = -lpthread -lm $(DEPS_LIBS) $(am__append_2) +noinst_LIBRARIES = libmeter.a libobis.a +libmeter_a_SOURCES = meter.c d0.c s0.c random.c onewire.c ltqnorm.c \ + $(am__append_1) +#libmeter_a_HEADERS = meter.h +libobis_a_SOURCES = obis.c +libmeter_a_LIBADD = libobis.a all: all-am .SUFFIXES: @@ -209,46 +216,17 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -vzlogger$(EXEEXT): $(vzlogger_OBJECTS) $(vzlogger_DEPENDENCIES) - @rm -f vzlogger$(EXEEXT) - $(LINK) $(vzlogger_OBJECTS) $(vzlogger_LDADD) $(LIBS) +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libmeter.a: $(libmeter_a_OBJECTS) $(libmeter_a_DEPENDENCIES) + -rm -f libmeter.a + $(libmeter_a_AR) libmeter.a $(libmeter_a_OBJECTS) $(libmeter_a_LIBADD) + $(RANLIB) libmeter.a +libobis.a: $(libobis_a_OBJECTS) $(libobis_a_DEPENDENCIES) + -rm -f libobis.a + $(libobis_a_AR) libobis.a $(libobis_a_OBJECTS) $(libobis_a_LIBADD) + $(RANLIB) libobis.a mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -256,17 +234,14 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -include ./$(DEPDIR)/api.Po -include ./$(DEPDIR)/buffer.Po -include ./$(DEPDIR)/channel.Po -include ./$(DEPDIR)/din62056.Po -include ./$(DEPDIR)/local.Po +include ./$(DEPDIR)/d0.Po include ./$(DEPDIR)/ltqnorm.Po -include ./$(DEPDIR)/main.Po +include ./$(DEPDIR)/meter.Po +include ./$(DEPDIR)/obis.Po include ./$(DEPDIR)/onewire.Po -include ./$(DEPDIR)/options.Po include ./$(DEPDIR)/random.Po -include ./$(DEPDIR)/rawS0.Po +include ./$(DEPDIR)/s0.Po +include ./$(DEPDIR)/sml.Po .c.o: $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -282,62 +257,6 @@ include ./$(DEPDIR)/rawS0.Po # DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ # $(COMPILE) -c `$(CYGPATH_W) '$<'` -onewire.o: protocols/onewire.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT onewire.o -MD -MP -MF $(DEPDIR)/onewire.Tpo -c -o onewire.o `test -f 'protocols/onewire.c' || echo '$(srcdir)/'`protocols/onewire.c - $(am__mv) $(DEPDIR)/onewire.Tpo $(DEPDIR)/onewire.Po -# source='protocols/onewire.c' object='onewire.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o onewire.o `test -f 'protocols/onewire.c' || echo '$(srcdir)/'`protocols/onewire.c - -onewire.obj: protocols/onewire.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT onewire.obj -MD -MP -MF $(DEPDIR)/onewire.Tpo -c -o onewire.obj `if test -f 'protocols/onewire.c'; then $(CYGPATH_W) 'protocols/onewire.c'; else $(CYGPATH_W) '$(srcdir)/protocols/onewire.c'; fi` - $(am__mv) $(DEPDIR)/onewire.Tpo $(DEPDIR)/onewire.Po -# source='protocols/onewire.c' object='onewire.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o onewire.obj `if test -f 'protocols/onewire.c'; then $(CYGPATH_W) 'protocols/onewire.c'; else $(CYGPATH_W) '$(srcdir)/protocols/onewire.c'; fi` - -din62056.o: protocols/din62056.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT din62056.o -MD -MP -MF $(DEPDIR)/din62056.Tpo -c -o din62056.o `test -f 'protocols/din62056.c' || echo '$(srcdir)/'`protocols/din62056.c - $(am__mv) $(DEPDIR)/din62056.Tpo $(DEPDIR)/din62056.Po -# source='protocols/din62056.c' object='din62056.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o din62056.o `test -f 'protocols/din62056.c' || echo '$(srcdir)/'`protocols/din62056.c - -din62056.obj: protocols/din62056.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT din62056.obj -MD -MP -MF $(DEPDIR)/din62056.Tpo -c -o din62056.obj `if test -f 'protocols/din62056.c'; then $(CYGPATH_W) 'protocols/din62056.c'; else $(CYGPATH_W) '$(srcdir)/protocols/din62056.c'; fi` - $(am__mv) $(DEPDIR)/din62056.Tpo $(DEPDIR)/din62056.Po -# source='protocols/din62056.c' object='din62056.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o din62056.obj `if test -f 'protocols/din62056.c'; then $(CYGPATH_W) 'protocols/din62056.c'; else $(CYGPATH_W) '$(srcdir)/protocols/din62056.c'; fi` - -rawS0.o: protocols/rawS0.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rawS0.o -MD -MP -MF $(DEPDIR)/rawS0.Tpo -c -o rawS0.o `test -f 'protocols/rawS0.c' || echo '$(srcdir)/'`protocols/rawS0.c - $(am__mv) $(DEPDIR)/rawS0.Tpo $(DEPDIR)/rawS0.Po -# source='protocols/rawS0.c' object='rawS0.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rawS0.o `test -f 'protocols/rawS0.c' || echo '$(srcdir)/'`protocols/rawS0.c - -rawS0.obj: protocols/rawS0.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rawS0.obj -MD -MP -MF $(DEPDIR)/rawS0.Tpo -c -o rawS0.obj `if test -f 'protocols/rawS0.c'; then $(CYGPATH_W) 'protocols/rawS0.c'; else $(CYGPATH_W) '$(srcdir)/protocols/rawS0.c'; fi` - $(am__mv) $(DEPDIR)/rawS0.Tpo $(DEPDIR)/rawS0.Po -# source='protocols/rawS0.c' object='rawS0.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rawS0.obj `if test -f 'protocols/rawS0.c'; then $(CYGPATH_W) 'protocols/rawS0.c'; else $(CYGPATH_W) '$(srcdir)/protocols/rawS0.c'; fi` - -random.o: protocols/random.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT random.o -MD -MP -MF $(DEPDIR)/random.Tpo -c -o random.o `test -f 'protocols/random.c' || echo '$(srcdir)/'`protocols/random.c - $(am__mv) $(DEPDIR)/random.Tpo $(DEPDIR)/random.Po -# source='protocols/random.c' object='random.o' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o random.o `test -f 'protocols/random.c' || echo '$(srcdir)/'`protocols/random.c - -random.obj: protocols/random.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT random.obj -MD -MP -MF $(DEPDIR)/random.Tpo -c -o random.obj `if test -f 'protocols/random.c'; then $(CYGPATH_W) 'protocols/random.c'; else $(CYGPATH_W) '$(srcdir)/protocols/random.c'; fi` - $(am__mv) $(DEPDIR)/random.Tpo $(DEPDIR)/random.Po -# source='protocols/random.c' object='random.obj' libtool=no \ -# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ -# $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o random.obj `if test -f 'protocols/random.c'; then $(CYGPATH_W) 'protocols/random.c'; else $(CYGPATH_W) '$(srcdir)/protocols/random.c'; fi` - ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ @@ -422,11 +341,8 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(PROGRAMS) +all-am: Makefile $(LIBRARIES) installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done install: install-am install-exec: install-exec-am install-data: install-data-am @@ -454,7 +370,7 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -480,7 +396,7 @@ install-dvi: install-dvi-am install-dvi-am: -install-exec-am: install-binPROGRAMS +install-exec-am: install-html: install-html-am @@ -519,22 +435,22 @@ ps: ps-am ps-am: -uninstall-am: uninstall-binPROGRAMS +uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic ctags distclean distclean-compile \ +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ distclean-generic distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-binPROGRAMS \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS + uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/Makefile.am b/src/Makefile.am index 5a92aea..4d07c75 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,16 +1,19 @@ -# what flags you want to pass to the C compiler & linker -AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 $(DEPS_CFLAGS) +AM_CFLAGS = -Wall -D_REENTRANT -std=gnu99 +AM_CPPFLAGS = -I$(top_srcdir)/include AM_LDFLAGS = -# this lists the binaries to produce, the (non-PHONY, binary) targets in -# the previous manual Makefile -bin_PROGRAMS = vzlogger +noinst_LIBRARIES = libmeter.a libobis.a -vzlogger_SOURCES = main.c api.c queue.c ltqnorm.c protocols/1wire.c protocols/obis.c protocols/rawS0.c protocols/random.c -vzlogger_LDADD = -lpthread -lm $(DEPS_LIBS) +libmeter_a_SOURCES = meter.c d0.c s0.c random.c onewire.c ltqnorm.c +#libmeter_a_HEADERS = meter.h -if LOCAL -vzlogger_SOURCES += local.c -vzlogger_LDADD += $(DEPS_LOCAL_LIBS) -AM_CFLAGS += $(DEPS_LOCAL_CFLAGS) +libobis_a_SOURCES = obis.c +#libobis_a_HEADERS = obis.h + +# SML support +#################################################################### +if SML_SUPPORT +libmeter_a_SOURCES += sml.c +libmeter_a_LIBADD = libobis.a +AM_CFLAGS += $(DEPS_SML_CFLAGS) endif diff --git a/src/protocols/obis.c b/src/d0.c similarity index 75% rename from src/protocols/obis.c rename to src/d0.c index b49fa86..1690122 100644 --- a/src/protocols/obis.c +++ b/src/d0.c @@ -1,5 +1,7 @@ /** - * OBIS protocol parser + * Plaintext protocol according to DIN EN 62056-21 + * + * This protocol uses OBIS to identify the readout data * * This is our example protocol. Use this skeleton to add your own * protocols and meters. @@ -33,14 +35,21 @@ #include #include -#include "obis.h" +#include "../include/d0.h" -void * obis_init(char *port) { +int meter_d0_open(meter_handle_d0_t *handle, char *options) { struct termios tio; - int *fd = malloc(sizeof(int)); - memset(&tio, 0, sizeof(tio)); - + + /* open serial port */ + handle->fd = open(options, O_RDWR); // | O_NONBLOCK); + + if (handle->fd < 0) { + return -1; + } + + // TODO save oldtio + tio.c_iflag = 0; tio.c_oflag = 0; tio.c_cflag = CS7|CREAD|CLOCAL; // 7n1, see termios.h for more information @@ -48,26 +57,22 @@ void * obis_init(char *port) { tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 5; - *fd = open(port, O_RDWR); // | O_NONBLOCK); cfsetospeed(&tio, B9600); // 9600 baud cfsetispeed(&tio, B9600); // 9600 baud - - return (void *) fd; + + return 0; } -void obis_close(void *handle) { - int *fd = (int *) handle; - - close(*fd); - free(handle); +void meter_d0_close(meter_handle_d0_t *handle) { + close(handle->fd); } -reading_t obis_get(void *handle) { - reading_t rd; - +meter_reading_t meter_d0_read(meter_handle_d0_t *handle) { + meter_reading_t rd; + rd.value = 33.3334; gettimeofday(&rd.tv, NULL); - + return rd; } diff --git a/src/main.c b/src/main.c deleted file mode 100644 index 4ba3cb7..0000000 --- a/src/main.c +++ /dev/null @@ -1,464 +0,0 @@ -/** - * Main source file - * - * @package vzlogger - * @copyright Copyright (c) 2011, The volkszaehler.org project - * @license http://www.gnu.org/licenses/gpl.txt GNU Public License - * @author Steffen Vogel - */ -/* - * This file is part of volkzaehler.org - * - * volkzaehler.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * volkzaehler.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with volkszaehler.org. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef LOCAL -#include -#include "local.h" -#endif - -#include "main.h" -#include "queue.h" -#include "api.h" - -#include "protocols/obis.h" -#include "protocols/1wire.h" -#include "protocols/rawS0.h" -#include "protocols/random.h" - -/** - * List of available protocols - * incl. function pointers - */ -static protocol_t protocols[] = { - {"1wire", "Dallas 1-Wire sensors (via OWFS)", onewire_get, onewire_init, onewire_close, SENSOR}, -// {"obis", "Plaintext OBIS", obis_get, obis_init, obis_close, SENSOR}, - {"random", "Random walk", random_get, random_init, random_close, SENSOR}, - {"rawS0", "S0 on RS232", rawS0_get, rawS0_init, rawS0_close, METER}, -// {"sml", "Smart Meter Language", sml_get, sml_init, sml_close, SENSOR}, -// {"fluksousb", "FluksoUSB board", flukso_get, flukso_init, flukso_close, SENSOR}, - {NULL} /* stop condition for iterator */ -}; - - -/** - * Command line options - */ -static struct option long_options[] = { - {"config", required_argument, 0, 'c'}, - {"daemon", required_argument, 0, 'd'}, -#ifdef LOCAL - {"local", no_argument, 0, 'l'}, - {"local-port", required_argument, 0, 'p'}, -#endif /* LOCAL */ - {"verbose", optional_argument, 0, 'v'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, - {NULL} /* stop condition for iterator */ -}; - -/** - * Descriptions vor command line options - */ -static char *long_options_descs[] = { - "config file with channel -> uuid mapping", - "run as daemon", -#ifdef LOCAL - "activate local interface (tiny webserver)", - "TCP port for local interface", -#endif /* LOCAL */ - "enable verbose output", - "show this help", - "show version of vzlogger", - NULL /* stop condition for iterator */ -}; - -/* - * Global variables - */ -channel_t chans[MAX_CHANNELS]; // TODO use dynamic allocation -options_t opts = { /* setting default options */ - NULL, /* config file */ - 8080, /* port for local interface */ - 0, /* debug level / verbosity */ - FALSE, /* daemon mode */ - FALSE /* local interface */ -}; - -/** - * Print available options and some other usefull information - */ -void usage(char * argv[]) { - char ** desc = long_options_descs; - struct option * op = long_options; - protocol_t * prot = protocols; - - printf("Usage: %s [options]\n\n", argv[0]); - printf(" following options are available:\n"); - - while (op->name && desc) { - printf("\t-%c, --%-12s\t%s\n", op->val, op->name, *desc); - op++; - desc++; - } - - printf("\n"); - printf(" following protocol types are supported:\n"); - - while (prot->name) { - printf("\t%-12s\t%s\n", prot->name, prot->desc); - prot++; - } - - printf("\n%s - volkszaehler.org logging utility\n", PACKAGE_STRING); - printf("by Steffen Vogel \n"); - printf("send bugreports to %s\n", PACKAGE_BUGREPORT); -} - -/** - * Wrapper to log notices and errors - * - * @param ch could be NULL for general messages - * @todo integrate into syslog - */ -void print(int level, char * format, channel_t *ch, ... ) { - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - va_list args; - - struct timeval now; - struct tm * timeinfo; - char buffer[16]; - - if (level <= (signed int) opts.verbose) { - gettimeofday(&now, NULL); - timeinfo = localtime(&now.tv_sec); - - strftime(buffer, 16, "%b %d %H:%M:%S", timeinfo); - - pthread_mutex_lock(&mutex); - fprintf((level > 0) ? stdout : stderr, "[%s.%3lu]", buffer, now.tv_usec / 1000); - - if (ch != NULL) { - fprintf((level > 0) ? stdout : stderr, "[ch#%i]\t", ch->id); - } - else { - fprintf((level > 0) ? stdout : stderr, "\t\t"); - } - - va_start(args, ch); - vfprintf((level > 0) ? stdout : stderr, format, args); - va_end(args); - fprintf((level > 0) ? stdout : stderr, "\n"); - pthread_mutex_unlock(&mutex); - } -} - -/** - * Parse options from command line - */ -void parse_options(int argc, char * argv[], options_t * opts) { - while (TRUE) { - /* getopt_long stores the option index here. */ - int option_index = 0; - - int c = getopt_long(argc, argv, "i:c:p:lhVdv::", long_options, &option_index); - - /* detect the end of the options. */ - if (c == -1) - break; - - switch (c) { - case 'v': - opts->verbose = (optarg == NULL) ? 1 : atoi(optarg); - break; - - case 'l': - opts->local = TRUE; - break; - - case 'd': - opts->daemon = TRUE; - break; - - case 'p': /* port for local interface */ - opts->port = atoi(optarg); - break; - - case 'c': /* read config file */ - opts->config = (char *) malloc(strlen(optarg)+1); - strcpy(opts->config, optarg); - break; - - case 'V': - printf("%s\n", VERSION); - exit(EXIT_SUCCESS); - break; - - case 'h': - case '?': - usage(argv); - exit((c == '?') ? EXIT_FAILURE : EXIT_SUCCESS); - } - } - - if (opts->config == NULL) { /* search for config file */ - if (access("vzlogger.conf", R_OK) == 0) { - opts->config = "vzlogger.conf"; - } - else if (access("/etc/vzlogger.conf", R_OK) == 0) { - opts->config = "/etc/vzlogger.conf"; - } - else { /* search in home directory */ - char *home_config = malloc(255); - strcat(home_config, getenv("HOME")); /* get home dir */ - strcat(home_config, "/.vzlogger.conf"); /* append my filename */ - - if (access(home_config, R_OK) == 0) { - opts->config = home_config; - } - } - } -} - -int parse_channels(char *filename, channel_t *chans) { - FILE *file = fopen(filename, "r"); /* open configuration */ - - if (!filename) { /* nothing found */ - print(-1, "No config file found! Please specify with --config!\n", NULL); - exit(EXIT_FAILURE); - } - - if (file == NULL) { - perror(filename); /* why didn't the file open? */ - exit(EXIT_FAILURE); - } - else { - print(2, "Start parsing configuration from %s", NULL, filename); - } - - char line[256]; - int chan_num = 0, line_num = 1; - - while (chan_num < MAX_CHANNELS && fgets(line, sizeof line, file) != NULL) { /* read a line */ - if (line[0] == ';' || line[0] == '\n') continue; /* skip comments */ - - channel_t ch = { - chan_num, - NULL, - NULL, - NULL, - 0, - NULL, - protocols - }; - - char *tok = strtok(line, " \t"); - - for (int i = 0; i < 7 && tok != NULL; i++) { - size_t len = strlen(tok); - - switch(i) { - case 0: /* protocol */ - while (ch.prot->name && strcmp(ch.prot->name, tok) != 0) ch.prot++; /* linear search */ - - if (ch.prot == NULL) { - print(-1, "Invalid protocol: %s in %s:%i", NULL, tok, filename, line_num); - exit(EXIT_FAILURE); - } - break; - - case 1: /* interval */ - ch.interval = strtol(tok, (char **) NULL, 10); - - if (errno == EINVAL || errno == ERANGE) { - print(-1, "Invalid interval: %s in %s:%i", NULL, tok, filename, line_num); - exit(EXIT_FAILURE); - } - break; - - case 2: /* uuid */ - if (len == 0) { // TODO add uuid validation - print(-1, "Missing uuid in %s:%i", NULL, filename, line_num); - exit(EXIT_FAILURE); - } - - ch.uuid = (char *) malloc(len+1); /* including string termination */ - strcpy(ch.uuid, tok); - break; - - case 3: /* middleware */ - if (len == 0) { // TODO add uuid validation - print(-1, "Missing middleware in %s:%i", NULL, filename, line_num); - exit(EXIT_FAILURE); - } - - ch.middleware = (char *) malloc(len+1); /* including string termination */ - strcpy(ch.middleware, tok); - break; - - case 4: /* options */ - ch.options = (char *) malloc(len); - strncpy(ch.options, tok, len-1); - ch.options[len-1] = '\0'; /* replace \n by \0 */ - break; - } - - tok = strtok(NULL, " \t"); - } - - print(1, "Parsed ch#%i (protocol=%s interval=%i uuid=%s middleware=%s options=%s)", &ch, ch.id, ch.prot->name, ch.interval, ch.uuid, ch.middleware, ch.options); - chans[chan_num] = ch; - - chan_num++; - line_num++; - } - - fclose(file); - - return chan_num; -} - -/** - * Read thread - * - * Aquires reading from meters/sensors - */ -void *read_thread(void *arg) { - channel_t *ch = (channel_t *) arg; /* casting argument */ - print(1, "Started reading thread", ch); - - /* initalize channel */ - ch->handle = ch->prot->init_func(ch->options); /* init sensor/meter */ - - do { - /** - * Aquire reading, - * may be blocking if interpreter == METER - */ - reading_t rd = ch->prot->read_func(ch->handle); - - pthread_mutex_lock(&ch->mutex); - if (!queue_push(&ch->queue, rd)) { - print(6, "Warning queue is full, discarding first tuple!", ch); - } - pthread_cond_broadcast(&ch->condition); /* notify webserver and logging thread */ - pthread_mutex_unlock(&ch->mutex); - - print(1, "Value read: %.1f", ch, rd.value); - - /* Debugging */ - if (opts.verbose >= 10) { - char *queue_str = queue_print(&ch->queue); - print(10, "Queue dump: %s write_p = %lu\t read_p = %lu", ch, queue_str, ch->queue.write_p, ch->queue.read_p); - free(queue_str); - } - - if (ch->prot->interpreter != METER) { /* for meters, the read_func call is blocking */ - print(5, "Next reading in %i seconds", ch, ch->interval); - sleep(ch->interval); /* else sleep and restart aquisition */ - } - - pthread_testcancel(); /* test for cancelation request */ - } while (opts.daemon || opts.local); - - /* close channel */ - ch->prot->close_func(ch->handle); - - return NULL; -} - -/** - * The main loop - */ -int main(int argc, char *argv[]) { - int num_chans; - -#ifdef LOCAL - struct MHD_Daemon *httpd_handle = NULL; -#endif /* LOCAL */ - - parse_options(argc, argv, &opts); /* parse command line arguments */ - num_chans = parse_channels(opts.config, chans); /* parse channels from configuration */ - - print(1, "Started %s with verbosity level %i", NULL, argv[0], opts.verbose); - - curl_global_init(CURL_GLOBAL_ALL); /* global intialization for all threads */ - - for (int i = 0; i < num_chans; i++) { - channel_t *ch = &chans[i]; - - /* initialize queue to buffer data */ - queue_init(&ch->queue, (BUFFER_LENGTH / ch->interval) + 1); - - /* initialize thread syncronization helpers */ - pthread_mutex_init(&ch->mutex, NULL); - pthread_cond_init(&ch->condition, NULL); - - /* start threads */ - pthread_create(&ch->reading_thread, NULL, read_thread, (void *) ch); - pthread_create(&ch->logging_thread, NULL, api_thread, (void *) ch); - } - -#ifdef LOCAL - /* start webserver for local interface */ - if (opts.local) { - httpd_handle = MHD_start_daemon( - MHD_USE_THREAD_PER_CONNECTION, - opts.port, - NULL, NULL, - handle_request, - &num_chans, - MHD_OPTION_END - ); - } -#endif /* LOCAL */ - - /* wait for all threads to terminate */ - // TODO bind signal for termination - for (int i = 0; i < num_chans; i++) { - channel_t * ch = &chans[i]; - - pthread_join(ch->reading_thread, NULL); - pthread_join(ch->logging_thread, NULL); - - // TODO close protocol handles - - free(ch->middleware); - free(ch->uuid); - free(ch->options); - queue_free(&ch->queue); - - pthread_cond_destroy(&ch->condition); - pthread_mutex_destroy(&ch->mutex); - } - -#ifdef LOCAL - /* stop webserver */ - if (httpd_handle) { - MHD_stop_daemon(httpd_handle); - } -#endif /* LOCAL */ - - return EXIT_SUCCESS; -} diff --git a/src/main.h b/src/main.h deleted file mode 100644 index 8db99b1..0000000 --- a/src/main.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Main header file - * - * @package vzlogger - * @copyright Copyright (c) 2011, The volkszaehler.org project - * @license http://www.gnu.org/licenses/gpl.txt GNU Public License - * @author Steffen Vogel - */ -/* - * This file is part of volkzaehler.org - * - * volkzaehler.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * volkzaehler.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with volkszaehler.org. If not, see . - */ - -#ifndef _MAIN_H_ -#define _MAIN_H_ - -#include -#include -#include - -#include "../config.h" - -#include "protocol.h" -#include "queue.h" - -#define MAX_CHANNELS 16 - -#define RETRY_PAUSE 10 //600 /* seconds to wait after failed request */ -#define BUFFER_LENGTH 60 //600 /* in seconds */ - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/** - * Datatype for every channel - */ -typedef struct { - int id; /* only for internal usage & debugging */ - - char *middleware; - char *uuid; - char *options; - - unsigned int interval; - - void *handle; /* handle to store connection status */ - protocol_t *prot; /* pointer to protocol */ - queue_t queue; /* circular queue to buffer readings */ - - pthread_t reading_thread; /* pthread for asynchronus reading */ - pthread_t logging_thread; /* pthread for asynchronus logging */ - pthread_mutex_t mutex; - pthread_cond_t condition; -} channel_t; - -/** - * Options from command line - */ -typedef struct { - char * config; /* path to config file */ - unsigned int port; /* tcp port for local interface */ - unsigned int verbose; /* verbosity level */ - - /* boolean bitfields, at the end of struct */ - int daemon:1; - int local:1; /* enable local interface */ -} options_t; - -/* Prototypes */ -void parse_options(int argc, char * argv[], options_t *opts); -int parse_channels(char * filename, channel_t *chans); -void print(int level, char * format, channel_t *ch, ... ); -void usage(char ** argv); - -#endif /* _MAIN_H_ */ diff --git a/src/meter.c b/src/meter.c new file mode 100644 index 0000000..fdf514f --- /dev/null +++ b/src/meter.c @@ -0,0 +1,126 @@ +/** + * Protocol interface + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include + +#include "../include/meter.h" + +/* List of available meter types */ +meter_type_t meter_types[] = { + {ONEWIRE, "onewire", "Dallas 1-Wire sensors (via OWFS)", 1}, + {RANDOM, "random", "Random walk", 1}, + {S0, "S0", "S0 on RS232", 0}, +// {D0, "D0", "On-site plaintext protocol (DIN EN 62056-21)", 0}, +#ifdef SML_SUPPORT + {SML, "sml", "Smart Meter Language", 0}, +#endif /* SML_SUPPORT */ + {} /* stop condition for iterator */ +}; + +void meter_init(meter_t *meter, meter_type_t *type, char *options) { + meter->type = type; + meter->options = strdup(options); +} + +void meter_free(meter_t *meter) { + free(meter->options); +} + +int meter_open(meter_t *meter) { + switch (meter->type->tag) { + case RANDOM: + return meter_random_open(&meter->handle.random, meter->options); + + case S0: + return meter_s0_open(&meter->handle.s0, meter->options); + + case D0: + return meter_d0_open(&meter->handle.d0, meter->options); + +#ifdef SML_SUPPORT + case SML: + return meter_sml_open(&meter->handle.sml, meter->options); +#endif /* SML_SUPPORT */ + + case ONEWIRE: + return meter_onewire_open(&meter->handle.onewire, meter->options); + + default: + return -1; + } +} + +void meter_close(meter_t *meter) { + switch (meter->type->tag) { + case RANDOM: + meter_random_close(&meter->handle.random); + break; + + case S0: + meter_s0_close(&meter->handle.s0); + break; + + case D0: + meter_d0_close(&meter->handle.d0); + break; + +#ifdef SML_SUPPORT + case SML: + meter_sml_close(&meter->handle.sml); + break; +#endif /* SML_SUPPORT */ + + case ONEWIRE: + meter_onewire_close(&meter->handle.onewire); + break; + } +} + +meter_reading_t meter_read(meter_t *meter) { + meter_reading_t rd; + + switch (meter->type->tag) { + case RANDOM: + return meter_random_read(&meter->handle.random); + + case S0: + return meter_s0_read(&meter->handle.s0); + + case D0: + return meter_d0_read(&meter->handle.d0); + +#ifdef SML_SUPPORT + case SML: + return meter_sml_read(&meter->handle.sml); +#endif /* SML_SUPPORT */ + + case ONEWIRE: + return meter_onewire_read(&meter->handle.onewire); + + default: + return rd; + } +} diff --git a/src/obis.c b/src/obis.c new file mode 100644 index 0000000..8b7b2c8 --- /dev/null +++ b/src/obis.c @@ -0,0 +1,110 @@ +/** + * OBIS IDs as specified in DIN EN 62056-61 + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include +#include +#include + +#include "../include/obis.h" + +obis_alias_t obis_aliases[] = { +// A B C D E F abbreviation description +//===================================================================================== +{{"\x81\x81\xC7\x82\x03\xFF"}, "voltage", ""}, +{{"\x81\x81\xC7\x82\x03\xFF"}, "current", ""}, +{{"\x81\x81\xC7\x82\x03\xFF"}, "frequency", ""}, +{{"\x81\x81\xC7\x82\x03\xFF"}, "powerfactor", ""}, + +/* ESYQ3B (Easymeter Q3B) */ +{{"\x81\x81\xC7\x82\x03\xFF"}, "vendor", "vendor specific"}, +{{"\x01\x00\x01\x08\x00\xFF"}, "counter", "Active Power Counter Total"}, +{{"\x01\x00\x01\x08\x01\xFF"}, "counter-tarif1","Active Power Counter Tariff 1"}, +{{"\x01\x00\x01\x08\x02\xFF"}, "counter-tarif2","Active Power Counter Tariff 2"}, +{{"\x01\x00\x01\x07\x00\xFF"}, "power", "Active Power Instantaneous value Total"}, +{{"\x01\x00\x15\x07\x00\xFF"}, "power-l1", "L1 Active Power Instantaneous value Total"}, +{{"\x01\x00\x29\x07\x00\xFF"}, "power-l2", "L1 Active Power Instantaneous value Total"}, +{{"\x01\x00\x3D\x07\x00\xFF"}, "power-l2", "L3 Active Power Instantaneous value Total"}, +{{"\x01\x00\x60\x05\x05\xFF"}, "status", "Meter status flag"}, +{} /* stop condition for iterator */ +}; + +obis_id_t obis_init(unsigned char *raw) { + obis_id_t id; + memcpy(id.raw, raw, 6); + return id; +} + +obis_id_t obis_parse(char *str) { + obis_id_t id; + regex_t expr; + regmatch_t matches[7]; + + regcomp(&expr, "^([0-9])-([a-f0-9]{,2}):([a-f0-9]{,2})\\.([a-f0-9]{,2})\\.([a-f0-9]{,2})(\\*[a-f0-9]{,2})?$", REG_EXTENDED | REG_ICASE); + + if (regexec(&expr, str, 7, matches, 0) == 0) { /* found string in OBIS notation */ + for (int i=0; i<6; i++) { + if (matches[i+1].rm_so != -1) { + id.raw[i] = strtoul(str+matches[i+1].rm_so, NULL, 16); + } + else { + id.raw[i] = 0xff; /* default value */ + } + } + } + else { /* looking for alias */ + obis_alias_t *it = obis_aliases; + do { /* linear search */ + if (strcmp(it->name, str) == 0) { + return it->id; + } + } while ((++it)->name); + } + + return id; +} + +char obis_is_manufacturer_specific(obis_id_t id) { + return ( + (id.groups.channel >= 128 && id.groups.channel <= 199) || + (id.groups.indicator >= 128 && id.groups.indicator <= 199) || + (id.groups.indicator == 240) || + (id.groups.mode >= 128 && id.groups.mode <= 254) || + (id.groups.quantities >= 128 && id.groups.quantities <= 254) || + (id.groups.storage >= 128 && id.groups.storage <= 254) + ); +} + +int obis_unparse(obis_id_t id, char *buffer) { + return sprintf(buffer, "%x-%x:%x.%x.%x*%x", + id.groups.media, + id.groups.channel, + id.groups.indicator, + id.groups.mode, + id.groups.quantities, + id.groups.storage + ); +} + diff --git a/src/protocols/1wire.c b/src/onewire.c similarity index 71% rename from src/protocols/1wire.c rename to src/onewire.c index b902f38..576ce74 100644 --- a/src/protocols/1wire.c +++ b/src/onewire.c @@ -23,12 +23,9 @@ * along with volkszaehler.org. If not, see . */ -#include #include -#include "../main.h" -#include "../protocol.h" -#include "1wire.h" +#include "../include/onewire.h" /** * Initialize sensor @@ -36,35 +33,27 @@ * @param address path to the sensor in the owfs * @return pointer to file descriptor */ -void * onewire_init(char *address) { - FILE * fd = fopen(address, "r"); +int meter_onewire_open(meter_handle_onewire_t *handle, char *options) { + handle->file = fopen(options, "r"); - if (fd == NULL) { - perror(address); - print(-1, "Failed to open sensor: %s", NULL, address); - exit(EXIT_FAILURE); - } - - return (void *) fd; + return (handle->file == NULL) ? -1 : 0; } -void onewire_close(void *handle) { - fclose((FILE *) handle); +void meter_onewire_close(meter_handle_onewire_t *handle) { + fclose(handle->file); } -reading_t onewire_get(void *handle) { - reading_t rd; +meter_reading_t meter_onewire_read(meter_handle_onewire_t *handle) { + meter_reading_t rd; char buffer[16]; int bytes; do { - rewind((FILE *) handle); - bytes = fread(buffer, 1, 16, (FILE *) handle); + rewind(handle->file); + bytes = fread(buffer, 1, 16, handle->file); buffer[bytes] = '\0'; /* zero terminated, required? */ if (bytes) { - print(4, "Read from sensor file: %s", NULL, buffer); - rd.value = strtof(buffer, NULL); gettimeofday(&rd.tv, NULL); } diff --git a/src/protocol.h b/src/protocol.h deleted file mode 100644 index be6ec0c..0000000 --- a/src/protocol.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _PROTOCOL_H_ -#define _PROTOCOL_H_ - -#include - -typedef struct { - float value; - struct timeval tv; -} reading_t; - -typedef void *(*ifp_t)(char *options); -typedef void (*cfp_t)(void *handle); -typedef reading_t (*rfp_t)(void *handle); - -typedef enum { - MODE_METER, - MODE_SENSOR -} mode_t; - -typedef struct { - char * name; /* short identifier for protocol */ - char * desc; /* more detailed description */ - rfp_t read_func; /* function pointer to read data */ - ifp_t init_func; /* function pointer to init a channel */ - cfp_t close_func; /* function pointer to close a channel */ - mode_t mode; /* should we wait for next pulse? */ -} protocol_t; - -#endif /* _PROTOCOL_H_ */ diff --git a/src/protocols/rawS0.c b/src/protocols/rawS0.c deleted file mode 100644 index 1b211bb..0000000 --- a/src/protocols/rawS0.c +++ /dev/null @@ -1,99 +0,0 @@ -/** - * S0 Hutschienenzähler directly connected to an rs232 port - * - * @package vzlogger - * @copyright Copyright (c) 2011, The volkszaehler.org project - * @license http://www.gnu.org/licenses/gpl.txt GNU Public License - * @author Steffen Vogel - */ -/* - * This file is part of volkzaehler.org - * - * volkzaehler.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * volkzaehler.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with volkszaehler.org. If not, see . - */ - -#include -#include -#include -#include - -#include "../main.h" -#include "../protocol.h" -#include "rawS0.h" - -/** - * Setup serial port - */ -void * rawS0_init(char *port) { - rawS0_state_t *state; - struct termios newtio; - - /* initialize handle */ - state = malloc(sizeof(rawS0_state_t)); - - state->fd = open(port, O_RDWR | O_NOCTTY); - if (state->fd < 0) { - char err[255]; - strerror_r(errno, err, 255); - print(-1, "%s: %s", NULL, port, err); - exit(EXIT_FAILURE); - } - - tcgetattr(state->fd, &state->oldtio); /* save current port settings */ - - - /* configure port */ - memset(&newtio, 0, sizeof(struct termios)); - - newtio.c_cflag = B300 | CS8 | CLOCAL | CREAD; - newtio.c_iflag = IGNPAR; - newtio.c_oflag = 0; - newtio.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */ - newtio.c_cc[VTIME] = 0; /* inter-character timer unused */ - newtio.c_cc[VMIN] = 1; /* blocking read until data is received */ - - /* apply configuration */ - tcsetattr(state->fd, TCSANOW, &newtio); - - return (void *) state; -} - -void rawS0_close(void *handle) { - rawS0_state_t *state = (rawS0_state_t *) handle; - - tcsetattr(state->fd, TCSANOW, &state->oldtio); - - close(state->fd); - free(handle); -} - -reading_t rawS0_get(void *handle) { - char buf[255]; - - rawS0_state_t *state = (rawS0_state_t *) handle; - reading_t rd; - - rd.value = 1; - - tcflush(state->fd, TCIOFLUSH); - - read(state->fd, buf, 255); /* blocking until one character/pulse is read */ - gettimeofday(&rd.tv, NULL); - - /* wait some ms for debouncing */ - usleep(30000); - - return rd; -} - diff --git a/src/protocols/sml.c b/src/protocols/sml.c deleted file mode 100644 index 45d91a8..0000000 --- a/src/protocols/sml.c +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Wrapper around libsml - * - * @package vzlogger - * @copyright Copyright (c) 2011, The volkszaehler.org project - * @copyright Copyright (c) 2011, DAI-Labor, TU-Berlin - * @license http://www.gnu.org/licenses/gpl.txt GNU Public License - * @author Steffen Vogel - * @author Juri Glass - * @author Mathias Runge - * @author Nadim El Sayed - */ -/* - * This file is part of volkzaehler.org - * - * volkzaehler.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * volkzaehler.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with volkszaehler.org. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -int sml_init(char *device) { - sml_state_t *state; - - /* initialize handle */ - state = malloc(sizeof(sml_state_t)); - - /* this example assumes that a EDL21 meter sending SML messages via a - * serial device. Adjust as needed. */ - int fd = serial_port_open(device); - - if (fd > 0) { - // start thread - - /* listen on the serial device, this call is blocking */ - sml_transport_listen(fd, &transport_receiver); - close(fd); - } -} - -void sml_close(void *handle) { - -} - -reading_t sml_get(void *handle) { - -} - -void sml_transport_receiver(unsigned char *buffer, size_t buffer_len) { - // the buffer contains the whole message, with transport escape sequences. - // these escape sequences are stripped here. - sml_file *file = sml_file_parse(buffer + 8, buffer_len - 16); - // the sml file is parsed now - - // read here some values .. - - // this prints some information about the file - sml_file_print(file); - - // free the malloc'd memory - sml_file_free(file); -} - -int sml_open_port(char *device) { - int bits; - struct termios config; - memset(&config, 0, sizeof(config)); - - int fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); - if (fd < 0) { - printf("error: open(%s): %s\n", device, strerror(errno)); - return -1; - } - - // set RTS - ioctl(fd, TIOCMGET, &bits); - bits |= TIOCM_RTS; - ioctl(fd, TIOCMSET, &bits); - - tcgetattr( fd, &config ) ; - - // set 8-N-1 - config.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - config.c_oflag &= ~OPOST; - config.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - config.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); - config.c_cflag |= CS8; - - // set speed to 9600 baud - cfsetispeed( &config, B9600); - cfsetospeed( &config, B9600); - - tcsetattr(fd, TCSANOW, &config); - return fd; -} diff --git a/src/queue.c b/src/queue.c deleted file mode 100644 index 37435c8..0000000 --- a/src/queue.c +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include - -#include "queue.h" - -bool_t queue_init(queue_t *q, size_t size) { - q->buf = malloc(sizeof(reading_t) * size); /* keep one slot open */ - - if (q->buf) { - q->size = size; - q->read_p = q->write_p = 0; /* queue is empty */ - - return TRUE; - } - else { /* cannot allocate memory */ - return FALSE; - } -} - -bool_t queue_is_empty(queue_t *q) { - return (q->read_p == q->write_p); -} - -void queue_free(queue_t *q) { - queue_clear(q); - free(q->buf); -} - -void queue_clear(queue_t *q) { - q->read_p = q->write_p; -} - -bool_t queue_push(queue_t *q, reading_t rd) { - q->buf[q->write_p] = rd; /* copy data to buffer */ - q->write_p++; /* increment write pointer */ - q->write_p %= q->size; - - if (q->read_p == q->write_p) { /* queue full */ - q->read_p++; /* discarding first tuple */ - return FALSE; - } - - return TRUE; -} - -bool_t queue_get(queue_t *q, size_t index, reading_t *rd) { - *rd = q->buf[index]; - - return (index < q->size); -} - -char * queue_print(queue_t *q) { - char *buf = malloc(q->size * 6); - char *ret = buf; - - buf += sprintf(buf, "[%.1f", q->buf[0].value); - for (int i = 1; i < q->size; i++) { - buf += sprintf(buf, "|%.2f", q->buf[i].value); - } - buf += sprintf(buf, "]"); - - return ret; -} diff --git a/src/protocols/random.c b/src/random.c similarity index 58% rename from src/protocols/random.c rename to src/random.c index 56c80de..72ba760 100644 --- a/src/protocols/random.c +++ b/src/random.c @@ -22,52 +22,42 @@ * You should have received a copy of the GNU General Public License * along with volkszaehler.org. If not, see . */ - + #include #include #include -#include "../main.h" -#include "../protocol.h" -#include "random.h" +#include "../include/random.h" -/** - * Initialize prng - * @return random_state_t - */ -void * random_init(char *options) { - random_state_t *state; - state = malloc(sizeof(random_state_t)); +int meter_random_open(meter_handle_random_t *handle, char *options) { + srand(time(NULL)); /* initialize PNRG */ - srand(time(NULL)); - - state->min = 0; // TODO parse from options - state->max = strtof(options, NULL); - state->last = state->max * ((float) rand() / RAND_MAX); /* start value */ - - return (void *) state; + handle->min = 0; // TODO parse from options + handle->max = strtof(options, NULL); + handle->last = handle->max * ((float) rand() / RAND_MAX); /* start value */ + + return 0; /* always succeeds */ } -void random_close(void *handle) { - free(handle); +void meter_random_close(meter_handle_random_t *handle) { + /* nothing todo */ } -reading_t random_get(void *handle) { - random_state_t *state = (random_state_t *) handle; - reading_t rd; - - state->last += ltqnorm((float) rand() / RAND_MAX); - +meter_reading_t meter_random_read(meter_handle_random_t *handle) { + meter_reading_t rd; + + handle->last += ltqnorm((float) rand() / RAND_MAX); + /* check bounaries */ - if (state->last > state->max) { - state->last = state->max; + if (handle->last > handle->max) { + handle->last = handle->max; } - else if (state->last < state->min) { - state->last = state->min; + else if (handle->last < handle->min) { + handle->last = handle->min; } - - rd.value = state->last; + + rd.value = handle->last; gettimeofday(&rd.tv, NULL); - + return rd; } diff --git a/src/s0.c b/src/s0.c new file mode 100644 index 0000000..0b4ed74 --- /dev/null +++ b/src/s0.c @@ -0,0 +1,91 @@ +/** + * S0 Hutschienenzähler directly connected to an rs232 port + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "../include/s0.h" + +/** + * Setup serial port + */ +int meter_s0_open(meter_handle_s0_t *handle, char *options) { + /* open port */ + handle->fd = open(options, O_RDWR | O_NOCTTY); + + if (handle->fd < 0) { + return -1; + } + + /* save current port settings */ + tcgetattr(handle->fd, &handle->oldtio); + + + /* configure port */ + struct termios tio; + memset(&tio, 0, sizeof(struct termios)); + + tio.c_cflag = B300 | CS8 | CLOCAL | CREAD; + tio.c_iflag = IGNPAR; + tio.c_oflag = 0; + tio.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */ + tio.c_cc[VTIME] = 0; /* inter-character timer unused */ + tio.c_cc[VMIN] = 1; /* blocking read until data is received */ + + /* apply configuration */ + tcsetattr(handle->fd, TCSANOW, &tio); + + return 0; +} + +void meter_s0_close(meter_handle_s0_t *handle) { + /* reset serial port */ + tcsetattr(handle->fd, TCSANOW, &handle->oldtio); + + /* close serial port */ + close(handle->fd); +} + +meter_reading_t meter_s0_read(meter_handle_s0_t *handle) { + char buf[8]; + + meter_reading_t rd; + + rd.value = 1; + + tcflush(handle->fd, TCIOFLUSH); + + read(handle->fd, buf, 8); /* blocking until one character/pulse is read */ + gettimeofday(&rd.tv, NULL); + + /* wait some ms for debouncing */ + usleep(30000); + + return rd; +} + diff --git a/src/sml.c b/src/sml.c new file mode 100644 index 0000000..63fc80c --- /dev/null +++ b/src/sml.c @@ -0,0 +1,191 @@ +/** + * Wrapper around libsml + * + * @package vzlogger + * @copyright Copyright (c) 2011, The volkszaehler.org project + * @copyright Copyright (c) 2011, DAI-Labor, TU-Berlin + * @license http://www.gnu.org/licenses/gpl.txt GNU Public License + * @author Steffen Vogel + * @author Juri Glass + * @author Mathias Runge + * @author Nadim El Sayed + */ +/* + * This file is part of volkzaehler.org + * + * volkzaehler.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * volkzaehler.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with volkszaehler.org. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +/* serial port */ +#include +#include +#include + +/* socket */ +#include +#include + +/* sml stuff */ +#include +#include + +#include "../include/sml.h" +#include "../include/obis.h" + +int meter_sml_open(meter_handle_sml_t *handle, char *options) { + char *node = strsep(&options, ":"); + char *service = strsep(&options, ":"); + + handle->id = obis_parse(options); + handle->fd = meter_sml_open_socket(node, service); + //handle->fd = meter_sml_open_port(options); + + return (handle->fd < 0) ? -1 : 0; +} + +void meter_sml_close(meter_handle_sml_t *handle) { + // TODO reset serial port + close(handle->fd); +} + +meter_reading_t meter_sml_read(meter_handle_sml_t *handle) { + unsigned char buffer[SML_BUFFER_LEN]; + size_t bytes; + sml_file *sml_file; + meter_reading_t rd; + + /* blocking read from fd */ + bytes = sml_transport_read(handle->fd, buffer, SML_BUFFER_LEN); + + /* sml parsing & stripping escape sequences */ + sml_file = sml_file_parse(buffer + 8, bytes - 16); + + /* extraction of readings */ + rd = meter_sml_parse(sml_file, handle->id); + + /* free the malloc'd memory */ + sml_file_free(sml_file); + + return rd; +} + +int meter_sml_open_socket(char *node, char *service) { + struct sockaddr_in sin; + struct addrinfo *ais; + int fd, res; + + getaddrinfo(node, service, NULL, &ais); + memcpy(&sin, ais->ai_addr, ais->ai_addrlen); + + fd = socket(PF_INET, SOCK_STREAM, 0); + + res = connect(fd, (struct sockaddr *) &sin, sizeof(sin)); + + return (res < 0) ? -1 : fd; +} + +int meter_sml_open_port(char *device) { + int bits; + struct termios config; + memset(&config, 0, sizeof(config)); + + int fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY); + if (fd < 0) { + printf("error: open(%s): %s\n", device, strerror(errno)); + return -1; + } + + // set RTS + ioctl(fd, TIOCMGET, &bits); + bits |= TIOCM_RTS; + ioctl(fd, TIOCMSET, &bits); + + tcgetattr( fd, &config ) ; + + // set 8-N-1 + config.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); + config.c_oflag &= ~OPOST; + config.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + config.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); + config.c_cflag |= CS8; + + // set speed to 9600 baud + cfsetispeed( &config, B9600); + cfsetospeed( &config, B9600); + + tcsetattr(fd, TCSANOW, &config); + return fd; +} + +meter_reading_t meter_sml_parse(sml_file *file, obis_id_t which) { + meter_reading_t rd; + + for (int i = 0; i < file->messages_len; i++) { + sml_message *message = file->messages[i]; + + if (*message->message_body->tag == SML_MESSAGE_GET_LIST_RESPONSE) { + sml_list *entry; + sml_get_list_response *body; + + body = (sml_get_list_response *) message->message_body->data; + + for (entry = body->val_list; entry != NULL; entry = entry->next) { /* linked list */ + obis_id_t id = obis_init(entry->obj_name->str); + + if (obis_compare(which, id) == 0) { + //int unit = (entry->unit) ? *entry->unit : 0; + int scaler = (entry->scaler) ? *entry->scaler : 1; + + switch (entry->value->type) { + case 0x51: rd.value = *entry->value->data.int8; break; + case 0x52: rd.value = *entry->value->data.int16; break; + case 0x54: rd.value = *entry->value->data.int32; break; + case 0x58: rd.value = *entry->value->data.int64; break; + case 0x61: rd.value = *entry->value->data.uint8; break; + case 0x62: rd.value = *entry->value->data.uint16; break; + case 0x64: rd.value = *entry->value->data.uint32; break; + case 0x68: rd.value = *entry->value->data.uint64; break; + + default: + fprintf(stderr, "Unknown value type: %x", entry->value->type); + } + + /* apply scaler */ + rd.value *= pow(10, scaler); + + + /* get time */ + if (entry->val_time) { // TODO handle SML_TIME_SEC_INDEX + rd.tv.tv_sec = *entry->val_time->data.timestamp; + rd.tv.tv_usec = 0; + } + else { + gettimeofday(&rd.tv, NULL); + } + + return rd; /* skipping rest */ + } + } + } + } + + return rd; +}