summaryrefslogtreecommitdiff
path: root/libparse
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-12-02 09:01:21 +0000
committer <>2014-12-04 16:11:25 +0000
commitbdab5265fcbf3f472545073a23f8999749a9f2b9 (patch)
treec6018dd03dea906f8f1fb5f105f05b71a7dc250a /libparse
downloadntp-bdab5265fcbf3f472545073a23f8999749a9f2b9.tar.gz
Imported from /home/lorry/working-area/delta_ntp/ntp-dev-4.2.7p482.tar.gz.ntp-dev-4.2.7p482
Diffstat (limited to 'libparse')
-rw-r--r--libparse/Makefile.am145
-rw-r--r--libparse/Makefile.in935
-rw-r--r--libparse/README96
-rw-r--r--libparse/binio.c156
-rw-r--r--libparse/clk_computime.c219
-rw-r--r--libparse/clk_dcf7000.c214
-rw-r--r--libparse/clk_hopf6021.c283
-rw-r--r--libparse/clk_meinberg.c776
-rw-r--r--libparse/clk_rawdcf.c658
-rw-r--r--libparse/clk_rcc8000.c198
-rw-r--r--libparse/clk_schmid.c258
-rw-r--r--libparse/clk_sel240x.c178
-rw-r--r--libparse/clk_trimtaip.c223
-rw-r--r--libparse/clk_trimtsip.c463
-rw-r--r--libparse/clk_varitext.c271
-rw-r--r--libparse/clk_wharton.c181
-rw-r--r--libparse/data_mbg.c539
-rw-r--r--libparse/gpstolfp.c77
-rw-r--r--libparse/ieee754io.c614
-rw-r--r--libparse/info_trimble.c94
-rw-r--r--libparse/mfp_mul.c207
-rw-r--r--libparse/mkinfo_rcmd.sed8
-rw-r--r--libparse/mkinfo_scmd.sed15
-rw-r--r--libparse/parse.c945
-rw-r--r--libparse/parse_conf.c182
-rw-r--r--libparse/parsesolaris.c1202
-rw-r--r--libparse/parsestreams.c1367
-rw-r--r--libparse/trim_info.c70
28 files changed, 10574 insertions, 0 deletions
diff --git a/libparse/Makefile.am b/libparse/Makefile.am
new file mode 100644
index 0000000..a92db15
--- /dev/null
+++ b/libparse/Makefile.am
@@ -0,0 +1,145 @@
+NULL=
+BUILT_SOURCES =
+CLEANFILES =
+noinst_LIBRARIES = @MAKE_LIBPARSE@ @MAKE_LIBPARSE_KERNEL@
+EXTRA_LIBRARIES = libparse.a libparse_kernel.a
+EXTRA_PROGRAMS = parsestreams parsesolaris
+noinst_PROGRAMS = @MAKE_PARSEKMODULE@
+
+K_CFLAGS = -DPARSESTREAM -DNTP_NEED_BOPS
+
+# info_trimble.c was mistakenly created in the build directory
+# previously. It is located in $(srcdir) and any updates must
+# end up there.
+
+libparse_a_SOURCES = parse.c \
+ parse_conf.c \
+ clk_meinberg.c \
+ clk_schmid.c \
+ clk_rawdcf.c \
+ clk_trimtsip.c \
+ clk_dcf7000.c \
+ clk_trimtaip.c \
+ clk_rcc8000.c \
+ clk_hopf6021.c \
+ clk_computime.c \
+ clk_wharton.c \
+ clk_varitext.c \
+ clk_sel240x.c \
+ data_mbg.c \
+ info_trimble.c \
+ trim_info.c \
+ binio.c \
+ ieee754io.c \
+ mfp_mul.c \
+ gpstolfp.c \
+ $(NULL)
+
+libparse_kernel_a_SOURCES =
+libparse_kernel_a_LIBADD = \
+ kparse.o \
+ kparse_conf.o \
+ kclk_computime.o \
+ kclk_dcf7000.o \
+ kclk_hopf6021.o \
+ kclk_meinberg.o \
+ kclk_rawdcf.o \
+ kclk_rcc8000.o \
+ kclk_schmid.o \
+ kclk_trimtaip.o \
+ kclk_trimtsip.o \
+ kclk_varitext.o \
+ kclk_wharton.o \
+ kclk_sel240x.o \
+ kbinio.o \
+ kieee754io.o \
+ kmfp_mul.o \
+ kgpstolfp.o \
+ $(NULL)
+
+AM_CFLAGS = $(CFLAGS_NTP)
+
+AM_CPPFLAGS = $(NTP_INCS)
+AM_CPPFLAGS += -I$(top_srcdir)/kernel
+AM_CPPFLAGS += $(CPPFLAGS_NTP)
+
+EXTRA_DIST = parsesolaris.c parsestreams.c mkinfo_scmd.sed mkinfo_rcmd.sed info_trimble.c
+
+$(srcdir)/info_trimble.c: $(top_srcdir)/include/trimble.h $(srcdir)/Makefile.am $(srcdir)/mkinfo_scmd.sed $(srcdir)/mkinfo_rcmd.sed
+ sed -n -f $(srcdir)/mkinfo_scmd.sed $(top_srcdir)/include/trimble.h > info_trimble.new
+ sed -n -f $(srcdir)/mkinfo_rcmd.sed $(top_srcdir)/include/trimble.h >> info_trimble.new
+ mv -f info_trimble.new $@
+
+kieee754io.o: $(srcdir)/ieee754io.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/ieee754io.c -o $@
+
+kmfp_mul.o: $(srcdir)/mfp_mul.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/mfp_mul.c -o $@
+
+kgpstolfp.o: $(srcdir)/gpstolfp.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/gpstolfp.c -o $@
+
+kbinio.o: $(srcdir)/binio.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/binio.c -o $@
+
+kclk_computime.o: $(srcdir)/clk_computime.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_computime.c -o $@
+
+kclk_dcf7000.o: $(srcdir)/clk_dcf7000.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_dcf7000.c -o $@
+
+kclk_hopf6021.o: $(srcdir)/clk_hopf6021.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_hopf6021.c -o $@
+
+kclk_meinberg.o: $(srcdir)/clk_meinberg.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_meinberg.c -o $@
+
+kclk_rawdcf.o: $(srcdir)/clk_rawdcf.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_rawdcf.c -o $@
+
+kclk_rcc8000.o: $(srcdir)/clk_rcc8000.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_rcc8000.c -o $@
+
+kclk_schmid.o: $(srcdir)/clk_schmid.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_schmid.c -o $@
+
+kclk_trimtaip.o: $(srcdir)/clk_trimtaip.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_trimtaip.c -o $@
+
+kclk_trimtsip.o: $(srcdir)/clk_trimtsip.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_trimtsip.c -o $@
+
+kclk_varitext.o: $(srcdir)/clk_varitext.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_varitext.c -o $@
+
+kclk_wharton.o: $(srcdir)/clk_wharton.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_wharton.c -o $@
+
+kclk_sel240x.o: $(srcdir)/clk_sel240x.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_sel240x.c -o $@
+
+kparse.o: $(srcdir)/parse.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/parse.c -o $@
+
+kparse_conf.o: $(srcdir)/parse_conf.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/parse_conf.c -o $@
+
+parsestreams.loadable_module.o: $(parsestreams_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+ $(LD) -r -o $@ $(parsestreams_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+
+parse: $(parsesolaris_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+ $(LD) -r -o $@ $(parsesolaris_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+
+parsesolaris.o: sys/systm.h
+
+sys/systm.h:
+ -mkdir sys
+ sed -e '/ffs(.*)/d' < /usr/include/sys/systm.h > sys/systm.h
+
+## check-libparse is invoked by ntpd/Makefile.am
+check-libparse: $(noinst_LIBRARIES)
+ @: do-nothing action to avoid default SCCS get
+
+include $(top_srcdir)/sntp/check-libntp.mf
+include $(top_srcdir)/depsver.mf
+include $(top_srcdir)/includes.mf
diff --git a/libparse/Makefile.in b/libparse/Makefile.in
new file mode 100644
index 0000000..0344c96
--- /dev/null
+++ b/libparse/Makefile.in
@@ -0,0 +1,935 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# 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.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+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 = :
+build_triplet = @build@
+host_triplet = @host@
+EXTRA_PROGRAMS = parsestreams$(EXEEXT) parsesolaris$(EXEEXT)
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/depsver.mf $(top_srcdir)/includes.mf \
+ $(top_srcdir)/sntp/check-libntp.mf
+subdir = libparse
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/sntp/libopts/m4/libopts.m4 \
+ $(top_srcdir)/sntp/libopts/m4/stdnoreturn.m4 \
+ $(top_srcdir)/sntp/libevent/m4/openldap-thread-check.m4 \
+ $(top_srcdir)/sntp/libevent/m4/openldap.m4 \
+ $(top_srcdir)/sntp/m4/define_dir.m4 \
+ $(top_srcdir)/sntp/m4/hms_search_lib.m4 \
+ $(top_srcdir)/sntp/m4/libtool.m4 \
+ $(top_srcdir)/sntp/m4/ltoptions.m4 \
+ $(top_srcdir)/sntp/m4/ltsugar.m4 \
+ $(top_srcdir)/sntp/m4/ltversion.m4 \
+ $(top_srcdir)/sntp/m4/lt~obsolete.m4 \
+ $(top_srcdir)/sntp/m4/ntp_cacheversion.m4 \
+ $(top_srcdir)/sntp/m4/ntp_compiler.m4 \
+ $(top_srcdir)/sntp/m4/ntp_crosscompile.m4 \
+ $(top_srcdir)/sntp/m4/ntp_debug.m4 \
+ $(top_srcdir)/sntp/m4/ntp_dir_sep.m4 \
+ $(top_srcdir)/sntp/m4/ntp_facilitynames.m4 \
+ $(top_srcdir)/sntp/m4/ntp_googletest.m4 \
+ $(top_srcdir)/sntp/m4/ntp_ipv6.m4 \
+ $(top_srcdir)/sntp/m4/ntp_lib_m.m4 \
+ $(top_srcdir)/sntp/m4/ntp_libevent.m4 \
+ $(top_srcdir)/sntp/m4/ntp_libntp.m4 \
+ $(top_srcdir)/sntp/m4/ntp_lineeditlibs.m4 \
+ $(top_srcdir)/sntp/m4/ntp_locinfo.m4 \
+ $(top_srcdir)/sntp/m4/ntp_openssl.m4 \
+ $(top_srcdir)/sntp/m4/ntp_pkg_config.m4 \
+ $(top_srcdir)/sntp/m4/ntp_prog_cc.m4 \
+ $(top_srcdir)/sntp/m4/ntp_rlimit.m4 \
+ $(top_srcdir)/sntp/m4/ntp_sntp.m4 \
+ $(top_srcdir)/sntp/m4/ntp_ver_suffix.m4 \
+ $(top_srcdir)/sntp/m4/ntp_vpathhack.m4 \
+ $(top_srcdir)/sntp/m4/os_cflags.m4 \
+ $(top_srcdir)/sntp/m4/snprintf.m4 \
+ $(top_srcdir)/sntp/m4/version.m4 $(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 =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_$(V))
+am__v_AR_ = $(am__v_AR_$(AM_DEFAULT_VERBOSITY))
+am__v_AR_0 = @echo " AR " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+libparse_a_AR = $(AR) $(ARFLAGS)
+libparse_a_LIBADD =
+am__objects_1 =
+am_libparse_a_OBJECTS = parse.$(OBJEXT) parse_conf.$(OBJEXT) \
+ clk_meinberg.$(OBJEXT) clk_schmid.$(OBJEXT) \
+ clk_rawdcf.$(OBJEXT) clk_trimtsip.$(OBJEXT) \
+ clk_dcf7000.$(OBJEXT) clk_trimtaip.$(OBJEXT) \
+ clk_rcc8000.$(OBJEXT) clk_hopf6021.$(OBJEXT) \
+ clk_computime.$(OBJEXT) clk_wharton.$(OBJEXT) \
+ clk_varitext.$(OBJEXT) clk_sel240x.$(OBJEXT) \
+ data_mbg.$(OBJEXT) info_trimble.$(OBJEXT) trim_info.$(OBJEXT) \
+ binio.$(OBJEXT) ieee754io.$(OBJEXT) mfp_mul.$(OBJEXT) \
+ gpstolfp.$(OBJEXT) $(am__objects_1)
+libparse_a_OBJECTS = $(am_libparse_a_OBJECTS)
+libparse_kernel_a_AR = $(AR) $(ARFLAGS)
+am__DEPENDENCIES_1 =
+libparse_kernel_a_DEPENDENCIES = kparse.o kparse_conf.o \
+ kclk_computime.o kclk_dcf7000.o kclk_hopf6021.o \
+ kclk_meinberg.o kclk_rawdcf.o kclk_rcc8000.o kclk_schmid.o \
+ kclk_trimtaip.o kclk_trimtsip.o kclk_varitext.o kclk_wharton.o \
+ kclk_sel240x.o kbinio.o kieee754io.o kmfp_mul.o kgpstolfp.o \
+ $(am__DEPENDENCIES_1)
+am_libparse_kernel_a_OBJECTS =
+libparse_kernel_a_OBJECTS = $(am_libparse_kernel_a_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
+parsesolaris_SOURCES = parsesolaris.c
+parsesolaris_OBJECTS = parsesolaris.$(OBJEXT)
+parsesolaris_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+parsestreams_SOURCES = parsestreams.c
+parsestreams_OBJECTS = parsestreams.$(OBJEXT)
+parsestreams_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/sntp/libevent/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libparse_a_SOURCES) $(libparse_kernel_a_SOURCES) \
+ parsesolaris.c parsestreams.c
+DIST_SOURCES = $(libparse_a_SOURCES) $(libparse_kernel_a_SOURCES) \
+ parsesolaris.c parsestreams.c
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CALC_TICKADJ_DB = @CALC_TICKADJ_DB@
+CALC_TICKADJ_DL = @CALC_TICKADJ_DL@
+CALC_TICKADJ_DS = @CALC_TICKADJ_DS@
+CALC_TICKADJ_MS = @CALC_TICKADJ_MS@
+CALC_TICKADJ_NI = @CALC_TICKADJ_NI@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CFLAGS_NTP = @CFLAGS_NTP@
+CHUTEST = @CHUTEST@
+CONFIG_SHELL = @CONFIG_SHELL@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPFLAGS_NTP = @CPPFLAGS_NTP@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DCFD = @DCFD@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EDITLINE_LIBS = @EDITLINE_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+GTEST_CONFIG = @GTEST_CONFIG@
+GTEST_CPPFLAGS = @GTEST_CPPFLAGS@
+GTEST_CXXFLAGS = @GTEST_CXXFLAGS@
+GTEST_LDFLAGS = @GTEST_LDFLAGS@
+GTEST_LIBS = @GTEST_LIBS@
+HAVE_INLINE = @HAVE_INLINE@
+HAVE_RLIMIT_MEMLOCK = @HAVE_RLIMIT_MEMLOCK@
+HAVE_RLIMIT_STACK = @HAVE_RLIMIT_STACK@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDADD_LIBNTP = @LDADD_LIBNTP@
+LDADD_NLIST = @LDADD_NLIST@
+LDADD_NTP = @LDADD_NTP@
+LDFLAGS = @LDFLAGS@
+LDFLAGS_NTP = @LDFLAGS_NTP@
+LIBISC_PTHREADS_NOTHREADS = @LIBISC_PTHREADS_NOTHREADS@
+LIBM = @LIBM@
+LIBOBJS = @LIBOBJS@
+LIBOPTS_CFLAGS = @LIBOPTS_CFLAGS@
+LIBOPTS_DIR = @LIBOPTS_DIR@
+LIBOPTS_LDADD = @LIBOPTS_LDADD@
+LIBPARSE = @LIBPARSE@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LSCF = @LSCF@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_ADJTIMED = @MAKE_ADJTIMED@
+MAKE_CHECK_LAYOUT = @MAKE_CHECK_LAYOUT@
+MAKE_CHECK_Y2K = @MAKE_CHECK_Y2K@
+MAKE_LIBNTPSIM = @MAKE_LIBNTPSIM@
+MAKE_LIBPARSE = @MAKE_LIBPARSE@
+MAKE_LIBPARSE_KERNEL = @MAKE_LIBPARSE_KERNEL@
+MAKE_NTPDSIM = @MAKE_NTPDSIM@
+MAKE_NTPSNMPD = @MAKE_NTPSNMPD@
+MAKE_NTPTIME = @MAKE_NTPTIME@
+MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@
+MAKE_TICKADJ = @MAKE_TICKADJ@
+MAKE_TIMETRIM = @MAKE_TIMETRIM@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MANTAGFMT = @MANTAGFMT@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NTPDATE_DB = @NTPDATE_DB@
+NTPDATE_DL = @NTPDATE_DL@
+NTPDATE_DS = @NTPDATE_DS@
+NTPDATE_MS = @NTPDATE_MS@
+NTPDATE_NI = @NTPDATE_NI@
+NTPDC_DB = @NTPDC_DB@
+NTPDC_DL = @NTPDC_DL@
+NTPDC_DS = @NTPDC_DS@
+NTPDC_MS = @NTPDC_MS@
+NTPDC_NI = @NTPDC_NI@
+NTPDSIM_DB = @NTPDSIM_DB@
+NTPDSIM_DL = @NTPDSIM_DL@
+NTPDSIM_DS = @NTPDSIM_DS@
+NTPDSIM_MS = @NTPDSIM_MS@
+NTPDSIM_NI = @NTPDSIM_NI@
+NTPD_DB = @NTPD_DB@
+NTPD_DL = @NTPD_DL@
+NTPD_DS = @NTPD_DS@
+NTPD_MS = @NTPD_MS@
+NTPD_NI = @NTPD_NI@
+NTPQ_DB = @NTPQ_DB@
+NTPQ_DL = @NTPQ_DL@
+NTPQ_DS = @NTPQ_DS@
+NTPQ_MS = @NTPQ_MS@
+NTPQ_NI = @NTPQ_NI@
+NTPSNMPD_DB = @NTPSNMPD_DB@
+NTPSNMPD_DL = @NTPSNMPD_DL@
+NTPSNMPD_DS = @NTPSNMPD_DS@
+NTPSNMPD_MS = @NTPSNMPD_MS@
+NTPSNMPD_NI = @NTPSNMPD_NI@
+NTPSWEEP_DB = @NTPSWEEP_DB@
+NTPSWEEP_DL = @NTPSWEEP_DL@
+NTPSWEEP_DS = @NTPSWEEP_DS@
+NTPSWEEP_MS = @NTPSWEEP_MS@
+NTPSWEEP_NI = @NTPSWEEP_NI@
+NTPTIME_DB = @NTPTIME_DB@
+NTPTIME_DL = @NTPTIME_DL@
+NTPTIME_DS = @NTPTIME_DS@
+NTPTIME_MS = @NTPTIME_MS@
+NTPTIME_NI = @NTPTIME_NI@
+NTPTRACE_DB = @NTPTRACE_DB@
+NTPTRACE_DL = @NTPTRACE_DL@
+NTPTRACE_DS = @NTPTRACE_DS@
+NTPTRACE_MS = @NTPTRACE_MS@
+NTPTRACE_NI = @NTPTRACE_NI@
+NTP_KEYGEN_DB = @NTP_KEYGEN_DB@
+NTP_KEYGEN_DL = @NTP_KEYGEN_DL@
+NTP_KEYGEN_DS = @NTP_KEYGEN_DS@
+NTP_KEYGEN_MS = @NTP_KEYGEN_MS@
+NTP_KEYGEN_NI = @NTP_KEYGEN_NI@
+NTP_KEYSDIR = @NTP_KEYSDIR@
+NTP_WAIT_DB = @NTP_WAIT_DB@
+NTP_WAIT_DL = @NTP_WAIT_DL@
+NTP_WAIT_DS = @NTP_WAIT_DS@
+NTP_WAIT_MS = @NTP_WAIT_MS@
+NTP_WAIT_NI = @NTP_WAIT_NI@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_NET_SNMP_CONFIG = @PATH_NET_SNMP_CONFIG@
+PATH_PERL = @PATH_PERL@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PATH_TEST = @PATH_TEST@
+PERLLIBDIR = @PERLLIBDIR@
+PKG_CONFIG = @PKG_CONFIG@
+POSIX_SHELL = @POSIX_SHELL@
+PROPDELAY = @PROPDELAY@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SNMP_CFLAGS = @SNMP_CFLAGS@
+SNMP_CPPFLAGS = @SNMP_CPPFLAGS@
+SNMP_LIBS = @SNMP_LIBS@
+SNTP = @SNTP@
+SNTP_DB = @SNTP_DB@
+SNTP_DL = @SNTP_DL@
+SNTP_DS = @SNTP_DS@
+SNTP_MS = @SNTP_MS@
+SNTP_NI = @SNTP_NI@
+STDNORETURN_H = @STDNORETURN_H@
+STRIP = @STRIP@
+TESTDCF = @TESTDCF@
+TICKADJ_DB = @TICKADJ_DB@
+TICKADJ_DL = @TICKADJ_DL@
+TICKADJ_DS = @TICKADJ_DS@
+TICKADJ_MS = @TICKADJ_MS@
+TICKADJ_NI = @TICKADJ_NI@
+TIMETRIM_DB = @TIMETRIM_DB@
+TIMETRIM_DL = @TIMETRIM_DL@
+TIMETRIM_DS = @TIMETRIM_DS@
+TIMETRIM_MS = @TIMETRIM_MS@
+TIMETRIM_NI = @TIMETRIM_NI@
+VERSION = @VERSION@
+VER_SUFFIX = @VER_SUFFIX@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+NULL =
+BUILT_SOURCES = check-libntp .deps-ver
+CLEANFILES = check-libntp .deps-ver
+noinst_LIBRARIES = @MAKE_LIBPARSE@ @MAKE_LIBPARSE_KERNEL@
+EXTRA_LIBRARIES = libparse.a libparse_kernel.a
+noinst_PROGRAMS = @MAKE_PARSEKMODULE@
+K_CFLAGS = -DPARSESTREAM -DNTP_NEED_BOPS
+
+# info_trimble.c was mistakenly created in the build directory
+# previously. It is located in $(srcdir) and any updates must
+# end up there.
+libparse_a_SOURCES = parse.c \
+ parse_conf.c \
+ clk_meinberg.c \
+ clk_schmid.c \
+ clk_rawdcf.c \
+ clk_trimtsip.c \
+ clk_dcf7000.c \
+ clk_trimtaip.c \
+ clk_rcc8000.c \
+ clk_hopf6021.c \
+ clk_computime.c \
+ clk_wharton.c \
+ clk_varitext.c \
+ clk_sel240x.c \
+ data_mbg.c \
+ info_trimble.c \
+ trim_info.c \
+ binio.c \
+ ieee754io.c \
+ mfp_mul.c \
+ gpstolfp.c \
+ $(NULL)
+
+libparse_kernel_a_SOURCES =
+libparse_kernel_a_LIBADD = \
+ kparse.o \
+ kparse_conf.o \
+ kclk_computime.o \
+ kclk_dcf7000.o \
+ kclk_hopf6021.o \
+ kclk_meinberg.o \
+ kclk_rawdcf.o \
+ kclk_rcc8000.o \
+ kclk_schmid.o \
+ kclk_trimtaip.o \
+ kclk_trimtsip.o \
+ kclk_varitext.o \
+ kclk_wharton.o \
+ kclk_sel240x.o \
+ kbinio.o \
+ kieee754io.o \
+ kmfp_mul.o \
+ kgpstolfp.o \
+ $(NULL)
+
+AM_CFLAGS = $(CFLAGS_NTP)
+AM_CPPFLAGS = $(NTP_INCS) -I$(top_srcdir)/kernel $(CPPFLAGS_NTP)
+EXTRA_DIST = parsesolaris.c parsestreams.c mkinfo_scmd.sed mkinfo_rcmd.sed info_trimble.c
+NTP_INCS = -I$(top_srcdir)/include -I$(top_srcdir)/lib/isc/include \
+ -I$(top_srcdir)/lib/isc/$(LIBISC_PTHREADS_NOTHREADS)/include \
+ -I$(top_srcdir)/lib/isc/unix/include
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(top_srcdir)/sntp/check-libntp.mf $(top_srcdir)/depsver.mf $(top_srcdir)/includes.mf $(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) --foreign libparse/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign libparse/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):
+
+clean-noinstLIBRARIES:
+ -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libparse.a: $(libparse_a_OBJECTS) $(libparse_a_DEPENDENCIES)
+ $(AM_V_at)-rm -f libparse.a
+ $(AM_V_AR)$(libparse_a_AR) libparse.a $(libparse_a_OBJECTS) $(libparse_a_LIBADD)
+ $(AM_V_at)$(RANLIB) libparse.a
+libparse_kernel.a: $(libparse_kernel_a_OBJECTS) $(libparse_kernel_a_DEPENDENCIES)
+ $(AM_V_at)-rm -f libparse_kernel.a
+ $(AM_V_AR)$(libparse_kernel_a_AR) libparse_kernel.a $(libparse_kernel_a_OBJECTS) $(libparse_kernel_a_LIBADD)
+ $(AM_V_at)$(RANLIB) libparse_kernel.a
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+parsesolaris$(EXEEXT): $(parsesolaris_OBJECTS) $(parsesolaris_DEPENDENCIES)
+ @rm -f parsesolaris$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(parsesolaris_OBJECTS) $(parsesolaris_LDADD) $(LIBS)
+parsestreams$(EXEEXT): $(parsestreams_OBJECTS) $(parsestreams_DEPENDENCIES)
+ @rm -f parsestreams$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(parsestreams_OBJECTS) $(parsestreams_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/binio.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_computime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_dcf7000.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_hopf6021.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_meinberg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_rawdcf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_rcc8000.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_schmid.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_sel240x.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_trimtaip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_trimtsip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_varitext.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clk_wharton.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data_mbg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpstolfp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ieee754io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info_trimble.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mfp_mul.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse_conf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parsesolaris.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parsestreams.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trim_info.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+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: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS)
+installdirs:
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) 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:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+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."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+ clean-noinstPROGRAMS 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-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 \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLIBRARIES clean-noinstPROGRAMS ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ 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 mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+$(srcdir)/info_trimble.c: $(top_srcdir)/include/trimble.h $(srcdir)/Makefile.am $(srcdir)/mkinfo_scmd.sed $(srcdir)/mkinfo_rcmd.sed
+ sed -n -f $(srcdir)/mkinfo_scmd.sed $(top_srcdir)/include/trimble.h > info_trimble.new
+ sed -n -f $(srcdir)/mkinfo_rcmd.sed $(top_srcdir)/include/trimble.h >> info_trimble.new
+ mv -f info_trimble.new $@
+
+kieee754io.o: $(srcdir)/ieee754io.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/ieee754io.c -o $@
+
+kmfp_mul.o: $(srcdir)/mfp_mul.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/mfp_mul.c -o $@
+
+kgpstolfp.o: $(srcdir)/gpstolfp.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/gpstolfp.c -o $@
+
+kbinio.o: $(srcdir)/binio.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/binio.c -o $@
+
+kclk_computime.o: $(srcdir)/clk_computime.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_computime.c -o $@
+
+kclk_dcf7000.o: $(srcdir)/clk_dcf7000.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_dcf7000.c -o $@
+
+kclk_hopf6021.o: $(srcdir)/clk_hopf6021.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_hopf6021.c -o $@
+
+kclk_meinberg.o: $(srcdir)/clk_meinberg.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_meinberg.c -o $@
+
+kclk_rawdcf.o: $(srcdir)/clk_rawdcf.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_rawdcf.c -o $@
+
+kclk_rcc8000.o: $(srcdir)/clk_rcc8000.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_rcc8000.c -o $@
+
+kclk_schmid.o: $(srcdir)/clk_schmid.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_schmid.c -o $@
+
+kclk_trimtaip.o: $(srcdir)/clk_trimtaip.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_trimtaip.c -o $@
+
+kclk_trimtsip.o: $(srcdir)/clk_trimtsip.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_trimtsip.c -o $@
+
+kclk_varitext.o: $(srcdir)/clk_varitext.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_varitext.c -o $@
+
+kclk_wharton.o: $(srcdir)/clk_wharton.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_wharton.c -o $@
+
+kclk_sel240x.o: $(srcdir)/clk_sel240x.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/clk_sel240x.c -o $@
+
+kparse.o: $(srcdir)/parse.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/parse.c -o $@
+
+kparse_conf.o: $(srcdir)/parse_conf.c
+ $(COMPILE) $(K_CFLAGS) -c $(srcdir)/parse_conf.c -o $@
+
+parsestreams.loadable_module.o: $(parsestreams_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+ $(LD) -r -o $@ $(parsestreams_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+
+parse: $(parsesolaris_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+ $(LD) -r -o $@ $(parsesolaris_OBJECTS) libparse_kernel.a ../libntp/libntp.a
+
+parsesolaris.o: sys/systm.h
+
+sys/systm.h:
+ -mkdir sys
+ sed -e '/ffs(.*)/d' < /usr/include/sys/systm.h > sys/systm.h
+
+check-libparse: $(noinst_LIBRARIES)
+ @: do-nothing action to avoid default SCCS get
+
+check-libntp: ../libntp/libntp.a
+ @echo stamp > $@
+
+../libntp/libntp.a:
+ cd ../libntp && $(MAKE) $(AM_MAKEFLAGS) libntp.a
+$(DEPDIR)/deps-ver: $(top_srcdir)/deps-ver
+ @[ -f $@ ] || \
+ cp $(top_srcdir)/deps-ver $@
+ @[ -w $@ ] || \
+ chmod ug+w $@
+ @cmp $(top_srcdir)/deps-ver $@ > /dev/null || ( \
+ $(MAKE) $(AM_MAKEFLAGS) clean && \
+ echo -n "Prior $(subdir)/$(DEPDIR) version " && \
+ cat $@ && \
+ rm -rf $(DEPDIR) && \
+ mkdir $(DEPDIR) && \
+ case "$(top_builddir)" in \
+ .) \
+ ./config.status Makefile depfiles \
+ ;; \
+ *) \
+ cd "$(top_builddir)" && \
+ ./config.status $(subdir)/Makefile depfiles && \
+ cd $(subdir) \
+ ;; \
+ esac && \
+ echo -n "Cleaned $(subdir)/$(DEPDIR) version " && \
+ cat $(top_srcdir)/deps-ver \
+ )
+ cp $(top_srcdir)/deps-ver $@
+
+.deps-ver: $(top_srcdir)/deps-ver
+ @[ ! -d $(DEPDIR) ] || $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/deps-ver
+ @touch $@
+
+#
+# depsver.mf included in Makefile.am for directories with .deps
+#
+# When building in the same directory with sources that change over
+# time, such as when tracking using bk, the .deps files can become
+# stale with respect to moved, deleted, or superceded headers. Most
+# commonly, this would exhibit as make reporting a failure to make a
+# header file which is no longer in the location given. To address
+# this issue, we use a deps-ver file which is updated with each change
+# that breaks old .deps files. A copy of deps-ver is made into
+# $(DEPDIR) if not already present. If $(DEPDIR)/deps-ver is present
+# with different contents than deps-ver, we make clean to ensure all
+# .o files built before the incompatible change are rebuilt along with
+# their updated .deps files, then remove $(DEPDIR) and recreate it as
+# empty stubs.
+#
+# It is normal when configured with --disable-dependency-tracking for
+# the DEPDIR to not have been created. For this reason, we use the
+# intermediate target .deps-ver, which invokes make recursively if
+# DEPDIR exists.
+#
+# If you modify depsver.mf, please make the changes to the master
+# copy, the one in sntp is copied by the bootstrap script from it.
+#
+# This comment block follows rather than leads the related code so that
+# it stays with it in the generated Makefile.in and Makefile.
+#
+
+# 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/libparse/README b/libparse/README
new file mode 100644
index 0000000..ac77054
--- /dev/null
+++ b/libparse/README
@@ -0,0 +1,96 @@
+PARSE reference clock driver:
+
+This directory contains the files making up the parser for
+the parse refclock driver. For reasonably sane clocks this refclock
+drivers allows a refclock implementation by just providing a
+conversion routine and the appropriate NTP parameters. Refclock
+support can run as low a 3k code with the parse refclock driver.
+
+The modules in here are designed to live in two worlds. In userlevel
+as part of the xntp daemon and in kernel land as part of a STREAMS module
+or, if someone gets to it, as part of a line discipline. Currently only
+SunOS4.x/SunOS5.x STREAMS are supported (volunteers for other vendors like HP?).
+This structure means, that refclock_parse can work with or without kernel
+support. Kernelsupport increases accuracy tremendingly. The current restriction
+of the parse driver is that it only supports SYSV type ttys and that kernel
+support is only available for Suns right now.
+
+Three kernel modules are part of this directory. These work only on
+SunOS (SunOS4 and SunOS5).
+
+ SunOS4 (aka Solaris 1.x):
+ parsestreams.loadable_module.o - standard parse module for SunOS 4
+
+ Both modules can be loaded via modload <modulename>.
+
+ SunOS5 (aka Solaris 2.x):
+ parse - auto loadable streams module
+
+ To install just drop "parse" into /kernel/strmod and
+ start the daemon (SunOS5 will do the rest).
+
+The structure of the parse reference clock driver is as follows:
+
+ ntpd - contains NTP implementation and calls a reference clock
+ 127.127.8.x which is implemented by
+ refclock_parse.c
+ - which contains several refclock decriptions. These are
+ selected by the x part of the refclock address.
+ The lower two bits specify the device to use. Thus the
+ value (x % 4) determines the device to open
+ (/dev/refclock-0 - /dev/refclock-3).
+
+ The kind of clock is selected by the mode parameter. This parameter
+ selects the clock type which deterimines how I/O is done,
+ the tty parameters and the NTP parameters.
+
+ refclock_parse operates on an abstract reference clock
+ that delivers time stamps and stati. Offsets and sychron-
+ isation information is derived from this data and passed
+ on to refclock_receive of xntp which uses that data for
+ syncronisation.
+
+ The abstract reference clock is generated by the parse*
+ routines. They parse the incoming data stream from the
+ clock and convert it to the appropriate time stamps.
+ The data is also mapped int the abstract clock states
+ POWERUP - clock has no valid phase and time code
+ information
+
+ NOSYNC - Time code is not confirmed, phase is probably
+ ok.
+ SYNC - Time code and phase are correct.
+
+ A clock is trusted for a certain time (type parameter) when
+ it leaves the SYNC state. This is derived from the
+ observation that quite a few clocks can still generate good
+ time code information when losing contact to their
+ synchronisation source. When the clock does not reagain
+ synchronisation in that trust period it will be deemed
+ unsynchronised until it regains synchronisation. The same
+ will happen if xntp sees the clock unsynchronised at
+ startup.
+
+ The upper bit of x specifies that all samples delivered
+ from the clock should be used to discipline the NTP
+ loopfilter. For clock with accurate once a second time
+ information this means big improvements for time keeping.
+ A prerequisite for passing on the time stamps to
+ the loopfilter is, that the clock is in synchronised state.
+
+ parse.c These are the general routines to parse the incoming data
+ stream. Usually these routines should not require
+ modification.
+
+ clk_*.c These files hole the conversion code for the time stamps
+ and the description how the time code can be parsed and
+ where the time stamps are to be taken.
+ If you want to add a new clock type this is the file
+ you need to write in addition to mention it in
+ parse_conf.c and setting up the NTP and TTY parameters
+ in refclock_parse.c.
+
+Further information can be found in parse/README.parse and the various source
+files.
+
+Frank Kardel
diff --git a/libparse/binio.c b/libparse/binio.c
new file mode 100644
index 0000000..24aa286
--- /dev/null
+++ b/libparse/binio.c
@@ -0,0 +1,156 @@
+/*
+ * /src/NTP/ntp4-dev/libntp/binio.c,v 4.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * binio.c,v 4.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Jul 20 12:55:33 1997 $
+ *
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include "binio.h"
+
+long
+get_lsb_short(
+ unsigned char **bufpp
+ )
+{
+ long retval;
+
+ retval = *((*bufpp)++);
+ retval |= *((*bufpp)++) << 8;
+
+ return (retval & 0x8000) ? (~0xFFFF | retval) : retval;
+}
+
+void
+put_lsb_short(
+ unsigned char **bufpp,
+ long val
+ )
+{
+ *((*bufpp)++) = (unsigned char) (val & 0xFF);
+ *((*bufpp)++) = (unsigned char) ((val >> 8) & 0xFF);
+}
+
+long
+get_lsb_long(
+ unsigned char **bufpp
+ )
+{
+ long retval;
+
+ retval = *((*bufpp)++);
+ retval |= *((*bufpp)++) << 8;
+ retval |= *((*bufpp)++) << 16;
+ retval |= (u_long)*((*bufpp)++) << 24;
+
+ return retval;
+}
+
+void
+put_lsb_long(
+ unsigned char **bufpp,
+ long val
+ )
+{
+ *((*bufpp)++) = (unsigned char)(val & 0xFF);
+ *((*bufpp)++) = (unsigned char)((val >> 8) & 0xFF);
+ *((*bufpp)++) = (unsigned char)((val >> 16) & 0xFF);
+ *((*bufpp)++) = (unsigned char)((val >> 24) & 0xFF);
+}
+
+long
+get_msb_short(
+ unsigned char **bufpp
+ )
+{
+ long retval;
+
+ retval = *((*bufpp)++) << 8;
+ retval |= *((*bufpp)++);
+
+ return (retval & 0x8000) ? (~0xFFFF | retval) : retval;
+}
+
+void
+put_msb_short(
+ unsigned char **bufpp,
+ long val
+ )
+{
+ *((*bufpp)++) = (unsigned char)((val >> 8) & 0xFF);
+ *((*bufpp)++) = (unsigned char)( val & 0xFF);
+}
+
+long
+get_msb_long(
+ unsigned char **bufpp
+ )
+{
+ long retval;
+
+ retval = (u_long)*((*bufpp)++) << 24;
+ retval |= *((*bufpp)++) << 16;
+ retval |= *((*bufpp)++) << 8;
+ retval |= *((*bufpp)++);
+
+ return retval;
+}
+
+void
+put_msb_long(
+ unsigned char **bufpp,
+ long val
+ )
+{
+ *((*bufpp)++) = (unsigned char)((val >> 24) & 0xFF);
+ *((*bufpp)++) = (unsigned char)((val >> 16) & 0xFF);
+ *((*bufpp)++) = (unsigned char)((val >> 8 ) & 0xFF);
+ *((*bufpp)++) = (unsigned char)( val & 0xFF);
+}
+
+/*
+ * binio.c,v
+ * Revision 4.2 1999/02/21 12:17:34 kardel
+ * 4.91f reconcilation
+ *
+ * Revision 4.1 1998/06/28 16:47:50 kardel
+ * added {get,put}_msb_{short,long} functions
+ *
+ * Revision 4.0 1998/04/10 19:46:16 kardel
+ * Start 4.0 release version numbering
+ *
+ * Revision 1.1 1998/04/10 19:27:46 kardel
+ * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
+ *
+ * Revision 1.1 1997/10/06 21:05:46 kardel
+ * new parse structure
+ *
+ */
diff --git a/libparse/clk_computime.c b/libparse/clk_computime.c
new file mode 100644
index 0000000..1068576
--- /dev/null
+++ b/libparse/clk_computime.c
@@ -0,0 +1,219 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_COMPUTIME)
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_computime.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * clk_computime.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * Supports Diem's Computime Radio Clock
+ *
+ * Used the Meinberg clock as a template for Diem's Computime Radio Clock
+ *
+ * adapted by Alois Camenzind <alois.camenzind@ubs.ch>
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+#include "ntp_stdlib.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+extern int printf (const char *, ...);
+#endif
+
+/*
+ * The Computime receiver sends a datagram in the following format every minute
+ *
+ * Timestamp T:YY:MM:MD:WD:HH:MM:SSCRLF
+ * Pos 0123456789012345678901 2 3
+ * 0000000000111111111122 2 2
+ * Parse T: : : : : : : rn
+ *
+ * T Startcharacter "T" specifies start of the timestamp
+ * YY Year MM Month 1-12
+ * MD Day of the month
+ * WD Day of week
+ * HH Hour
+ * MM Minute
+ * SS Second
+ * CR Carriage return
+ * LF Linefeed
+ *
+ */
+
+static struct format computime_fmt =
+{
+ {
+ {8, 2}, {5, 2}, {2, 2}, /* day, month, year */
+ {14, 2}, {17, 2}, {20, 2}, /* hour, minute, second */
+ {11, 2}, /* dayofweek, */
+ },
+ (const unsigned char *)"T: : : : : : : \r\n",
+ 0
+};
+
+static u_long cvt_computime (unsigned char *, int, struct format *, clocktime_t *, void *);
+static unsigned long inp_computime (parse_t *, unsigned int, timestamp_t *);
+
+clockformat_t clock_computime =
+{
+ inp_computime, /* Computime input handling */
+ cvt_computime, /* Computime conversion */
+ 0, /* no PPS monitoring */
+ (void *)&computime_fmt, /* conversion configuration */
+ "Diem's Computime Radio Clock", /* Computime Radio Clock */
+ 24, /* string buffer */
+ 0 /* no private data (complete pakets) */
+};
+
+/*
+ * cvt_computime
+ *
+ * convert simple type format
+ */
+static u_long
+cvt_computime(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+
+ if (!Strok(buffer, format->fixed_string)) {
+ return CVT_NONE;
+ } else {
+ if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
+ format->field_offsets[O_DAY].length) ||
+ Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
+ format->field_offsets[O_MONTH].length) ||
+ Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
+ format->field_offsets[O_YEAR].length) ||
+ Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
+ format->field_offsets[O_HOUR].length) ||
+ Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
+ format->field_offsets[O_MIN].length) ||
+ Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
+ format->field_offsets[O_SEC].length)) {
+ return CVT_FAIL | CVT_BADFMT;
+ } else {
+
+ clock_time->flags = 0;
+ clock_time->utcoffset = 0; /* We have UTC time */
+
+ return CVT_OK;
+ }
+ }
+}
+
+/*
+ * inp_computime
+ *
+ * grep data from input stream
+ */
+static u_long
+inp_computime(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("inp_computime(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case 'T':
+ parseprintf(DD_PARSE, ("inp_computime: START seen\n"));
+
+ parseio->parse_index = 1;
+ parseio->parse_data[0] = ch;
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ return PARSE_INP_SKIP;
+
+ case '\n':
+ parseprintf(DD_PARSE, ("inp_computime: END seen\n"));
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+ default:
+ return parse_addchar(parseio, ch);
+ }
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_COMPUTIME) */
+int clk_computime_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_COMPUTIME) */
+
+/*
+ * clk_computime.c,v
+ * Revision 4.10 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.9 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.6 1999/11/28 09:13:49 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.5 1998/06/14 21:09:34 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.4 1998/06/13 12:00:38 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:26 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/06/12 09:13:24 kardel
+ * conditional compile macros fixed
+ * printf prototype
+ *
+ * Revision 4.1 1998/05/24 09:39:51 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:27 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 1.8 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/clk_dcf7000.c b/libparse/clk_dcf7000.c
new file mode 100644
index 0000000..bfd9a74
--- /dev/null
+++ b/libparse/clk_dcf7000.c
@@ -0,0 +1,214 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_dcf7000.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * clk_dcf7000.c,v 4.10 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * ELV DCF7000 module
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_DCF7000)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include "ntp_stdlib.h"
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+extern int printf (const char *, ...);
+#endif
+
+static struct format dcf7000_fmt =
+{ /* ELV DCF7000 */
+ {
+ { 6, 2}, { 3, 2}, { 0, 2},
+ { 12, 2}, { 15, 2}, { 18, 2},
+ { 9, 2}, { 21, 2},
+ },
+ (const unsigned char *)" - - - - - - - \r",
+ 0
+};
+static u_long cvt_dcf7000 (unsigned char *, int, struct format *, clocktime_t *, void *);
+static unsigned long inp_dcf7000 (parse_t *, unsigned int, timestamp_t *);
+
+clockformat_t clock_dcf7000 =
+{
+ inp_dcf7000, /* DCF7000 input handling */
+ cvt_dcf7000, /* ELV DCF77 conversion */
+ 0, /* no direct PPS monitoring */
+ (void *)&dcf7000_fmt, /* conversion configuration */
+ "ELV DCF7000", /* ELV clock */
+ 24, /* string buffer */
+ 0 /* no private data (complete pakets) */
+};
+
+/*
+ * cvt_dcf7000
+ *
+ * convert dcf7000 type format
+ */
+static u_long
+cvt_dcf7000(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ if (!Strok(buffer, format->fixed_string))
+ {
+ return CVT_NONE;
+ }
+ else
+ {
+ if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
+ format->field_offsets[O_DAY].length) ||
+ Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
+ format->field_offsets[O_MONTH].length) ||
+ Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
+ format->field_offsets[O_YEAR].length) ||
+ Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
+ format->field_offsets[O_HOUR].length) ||
+ Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
+ format->field_offsets[O_MIN].length) ||
+ Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
+ format->field_offsets[O_SEC].length))
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ else
+ {
+ unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
+ long flags;
+
+ clock_time->flags = 0;
+ clock_time->usecond = 0;
+
+ if (Stoi(f, &flags, format->field_offsets[O_FLAGS].length))
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ else
+ {
+ if (flags & 0x1)
+ clock_time->utcoffset = -2*60*60;
+ else
+ clock_time->utcoffset = -1*60*60;
+
+ if (flags & 0x2)
+ clock_time->flags |= PARSEB_ANNOUNCE;
+
+ if (flags & 0x4)
+ clock_time->flags |= PARSEB_NOSYNC;
+ }
+ return CVT_OK;
+ }
+ }
+}
+
+/*
+ * inp_dcf700
+ *
+ * grep data from input stream
+ */
+static u_long
+inp_dcf7000(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("inp_dcf7000(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case '\r':
+ parseprintf(DD_PARSE, ("inp_dcf7000: EOL seen\n"));
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+ default:
+ return parse_addchar(parseio, ch);
+ }
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_DCF7000) */
+int clk_dcf7000_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_DCF7000) */
+
+/*
+ * History:
+ *
+ * clk_dcf7000.c,v
+ * Revision 4.10 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.9 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.6 1999/11/28 09:13:49 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.5 1998/06/14 21:09:34 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.4 1998/06/13 12:01:59 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:27 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/06/12 09:13:24 kardel
+ * conditional compile macros fixed
+ * printf prototype
+ *
+ * Revision 4.1 1998/05/24 09:39:51 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:28 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.18 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/clk_hopf6021.c b/libparse/clk_hopf6021.c
new file mode 100644
index 0000000..033d2d2
--- /dev/null
+++ b/libparse/clk_hopf6021.c
@@ -0,0 +1,283 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_hopf6021.c,v 4.10 2004/11/14 15:29:41 kardel RELEASE_20050508_A
+ *
+ * clk_hopf6021.c,v 4.10 2004/11/14 15:29:41 kardel RELEASE_20050508_A
+ *
+ * Radiocode Clocks HOPF Funkuhr 6021 mit serieller Schnittstelle
+ * base code version from 24th Nov 1995 - history at end
+ *
+ * Created by F.Schnekenbuehl <frank@comsys.dofn.de> from clk_rcc8000.c
+ * Nortel DASA Network Systems GmbH, Department: ND250
+ * A Joint venture of Daimler-Benz Aerospace and Nortel
+ *
+ * This program 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_HOPF6021)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+#include "ascii.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include "ntp_stdlib.h"
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+extern int printf (const char *, ...);
+#endif
+
+/*
+ * hopf Funkuhr 6021
+ * used with 9600,8N1,
+ * UTC ueber serielle Schnittstelle
+ * Sekundenvorlauf ON
+ * ETX zum Sekundenvorlauf ON
+ * Datenstring 6021
+ * Ausgabe Uhrzeit und Datum
+ * Senden mit Steuerzeichen
+ * Senden sekuendlich
+ */
+
+/*
+ * Type 6021 Serial Output format
+ *
+ * 000000000011111111 / char
+ * 012345678901234567 \ position
+ * sABHHMMSSDDMMYYnre Actual
+ * C4110046231195 Parse
+ * s enr Check
+ *
+ * s = STX (0x02), e = ETX (0x03)
+ * n = NL (0x0A), r = CR (0x0D)
+ *
+ * A B - Status and weekday
+ *
+ * A - Status
+ *
+ * 8 4 2 1
+ * x x x 0 - no announcement
+ * x x x 1 - Summertime - wintertime - summertime announcement
+ * x x 0 x - Wintertime
+ * x x 1 x - Summertime
+ * 0 0 x x - Time/Date invalid
+ * 0 1 x x - Internal clock used
+ * 1 0 x x - Radio clock
+ * 1 1 x x - Radio clock highprecision
+ *
+ * B - 8 4 2 1
+ * 0 x x x - MESZ/MEZ
+ * 1 x x x - UTC
+ * x 0 0 1 - Monday
+ * x 0 1 0 - Tuesday
+ * x 0 1 1 - Wednesday
+ * x 1 0 0 - Thursday
+ * x 1 0 1 - Friday
+ * x 1 1 0 - Saturday
+ * x 1 1 1 - Sunday
+ */
+
+#define HOPF_DSTWARN 0x01 /* DST switch warning */
+#define HOPF_DST 0x02 /* DST in effect */
+
+#define HOPF_MODE 0x0C /* operation mode mask */
+#define HOPF_INVALID 0x00 /* no time code available */
+#define HOPF_INTERNAL 0x04 /* internal clock */
+#define HOPF_RADIO 0x08 /* radio clock */
+#define HOPF_RADIOHP 0x0C /* high precision radio clock */
+
+#define HOPF_UTC 0x08 /* time code in UTC */
+#define HOPF_WMASK 0x07 /* mask for weekday code */
+
+static struct format hopf6021_fmt =
+{
+ {
+ { 9, 2 }, {11, 2}, { 13, 2}, /* Day, Month, Year */
+ { 3, 2 }, { 5, 2}, { 7, 2}, /* Hour, Minute, Second */
+ { 2, 1 }, { 1, 1}, { 0, 0}, /* Weekday, Flags, Zone */
+ /* ... */
+ },
+ (const unsigned char *)"\002 \n\r\003",
+ 0
+};
+
+#define OFFS(x) format->field_offsets[(x)].offset
+#define STOI(x, y) Stoi(&buffer[OFFS(x)], y, format->field_offsets[(x)].length)
+#define hexval(x) (('0' <= (x) && (x) <= '9') ? (x) - '0' : \
+ ('a' <= (x) && (x) <= 'f') ? (x) - 'a' + 10 : \
+ ('A' <= (x) && (x) <= 'F') ? (x) - 'A' + 10 : \
+ -1)
+
+static unsigned long cvt_hopf6021 (unsigned char *, int, struct format *, clocktime_t *, void *);
+static unsigned long inp_hopf6021 (parse_t *, unsigned int, timestamp_t *);
+
+clockformat_t clock_hopf6021 =
+{
+ inp_hopf6021, /* HOPF 6021 input handling */
+ cvt_hopf6021, /* Radiocode clock conversion */
+ 0, /* no direct PPS monitoring */
+ (void *)&hopf6021_fmt, /* conversion configuration */
+ "hopf Funkuhr 6021", /* clock format name */
+ 19, /* string buffer */
+ 0 /* private data length, no private data */
+};
+
+static unsigned long
+cvt_hopf6021(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ unsigned char status,weekday;
+
+ if (!Strok(buffer, format->fixed_string))
+ {
+ return CVT_NONE;
+ }
+
+ if ( STOI(O_DAY, &clock_time->day) ||
+ STOI(O_MONTH, &clock_time->month) ||
+ STOI(O_YEAR, &clock_time->year) ||
+ STOI(O_HOUR, &clock_time->hour) ||
+ STOI(O_MIN, &clock_time->minute) ||
+ STOI(O_SEC, &clock_time->second)
+ )
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ clock_time->usecond = 0;
+ clock_time->utcoffset = 0;
+
+ status = hexval(buffer[OFFS(O_FLAGS)]);
+ weekday= hexval(buffer[OFFS(O_WDAY)]);
+
+ if ((status == 0xFF) || (weekday == 0xFF))
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ clock_time->flags = 0;
+
+ if (weekday & HOPF_UTC)
+ {
+ clock_time->flags |= PARSEB_UTC;
+ }
+ else
+ {
+ if (status & HOPF_DST)
+ {
+ clock_time->flags |= PARSEB_DST;
+ clock_time->utcoffset = -2*60*60; /* MET DST */
+ }
+ else
+ {
+ clock_time->utcoffset = -1*60*60; /* MET */
+ }
+ }
+
+ clock_time->flags |= (status & HOPF_DSTWARN) ? PARSEB_ANNOUNCE : 0;
+
+ switch (status & HOPF_MODE)
+ {
+ case HOPF_INVALID: /* Time/Date invalid */
+ clock_time->flags |= PARSEB_POWERUP;
+ break;
+
+ case HOPF_INTERNAL: /* internal clock */
+ clock_time->flags |= PARSEB_NOSYNC;
+ break;
+
+ case HOPF_RADIO: /* Radio clock */
+ case HOPF_RADIOHP: /* Radio clock high precision */
+ break;
+
+ default:
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ return CVT_OK;
+}
+
+/*
+ * inp_hopf6021
+ *
+ * grep data from input stream
+ */
+static u_long
+inp_hopf6021(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("inp_hopf6021(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case ETX:
+ parseprintf(DD_PARSE, ("inp_hopf6021: EOL seen\n"));
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+ default:
+ return parse_addchar(parseio, ch);
+ }
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_HOPF6021) */
+int clk_hopf6021_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_HOPF6021) */
+
+/*
+ * History:
+ *
+ * clk_hopf6021.c,v
+ * Revision 4.10 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.7 1999/11/28 09:13:49 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.6 1998/11/15 20:27:57 kardel
+ * Release 4.0.73e13 reconcilation
+ *
+ * Revision 4.5 1998/06/14 21:09:35 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.4 1998/06/13 12:02:38 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:27 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/06/12 09:13:25 kardel
+ * conditional compile macros fixed
+ * printf prototype
+ *
+ * Revision 4.1 1998/05/24 09:39:52 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:29 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.6 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/clk_meinberg.c b/libparse/clk_meinberg.c
new file mode 100644
index 0000000..bc0ac0e
--- /dev/null
+++ b/libparse/clk_meinberg.c
@@ -0,0 +1,776 @@
+/*
+ * /src/NTP/REPOSITORY/ntp4-dev/libparse/clk_meinberg.c,v 4.12.2.1 2005/09/25 10:22:35 kardel RELEASE_20050925_A
+ *
+ * clk_meinberg.c,v 4.12.2.1 2005/09/25 10:22:35 kardel RELEASE_20050925_A
+ *
+ * Meinberg clock support
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_MEINBERG)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "ntp_machine.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+#endif
+
+#include "ntp_stdlib.h"
+
+#include "ntp_stdlib.h"
+
+#include "mbg_gps166.h"
+#include "binio.h"
+#include "ascii.h"
+
+/*
+ * The Meinberg receiver every second sends a datagram of the following form
+ * (Standard Format)
+ *
+ * <STX>D:<dd>.<mm>.<yy>;T:<w>;U:<hh>:<mm>:<ss>;<S><F><D><A><ETX>
+ * pos: 0 00 00 0 00 0 11 111 1 111 12 2 22 2 22 2 2 2 3 3 3
+ * 1 23 45 6 78 9 01 234 5 678 90 1 23 4 56 7 8 9 0 1 2
+ * <STX> = '\002' ASCII start of text
+ * <ETX> = '\003' ASCII end of text
+ * <dd>,<mm>,<yy> = day, month, year(2 digits!!)
+ * <w> = day of week (sunday= 0)
+ * <hh>,<mm>,<ss> = hour, minute, second
+ * <S> = '#' if never synced since powerup for DCF C51
+ * = '#' if not PZF sychronisation available for PZF 535/509
+ * = ' ' if ok
+ * <F> = '*' if time comes from internal quartz
+ * = ' ' if completely synched
+ * <D> = 'S' if daylight saving time is active
+ * = 'U' if time is represented in UTC
+ * = ' ' if no special condition exists
+ * <A> = '!' during the hour preceeding an daylight saving time
+ * start/end change
+ * = 'A' leap second insert warning
+ * = ' ' if no special condition exists
+ *
+ * Extended data format (PZFUERL for PZF type clocks)
+ *
+ * <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <U><S><F><D><A><L><R><ETX>
+ * pos: 0 00 0 00 0 00 11 1 11 11 1 11 2 22 22 2 2 2 2 2 3 3 3
+ * 1 23 4 56 7 89 01 2 34 56 7 89 0 12 34 5 6 7 8 9 0 1 2
+ * <STX> = '\002' ASCII start of text
+ * <ETX> = '\003' ASCII end of text
+ * <dd>,<mm>,<yy> = day, month, year(2 digits!!)
+ * <w> = day of week (sunday= 0)
+ * <hh>,<mm>,<ss> = hour, minute, second
+ * <U> = 'U' UTC time display
+ * <S> = '#' if never synced since powerup else ' ' for DCF C51
+ * '#' if not PZF sychronisation available else ' ' for PZF 535/509
+ * <F> = '*' if time comes from internal quartz else ' '
+ * <D> = 'S' if daylight saving time is active else ' '
+ * <A> = '!' during the hour preceeding an daylight saving time
+ * start/end change
+ * <L> = 'A' LEAP second announcement
+ * <R> = 'R' alternate antenna
+ *
+ * Meinberg GPS166 receiver
+ *
+ * You must get the Uni-Erlangen firmware for the GPS receiver support
+ * to work to full satisfaction !
+ *
+ * <STX><dd>.<mm>.<yy>; <w>; <hh>:<mm>:<ss>; <+/-><00:00>; <U><S><F><D><A><L><R><L>; <position...><ETX>
+ *
+ * 000000000111111111122222222223333333333444444444455555555556666666
+ * 123456789012345678901234567890123456789012345678901234567890123456
+ * \x0209.07.93; 5; 08:48:26; +00:00; #*S!A L; 49.5736N 11.0280E 373m\x03
+ *
+ *
+ * <STX> = '\002' ASCII start of text
+ * <ETX> = '\003' ASCII end of text
+ * <dd>,<mm>,<yy> = day, month, year(2 digits!!)
+ * <w> = day of week (sunday= 0)
+ * <hh>,<mm>,<ss> = hour, minute, second
+ * <+/->,<00:00> = offset to UTC
+ * <S> = '#' if never synced since powerup else ' '
+ * <F> = '*' if position is not confirmed else ' '
+ * <D> = 'S' if daylight saving time is active else ' '
+ * <A> = '!' during the hour preceeding an daylight saving time
+ * start/end change
+ * <L> = 'A' LEAP second announcement
+ * <R> = 'R' alternate antenna (reminiscent of PZF535) usually ' '
+ * <L> = 'L' on 23:59:60
+ *
+ * Binary messages have a lead in for a fixed header of SOH
+ */
+
+/*--------------------------------------------------------------*/
+/* Name: csum() */
+/* */
+/* Purpose: Compute a checksum about a number of bytes */
+/* */
+/* Input: uchar *p address of the first byte */
+/* short n the number of bytes */
+/* */
+/* Output: -- */
+/* */
+/* Ret val: the checksum */
+/*+-------------------------------------------------------------*/
+
+unsigned long
+mbg_csum(
+ unsigned char *p,
+ unsigned int n
+ )
+{
+ unsigned long sum = 0;
+ short i;
+
+ for ( i = 0; i < n; i++ )
+ sum += *p++;
+
+ return( sum );
+} /* csum */
+
+void
+get_mbg_header(
+ unsigned char **bufpp,
+ GPS_MSG_HDR *headerp
+ )
+{
+ headerp->gps_cmd = get_lsb_short(bufpp);
+ headerp->gps_len = get_lsb_short(bufpp);
+ headerp->gps_data_csum = get_lsb_short(bufpp);
+ headerp->gps_hdr_csum = get_lsb_short(bufpp);
+}
+
+static struct format meinberg_fmt[] =
+{
+ {
+ {
+ { 3, 2}, { 6, 2}, { 9, 2},
+ { 18, 2}, { 21, 2}, { 24, 2},
+ { 14, 1}, { 27, 4}, { 29, 1},
+ },
+ (const unsigned char *)"\2D: . . ;T: ;U: . . ; \3",
+ 0
+ },
+ { /* special extended FAU Erlangen extended format */
+ {
+ { 1, 2}, { 4, 2}, { 7, 2},
+ { 14, 2}, { 17, 2}, { 20, 2},
+ { 11, 1}, { 25, 4}, { 27, 1},
+ },
+ (const unsigned char *)"\2 . . ; ; : : ; \3",
+ MBG_EXTENDED
+ },
+ { /* special extended FAU Erlangen GPS format */
+ {
+ { 1, 2}, { 4, 2}, { 7, 2},
+ { 14, 2}, { 17, 2}, { 20, 2},
+ { 11, 1}, { 32, 7}, { 35, 1},
+ { 25, 2}, { 28, 2}, { 24, 1}
+ },
+ (const unsigned char *)"\2 . . ; ; : : ; : ; ; . . ",
+ 0
+ }
+};
+
+static u_long cvt_meinberg (unsigned char *, int, struct format *, clocktime_t *, void *);
+static u_long cvt_mgps (unsigned char *, int, struct format *, clocktime_t *, void *);
+static u_long mbg_input (parse_t *, unsigned int, timestamp_t *);
+static u_long gps_input (parse_t *, unsigned int, timestamp_t *);
+
+struct msg_buf
+{
+ unsigned short len; /* len to fill */
+ unsigned short phase; /* current input phase */
+};
+
+#define MBG_NONE 0 /* no data input */
+#define MBG_HEADER 1 /* receiving header */
+#define MBG_DATA 2 /* receiving data */
+#define MBG_STRING 3 /* receiving standard data message */
+
+clockformat_t clock_meinberg[] =
+{
+ {
+ mbg_input, /* normal input handling */
+ cvt_meinberg, /* Meinberg conversion */
+ pps_one, /* easy PPS monitoring */
+ 0, /* conversion configuration */
+ "Meinberg Standard", /* Meinberg simple format - beware */
+ 32, /* string buffer */
+ 0 /* no private data (complete pakets) */
+ },
+ {
+ mbg_input, /* normal input handling */
+ cvt_meinberg, /* Meinberg conversion */
+ pps_one, /* easy PPS monitoring */
+ 0, /* conversion configuration */
+ "Meinberg Extended", /* Meinberg enhanced format */
+ 32, /* string buffer */
+ 0 /* no private data (complete pakets) */
+ },
+ {
+ gps_input, /* no input handling */
+ cvt_mgps, /* Meinberg GPS166 conversion */
+ pps_one, /* easy PPS monitoring */
+ (void *)&meinberg_fmt[2], /* conversion configuration */
+ "Meinberg GPS Extended", /* Meinberg FAU GPS format */
+ 512, /* string buffer */
+ sizeof(struct msg_buf) /* no private data (complete pakets) */
+ }
+};
+
+/*
+ * cvt_meinberg
+ *
+ * convert simple type format
+ */
+static u_long
+cvt_meinberg(
+ unsigned char *buffer,
+ int size,
+ struct format *unused,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ struct format *format;
+
+ /*
+ * select automagically correct data format
+ */
+ if (Strok(buffer, meinberg_fmt[0].fixed_string))
+ {
+ format = &meinberg_fmt[0];
+ }
+ else
+ {
+ if (Strok(buffer, meinberg_fmt[1].fixed_string))
+ {
+ format = &meinberg_fmt[1];
+ }
+ else
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ }
+
+ /*
+ * collect data
+ */
+ if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
+ format->field_offsets[O_DAY].length) ||
+ Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
+ format->field_offsets[O_MONTH].length) ||
+ Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
+ format->field_offsets[O_YEAR].length) ||
+ Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
+ format->field_offsets[O_HOUR].length) ||
+ Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
+ format->field_offsets[O_MIN].length) ||
+ Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
+ format->field_offsets[O_SEC].length))
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ else
+ {
+ unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
+
+ clock_time->usecond = 0;
+ clock_time->flags = PARSEB_S_LEAP;
+
+ if (clock_time->second == 60)
+ clock_time->flags |= PARSEB_LEAPSECOND;
+
+ /*
+ * in the extended timecode format we have also the
+ * indication that the timecode is in UTC
+ * for compatibilty reasons we start at the USUAL
+ * offset (POWERUP flag) and know that the UTC indication
+ * is the character before the powerup flag
+ */
+ if ((format->flags & MBG_EXTENDED) && (f[-1] == 'U'))
+ {
+ /*
+ * timecode is in UTC
+ */
+ clock_time->utcoffset = 0; /* UTC */
+ clock_time->flags |= PARSEB_UTC;
+ }
+ else
+ {
+ /*
+ * only calculate UTC offset if MET/MED is in time code
+ * or we have the old time code format, where we do not
+ * know whether it is UTC time or MET/MED
+ * pray that nobody switches to UTC in the *old* standard time code
+ * ROMS !!!! The new ROMS have 'U' at the ZONE field - good.
+ */
+ switch (buffer[format->field_offsets[O_ZONE].offset])
+ {
+ case ' ':
+ clock_time->utcoffset = -1*60*60; /* MET */
+ break;
+
+ case 'S':
+ clock_time->utcoffset = -2*60*60; /* MED */
+ break;
+
+ case 'U':
+ /*
+ * timecode is in UTC
+ */
+ clock_time->utcoffset = 0; /* UTC */
+ clock_time->flags |= PARSEB_UTC;
+ break;
+
+ default:
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ }
+
+ /*
+ * gather status flags
+ */
+ if (buffer[format->field_offsets[O_ZONE].offset] == 'S')
+ clock_time->flags |= PARSEB_DST;
+
+ if (f[0] == '#')
+ clock_time->flags |= PARSEB_POWERUP;
+
+ if (f[1] == '*')
+ clock_time->flags |= PARSEB_NOSYNC;
+
+ if (f[3] == '!')
+ clock_time->flags |= PARSEB_ANNOUNCE;
+
+ /*
+ * oncoming leap second
+ * 'a' code not confirmed - earth is not
+ * expected to speed up
+ */
+ if (f[3] == 'A')
+ clock_time->flags |= PARSEB_LEAPADD;
+
+ if (f[3] == 'a')
+ clock_time->flags |= PARSEB_LEAPDEL;
+
+
+ if (format->flags & MBG_EXTENDED)
+ {
+ clock_time->flags |= PARSEB_S_ANTENNA;
+
+ /*
+ * DCF77 does not encode the direction -
+ * so we take the current default -
+ * earth slowing down
+ */
+ clock_time->flags &= ~PARSEB_LEAPDEL;
+
+ if (f[4] == 'A')
+ clock_time->flags |= PARSEB_LEAPADD;
+
+ if (f[5] == 'R')
+ clock_time->flags |= PARSEB_ALTERNATE;
+ }
+ return CVT_OK;
+ }
+}
+
+
+/*
+ * mbg_input
+ *
+ * grep data from input stream
+ */
+static u_long
+mbg_input(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("mbg_input(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case STX:
+ parseprintf(DD_PARSE, ("mbg_input: STX seen\n"));
+
+ parseio->parse_index = 1;
+ parseio->parse_data[0] = ch;
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ return PARSE_INP_SKIP;
+
+ case ETX:
+ parseprintf(DD_PARSE, ("mbg_input: ETX seen\n"));
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+ default:
+ return parse_addchar(parseio, ch);
+ }
+}
+
+
+/*
+ * cvt_mgps
+ *
+ * convert Meinberg GPS format
+ */
+static u_long
+cvt_mgps(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ if (!Strok(buffer, format->fixed_string))
+ {
+ return cvt_meinberg(buffer, size, format, clock_time, local);
+ }
+ else
+ {
+ if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
+ format->field_offsets[O_DAY].length) ||
+ Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
+ format->field_offsets[O_MONTH].length) ||
+ Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
+ format->field_offsets[O_YEAR].length) ||
+ Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
+ format->field_offsets[O_HOUR].length) ||
+ Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
+ format->field_offsets[O_MIN].length) ||
+ Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
+ format->field_offsets[O_SEC].length))
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ else
+ {
+ long h;
+ unsigned char *f = &buffer[format->field_offsets[O_FLAGS].offset];
+
+ clock_time->flags = PARSEB_S_LEAP|PARSEB_S_POSITION;
+
+ clock_time->usecond = 0;
+
+ /*
+ * calculate UTC offset
+ */
+ if (Stoi(&buffer[format->field_offsets[O_UTCHOFFSET].offset], &h,
+ format->field_offsets[O_UTCHOFFSET].length))
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+ else
+ {
+ if (Stoi(&buffer[format->field_offsets[O_UTCMOFFSET].offset], &clock_time->utcoffset,
+ format->field_offsets[O_UTCMOFFSET].length))
+ {
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ clock_time->utcoffset += TIMES60(h);
+ clock_time->utcoffset = TIMES60(clock_time->utcoffset);
+
+ if (buffer[format->field_offsets[O_UTCSOFFSET].offset] != '-')
+ {
+ clock_time->utcoffset = -clock_time->utcoffset;
+ }
+ }
+
+ /*
+ * gather status flags
+ */
+ if (buffer[format->field_offsets[O_ZONE].offset] == 'S')
+ clock_time->flags |= PARSEB_DST;
+
+ if (clock_time->utcoffset == 0)
+ clock_time->flags |= PARSEB_UTC;
+
+ /*
+ * no sv's seen - no time & position
+ */
+ if (f[0] == '#')
+ clock_time->flags |= PARSEB_POWERUP;
+
+ /*
+ * at least one sv seen - time (for last position)
+ */
+ if (f[1] == '*')
+ clock_time->flags |= PARSEB_NOSYNC;
+ else
+ if (!(clock_time->flags & PARSEB_POWERUP))
+ clock_time->flags |= PARSEB_POSITION;
+
+ /*
+ * oncoming zone switch
+ */
+ if (f[3] == '!')
+ clock_time->flags |= PARSEB_ANNOUNCE;
+
+ /*
+ * oncoming leap second
+ * 'a' code not confirmed - earth is not
+ * expected to speed up
+ */
+ if (f[4] == 'A')
+ clock_time->flags |= PARSEB_LEAPADD;
+
+ if (f[4] == 'a')
+ clock_time->flags |= PARSEB_LEAPDEL;
+
+ /*
+ * f[5] == ' '
+ */
+
+ /*
+ * this is the leap second
+ */
+ if ((f[6] == 'L') || (clock_time->second == 60))
+ clock_time->flags |= PARSEB_LEAPSECOND;
+
+ return CVT_OK;
+ }
+ }
+}
+
+/*
+ * gps_input
+ *
+ * grep binary data from input stream
+ */
+static u_long
+gps_input(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ CSUM calc_csum; /* used to compare the incoming csums */
+ GPS_MSG_HDR header;
+ struct msg_buf *msg_buf;
+
+ msg_buf = (struct msg_buf *)parseio->parse_pdata;
+
+ parseprintf(DD_PARSE, ("gps_input(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ if (!msg_buf)
+ return PARSE_INP_SKIP;
+
+ if ( msg_buf->phase == MBG_NONE )
+ { /* not receiving yet */
+ switch (ch)
+ {
+ case SOH:
+ parseprintf(DD_PARSE, ("gps_input: SOH seen\n"));
+
+ msg_buf->len = sizeof( header ); /* prepare to receive msg header */
+ msg_buf->phase = MBG_HEADER; /* receiving header */
+ break;
+
+ case STX:
+ parseprintf(DD_PARSE, ("gps_input: STX seen\n"));
+
+ msg_buf->len = 0;
+ msg_buf->phase = MBG_STRING; /* prepare to receive ASCII ETX delimited message */
+ parseio->parse_index = 1;
+ parseio->parse_data[0] = ch;
+ break;
+
+ default:
+ return PARSE_INP_SKIP; /* keep searching */
+ }
+
+ parseio->parse_dtime.parse_msglen = 1; /* reset buffer pointer */
+ parseio->parse_dtime.parse_msg[0] = ch; /* fill in first character */
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ return PARSE_INP_SKIP;
+ }
+
+ /* SOH/STX has already been received */
+
+ /* save incoming character in both buffers if needbe */
+ if ((msg_buf->phase == MBG_STRING) &&
+ (parseio->parse_index < parseio->parse_dsize))
+ parseio->parse_data[parseio->parse_index++] = ch;
+
+ parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
+
+ if (parseio->parse_dtime.parse_msglen > sizeof(parseio->parse_dtime.parse_msg))
+ {
+ msg_buf->phase = MBG_NONE; /* buffer overflow - discard */
+ parseio->parse_data[parseio->parse_index] = '\0';
+ memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
+ parseio->parse_ldsize = parseio->parse_index;
+ return PARSE_INP_DATA;
+ }
+
+ switch (msg_buf->phase)
+ {
+ case MBG_HEADER:
+ case MBG_DATA:
+ msg_buf->len--;
+
+ if ( msg_buf->len ) /* transfer not complete */
+ return PARSE_INP_SKIP;
+
+ parseprintf(DD_PARSE, ("gps_input: %s complete\n", (msg_buf->phase == MBG_DATA) ? "data" : "header"));
+
+ break;
+
+ case MBG_STRING:
+ if ((ch == ETX) || (parseio->parse_index >= parseio->parse_dsize))
+ {
+ msg_buf->phase = MBG_NONE;
+ parseprintf(DD_PARSE, ("gps_input: string complete\n"));
+ parseio->parse_data[parseio->parse_index] = '\0';
+ memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
+ parseio->parse_ldsize = parseio->parse_index;
+ parseio->parse_index = 0;
+ return PARSE_INP_TIME;
+ }
+ else
+ {
+ return PARSE_INP_SKIP;
+ }
+ }
+
+ /* cnt == 0, so the header or the whole message is complete */
+
+ if ( msg_buf->phase == MBG_HEADER )
+ { /* header complete now */
+ unsigned char *datap = parseio->parse_dtime.parse_msg + 1;
+
+ get_mbg_header(&datap, &header);
+
+ parseprintf(DD_PARSE, ("gps_input: header: cmd 0x%x, len %d, dcsum 0x%x, hcsum 0x%x\n",
+ (int)header.gps_cmd, (int)header.gps_len, (int)header.gps_data_csum,
+ (int)header.gps_hdr_csum));
+
+
+ calc_csum = mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg + 1, (unsigned short)6 );
+
+ if ( calc_csum != header.gps_hdr_csum )
+ {
+ parseprintf(DD_PARSE, ("gps_input: header checksum mismatch expected 0x%x, got 0x%x\n",
+ (int)calc_csum, (int)mbg_csum( (unsigned char *) parseio->parse_dtime.parse_msg, (unsigned short)6 )));
+
+ msg_buf->phase = MBG_NONE; /* back to hunting mode */
+ return PARSE_INP_DATA; /* invalid header checksum received - pass up for detection */
+ }
+
+ if ((header.gps_len == 0) || /* no data to wait for */
+ (header.gps_len >= (sizeof (parseio->parse_dtime.parse_msg) - sizeof(header) - 1))) /* blows anything we have space for */
+ {
+ msg_buf->phase = MBG_NONE; /* back to hunting mode */
+ return (header.gps_len == 0) ? PARSE_INP_DATA : PARSE_INP_SKIP; /* message complete/throwaway */
+ }
+
+ parseprintf(DD_PARSE, ("gps_input: expecting %d bytes of data message\n", (int)header.gps_len));
+
+ msg_buf->len = header.gps_len;/* save number of bytes to wait for */
+ msg_buf->phase = MBG_DATA; /* flag header already complete */
+ return PARSE_INP_SKIP;
+ }
+
+ parseprintf(DD_PARSE, ("gps_input: message data complete\n"));
+
+ /* Header and data have been received. The header checksum has been */
+ /* checked */
+
+ msg_buf->phase = MBG_NONE; /* back to hunting mode */
+ return PARSE_INP_DATA; /* message complete, must be evaluated */
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_MEINBERG) */
+int clk_meinberg_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_MEINBERG) */
+
+/*
+ * History:
+ *
+ * clk_meinberg.c,v
+ * Revision 4.12.2.1 2005/09/25 10:22:35 kardel
+ * cleanup buffer bounds
+ *
+ * Revision 4.12 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.11 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.8 1999/11/28 09:13:50 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.7 1999/02/21 11:09:14 kardel
+ * cleanup
+ *
+ * Revision 4.6 1998/06/14 21:09:36 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.5 1998/06/13 15:18:54 kardel
+ * fix mem*() to b*() function macro emulation
+ *
+ * Revision 4.4 1998/06/13 12:03:23 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:28 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/05/24 16:14:42 kardel
+ * support current Meinberg standard data formats
+ *
+ * Revision 4.1 1998/05/24 09:39:52 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:29 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.23 - log info deleted 1998/04/11 kardel
+ *
+ */
diff --git a/libparse/clk_rawdcf.c b/libparse/clk_rawdcf.c
new file mode 100644
index 0000000..98848be
--- /dev/null
+++ b/libparse/clk_rawdcf.c
@@ -0,0 +1,658 @@
+/*
+ * /src/NTP/REPOSITORY/ntp4-dev/libparse/clk_rawdcf.c,v 4.18 2006/06/22 18:40:01 kardel RELEASE_20060622_A
+ *
+ * clk_rawdcf.c,v 4.18 2006/06/22 18:40:01 kardel RELEASE_20060622_A
+ *
+ * Raw DCF77 pulse clock support
+ *
+ * Copyright (c) 1995-2006 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_RAWDCF)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "parse.h"
+#ifdef PARSESTREAM
+# include <sys/parsestreams.h>
+#endif
+
+#ifndef PARSEKERNEL
+# include "ntp_stdlib.h"
+#endif
+
+/*
+ * DCF77 raw time code
+ *
+ * From "Zur Zeit", Physikalisch-Technische Bundesanstalt (PTB), Braunschweig
+ * und Berlin, Maerz 1989
+ *
+ * Timecode transmission:
+ * AM:
+ * time marks are send every second except for the second before the
+ * next minute mark
+ * time marks consist of a reduction of transmitter power to 25%
+ * of the nominal level
+ * the falling edge is the time indication (on time)
+ * time marks of a 100ms duration constitute a logical 0
+ * time marks of a 200ms duration constitute a logical 1
+ * FM:
+ * see the spec. (basically a (non-)inverted psuedo random phase shift)
+ *
+ * Encoding:
+ * Second Contents
+ * 0 - 10 AM: free, FM: 0
+ * 11 - 14 free
+ * 15 R - alternate antenna
+ * 16 A1 - expect zone change (1 hour before)
+ * 17 - 18 Z1,Z2 - time zone
+ * 0 0 illegal
+ * 0 1 MEZ (MET)
+ * 1 0 MESZ (MED, MET DST)
+ * 1 1 illegal
+ * 19 A2 - expect leap insertion/deletion (1 hour before)
+ * 20 S - start of time code (1)
+ * 21 - 24 M1 - BCD (lsb first) Minutes
+ * 25 - 27 M10 - BCD (lsb first) 10 Minutes
+ * 28 P1 - Minute Parity (even)
+ * 29 - 32 H1 - BCD (lsb first) Hours
+ * 33 - 34 H10 - BCD (lsb first) 10 Hours
+ * 35 P2 - Hour Parity (even)
+ * 36 - 39 D1 - BCD (lsb first) Days
+ * 40 - 41 D10 - BCD (lsb first) 10 Days
+ * 42 - 44 DW - BCD (lsb first) day of week (1: Monday -> 7: Sunday)
+ * 45 - 49 MO - BCD (lsb first) Month
+ * 50 MO0 - 10 Months
+ * 51 - 53 Y1 - BCD (lsb first) Years
+ * 54 - 57 Y10 - BCD (lsb first) 10 Years
+ * 58 P3 - Date Parity (even)
+ * 59 - usually missing (minute indication), except for leap insertion
+ */
+
+static u_long pps_rawdcf (parse_t *, int, timestamp_t *);
+static u_long cvt_rawdcf (unsigned char *, int, struct format *, clocktime_t *, void *);
+static u_long inp_rawdcf (parse_t *, unsigned int, timestamp_t *);
+
+typedef struct last_tcode {
+ time_t tcode; /* last converted time code */
+} last_tcode_t;
+
+#define BUFFER_MAX 61
+
+clockformat_t clock_rawdcf =
+{
+ inp_rawdcf, /* DCF77 input handling */
+ cvt_rawdcf, /* raw dcf input conversion */
+ pps_rawdcf, /* examining PPS information */
+ 0, /* no private configuration data */
+ "RAW DCF77 Timecode", /* direct decoding / time synthesis */
+
+ BUFFER_MAX, /* bit buffer */
+ sizeof(last_tcode_t)
+};
+
+static struct dcfparam
+{
+ unsigned char *onebits;
+ unsigned char *zerobits;
+} dcfparameter =
+{
+ (unsigned char *)"###############RADMLS1248124P124812P1248121241248112481248P??", /* 'ONE' representation */
+ (unsigned char *)"--------------------s-------p------p----------------------p__" /* 'ZERO' representation */
+};
+
+static struct rawdcfcode
+{
+ char offset; /* start bit */
+} rawdcfcode[] =
+{
+ { 0 }, { 15 }, { 16 }, { 17 }, { 19 }, { 20 }, { 21 }, { 25 }, { 28 }, { 29 },
+ { 33 }, { 35 }, { 36 }, { 40 }, { 42 }, { 45 }, { 49 }, { 50 }, { 54 }, { 58 }, { 59 }
+};
+
+#define DCF_M 0
+#define DCF_R 1
+#define DCF_A1 2
+#define DCF_Z 3
+#define DCF_A2 4
+#define DCF_S 5
+#define DCF_M1 6
+#define DCF_M10 7
+#define DCF_P1 8
+#define DCF_H1 9
+#define DCF_H10 10
+#define DCF_P2 11
+#define DCF_D1 12
+#define DCF_D10 13
+#define DCF_DW 14
+#define DCF_MO 15
+#define DCF_MO0 16
+#define DCF_Y1 17
+#define DCF_Y10 18
+#define DCF_P3 19
+
+static struct partab
+{
+ char offset; /* start bit of parity field */
+} partab[] =
+{
+ { 21 }, { 29 }, { 36 }, { 59 }
+};
+
+#define DCF_P_P1 0
+#define DCF_P_P2 1
+#define DCF_P_P3 2
+
+#define DCF_Z_MET 0x2
+#define DCF_Z_MED 0x1
+
+static u_long
+ext_bf(
+ unsigned char *buf,
+ int idx,
+ unsigned char *zero
+ )
+{
+ u_long sum = 0;
+ int i, first;
+
+ first = rawdcfcode[idx].offset;
+
+ for (i = rawdcfcode[idx+1].offset - 1; i >= first; i--)
+ {
+ sum <<= 1;
+ sum |= (buf[i] != zero[i]);
+ }
+ return sum;
+}
+
+static unsigned
+pcheck(
+ unsigned char *buf,
+ int idx,
+ unsigned char *zero
+ )
+{
+ int i,last;
+ unsigned psum = 1;
+
+ last = partab[idx+1].offset;
+
+ for (i = partab[idx].offset; i < last; i++)
+ psum ^= (buf[i] != zero[i]);
+
+ return psum;
+}
+
+static u_long
+convert_rawdcf(
+ unsigned char *buffer,
+ int size,
+ struct dcfparam *dcfprm,
+ clocktime_t *clock_time
+ )
+{
+ unsigned char *s = buffer;
+ unsigned char *b = dcfprm->onebits;
+ unsigned char *c = dcfprm->zerobits;
+ int i;
+
+ parseprintf(DD_RAWDCF,("parse: convert_rawdcf: \"%s\"\n", buffer));
+
+ if (size < 57)
+ {
+#ifndef PARSEKERNEL
+ msyslog(LOG_ERR, "parse: convert_rawdcf: INCOMPLETE DATA - time code only has %d bits", size);
+#endif
+ return CVT_NONE;
+ }
+
+ for (i = 0; i < size; i++)
+ {
+ if ((*s != *b) && (*s != *c))
+ {
+ /*
+ * we only have two types of bytes (ones and zeros)
+ */
+#ifndef PARSEKERNEL
+ msyslog(LOG_ERR, "parse: convert_rawdcf: BAD DATA - no conversion");
+#endif
+ return CVT_NONE;
+ }
+ if (*b) b++;
+ if (*c) c++;
+ s++;
+ }
+
+ /*
+ * check Start and Parity bits
+ */
+ if ((ext_bf(buffer, DCF_S, dcfprm->zerobits) == 1) &&
+ pcheck(buffer, DCF_P_P1, dcfprm->zerobits) &&
+ pcheck(buffer, DCF_P_P2, dcfprm->zerobits) &&
+ pcheck(buffer, DCF_P_P3, dcfprm->zerobits))
+ {
+ /*
+ * buffer OK
+ */
+ parseprintf(DD_RAWDCF,("parse: convert_rawdcf: parity check passed\n"));
+
+ clock_time->flags = PARSEB_S_ANTENNA|PARSEB_S_LEAP;
+ clock_time->utctime= 0;
+ clock_time->usecond= 0;
+ clock_time->second = 0;
+ clock_time->minute = ext_bf(buffer, DCF_M10, dcfprm->zerobits);
+ clock_time->minute = TIMES10(clock_time->minute) + ext_bf(buffer, DCF_M1, dcfprm->zerobits);
+ clock_time->hour = ext_bf(buffer, DCF_H10, dcfprm->zerobits);
+ clock_time->hour = TIMES10(clock_time->hour) + ext_bf(buffer, DCF_H1, dcfprm->zerobits);
+ clock_time->day = ext_bf(buffer, DCF_D10, dcfprm->zerobits);
+ clock_time->day = TIMES10(clock_time->day) + ext_bf(buffer, DCF_D1, dcfprm->zerobits);
+ clock_time->month = ext_bf(buffer, DCF_MO0, dcfprm->zerobits);
+ clock_time->month = TIMES10(clock_time->month) + ext_bf(buffer, DCF_MO, dcfprm->zerobits);
+ clock_time->year = ext_bf(buffer, DCF_Y10, dcfprm->zerobits);
+ clock_time->year = TIMES10(clock_time->year) + ext_bf(buffer, DCF_Y1, dcfprm->zerobits);
+
+ switch (ext_bf(buffer, DCF_Z, dcfprm->zerobits))
+ {
+ case DCF_Z_MET:
+ clock_time->utcoffset = -1*60*60;
+ break;
+
+ case DCF_Z_MED:
+ clock_time->flags |= PARSEB_DST;
+ clock_time->utcoffset = -2*60*60;
+ break;
+
+ default:
+ parseprintf(DD_RAWDCF,("parse: convert_rawdcf: BAD TIME ZONE\n"));
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ if (ext_bf(buffer, DCF_A1, dcfprm->zerobits))
+ clock_time->flags |= PARSEB_ANNOUNCE;
+
+ if (ext_bf(buffer, DCF_A2, dcfprm->zerobits))
+ clock_time->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */
+
+ if (ext_bf(buffer, DCF_R, dcfprm->zerobits))
+ clock_time->flags |= PARSEB_ALTERNATE;
+
+ parseprintf(DD_RAWDCF,("parse: convert_rawdcf: TIME CODE OK: %d:%d, %d.%d.%d, flags 0x%lx\n",
+ (int)clock_time->hour, (int)clock_time->minute, (int)clock_time->day, (int)clock_time->month,(int) clock_time->year,
+ (u_long)clock_time->flags));
+ return CVT_OK;
+ }
+ else
+ {
+ /*
+ * bad format - not for us
+ */
+#ifndef PARSEKERNEL
+ msyslog(LOG_ERR, "parse: convert_rawdcf: parity check FAILED for \"%s\"", buffer);
+#endif
+ return CVT_FAIL|CVT_BADFMT;
+ }
+}
+
+/*
+ * raw dcf input routine - needs to fix up 50 baud
+ * characters for 1/0 decision
+ */
+static u_long
+cvt_rawdcf(
+ unsigned char *buffer,
+ int size,
+ struct format *param,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ last_tcode_t *t = (last_tcode_t *)local;
+ unsigned char *s = (unsigned char *)buffer;
+ unsigned char *e = s + size;
+ unsigned char *b = dcfparameter.onebits;
+ unsigned char *c = dcfparameter.zerobits;
+ u_long rtc = CVT_NONE;
+ unsigned int i, lowmax, highmax, cutoff, span;
+#define BITS 9
+ unsigned char histbuf[BITS];
+ /*
+ * the input buffer contains characters with runs of consecutive
+ * bits set. These set bits are an indication of the DCF77 pulse
+ * length. We assume that we receive the pulse at 50 Baud. Thus
+ * a 100ms pulse would generate a 4 bit train (20ms per bit and
+ * start bit)
+ * a 200ms pulse would create all zeroes (and probably a frame error)
+ */
+
+ for (i = 0; i < BITS; i++)
+ {
+ histbuf[i] = 0;
+ }
+
+ cutoff = 0;
+ lowmax = 0;
+
+ while (s < e)
+ {
+ unsigned int ch = *s ^ 0xFF;
+ /*
+ * these lines are left as an excercise to the reader 8-)
+ */
+ if (!((ch+1) & ch) || !*s)
+ {
+
+ for (i = 0; ch; i++)
+ {
+ ch >>= 1;
+ }
+
+ *s = i;
+ histbuf[i]++;
+ cutoff += i;
+ lowmax++;
+ }
+ else
+ {
+ parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: character check for 0x%x@%d FAILED\n", *s, (int)(s - (unsigned char *)buffer)));
+ *s = (unsigned char)~0;
+ rtc = CVT_FAIL|CVT_BADFMT;
+ }
+ s++;
+ }
+
+ if (lowmax)
+ {
+ cutoff /= lowmax;
+ }
+ else
+ {
+ cutoff = 4; /* doesn't really matter - it'll fail anyway, but gives error output */
+ }
+
+ parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: average bit count: %d\n", cutoff));
+
+ lowmax = 0;
+ highmax = 0;
+
+ parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: histogram:"));
+ for (i = 0; i <= cutoff; i++)
+ {
+ lowmax+=histbuf[i] * i;
+ highmax += histbuf[i];
+ parseprintf(DD_RAWDCF,(" %d", histbuf[i]));
+ }
+ parseprintf(DD_RAWDCF, (" <M>"));
+
+ lowmax += highmax / 2;
+
+ if (highmax)
+ {
+ lowmax /= highmax;
+ }
+ else
+ {
+ lowmax = 0;
+ }
+
+ highmax = 0;
+ cutoff = 0;
+
+ for (; i < BITS; i++)
+ {
+ highmax+=histbuf[i] * i;
+ cutoff +=histbuf[i];
+ parseprintf(DD_RAWDCF,(" %d", histbuf[i]));
+ }
+ parseprintf(DD_RAWDCF,("\n"));
+
+ if (cutoff)
+ {
+ highmax /= cutoff;
+ }
+ else
+ {
+ highmax = BITS-1;
+ }
+
+ span = cutoff = lowmax;
+ for (i = lowmax; i <= highmax; i++)
+ {
+ if (histbuf[cutoff] > histbuf[i])
+ {
+ cutoff = i;
+ span = i;
+ }
+ else
+ if (histbuf[cutoff] == histbuf[i])
+ {
+ span = i;
+ }
+ }
+
+ cutoff = (cutoff + span) / 2;
+
+ parseprintf(DD_RAWDCF,("parse: cvt_rawdcf: lower maximum %d, higher maximum %d, cutoff %d\n", lowmax, highmax, cutoff));
+
+ s = (unsigned char *)buffer;
+ while (s < e)
+ {
+ if (*s == (unsigned char)~0)
+ {
+ *s = '?';
+ }
+ else
+ {
+ *s = (*s >= cutoff) ? *b : *c;
+ }
+ s++;
+ if (*b) b++;
+ if (*c) c++;
+ }
+
+ if (rtc == CVT_NONE)
+ {
+ rtc = convert_rawdcf(buffer, size, &dcfparameter, clock_time);
+ if (rtc == CVT_OK)
+ {
+ time_t newtime;
+
+ newtime = parse_to_unixtime(clock_time, &rtc);
+ if ((rtc == CVT_OK) && t)
+ {
+ if ((newtime - t->tcode) == 60) /* guard against multi bit errors */
+ {
+ clock_time->utctime = newtime;
+ }
+ else
+ {
+ rtc = CVT_FAIL|CVT_BADTIME;
+ }
+ t->tcode = newtime;
+ }
+ }
+ }
+
+ return rtc;
+}
+
+/*
+ * pps_rawdcf
+ *
+ * currently a very stupid version - should be extended to decode
+ * also ones and zeros (which is easy)
+ */
+/*ARGSUSED*/
+static u_long
+pps_rawdcf(
+ parse_t *parseio,
+ int status,
+ timestamp_t *ptime
+ )
+{
+ if (!status) /* negative edge for simpler wiring (Rx->DCD) */
+ {
+ parseio->parse_dtime.parse_ptime = *ptime;
+ parseio->parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
+ }
+
+ return CVT_NONE;
+}
+
+static u_long
+snt_rawdcf(
+ parse_t *parseio,
+ timestamp_t *ptime
+ )
+{
+ if ((parseio->parse_dtime.parse_status & CVT_MASK) == CVT_OK)
+ {
+ parseio->parse_dtime.parse_stime = *ptime;
+
+#ifdef PARSEKERNEL
+ parseio->parse_dtime.parse_time.tv.tv_sec++;
+#else
+ parseio->parse_dtime.parse_time.fp.l_ui++;
+#endif
+
+ parseprintf(DD_RAWDCF,("parse: snt_rawdcf: time stamp synthesized offset %d seconds\n", parseio->parse_index - 1));
+
+ return updatetimeinfo(parseio, parseio->parse_lstate);
+ }
+ return CVT_NONE;
+}
+
+/*
+ * inp_rawdcf
+ *
+ * grab DCF77 data from input stream
+ */
+static u_long
+inp_rawdcf(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ static struct timeval timeout = { 1, 500000 }; /* 1.5 secongs denote second #60 */
+
+ parseprintf(DD_PARSE, ("inp_rawdcf(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+
+ if (parse_timedout(parseio, tstamp, &timeout))
+ {
+ parseprintf(DD_PARSE, ("inp_rawdcf: time out seen\n"));
+
+ (void) parse_end(parseio);
+ (void) parse_addchar(parseio, ch);
+ return PARSE_INP_TIME;
+ }
+ else
+ {
+ unsigned int rtc;
+
+ rtc = parse_addchar(parseio, ch);
+ if (rtc == PARSE_INP_SKIP)
+ {
+ if (snt_rawdcf(parseio, tstamp) == CVT_OK)
+ return PARSE_INP_SYNTH;
+ }
+ return rtc;
+ }
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RAWDCF) */
+int clk_rawdcf_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RAWDCF) */
+
+/*
+ * History:
+ *
+ * clk_rawdcf.c,v
+ * Revision 4.18 2006/06/22 18:40:01 kardel
+ * clean up signedness (gcc 4)
+ *
+ * Revision 4.17 2006/01/22 16:01:55 kardel
+ * update version information
+ *
+ * Revision 4.16 2006/01/22 15:51:22 kardel
+ * generate reasonable timecode output on invalid input
+ *
+ * Revision 4.15 2005/08/06 19:17:06 kardel
+ * clean log output
+ *
+ * Revision 4.14 2005/08/06 17:39:40 kardel
+ * cleanup size handling wrt/ to buffer boundaries
+ *
+ * Revision 4.13 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.12 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.9 1999/12/06 13:42:23 kardel
+ * transfer correctly converted time codes always into tcode
+ *
+ * Revision 4.8 1999/11/28 09:13:50 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.7 1999/04/01 20:07:20 kardel
+ * added checking for minutie increment of timestamps in clk_rawdcf.c
+ *
+ * Revision 4.6 1998/06/14 21:09:37 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.5 1998/06/13 12:04:16 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.4 1998/06/12 15:22:28 kardel
+ * fix prototypes
+ *
+ * Revision 4.3 1998/06/06 18:33:36 kardel
+ * simplified condidional compile expression
+ *
+ * Revision 4.2 1998/05/24 11:04:18 kardel
+ * triggering PPS on negative edge for simpler wiring (Rx->DCD)
+ *
+ * Revision 4.1 1998/05/24 09:39:53 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:30 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.24 log info deleted 1998/04/11 kardel
+ *
+ */
diff --git a/libparse/clk_rcc8000.c b/libparse/clk_rcc8000.c
new file mode 100644
index 0000000..6dca166
--- /dev/null
+++ b/libparse/clk_rcc8000.c
@@ -0,0 +1,198 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_rcc8000.c,v 4.9 2004/11/14 15:29:41 kardel RELEASE_20050508_A
+ *
+ * clk_rcc8000.c,v 4.9 2004/11/14 15:29:41 kardel RELEASE_20050508_A
+ *
+ * Radiocode Clocks Ltd RCC 8000 Intelligent Off-Air Master Clock support
+ *
+ * Created by R.E.Broughton from clk_trimtaip.c
+ *
+ * This program 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.
+ *
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_RCC8000)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include "ntp_stdlib.h"
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+extern int printf (const char *, ...);
+#endif
+
+/* Type II Serial Output format
+ *
+ * 0000000000111111111122222222223 / char
+ * 0123456789012345678901234567890 \ posn
+ * HH:MM:SS.XYZ DD/MM/YY DDD W Prn Actual
+ * 33 44 55 666 00 11 22 7 Parse
+ * : : . / / rn Check
+ * "15:50:36.534 30/09/94 273 5 A\x0d\x0a"
+ *
+ * DDD - Day of year number
+ * W - Day of week number (Sunday is 0)
+ * P is the Status. See comment below for details.
+ */
+
+#define O_USEC O_WDAY
+static struct format rcc8000_fmt =
+{ { { 13, 2 }, {16, 2}, { 19, 2}, /* Day, Month, Year */
+ { 0, 2 }, { 3, 2}, { 6, 2}, /* Hour, Minute, Second */
+ { 9, 3 }, {28, 1}, { 0, 0}, /* uSec, Status (Valid,Reject,BST,Leapyear) */ },
+ (const unsigned char *)" : : . / / \r\n",
+ /*"15:50:36.534 30/09/94 273 5 A\x0d\x0a" */
+ 0
+};
+
+static unsigned long cvt_rcc8000 (unsigned char *, int, struct format *, clocktime_t *, void *);
+static unsigned long inp_rcc8000 (parse_t *, unsigned int, timestamp_t *);
+
+clockformat_t clock_rcc8000 =
+{
+ inp_rcc8000, /* no input handling */
+ cvt_rcc8000, /* Radiocode clock conversion */
+ 0, /* no direct PPS monitoring */
+ (void *)&rcc8000_fmt, /* conversion configuration */
+ "Radiocode RCC8000",
+ 31, /* string buffer */
+ 0 /* no private data */
+};
+
+static unsigned long
+cvt_rcc8000(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ if (!Strok(buffer, format->fixed_string)) return CVT_NONE;
+#define OFFS(x) format->field_offsets[(x)].offset
+#define STOI(x, y) Stoi(&buffer[OFFS(x)], y, format->field_offsets[(x)].length)
+ if ( STOI(O_DAY, &clock_time->day) ||
+ STOI(O_MONTH, &clock_time->month) ||
+ STOI(O_YEAR, &clock_time->year) ||
+ STOI(O_HOUR, &clock_time->hour) ||
+ STOI(O_MIN, &clock_time->minute) ||
+ STOI(O_SEC, &clock_time->second) ||
+ STOI(O_USEC, &clock_time->usecond)
+ ) return CVT_FAIL|CVT_BADFMT;
+ clock_time->usecond *= 1000;
+
+ clock_time->utcoffset = 0;
+
+#define RCCP buffer[28]
+ /*
+ * buffer[28] is the ASCII representation of a hex character ( 0 through F )
+ * The four bits correspond to:
+ * 8 - Valid Time
+ * 4 - Reject Code
+ * 2 - British Summer Time (receiver set to emit GMT all year.)
+ * 1 - Leap year
+ */
+#define RCC8000_VALID 0x8
+#define RCC8000_REJECT 0x4
+#define RCC8000_BST 0x2
+#define RCC8000_LEAPY 0x1
+
+ clock_time->flags = 0;
+
+ if ( (RCCP >= '0' && RCCP <= '9') || (RCCP >= 'A' && RCCP <= 'F') )
+ {
+ register int flag;
+
+ flag = (RCCP >= '0' && RCCP <= '9' ) ? RCCP - '0' : RCCP - 'A' + 10;
+
+ if (!(flag & RCC8000_VALID))
+ clock_time->flags |= PARSEB_POWERUP;
+
+ clock_time->flags |= PARSEB_UTC; /* British special - guess why 8-) */
+
+ /* other flags not used */
+ }
+ return CVT_OK;
+}
+/*
+ * inp_rcc8000
+ *
+ * grep data from input stream
+ */
+static u_long
+inp_rcc8000(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("inp_rcc8000(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case '\n':
+ parseprintf(DD_PARSE, ("inp_rcc8000: EOL seen\n"));
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+
+ default:
+ if (parseio->parse_index == 0) /* take sample at start of message */
+ {
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ }
+ return parse_addchar(parseio, ch);
+ }
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RCC8000) */
+int clk_rcc8000_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_RCC8000) */
+
+/*
+ * History:
+ *
+ * clk_rcc8000.c,v
+ * Revision 4.9 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.6 1999/11/28 09:13:51 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.5 1998/06/14 21:09:38 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.4 1998/06/13 12:05:02 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:29 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/06/12 09:13:25 kardel
+ * conditional compile macros fixed
+ * printf prototype
+ *
+ * Revision 4.1 1998/05/24 09:39:53 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:30 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.5 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/clk_schmid.c b/libparse/clk_schmid.c
new file mode 100644
index 0000000..045f0fc
--- /dev/null
+++ b/libparse/clk_schmid.c
@@ -0,0 +1,258 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_schmid.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * clk_schmid.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * Schmid clock support
+ * based on information and testing from Adam W. Feigin et. al (Swisstime iis.ethz.ch)
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SCHMID)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include "ntp_stdlib.h"
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+extern int printf (const char *, ...);
+#endif
+
+/*
+ * Description courtesy of Adam W. Feigin et. al (Swisstime iis.ethz.ch)
+ *
+ * The command to Schmid's DCF77 clock is a single byte; each bit
+ * allows the user to select some part of the time string, as follows (the
+ * output for the lsb is sent first).
+ *
+ * Bit 0: time in MEZ, 4 bytes *binary, not BCD*; hh.mm.ss.tenths
+ * Bit 1: date 3 bytes *binary, not BCD: dd.mm.yy
+ * Bit 2: week day, 1 byte (unused here)
+ * Bit 3: time zone, 1 byte, 0=MET, 1=MEST. (unused here)
+ * Bit 4: clock status, 1 byte, 0=time invalid,
+ * 1=time from crystal backup,
+ * 3=time from DCF77
+ * Bit 5: transmitter status, 1 byte,
+ * bit 0: backup antenna
+ * bit 1: time zone change within 1h
+ * bit 3,2: TZ 01=MEST, 10=MET
+ * bit 4: leap second will be
+ * added within one hour
+ * bits 5-7: Zero
+ * Bit 6: time in backup mode, units of 5 minutes (unused here)
+ *
+ */
+#define WS_TIME 0x01
+#define WS_SIGNAL 0x02
+
+#define WS_ALTERNATE 0x01
+#define WS_ANNOUNCE 0x02
+#define WS_TZ 0x0c
+#define WS_MET 0x08
+#define WS_MEST 0x04
+#define WS_LEAP 0x10
+
+static u_long cvt_schmid (unsigned char *, int, struct format *, clocktime_t *, void *);
+static unsigned long inp_schmid (parse_t *, unsigned int, timestamp_t *);
+
+clockformat_t clock_schmid =
+{
+ inp_schmid, /* no input handling */
+ cvt_schmid, /* Schmid conversion */
+ 0, /* not direct PPS monitoring */
+ 0, /* conversion configuration */
+ "Schmid", /* Schmid receiver */
+ 12, /* binary data buffer */
+ 0, /* no private data (complete messages) */
+};
+
+
+static u_long
+cvt_schmid(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ if ((size != 11) || (buffer[10] != (unsigned char)'\375'))
+ {
+ return CVT_NONE;
+ }
+ else
+ {
+ if (buffer[0] > 23 || buffer[1] > 59 || buffer[2] > 59 || buffer[3] > 9) /* Time */
+ {
+ return CVT_FAIL|CVT_BADTIME;
+ }
+ else
+ if (buffer[4] < 1 || buffer[4] > 31 || buffer[5] < 1 || buffer[5] > 12
+ || buffer[6] > 99)
+ {
+ return CVT_FAIL|CVT_BADDATE;
+ }
+ else
+ {
+ clock_time->hour = buffer[0];
+ clock_time->minute = buffer[1];
+ clock_time->second = buffer[2];
+ clock_time->usecond = buffer[3] * 100000;
+ clock_time->day = buffer[4];
+ clock_time->month = buffer[5];
+ clock_time->year = buffer[6];
+
+ clock_time->flags = 0;
+
+ switch (buffer[8] & WS_TZ)
+ {
+ case WS_MET:
+ clock_time->utcoffset = -1*60*60;
+ break;
+
+ case WS_MEST:
+ clock_time->utcoffset = -2*60*60;
+ clock_time->flags |= PARSEB_DST;
+ break;
+
+ default:
+ return CVT_FAIL|CVT_BADFMT;
+ }
+
+ if (!(buffer[7] & WS_TIME))
+ {
+ clock_time->flags |= PARSEB_POWERUP;
+ }
+
+ if (!(buffer[7] & WS_SIGNAL))
+ {
+ clock_time->flags |= PARSEB_NOSYNC;
+ }
+
+ if (buffer[7] & WS_SIGNAL)
+ {
+ if (buffer[8] & WS_ALTERNATE)
+ {
+ clock_time->flags |= PARSEB_ALTERNATE;
+ }
+
+ if (buffer[8] & WS_ANNOUNCE)
+ {
+ clock_time->flags |= PARSEB_ANNOUNCE;
+ }
+
+ if (buffer[8] & WS_LEAP)
+ {
+ clock_time->flags |= PARSEB_LEAPADD; /* default: DCF77 data format deficiency */
+ }
+ }
+
+ clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_ANTENNA;
+
+ return CVT_OK;
+ }
+ }
+}
+
+/*
+ * inp_schmid
+ *
+ * grep data from input stream
+ */
+static u_long
+inp_schmid(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("inp_schmid(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case 0xFD: /* */
+ parseprintf(DD_PARSE, ("mbg_input: ETX seen\n"));
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+ default:
+ return parse_addchar(parseio, ch);
+ }
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */
+int clk_schmid_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SCHMID) */
+
+/*
+ * History:
+ *
+ * clk_schmid.c,v
+ * Revision 4.9 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.8 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.5 1999/11/28 09:13:51 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.4 1998/06/13 12:06:03 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:29 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/06/12 09:13:26 kardel
+ * conditional compile macros fixed
+ * printf prototype
+ *
+ * Revision 4.1 1998/05/24 09:39:53 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:31 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.22 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/clk_sel240x.c b/libparse/clk_sel240x.c
new file mode 100644
index 0000000..a09d347
--- /dev/null
+++ b/libparse/clk_sel240x.c
@@ -0,0 +1,178 @@
+//////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2009,2012 -
+// Schweitzer Engineering Laboratories, Inc. <opensource@selinc.com>
+//////////////////////////////////////////////////////////////////////////////
+
+// Need to have _XOPEN_SOURCE defined for time.h to give the
+// correct strptime signature. As per feature_test_macros(7),
+// define this before including any header files.
+
+// #ifndef _XOPEN_SOURCE
+// #define _XOPEN_SOURCE
+// #endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_SEL240X)
+
+#include "ntp_syslog.h"
+#include "ntp_types.h"
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+#include "ntp_machine.h"
+#include "ntp_stdlib.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+# include <stdio.h>
+#else
+# include "sys/parsestreams.h"
+#endif
+
+#include <time.h>
+
+//////////////////////////////////////////////////////////////////////////////
+// The B8 output has the following format B8 = '\x01YYYY:ddd:hh:mm:ssq\r\n'
+// where q = ' ' locked
+// '.' <1 us
+// '*' <10 us
+// '#' <100 us
+// '?' >100 us
+//
+// Based on this we need to recored the stime when we receive the <SOH>
+// character and end it when we see the \n.
+//
+// The q or quality character indicates satellite lock and sync. For the
+// purposes of NTP we are going to call it valid when we receive anything but
+// a '?'. But we are only going to call it synced when we receive a ' '
+//////////////////////////////////////////////////////////////////////////////
+
+static unsigned long inp_sel240x( parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp);
+static unsigned long cvt_sel240x( unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local );
+
+// Parse clock format structure describing the message above
+static struct format sel240x_fmt =
+{ { { 6, 3 },
+ { 0, 0 },
+ { 1, 4 },
+ { 10, 2 },
+ { 13, 2 },
+ { 16, 2 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 }
+ },
+ (const unsigned char *)"\x01 : : : : \x0d\x0a",
+ 0
+};
+
+// Structure desctibing the parser
+clockformat_t clock_sel240x =
+{
+ inp_sel240x,
+ cvt_sel240x,
+ pps_one,
+ (void*)&sel240x_fmt,
+ "SEL B8",
+ 25,
+ 0
+};
+
+//////////////////////////////////////////////////////////////////////////////
+static unsigned long
+inp_sel240x( parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned long rc;
+
+ parseprintf( DD_PARSE,
+ ("inp_sel240x(0x%lx, 0x%x, ...)\n",(long)parseio, ch));
+
+ switch( ch )
+ {
+ case '\x01':
+ parseio->parse_index = 1;
+ parseio->parse_data[0] = ch;
+ parseio->parse_dtime.parse_stime = *tstamp;
+ rc = PARSE_INP_SKIP;
+ break;
+ case '\n':
+ if( (rc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP )
+ {
+ rc = parse_end( parseio );
+ }
+ break;
+ default:
+ rc = parse_addchar( parseio, ch );
+ }
+
+ return rc;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+static unsigned long
+cvt_sel240x( unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ unsigned long rc = CVT_NONE;
+
+ if( Strok(buffer, format->fixed_string) )
+ {
+ struct tm ptime;
+ buffer++;
+ buffer = (unsigned char *) strptime(
+ (const char *)buffer, "%Y:%j:%H:%M:%S", &ptime );
+ if( *(buffer+1) != '\x0d' )
+ {
+ rc = CVT_FAIL | CVT_BADFMT;
+ }
+ else
+ {
+ clock_time->day = ptime.tm_mday;
+ clock_time->month = ptime.tm_mon + 1;
+ clock_time->year = ptime.tm_year + 1900;
+ clock_time->hour = ptime.tm_hour;
+ clock_time->minute = ptime.tm_min;
+ clock_time->second = ptime.tm_sec;
+ clock_time->usecond = 0;
+ clock_time->utcoffset = 0;
+ clock_time->flags = PARSEB_UTC;
+
+ if( *buffer == '?' )
+ {
+ clock_time->flags |= PARSEB_POWERUP;
+ }
+ else if( *buffer != ' ' )
+ {
+ clock_time->flags |= PARSEB_NOSYNC;
+ }
+
+ rc = CVT_OK;
+ }
+ }
+
+ return rc;
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */
+int clk_sel240x_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_SEL240X) */
diff --git a/libparse/clk_trimtaip.c b/libparse/clk_trimtaip.c
new file mode 100644
index 0000000..322d0fa
--- /dev/null
+++ b/libparse/clk_trimtaip.c
@@ -0,0 +1,223 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_trimtaip.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * clk_trimtaip.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * Trimble SV6 clock support - several collected codepieces
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_TRIMTAIP)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include "ntp_stdlib.h"
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+extern int printf (const char *, ...);
+#endif
+
+/* 0000000000111111111122222222223333333 / char
+ * 0123456789012345678901234567890123456 \ posn
+ * >RTMhhmmssdddDDMMYYYYoodnnvrrrrr;*xx< Actual
+ * ----33445566600112222BB7__-_____--99- Parse
+ * >RTM 1 ;* <", Check
+ */
+
+#define hexval(x) (('0' <= (x) && (x) <= '9') ? (x) - '0' : \
+ ('a' <= (x) && (x) <= 'f') ? (x) - 'a' + 10 : \
+ ('A' <= (x) && (x) <= 'F') ? (x) - 'A' + 10 : \
+ -1)
+#define O_USEC O_WDAY
+#define O_GPSFIX O_FLAGS
+#define O_CHKSUM O_UTCHOFFSET
+ static struct format trimsv6_fmt =
+{ { { 13, 2 }, {15, 2}, { 17, 4}, /* Day, Month, Year */
+ { 4, 2 }, { 6, 2}, { 8, 2}, /* Hour, Minute, Second */
+ { 10, 3 }, {23, 1}, { 0, 0}, /* uSec, FIXes (WeekDAY, FLAGS, ZONE) */
+ { 34, 2 }, { 0, 0}, { 21, 2}, /* cksum, -, utcS (UTC[HMS]OFFSET) */
+},
+ (const unsigned char *)">RTM 1 ;* <",
+ 0
+};
+
+static unsigned long cvt_trimtaip (unsigned char *, int, struct format *, clocktime_t *, void *);
+static unsigned long inp_trimtaip (parse_t *, unsigned int, timestamp_t *);
+
+clockformat_t clock_trimtaip =
+{
+ inp_trimtaip, /* no input handling */
+ cvt_trimtaip, /* Trimble conversion */
+ pps_one, /* easy PPS monitoring */
+ (void *)&trimsv6_fmt, /* conversion configuration */
+ "Trimble TAIP",
+ 37, /* string buffer */
+ 0 /* no private data */
+};
+
+static unsigned long
+cvt_trimtaip(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ long gpsfix;
+ u_char calc_csum = 0;
+ long recv_csum;
+ int i;
+
+ if (!Strok(buffer, format->fixed_string)) return CVT_NONE;
+#define OFFS(x) format->field_offsets[(x)].offset
+#define STOI(x, y) \
+ Stoi(&buffer[OFFS(x)], y, \
+ format->field_offsets[(x)].length)
+ if ( STOI(O_DAY, &clock_time->day) ||
+ STOI(O_MONTH, &clock_time->month) ||
+ STOI(O_YEAR, &clock_time->year) ||
+ STOI(O_HOUR, &clock_time->hour) ||
+ STOI(O_MIN, &clock_time->minute) ||
+ STOI(O_SEC, &clock_time->second) ||
+ STOI(O_USEC, &clock_time->usecond)||
+ STOI(O_GPSFIX, &gpsfix)
+ ) return CVT_FAIL|CVT_BADFMT;
+
+ clock_time->usecond *= 1000;
+ /* Check that the checksum is right */
+ for (i=OFFS(O_CHKSUM)-1; i >= 0; i--) calc_csum ^= buffer[i];
+ recv_csum = (hexval(buffer[OFFS(O_CHKSUM)]) << 4) |
+ hexval(buffer[OFFS(O_CHKSUM)+1]);
+ if (recv_csum < 0) return CVT_FAIL|CVT_BADTIME;
+ if (((u_char) recv_csum) != calc_csum) return CVT_FAIL|CVT_BADTIME;
+
+ clock_time->utcoffset = 0;
+
+ /* What should flags be set to ? */
+ clock_time->flags = PARSEB_UTC;
+
+ /* if the current GPS fix is 9 (unknown), reject */
+ if (0 > gpsfix || gpsfix > 9) clock_time->flags |= PARSEB_POWERUP;
+
+ return CVT_OK;
+}
+
+/*
+ * inp_trimtaip
+ *
+ * grep data from input stream
+ */
+static u_long
+inp_trimtaip(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("inp_trimtaip(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case '>':
+ parseprintf(DD_PARSE, ("inp_trimptaip: START seen\n"));
+
+ parseio->parse_index = 1;
+ parseio->parse_data[0] = ch;
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ return PARSE_INP_SKIP;
+
+ case '<':
+ parseprintf(DD_PARSE, ("inp_trimtaip: END seen\n"));
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+
+ default:
+ return parse_addchar(parseio, ch);
+ }
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTAIP) */
+int clk_trimtaip_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTAIP) */
+
+/*
+ * History:
+ *
+ * clk_trimtaip.c,v
+ * Revision 4.11 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.10 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.7 1999/11/28 09:13:51 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.6 1998/08/16 18:46:27 kardel
+ * (clock_trimtaip =): changed format name
+ *
+ * Revision 4.5 1998/06/14 21:09:38 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.4 1998/06/13 12:06:57 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:29 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/06/12 09:13:26 kardel
+ * conditional compile macros fixed
+ * printf prototype
+ *
+ * Revision 4.1 1998/05/24 09:39:54 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:31 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 1.4 log info deleted 1998/04/11 kardel
+ */
+
diff --git a/libparse/clk_trimtsip.c b/libparse/clk_trimtsip.c
new file mode 100644
index 0000000..743e39c
--- /dev/null
+++ b/libparse/clk_trimtsip.c
@@ -0,0 +1,463 @@
+/*
+ * /src/NTP/REPOSITORY/ntp4-dev/libparse/clk_trimtsip.c,v 4.19 2009/11/01 10:47:49 kardel RELEASE_20091101_A
+ *
+ * clk_trimtsip.c,v 4.19 2009/11/01 10:47:49 kardel RELEASE_20091101_A
+ *
+ * Trimble TSIP support
+ * Thanks to Sven Dietrich for providing test hardware
+ *
+ * Copyright (c) 1995-2009 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_TRIMTSIP)
+
+#include "ntp_syslog.h"
+#include "ntp_types.h"
+#include "ntp_fp.h"
+#include "timevalops.h"
+#include "ntp_calendar.h"
+#include "ntp_machine.h"
+#include "ntp_stdlib.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+# include <stdio.h>
+#else
+# include "sys/parsestreams.h"
+#endif
+
+#include "ascii.h"
+#include "binio.h"
+#include "ieee754io.h"
+#include "trimble.h"
+
+/*
+ * Trimble low level TSIP parser / time converter
+ *
+ * The receiver uses a serial message protocol called Trimble Standard
+ * Interface Protocol (it can support others but this driver only supports
+ * TSIP). Messages in this protocol have the following form:
+ *
+ * <DLE><id> ... <data> ... <DLE><ETX>
+ *
+ * Any bytes within the <data> portion of value 10 hex (<DLE>) are doubled
+ * on transmission and compressed back to one on reception. Otherwise
+ * the values of data bytes can be anything. The serial interface is RS-422
+ * asynchronous using 9600 baud, 8 data bits with odd party (**note** 9 bits
+ * in total!), and 1 stop bit. The protocol supports byte, integer, single,
+ * and double datatypes. Integers are two bytes, sent most significant first.
+ * Singles are IEEE754 single precision floating point numbers (4 byte) sent
+ * sign & exponent first. Doubles are IEEE754 double precision floating point
+ * numbers (8 byte) sent sign & exponent first.
+ * The receiver supports a large set of messages, only a very small subset of
+ * which is used here.
+ *
+ * From this module the following are recognised:
+ *
+ * ID Description
+ *
+ * 41 GPS Time
+ * 46 Receiver health
+ * 4F UTC correction data (used to get leap second warnings)
+ *
+ * All others are accepted but ignored for time conversion - they are passed up to higher layers.
+ *
+ */
+
+static offsets_t trim_offsets = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+struct trimble
+{
+ u_char t_in_pkt; /* first DLE received */
+ u_char t_dle; /* subsequent DLE received */
+ u_short t_week; /* GPS week */
+ u_short t_weekleap; /* GPS week of next/last week */
+ u_short t_dayleap; /* day in week */
+ u_short t_gpsutc; /* GPS - UTC offset */
+ u_short t_gpsutcleap; /* offset at next/last leap */
+ u_char t_operable; /* receiver feels OK */
+ u_char t_mode; /* actual operating mode */
+ u_char t_leap; /* possible leap warning */
+ u_char t_utcknown; /* utc offset known */
+};
+
+#define STATUS_BAD 0 /* BAD or UNINITIALIZED receiver status */
+#define STATUS_UNSAFE 1 /* not enough receivers for full precision */
+#define STATUS_SYNC 2 /* enough information for good operation */
+
+static unsigned long inp_tsip (parse_t *, unsigned int, timestamp_t *);
+static unsigned long cvt_trimtsip (unsigned char *, int, struct format *, clocktime_t *, void *);
+
+struct clockformat clock_trimtsip =
+{
+ inp_tsip, /* Trimble TSIP input handler */
+ cvt_trimtsip, /* Trimble TSIP conversion */
+ pps_one, /* easy PPS monitoring */
+ 0, /* no configuration data */
+ "Trimble TSIP",
+ 400, /* input buffer */
+ sizeof(struct trimble) /* private data */
+};
+
+#define ADDSECOND 0x01
+#define DELSECOND 0x02
+
+static unsigned long
+inp_tsip(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ struct trimble *t = (struct trimble *)parseio->parse_pdata;
+
+ if (!t)
+ return PARSE_INP_SKIP; /* local data not allocated - sigh! */
+
+ if (!t->t_in_pkt && ch != DLE) {
+ /* wait for start of packet */
+ return PARSE_INP_SKIP;
+ }
+
+ if ((parseio->parse_index >= (parseio->parse_dsize - 2)) ||
+ (parseio->parse_dtime.parse_msglen >= (sizeof(parseio->parse_dtime.parse_msg) - 2)))
+ { /* OVERFLOW - DROP! */
+ t->t_in_pkt = t->t_dle = 0;
+ parseio->parse_index = 0;
+ parseio->parse_dtime.parse_msglen = 0;
+ return PARSE_INP_SKIP;
+ }
+
+ switch (ch) {
+ case DLE:
+ if (!t->t_in_pkt) {
+ t->t_dle = 0;
+ t->t_in_pkt = 1;
+ parseio->parse_index = 0;
+ parseio->parse_data[parseio->parse_index++] = ch;
+ parseio->parse_dtime.parse_msglen = 0;
+ parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
+ parseio->parse_dtime.parse_stime = *tstamp; /* pick up time stamp at packet start */
+ } else if (t->t_dle) {
+ /* Double DLE -> insert a DLE */
+ t->t_dle = 0;
+ parseio->parse_data[parseio->parse_index++] = DLE;
+ parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = DLE;
+ } else
+ t->t_dle = 1;
+ break;
+
+ case ETX:
+ if (t->t_dle) {
+ /* DLE,ETX -> end of packet */
+ parseio->parse_data[parseio->parse_index++] = DLE;
+ parseio->parse_data[parseio->parse_index] = ch;
+ parseio->parse_ldsize = parseio->parse_index+1;
+ memcpy(parseio->parse_ldata, parseio->parse_data, parseio->parse_ldsize);
+ parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = DLE;
+ parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
+ t->t_in_pkt = t->t_dle = 0;
+ return PARSE_INP_TIME|PARSE_INP_DATA;
+ }
+ /*FALLTHROUGH*/
+
+ default: /* collect data */
+ t->t_dle = 0;
+ parseio->parse_data[parseio->parse_index++] = ch;
+ parseio->parse_dtime.parse_msg[parseio->parse_dtime.parse_msglen++] = ch;
+ }
+
+ return PARSE_INP_SKIP;
+}
+
+static int
+getshort(
+ unsigned char *p
+ )
+{
+ return get_msb_short(&p);
+}
+
+/*
+ * cvt_trimtsip
+ *
+ * convert TSIP type format
+ */
+static unsigned long
+cvt_trimtsip(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ register struct trimble *t = (struct trimble *)local; /* get local data space */
+#define mb(_X_) (buffer[2+(_X_)]) /* shortcut for buffer access */
+ register u_char cmd;
+
+ clock_time->flags = 0;
+
+ if (!t) {
+ return CVT_NONE; /* local data not allocated - sigh! */
+ }
+
+ if ((size < 4) ||
+ (buffer[0] != DLE) ||
+ (buffer[size-1] != ETX) ||
+ (buffer[size-2] != DLE))
+ {
+ printf("TRIMBLE BAD packet, size %d:\n", size);
+ return CVT_NONE;
+ }
+ else
+ {
+ unsigned char *bp;
+ cmd = buffer[1];
+
+ switch(cmd)
+ {
+ case CMD_RCURTIME:
+ { /* GPS time */
+ l_fp secs;
+ int week = getshort((unsigned char *)&mb(4));
+ l_fp utcoffset;
+ l_fp gpstime;
+
+ bp = &mb(0);
+ if (fetch_ieee754(&bp, IEEE_SINGLE, &secs, trim_offsets) != IEEE_OK)
+ return CVT_FAIL|CVT_BADFMT;
+
+ if ((secs.l_i <= 0) ||
+ (t->t_utcknown == 0))
+ {
+ clock_time->flags = PARSEB_POWERUP;
+ return CVT_OK;
+ }
+ if (week < 990) {
+ week += 1024;
+ }
+
+ /* time OK */
+
+ /* fetch UTC offset */
+ bp = &mb(6);
+ if (fetch_ieee754(&bp, IEEE_SINGLE, &utcoffset, trim_offsets) != IEEE_OK)
+ return CVT_FAIL|CVT_BADFMT;
+
+ L_SUB(&secs, &utcoffset); /* adjust GPS time to UTC time */
+
+ gpstolfp((unsigned short)week, (unsigned short)0,
+ secs.l_ui, &gpstime);
+
+ gpstime.l_uf = secs.l_uf;
+
+ clock_time->utctime = gpstime.l_ui - JAN_1970;
+
+ TSFTOTVU(gpstime.l_uf, clock_time->usecond);
+
+ if (t->t_leap == ADDSECOND)
+ clock_time->flags |= PARSEB_LEAPADD;
+
+ if (t->t_leap == DELSECOND)
+ clock_time->flags |= PARSEB_LEAPDEL;
+
+ switch (t->t_operable)
+ {
+ case STATUS_SYNC:
+ clock_time->flags &= ~(PARSEB_POWERUP|PARSEB_NOSYNC);
+ break;
+
+ case STATUS_UNSAFE:
+ clock_time->flags |= PARSEB_NOSYNC;
+ break;
+
+ case STATUS_BAD:
+ clock_time->flags |= PARSEB_NOSYNC|PARSEB_POWERUP;
+ break;
+ }
+
+ if (t->t_mode == 0)
+ clock_time->flags |= PARSEB_POSITION;
+
+ clock_time->flags |= PARSEB_S_LEAP|PARSEB_S_POSITION;
+
+ return CVT_OK;
+
+ } /* case 0x41 */
+
+ case CMD_RRECVHEALTH:
+ {
+ /* TRIMBLE health */
+ u_char status = mb(0);
+
+ switch (status)
+ {
+ case 0x00: /* position fixes */
+ t->t_operable = STATUS_SYNC;
+ break;
+
+ case 0x09: /* 1 satellite */
+ case 0x0A: /* 2 satellites */
+ case 0x0B: /* 3 satellites */
+ t->t_operable = STATUS_UNSAFE;
+ break;
+
+ default:
+ t->t_operable = STATUS_BAD;
+ break;
+ }
+ t->t_mode = status;
+ }
+ break;
+
+ case CMD_RUTCPARAM:
+ {
+ l_fp t0t;
+ unsigned char *lbp;
+
+ /* UTC correction data - derive a leap warning */
+ int tls = t->t_gpsutc = getshort((unsigned char *)&mb(12)); /* current leap correction (GPS-UTC) */
+ int tlsf = t->t_gpsutcleap = getshort((unsigned char *)&mb(24)); /* new leap correction */
+
+ t->t_weekleap = getshort((unsigned char *)&mb(20)); /* week no of leap correction */
+ if (t->t_weekleap < 990)
+ t->t_weekleap += 1024;
+
+ t->t_dayleap = getshort((unsigned char *)&mb(22)); /* day in week of leap correction */
+ t->t_week = getshort((unsigned char *)&mb(18)); /* current week no */
+ if (t->t_week < 990)
+ t->t_week += 1024;
+
+ lbp = (unsigned char *)&mb(14); /* last update time */
+ if (fetch_ieee754(&lbp, IEEE_SINGLE, &t0t, trim_offsets) != IEEE_OK)
+ return CVT_FAIL|CVT_BADFMT;
+
+ t->t_utcknown = t0t.l_ui != 0;
+
+ if ((t->t_utcknown) && /* got UTC information */
+ (tlsf != tls) && /* something will change */
+ ((t->t_weekleap - t->t_week) < 5)) /* and close in the future */
+ {
+ /* generate a leap warning */
+ if (tlsf > tls)
+ t->t_leap = ADDSECOND;
+ else
+ t->t_leap = DELSECOND;
+ }
+ else
+ {
+ t->t_leap = 0;
+ }
+ }
+ break;
+
+ default:
+ /* it's validly formed, but we don't care about it! */
+ break;
+ }
+ }
+ return CVT_SKIP;
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTSIP && !PARSESTREAM) */
+int clk_trimtsip_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_TRIMTSIP && !PARSESTREAM) */
+
+/*
+ * History:
+ *
+ * clk_trimtsip.c,v
+ * Revision 4.19 2009/11/01 10:47:49 kardel
+ * de-P()
+ *
+ * Revision 4.18 2009/11/01 08:46:46 kardel
+ * clarify case FALLTHROUGH
+ *
+ * Revision 4.17 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.16 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.13 1999/11/28 09:13:51 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.12 1999/02/28 13:00:08 kardel
+ * *** empty log message ***
+ *
+ * Revision 4.11 1999/02/28 11:47:54 kardel
+ * (struct trimble): new member t_utcknown
+ * (cvt_trimtsip): fixed status monitoring, bad receiver states are
+ * now recognized
+ *
+ * Revision 4.10 1999/02/27 15:57:15 kardel
+ * use mmemcpy instead of bcopy
+ *
+ * Revision 4.9 1999/02/21 12:17:42 kardel
+ * 4.91f reconcilation
+ *
+ * Revision 4.8 1998/11/15 20:27:58 kardel
+ * Release 4.0.73e13 reconcilation
+ *
+ * Revision 4.7 1998/08/16 18:49:20 kardel
+ * (cvt_trimtsip): initial kernel capable version (no more floats)
+ * (clock_trimtsip =): new format name
+ *
+ * Revision 4.6 1998/08/09 22:26:05 kardel
+ * Trimble TSIP support
+ *
+ * Revision 4.5 1998/08/02 10:37:05 kardel
+ * working TSIP parser
+ *
+ * Revision 4.4 1998/06/28 16:50:40 kardel
+ * (getflt): fixed ENDIAN issue
+ * (getdbl): fixed ENDIAN issue
+ * (getint): use get_msb_short()
+ * (cvt_trimtsip): use gpstolfp() for conversion
+ *
+ * Revision 4.3 1998/06/13 12:07:31 kardel
+ * fix SYSV clock name clash
+ *
+ * Revision 4.2 1998/06/12 15:22:30 kardel
+ * fix prototypes
+ *
+ * Revision 4.1 1998/05/24 09:39:54 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:32 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 1.8 loginfo deleted 1998/04/11 kardel
+ */
diff --git a/libparse/clk_varitext.c b/libparse/clk_varitext.c
new file mode 100644
index 0000000..295ce0a
--- /dev/null
+++ b/libparse/clk_varitext.c
@@ -0,0 +1,271 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_VARITEXT)
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_varitext.c,v 1.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * clk_varitext.c,v 1.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * Varitext code variant by A.McConnell 1997/01/19
+ *
+ * Supports Varitext's Radio Clock
+ *
+ * Used the Meinberg/Computime clock as a template for Varitext Radio Clock
+ *
+ * Codebase:
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+# include "ntp_stdlib.h"
+# include <stdio.h>
+#else
+# include "sys/parsestreams.h"
+extern int printf (const char *, ...);
+#endif
+
+static const u_char VT_INITIALISED = 0x01;
+static const u_char VT_SYNCHRONISED = 0x02;
+static const u_char VT_ALARM_STATE = 0x04;
+static const u_char VT_BST = 0x08;
+static const u_char VT_SEASON_CHANGE = 0x10;
+static const u_char VT_LAST_TELEGRAM_OK = 0x20;
+
+/*
+ * The Varitext receiver sends a datagram in the following format every minute
+ *
+ * Timestamp T:YY:MM:MD:WD:HH:MM:SSCRLFSTXXX
+ * Pos 0123456789012345678901 2 3 4567
+ * 0000000000111111111122 2 2 2222
+ * Parse T: : : : : : : \r\n
+ *
+ * T Startcharacter "T" specifies start of the timestamp
+ * YY Year MM Month 1-12
+ * MD Day of the month
+ * WD Day of week
+ * HH Hour
+ * MM Minute
+ * SS Second
+ * CR Carriage return
+ * LF Linefeed
+ * ST Status character
+ * Bit 0 - Set= Initialised; Reset=Time Invalid (DO NOT USE)
+ * Bit 1 - Set= Synchronised; Reset= Unsynchronised
+ * Bit 2 - Set= Alarm state; Reset= No alarm
+ * Bit 3 - Set= BST; Reset= GMT
+ * Bit 4 - Set= Seasonal change in approx hour; Reset= No seasonal change expected
+ * Bit 5 - Set= Last MSF telegram was OK; Reset= Last telegram was in error;
+ * Bit 6 - Always set
+ * Bit 7 - Unused
+ * XXX Checksum calculated using Fletcher's method (ignored for now).
+ */
+
+static struct format varitext_fmt =
+{
+ {
+ {8, 2}, {5, 2}, {2, 2}, /* day, month, year */
+ {14, 2}, {17, 2}, {20, 2}, /* hour, minute, second */
+ {11, 2}, {24, 1} /* dayofweek, status */
+ },
+ (const unsigned char*)"T: : : : : : : \r\n ",
+ 0
+};
+
+static u_long cvt_varitext (unsigned char *, int, struct format *, clocktime_t *, void *);
+static u_long inp_varitext (parse_t *, unsigned int, timestamp_t *);
+
+struct varitext {
+ unsigned char start_found;
+ unsigned char end_found;
+ unsigned char end_count;
+ unsigned char previous_ch;
+ timestamp_t tstamp;
+};
+
+clockformat_t clock_varitext =
+{
+ inp_varitext, /* Because of the strange format we need to parse it ourselves */
+ cvt_varitext, /* Varitext conversion */
+ 0, /* no PPS monitoring */
+ (void *)&varitext_fmt, /* conversion configuration */
+ "Varitext Radio Clock", /* Varitext Radio Clock */
+ 30, /* string buffer */
+ sizeof(struct varitext), /* Private data size required to hold current parse state */
+};
+
+/*
+ * cvt_varitext
+ *
+ * convert simple type format
+ */
+static u_long
+cvt_varitext(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+
+ if (!Strok(buffer, format->fixed_string)) {
+ return CVT_NONE;
+ } else {
+ if (Stoi(&buffer[format->field_offsets[O_DAY].offset], &clock_time->day,
+ format->field_offsets[O_DAY].length) ||
+ Stoi(&buffer[format->field_offsets[O_MONTH].offset], &clock_time->month,
+ format->field_offsets[O_MONTH].length) ||
+ Stoi(&buffer[format->field_offsets[O_YEAR].offset], &clock_time->year,
+ format->field_offsets[O_YEAR].length) ||
+ Stoi(&buffer[format->field_offsets[O_HOUR].offset], &clock_time->hour,
+ format->field_offsets[O_HOUR].length) ||
+ Stoi(&buffer[format->field_offsets[O_MIN].offset], &clock_time->minute,
+ format->field_offsets[O_MIN].length) ||
+ Stoi(&buffer[format->field_offsets[O_SEC].offset], &clock_time->second,
+ format->field_offsets[O_SEC].length)) {
+ return CVT_FAIL | CVT_BADFMT;
+ } else {
+ u_char *f = (u_char*) &buffer[format->field_offsets[O_FLAGS].offset];
+
+ clock_time->flags = 0;
+ clock_time->utcoffset = 0;
+
+ if (((*f) & VT_BST)) /* BST flag is set so set to indicate daylight saving time is active and utc offset */
+ {
+ clock_time->utcoffset = -1*60*60;
+ clock_time->flags |= PARSEB_DST;
+ }
+ /*
+ if (!((*f) & VT_INITIALISED)) Clock not initialised
+ clock_time->flags |= PARSEB_POWERUP;
+
+ if (!((*f) & VT_SYNCHRONISED)) Clock not synchronised
+ clock_time->flags |= PARSEB_NOSYNC;
+
+ if (((*f) & VT_SEASON_CHANGE)) Seasonal change expected in the next hour
+ clock_time->flags |= PARSEB_ANNOUNCE;
+ */
+ return CVT_OK;
+ }
+ }
+}
+
+static u_long
+inp_varitext(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ struct varitext *t = (struct varitext *)parseio->parse_pdata;
+ int rtc;
+
+ parseprintf(DD_PARSE, ("inp_varitext(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ if (!t)
+ return PARSE_INP_SKIP; /* local data not allocated - sigh! */
+
+ if (ch == 'T')
+ t->tstamp = *tstamp;
+
+ if ((t->previous_ch == 'T') && (ch == ':'))
+ {
+ parseprintf(DD_PARSE, ("inp_varitext: START seen\n"));
+
+ parseio->parse_data[0] = 'T';
+ parseio->parse_index=1;
+ parseio->parse_dtime.parse_stime = t->tstamp; /* Time stamp at packet start */
+ t->start_found = 1;
+ t->end_found = 0;
+ t->end_count = 0;
+ }
+
+ if (t->start_found)
+ {
+ if ((rtc = parse_addchar(parseio, ch)) != PARSE_INP_SKIP)
+ {
+ parseprintf(DD_PARSE, ("inp_varitext: ABORTED due to too many characters\n"));
+
+ memset(t, 0, sizeof(struct varitext));
+ return rtc;
+ }
+
+ if (t->end_found)
+ {
+ if (++(t->end_count) == 4) /* Finally found the end of the message */
+ {
+ parseprintf(DD_PARSE, ("inp_varitext: END seen\n"));
+
+ memset(t, 0, sizeof(struct varitext));
+ if ((rtc = parse_addchar(parseio, 0)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+ }
+ }
+
+ if ((t->previous_ch == '\r') && (ch == '\n'))
+ {
+ t->end_found = 1;
+ }
+
+ }
+
+ t->previous_ch = ch;
+
+ return PARSE_INP_SKIP;
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_VARITEXT) */
+int clk_varitext_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_VARITEXT) */
+
+/*
+ * History:
+ *
+ * clk_varitext.c,v
+ * Revision 1.5 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 1.4 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ *
+ * Revision 1.0 1997/06/02 13:16:30 McConnell
+ * File created
+ *
+ */
diff --git a/libparse/clk_wharton.c b/libparse/clk_wharton.c
new file mode 100644
index 0000000..55ab43a
--- /dev/null
+++ b/libparse/clk_wharton.c
@@ -0,0 +1,181 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/clk_wharton.c,v 4.2 2004/11/14 15:29:41 kardel RELEASE_20050508_A
+ *
+ * clk_wharton.c,v 4.2 2004/11/14 15:29:41 kardel RELEASE_20050508_A
+ *
+ * From Philippe De Muyter <phdm@macqel.be>, 1999
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE) && defined(CLOCK_WHARTON_400A)
+/*
+ * Support for WHARTON 400A Series clock + 404.2 serial interface.
+ *
+ * Copyright (C) 1999, 2000 by Philippe De Muyter <phdm@macqel.be>
+ *
+ * This program 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.
+ *
+ */
+
+#include "ntp_fp.h"
+#include "ascii.h"
+#include "parse.h"
+
+#ifndef PARSESTREAM
+#include "ntp_stdlib.h"
+#include <stdio.h>
+#else
+#include "sys/parsestreams.h"
+extern void printf (const char *, ...);
+#endif
+
+/*
+ * In private e-mail alastair@wharton.co.uk said :
+ * "If you are going to use the 400A and 404.2 system [for ntp] I recommend
+ * that you set the 400A to output the message every second. The start of
+ * transmission of the first byte of the message is synchronised to the
+ * second edge."
+ * The WHARTON 400A Series is able to send date/time serial messages
+ * in 7 output formats. We use format 1 here because it is the shortest.
+ * For use with this driver, the WHARTON 400A Series clock must be set-up
+ * as follows :
+ * Programmable Selected
+ * Option No Option
+ * BST or CET display 3 9 or 11
+ * No external controller 7 0
+ * Serial Output Format 1 9 1
+ * Baud rate 9600 bps 10 96
+ * Bit length 8 bits 11 8
+ * Parity even 12 E
+ *
+ * WHARTON 400A Series output format 1 is as follows :
+ *
+ * Timestamp STXssmmhhDDMMYYSETX
+ * Pos 0 12345678901234
+ * 0 00000000011111
+ *
+ * STX start transmission (ASCII 0x02)
+ * ETX end transmission (ASCII 0x03)
+ * ss Second expressed in reversed decimal (units then tens)
+ * mm Minute expressed in reversed decimal
+ * hh Hour expressed in reversed decimal
+ * DD Day of month expressed in reversed decimal
+ * MM Month expressed in reversed decimal (January is 1)
+ * YY Year (without century) expressed in reversed decimal
+ * S Status byte : 0x30 +
+ * bit 0 0 = MSF source 1 = DCF source
+ * bit 1 0 = Winter time 1 = Summer time
+ * bit 2 0 = not synchronised 1 = synchronised
+ * bit 3 0 = no early warning 1 = early warning
+ *
+ */
+
+/*
+ * cvt_wharton_400a
+ *
+ * convert simple type format
+ */
+static u_long
+cvt_wharton_400a(
+ unsigned char *buffer,
+ int size,
+ struct format *format,
+ clocktime_t *clock_time,
+ void *local
+ )
+{
+ int i;
+
+ /* The given `size' includes a terminating null-character. */
+ if (size != 15 || buffer[0] != STX || buffer[14] != ETX
+ || buffer[13] < '0' || buffer[13] > ('0' + 0xf))
+ return CVT_NONE;
+ for (i = 1; i < 13; i += 1)
+ if (buffer[i] < '0' || buffer[i] > '9')
+ return CVT_NONE;
+ clock_time->second = (buffer[2] - '0') * 10 + buffer[1] - '0';
+ clock_time->minute = (buffer[4] - '0') * 10 + buffer[3] - '0';
+ clock_time->hour = (buffer[6] - '0') * 10 + buffer[5] - '0';
+ clock_time->day = (buffer[8] - '0') * 10 + buffer[7] - '0';
+ clock_time->month = (buffer[10] - '0') * 10 + buffer[9] - '0';
+ clock_time->year = (buffer[12] - '0') * 10 + buffer[11] - '0';
+ clock_time->usecond = 0;
+ if (buffer[13] & 0x1) /* We have CET time */
+ clock_time->utcoffset = -1*60*60;
+ else /* We have BST time */
+ clock_time->utcoffset = 0;
+ if (buffer[13] & 0x2) {
+ clock_time->flags |= PARSEB_DST;
+ clock_time->utcoffset += -1*60*60;
+ }
+ if (!(buffer[13] & 0x4))
+ clock_time->flags |= PARSEB_NOSYNC;
+ if (buffer[13] & 0x8)
+ clock_time->flags |= PARSEB_ANNOUNCE;
+
+ return CVT_OK;
+}
+
+/*
+ * inp_wharton_400a
+ *
+ * grep data from input stream
+ */
+static u_long
+inp_wharton_400a(
+ parse_t *parseio,
+ unsigned int ch,
+ timestamp_t *tstamp
+ )
+{
+ unsigned int rtc;
+
+ parseprintf(DD_PARSE, ("inp_wharton_400a(0x%lx, 0x%x, ...)\n", (long)parseio, ch));
+
+ switch (ch)
+ {
+ case STX:
+ parseprintf(DD_PARSE, ("inp_wharton_400a: STX seen\n"));
+
+ parseio->parse_index = 1;
+ parseio->parse_data[0] = ch;
+ parseio->parse_dtime.parse_stime = *tstamp; /* collect timestamp */
+ return PARSE_INP_SKIP;
+
+ case ETX:
+ parseprintf(DD_PARSE, ("inp_wharton_400a: ETX seen\n"));
+ if ((rtc = parse_addchar(parseio, ch)) == PARSE_INP_SKIP)
+ return parse_end(parseio);
+ else
+ return rtc;
+
+ default:
+ return parse_addchar(parseio, ch);
+ }
+}
+
+clockformat_t clock_wharton_400a =
+{
+ inp_wharton_400a, /* input handling function */
+ cvt_wharton_400a, /* conversion function */
+ 0, /* no PPS monitoring */
+ 0, /* conversion configuration */
+ "WHARTON 400A Series clock Output Format 1", /* String format name */
+ 15, /* string buffer */
+ 0 /* no private data (complete pakets) */
+};
+
+#else /* not (REFCLOCK && CLOCK_PARSE && CLOCK_WHARTON_400A) */
+int clk_wharton_400a_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE && CLOCK_WHARTON_400A) */
+
+/*
+ * clk_wharton.c,v
+ * Revision 4.1 1999/02/28 15:27:24 kardel
+ * wharton clock integration
+ *
+ */
diff --git a/libparse/data_mbg.c b/libparse/data_mbg.c
new file mode 100644
index 0000000..97bef35
--- /dev/null
+++ b/libparse/data_mbg.c
@@ -0,0 +1,539 @@
+/*
+ * /src/NTP/REPOSITORY/ntp4-dev/libparse/data_mbg.c,v 4.8 2006/06/22 18:40:01 kardel RELEASE_20060622_A
+ *
+ * data_mbg.c,v 4.8 2006/06/22 18:40:01 kardel RELEASE_20060622_A
+ *
+ * $Created: Sun Jul 20 12:08:14 1997 $
+ *
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#ifdef PARSESTREAM
+#define NEED_BOPS
+#include "ntp_string.h"
+#else
+#include <stdio.h>
+#endif
+#include "ntp_types.h"
+#include "ntp_stdlib.h"
+#include "ntp_fp.h"
+#include "mbg_gps166.h"
+#include "binio.h"
+#include "ieee754io.h"
+
+static void get_mbg_tzname (unsigned char **, char *);
+static void mbg_time_status_str (char **, unsigned int, int);
+
+#if 0 /* no actual floats on Meinberg binary interface */
+static offsets_t mbg_float = { 1, 0, 3, 2, 0, 0, 0, 0 }; /* byte order for meinberg floats */
+#endif
+static offsets_t mbg_double = { 1, 0, 3, 2, 5, 4, 7, 6 }; /* byte order for meinberg doubles */
+static int32 rad2deg_i = 57;
+static u_int32 rad2deg_f = 0x4BB834C7; /* 57.2957795131 == 180/PI */
+
+void
+put_mbg_header(
+ unsigned char **bufpp,
+ GPS_MSG_HDR *headerp
+ )
+{
+ put_lsb_short(bufpp, headerp->gps_cmd);
+ put_lsb_short(bufpp, headerp->gps_len);
+ put_lsb_short(bufpp, headerp->gps_data_csum);
+ put_lsb_short(bufpp, headerp->gps_hdr_csum);
+}
+
+void
+get_mbg_sw_rev(
+ unsigned char **bufpp,
+ SW_REV *sw_revp
+ )
+{
+ sw_revp->code = get_lsb_short(bufpp);
+ memcpy(sw_revp->name, *bufpp, sizeof(sw_revp->name));
+ *bufpp += sizeof(sw_revp->name);
+}
+
+void
+get_mbg_ascii_msg(
+ unsigned char **bufpp,
+ ASCII_MSG *ascii_msgp
+ )
+{
+ ascii_msgp->csum = get_lsb_short(bufpp);
+ ascii_msgp->valid = get_lsb_short(bufpp);
+ memcpy(ascii_msgp->s, *bufpp, sizeof(ascii_msgp->s));
+ *bufpp += sizeof(ascii_msgp->s);
+}
+
+void
+get_mbg_svno(
+ unsigned char **bufpp,
+ SVNO *svnop
+ )
+{
+ *svnop = get_lsb_short(bufpp);
+}
+
+void
+get_mbg_health(
+ unsigned char **bufpp,
+ HEALTH *healthp
+ )
+{
+ *healthp = get_lsb_short(bufpp);
+}
+
+void
+get_mbg_cfg(
+ unsigned char **bufpp,
+ CFG *cfgp
+ )
+{
+ *cfgp = get_lsb_short(bufpp);
+}
+
+void
+get_mbg_tgps(
+ unsigned char **bufpp,
+ T_GPS *tgpsp
+ )
+{
+ tgpsp->wn = get_lsb_short(bufpp);
+ tgpsp->sec = get_lsb_long(bufpp);
+ tgpsp->tick = get_lsb_long(bufpp);
+}
+
+void
+get_mbg_tm(
+ unsigned char **buffpp,
+ TM *tmp
+ )
+{
+ tmp->year = get_lsb_short(buffpp);
+ tmp->month = *(*buffpp)++;
+ tmp->mday = *(*buffpp)++;
+ tmp->yday = get_lsb_short(buffpp);
+ tmp->wday = *(*buffpp)++;
+ tmp->hour = *(*buffpp)++;
+ tmp->minute = *(*buffpp)++;
+ tmp->second = *(*buffpp)++;
+ tmp->frac = get_lsb_long(buffpp);
+ tmp->offs_from_utc = get_lsb_long(buffpp);
+ tmp->status= get_lsb_short(buffpp);
+}
+
+void
+get_mbg_ttm(
+ unsigned char **buffpp,
+ TTM *ttmp
+ )
+{
+ ttmp->channel = get_lsb_short(buffpp);
+ get_mbg_tgps(buffpp, &ttmp->t);
+ get_mbg_tm(buffpp, &ttmp->tm);
+}
+
+void
+get_mbg_synth(
+ unsigned char **buffpp,
+ SYNTH *synthp
+ )
+{
+ synthp->freq = get_lsb_short(buffpp);
+ synthp->range = get_lsb_short(buffpp);
+ synthp->phase = get_lsb_short(buffpp);
+}
+
+static void
+get_mbg_tzname(
+ unsigned char **buffpp,
+ char *tznamep
+ )
+{
+ strlcpy(tznamep, (char *)*buffpp, sizeof(TZ_NAME));
+ *buffpp += sizeof(TZ_NAME);
+}
+
+void
+get_mbg_tzdl(
+ unsigned char **buffpp,
+ TZDL *tzdlp
+ )
+{
+ tzdlp->offs = get_lsb_long(buffpp);
+ tzdlp->offs_dl = get_lsb_long(buffpp);
+ get_mbg_tm(buffpp, &tzdlp->tm_on);
+ get_mbg_tm(buffpp, &tzdlp->tm_off);
+ get_mbg_tzname(buffpp, (char *)tzdlp->name[0]);
+ get_mbg_tzname(buffpp, (char *)tzdlp->name[1]);
+}
+
+void
+get_mbg_antinfo(
+ unsigned char **buffpp,
+ ANT_INFO *antinfop
+ )
+{
+ antinfop->status = get_lsb_short(buffpp);
+ get_mbg_tm(buffpp, &antinfop->tm_disconn);
+ get_mbg_tm(buffpp, &antinfop->tm_reconn);
+ antinfop->delta_t = get_lsb_long(buffpp);
+}
+
+static void
+mbg_time_status_str(
+ char **buffpp,
+ unsigned int status,
+ int size
+ )
+{
+ static struct state
+ {
+ int flag; /* bit flag */
+ const char *string; /* bit name */
+ } states[] =
+ {
+ { TM_UTC, "UTC CORR" },
+ { TM_LOCAL, "LOCAL TIME" },
+ { TM_DL_ANN, "DST WARN" },
+ { TM_DL_ENB, "DST" },
+ { TM_LS_ANN, "LEAP WARN" },
+ { TM_LS_ENB, "LEAP SEC" },
+ { 0, "" }
+ };
+
+ if (status)
+ {
+ char *start, *p;
+ struct state *s;
+
+ start = p = *buffpp;
+
+ for (s = states; s->flag; s++)
+ {
+ if (s->flag & status)
+ {
+ if (p != *buffpp)
+ {
+ strlcpy(p, ", ", size - (p - start));
+ p += 2;
+ }
+ strlcpy(p, s->string, size - (p - start));
+ p += strlen(p);
+ }
+ }
+ *buffpp = p;
+ }
+}
+
+void
+mbg_tm_str(
+ char **buffpp,
+ TM *tmp,
+ int size
+ )
+{
+ char *s = *buffpp;
+
+ snprintf(*buffpp, size, "%04d-%02d-%02d %02d:%02d:%02d.%07ld (%c%02d%02d) ",
+ tmp->year, tmp->month, tmp->mday,
+ tmp->hour, tmp->minute, tmp->second, tmp->frac,
+ (tmp->offs_from_utc < 0) ? '-' : '+',
+ abs(tmp->offs_from_utc) / 3600,
+ (abs(tmp->offs_from_utc) / 60) % 60);
+ *buffpp += strlen(*buffpp);
+
+ mbg_time_status_str(buffpp, tmp->status, size - (*buffpp - s));
+}
+
+void
+mbg_tgps_str(
+ char **buffpp,
+ T_GPS *tgpsp,
+ int size
+ )
+{
+ snprintf(*buffpp, size, "week %d + %ld days + %ld.%07ld sec",
+ tgpsp->wn, tgpsp->sec / 86400,
+ tgpsp->sec % 86400, tgpsp->tick);
+ *buffpp += strlen(*buffpp);
+}
+
+void
+get_mbg_cfgh(
+ unsigned char **buffpp,
+ CFGH *cfghp
+ )
+{
+ int i;
+
+ cfghp->csum = get_lsb_short(buffpp);
+ cfghp->valid = get_lsb_short(buffpp);
+ get_mbg_tgps(buffpp, &cfghp->tot_51);
+ get_mbg_tgps(buffpp, &cfghp->tot_63);
+ get_mbg_tgps(buffpp, &cfghp->t0a);
+
+ for (i = MIN_SVNO; i <= MAX_SVNO; i++)
+ {
+ get_mbg_cfg(buffpp, &cfghp->cfg[i]);
+ }
+
+ for (i = MIN_SVNO; i <= MAX_SVNO; i++)
+ {
+ get_mbg_health(buffpp, &cfghp->health[i]);
+ }
+}
+
+void
+get_mbg_utc(
+ unsigned char **buffpp,
+ UTC *utcp
+ )
+{
+ utcp->csum = get_lsb_short(buffpp);
+ utcp->valid = get_lsb_short(buffpp);
+
+ get_mbg_tgps(buffpp, &utcp->t0t);
+
+ if (fetch_ieee754(buffpp, IEEE_DOUBLE, &utcp->A0, mbg_double) != IEEE_OK)
+ {
+ L_CLR(&utcp->A0);
+ }
+
+ if (fetch_ieee754(buffpp, IEEE_DOUBLE, &utcp->A1, mbg_double) != IEEE_OK)
+ {
+ L_CLR(&utcp->A1);
+ }
+
+ utcp->WNlsf = get_lsb_short(buffpp);
+ utcp->DNt = get_lsb_short(buffpp);
+ utcp->delta_tls = *(*buffpp)++;
+ utcp->delta_tlsf = *(*buffpp)++;
+}
+
+void
+get_mbg_lla(
+ unsigned char **buffpp,
+ LLA lla
+ )
+{
+ int i;
+
+ for (i = LAT; i <= ALT; i++)
+ {
+ if (fetch_ieee754(buffpp, IEEE_DOUBLE, &lla[i], mbg_double) != IEEE_OK)
+ {
+ L_CLR(&lla[i]);
+ }
+ else
+ if (i != ALT)
+ { /* convert to degrees (* 180/PI) */
+ mfp_mul(&lla[i].l_i, &lla[i].l_uf, lla[i].l_i, lla[i].l_uf, rad2deg_i, rad2deg_f);
+ }
+ }
+}
+
+void
+get_mbg_xyz(
+ unsigned char **buffpp,
+ XYZ xyz
+ )
+{
+ int i;
+
+ for (i = XP; i <= ZP; i++)
+ {
+ if (fetch_ieee754(buffpp, IEEE_DOUBLE, &xyz[i], mbg_double) != IEEE_OK)
+ {
+ L_CLR(&xyz[i]);
+ }
+ }
+}
+
+static void
+get_mbg_comparam(
+ unsigned char **buffpp,
+ COM_PARM *comparamp
+ )
+{
+ int i;
+
+ comparamp->baud_rate = get_lsb_long(buffpp);
+ for (i = 0; i < sizeof(comparamp->framing); i++)
+ {
+ comparamp->framing[i] = *(*buffpp)++;
+ }
+ comparamp->handshake = get_lsb_short(buffpp);
+}
+
+void
+get_mbg_portparam(
+ unsigned char **buffpp,
+ PORT_PARM *portparamp
+ )
+{
+ int i;
+
+ for (i = 0; i < N_COM; i++)
+ {
+ get_mbg_comparam(buffpp, &portparamp->com[i]);
+ }
+ for (i = 0; i < N_COM; i++)
+ {
+ portparamp->mode[i] = *(*buffpp)++;
+ }
+}
+
+#define FETCH_DOUBLE(src, addr) \
+ if (fetch_ieee754(src, IEEE_DOUBLE, addr, mbg_double) != IEEE_OK) \
+ { \
+ L_CLR(addr); \
+ }
+
+void
+get_mbg_eph(
+ unsigned char ** buffpp,
+ EPH *ephp
+ )
+{
+ ephp->csum = get_lsb_short(buffpp);
+ ephp->valid = get_lsb_short(buffpp);
+
+ ephp->health = get_lsb_short(buffpp);
+ ephp->IODC = get_lsb_short(buffpp);
+ ephp->IODE2 = get_lsb_short(buffpp);
+ ephp->IODE3 = get_lsb_short(buffpp);
+
+ get_mbg_tgps(buffpp, &ephp->tt);
+ get_mbg_tgps(buffpp, &ephp->t0c);
+ get_mbg_tgps(buffpp, &ephp->t0e);
+
+ FETCH_DOUBLE(buffpp, &ephp->sqrt_A);
+ FETCH_DOUBLE(buffpp, &ephp->e);
+ FETCH_DOUBLE(buffpp, &ephp->M0);
+ FETCH_DOUBLE(buffpp, &ephp->omega);
+ FETCH_DOUBLE(buffpp, &ephp->OMEGA0);
+ FETCH_DOUBLE(buffpp, &ephp->OMEGADOT);
+ FETCH_DOUBLE(buffpp, &ephp->deltan);
+ FETCH_DOUBLE(buffpp, &ephp->i0);
+ FETCH_DOUBLE(buffpp, &ephp->idot);
+ FETCH_DOUBLE(buffpp, &ephp->crc);
+ FETCH_DOUBLE(buffpp, &ephp->crs);
+ FETCH_DOUBLE(buffpp, &ephp->cuc);
+ FETCH_DOUBLE(buffpp, &ephp->cus);
+ FETCH_DOUBLE(buffpp, &ephp->cic);
+ FETCH_DOUBLE(buffpp, &ephp->cis);
+
+ FETCH_DOUBLE(buffpp, &ephp->af0);
+ FETCH_DOUBLE(buffpp, &ephp->af1);
+ FETCH_DOUBLE(buffpp, &ephp->af2);
+ FETCH_DOUBLE(buffpp, &ephp->tgd);
+
+ ephp->URA = get_lsb_short(buffpp);
+
+ ephp->L2code = *(*buffpp)++;
+ ephp->L2flag = *(*buffpp)++;
+}
+
+void
+get_mbg_alm(
+ unsigned char **buffpp,
+ ALM *almp
+ )
+{
+ almp->csum = get_lsb_short(buffpp);
+ almp->valid = get_lsb_short(buffpp);
+
+ almp->health = get_lsb_short(buffpp);
+ get_mbg_tgps(buffpp, &almp->t0a);
+
+
+ FETCH_DOUBLE(buffpp, &almp->sqrt_A);
+ FETCH_DOUBLE(buffpp, &almp->e);
+
+ FETCH_DOUBLE(buffpp, &almp->M0);
+ FETCH_DOUBLE(buffpp, &almp->omega);
+ FETCH_DOUBLE(buffpp, &almp->OMEGA0);
+ FETCH_DOUBLE(buffpp, &almp->OMEGADOT);
+ FETCH_DOUBLE(buffpp, &almp->deltai);
+ FETCH_DOUBLE(buffpp, &almp->af0);
+ FETCH_DOUBLE(buffpp, &almp->af1);
+}
+
+void
+get_mbg_iono(
+ unsigned char **buffpp,
+ IONO *ionop
+ )
+{
+ ionop->csum = get_lsb_short(buffpp);
+ ionop->valid = get_lsb_short(buffpp);
+
+ FETCH_DOUBLE(buffpp, &ionop->alpha_0);
+ FETCH_DOUBLE(buffpp, &ionop->alpha_1);
+ FETCH_DOUBLE(buffpp, &ionop->alpha_2);
+ FETCH_DOUBLE(buffpp, &ionop->alpha_3);
+
+ FETCH_DOUBLE(buffpp, &ionop->beta_0);
+ FETCH_DOUBLE(buffpp, &ionop->beta_1);
+ FETCH_DOUBLE(buffpp, &ionop->beta_2);
+ FETCH_DOUBLE(buffpp, &ionop->beta_3);
+}
+
+/*
+ * data_mbg.c,v
+ * Revision 4.8 2006/06/22 18:40:01 kardel
+ * clean up signedness (gcc 4)
+ *
+ * Revision 4.7 2005/10/07 22:11:10 kardel
+ * bounded buffer implementation
+ *
+ * Revision 4.6.2.1 2005/09/25 10:23:06 kardel
+ * support bounded buffers
+ *
+ * Revision 4.6 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.5 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.3 1999/02/21 12:17:42 kardel
+ * 4.91f reconcilation
+ *
+ * Revision 4.2 1998/06/14 21:09:39 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.1 1998/05/24 08:02:06 kardel
+ * trimmed version log
+ *
+ * Revision 4.0 1998/04/10 19:45:33 kardel
+ * Start 4.0 release version numbering
+ */
+
diff --git a/libparse/gpstolfp.c b/libparse/gpstolfp.c
new file mode 100644
index 0000000..5354dd3
--- /dev/null
+++ b/libparse/gpstolfp.c
@@ -0,0 +1,77 @@
+/*
+ * /src/NTP/ntp4-dev/libntp/gpstolfp.c,v 4.8 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * gpstolfp.c,v 4.8 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Jun 28 16:30:38 1998 $
+ *
+ * Copyright (c) 1998-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#include <config.h>
+#include "ntp_fp.h"
+
+#define GPSORIGIN 2524953600UL /* NTP origin - GPS origin in seconds */
+#define SECSPERWEEK (unsigned)(604800) /* seconds per week - GPS tells us about weeks */
+#define GPSWRAP 990 /* assume week count less than this in the previous epoch */
+
+void
+gpstolfp(
+ int weeks,
+ int days,
+ unsigned long seconds,
+ l_fp * lfp
+ )
+{
+ if (weeks < GPSWRAP)
+ {
+ weeks += 1024;
+ }
+
+ lfp->l_ui = weeks * SECSPERWEEK + days * 86400 + seconds + GPSORIGIN; /* convert to NTP time */
+ lfp->l_uf = 0;
+}
+
+/*
+ * History:
+ *
+ * gpstolfp.c,v
+ * Revision 4.8 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.7 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.3 1999/02/28 11:42:44 kardel
+ * (GPSWRAP): update GPS rollover to 990 weeks
+ *
+ * Revision 4.2 1998/07/11 10:05:25 kardel
+ * Release 4.0.73d reconcilation
+ *
+ * Revision 4.1 1998/06/28 16:47:15 kardel
+ * added gpstolfp() function
+ */
diff --git a/libparse/ieee754io.c b/libparse/ieee754io.c
new file mode 100644
index 0000000..61bc853
--- /dev/null
+++ b/libparse/ieee754io.c
@@ -0,0 +1,614 @@
+/*
+ * /src/NTP/ntp4-dev/libntp/ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * ieee754io.c,v 4.12 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Jul 13 09:12:02 1997 $
+ *
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include "l_stdlib.h"
+#include "ntp_stdlib.h"
+#include "ntp_fp.h"
+#include "ieee754io.h"
+
+static unsigned char get_byte (unsigned char *, offsets_t, int *);
+#ifdef __not_yet__
+static void put_byte (unsigned char *, offsets_t, int *, unsigned char);
+#endif
+
+#ifdef LIBDEBUG
+
+#include "lib_strbuf.h"
+
+static char *
+fmt_blong(
+ unsigned long val,
+ int cnt
+ )
+{
+ char *buf, *s;
+ int i = cnt;
+
+ val <<= 32 - cnt;
+ LIB_GETBUF(buf);
+ s = buf;
+
+ while (i--)
+ {
+ if (val & 0x80000000)
+ {
+ *s++ = '1';
+ }
+ else
+ {
+ *s++ = '0';
+ }
+ val <<= 1;
+ }
+ *s = '\0';
+ return buf;
+}
+
+static char *
+fmt_flt(
+ unsigned int sign,
+ unsigned long mh,
+ unsigned long ml,
+ unsigned long ch
+ )
+{
+ char *buf;
+
+ LIB_GETBUF(buf);
+ snprintf(buf, LIB_BUFLENGTH, "%c %s %s %s", sign ? '-' : '+',
+ fmt_blong(ch, 11),
+ fmt_blong(mh, 20),
+ fmt_blong(ml, 32));
+
+ return buf;
+}
+
+static char *
+fmt_hex(
+ unsigned char *bufp,
+ int length
+ )
+{
+ char * buf;
+ char hex[4];
+ int i;
+
+ LIB_GETBUF(buf);
+ buf[0] = '\0';
+ for (i = 0; i < length; i++) {
+ snprintf(hex, sizeof(hex), "%02x", bufp[i]);
+ strlcat(buf, hex, LIB_BUFLENGTH);
+ }
+
+ return buf;
+}
+
+#endif
+
+static unsigned char
+get_byte(
+ unsigned char *bufp,
+ offsets_t offset,
+ int *fieldindex
+ )
+{
+ unsigned char val;
+
+ val = *(bufp + offset[*fieldindex]);
+#ifdef LIBDEBUG
+ if (debug > 4)
+ printf("fetchieee754: getbyte(0x%08x, %d) = 0x%02x\n", (unsigned int)(bufp)+offset[*fieldindex], *fieldindex, val);
+#endif
+ (*fieldindex)++;
+ return val;
+}
+
+#ifdef __not_yet__
+static void
+put_byte(
+ unsigned char *bufp,
+ offsets_t offsets,
+ int *fieldindex,
+ unsigned char val
+ )
+{
+ *(bufp + offsets[*fieldindex]) = val;
+ (*fieldindex)++;
+}
+#endif
+
+/*
+ * make conversions to and from external IEEE754 formats and internal
+ * NTP FP format.
+ */
+int
+fetch_ieee754(
+ unsigned char **buffpp,
+ int size,
+ l_fp *lfpp,
+ offsets_t offsets
+ )
+{
+ unsigned char *bufp = *buffpp;
+ unsigned int sign;
+ unsigned int bias;
+ unsigned int maxexp;
+ int mbits;
+ u_long mantissa_low;
+ u_long mantissa_high;
+ u_long characteristic;
+ long exponent;
+#ifdef LIBDEBUG
+ int length;
+#endif
+ unsigned char val;
+ int fieldindex = 0;
+
+ switch (size)
+ {
+ case IEEE_DOUBLE:
+#ifdef LIBDEBUG
+ length = 8;
+#endif
+ mbits = 52;
+ bias = 1023;
+ maxexp = 2047;
+ break;
+
+ case IEEE_SINGLE:
+#ifdef LIBDEBUG
+ length = 4;
+#endif
+ mbits = 23;
+ bias = 127;
+ maxexp = 255;
+ break;
+
+ default:
+ return IEEE_BADCALL;
+ }
+
+ val = get_byte(bufp, offsets, &fieldindex); /* fetch sign byte & first part of characteristic */
+
+ sign = (val & 0x80) != 0;
+ characteristic = (val & 0x7F);
+
+ val = get_byte(bufp, offsets, &fieldindex); /* fetch rest of characteristic and start of mantissa */
+
+ switch (size)
+ {
+ case IEEE_SINGLE:
+ characteristic <<= 1;
+ characteristic |= (val & 0x80) != 0; /* grab last characteristic bit */
+
+ mantissa_high = 0;
+
+ mantissa_low = (val &0x7F) << 16;
+ mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
+ mantissa_low |= get_byte(bufp, offsets, &fieldindex);
+ break;
+
+ case IEEE_DOUBLE:
+ characteristic <<= 4;
+ characteristic |= (val & 0xF0) >> 4; /* grab lower characteristic bits */
+
+ mantissa_high = (val & 0x0F) << 16;
+ mantissa_high |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
+ mantissa_high |= get_byte(bufp, offsets, &fieldindex);
+
+ mantissa_low = (u_long)get_byte(bufp, offsets, &fieldindex) << 24;
+ mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 16;
+ mantissa_low |= (u_long)get_byte(bufp, offsets, &fieldindex) << 8;
+ mantissa_low |= get_byte(bufp, offsets, &fieldindex);
+ break;
+
+ default:
+ return IEEE_BADCALL;
+ }
+#ifdef LIBDEBUG
+ if (debug > 4)
+ {
+ double d;
+ float f;
+
+ if (size == IEEE_SINGLE)
+ {
+ int i;
+
+ for (i = 0; i < length; i++)
+ {
+ *((unsigned char *)(&f)+i) = *(*buffpp + offsets[i]);
+ }
+ d = f;
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < length; i++)
+ {
+ *((unsigned char *)(&d)+i) = *(*buffpp + offsets[i]);
+ }
+ }
+
+ printf("fetchieee754: FP: %s -> %s -> %e(=%s)\n", fmt_hex(*buffpp, length),
+ fmt_flt(sign, mantissa_high, mantissa_low, characteristic),
+ d, fmt_hex((unsigned char *)&d, length));
+ }
+#endif
+
+ *buffpp += fieldindex;
+
+ /*
+ * detect funny numbers
+ */
+ if (characteristic == maxexp)
+ {
+ /*
+ * NaN or Infinity
+ */
+ if (mantissa_low || mantissa_high)
+ {
+ /*
+ * NaN
+ */
+ return IEEE_NAN;
+ }
+ else
+ {
+ /*
+ * +Inf or -Inf
+ */
+ return sign ? IEEE_NEGINFINITY : IEEE_POSINFINITY;
+ }
+ }
+ else
+ {
+ /*
+ * collect real numbers
+ */
+
+ L_CLR(lfpp);
+
+ /*
+ * check for overflows
+ */
+ exponent = characteristic - bias;
+
+ if (exponent > 31) /* sorry - hardcoded */
+ {
+ /*
+ * overflow only in respect to NTP-FP representation
+ */
+ return sign ? IEEE_NEGOVERFLOW : IEEE_POSOVERFLOW;
+ }
+ else
+ {
+ int frac_offset; /* where the fraction starts */
+
+ frac_offset = mbits - exponent;
+
+ if (characteristic == 0)
+ {
+ /*
+ * de-normalized or tiny number - fits only as 0
+ */
+ return IEEE_OK;
+ }
+ else
+ {
+ /*
+ * adjust for implied 1
+ */
+ if (mbits > 31)
+ mantissa_high |= 1 << (mbits - 32);
+ else
+ mantissa_low |= 1 << mbits;
+
+ /*
+ * take mantissa apart - if only all machine would support
+ * 64 bit operations 8-(
+ */
+ if (frac_offset > mbits)
+ {
+ lfpp->l_ui = 0; /* only fractional number */
+ frac_offset -= mbits + 1; /* will now contain right shift count - 1*/
+ if (mbits > 31)
+ {
+ lfpp->l_uf = mantissa_high << (63 - mbits);
+ lfpp->l_uf |= mantissa_low >> (mbits - 33);
+ lfpp->l_uf >>= frac_offset;
+ }
+ else
+ {
+ lfpp->l_uf = mantissa_low >> frac_offset;
+ }
+ }
+ else
+ {
+ if (frac_offset > 32)
+ {
+ /*
+ * must split in high word
+ */
+ lfpp->l_ui = mantissa_high >> (frac_offset - 32);
+ lfpp->l_uf = (mantissa_high & ((1 << (frac_offset - 32)) - 1)) << (64 - frac_offset);
+ lfpp->l_uf |= mantissa_low >> (frac_offset - 32);
+ }
+ else
+ {
+ /*
+ * must split in low word
+ */
+ lfpp->l_ui = mantissa_high << (32 - frac_offset);
+ lfpp->l_ui |= (mantissa_low >> frac_offset) & ((1 << (32 - frac_offset)) - 1);
+ lfpp->l_uf = (mantissa_low & ((1 << frac_offset) - 1)) << (32 - frac_offset);
+ }
+ }
+
+ /*
+ * adjust for sign
+ */
+ if (sign)
+ {
+ L_NEG(lfpp);
+ }
+
+ return IEEE_OK;
+ }
+ }
+ }
+}
+
+int
+put_ieee754(
+ unsigned char **bufpp,
+ int size,
+ l_fp *lfpp,
+ offsets_t offsets
+ )
+{
+ l_fp outlfp;
+#ifdef LIBDEBUG
+ unsigned int sign;
+ unsigned int bias;
+#endif
+/*unsigned int maxexp;*/
+ int mbits;
+ int msb;
+ u_long mantissa_low = 0;
+ u_long mantissa_high = 0;
+#ifdef LIBDEBUG
+ u_long characteristic = 0;
+ long exponent;
+#endif
+/*int length;*/
+ unsigned long mask;
+
+ outlfp = *lfpp;
+
+ switch (size)
+ {
+ case IEEE_DOUBLE:
+ /*length = 8;*/
+ mbits = 52;
+#ifdef LIBDEBUG
+ bias = 1023;
+#endif
+ /*maxexp = 2047;*/
+ break;
+
+ case IEEE_SINGLE:
+ /*length = 4;*/
+ mbits = 23;
+#ifdef LIBDEBUG
+ bias = 127;
+#endif
+ /*maxexp = 255;*/
+ break;
+
+ default:
+ return IEEE_BADCALL;
+ }
+
+ /*
+ * find sign
+ */
+ if (L_ISNEG(&outlfp))
+ {
+ L_NEG(&outlfp);
+#ifdef LIBDEBUG
+ sign = 1;
+#endif
+ }
+ else
+ {
+#ifdef LIBDEBUG
+ sign = 0;
+#endif
+ }
+
+ if (L_ISZERO(&outlfp))
+ {
+#ifdef LIBDEBUG
+ exponent = mantissa_high = mantissa_low = 0; /* true zero */
+#endif
+ }
+ else
+ {
+ /*
+ * find number of significant integer bits
+ */
+ mask = 0x80000000;
+ if (outlfp.l_ui)
+ {
+ msb = 63;
+ while (mask && ((outlfp.l_ui & mask) == 0))
+ {
+ mask >>= 1;
+ msb--;
+ }
+ }
+ else
+ {
+ msb = 31;
+ while (mask && ((outlfp.l_uf & mask) == 0))
+ {
+ mask >>= 1;
+ msb--;
+ }
+ }
+
+ switch (size)
+ {
+ case IEEE_SINGLE:
+ mantissa_high = 0;
+ if (msb >= 32)
+ {
+ mantissa_low = (outlfp.l_ui & ((1 << (msb - 32)) - 1)) << (mbits - (msb - 32));
+ mantissa_low |= outlfp.l_uf >> (mbits - (msb - 32));
+ }
+ else
+ {
+ mantissa_low = (outlfp.l_uf << (mbits - msb)) & ((1 << mbits) - 1);
+ }
+ break;
+
+ case IEEE_DOUBLE:
+ if (msb >= 32)
+ {
+ mantissa_high = (outlfp.l_ui << (mbits - msb)) & ((1 << (mbits - 32)) - 1);
+ mantissa_high |= outlfp.l_uf >> (32 - (mbits - msb));
+ mantissa_low = (outlfp.l_ui & ((1 << (msb - mbits)) - 1)) << (32 - (msb - mbits));
+ mantissa_low |= outlfp.l_uf >> (msb - mbits);
+ }
+ else
+ {
+ mantissa_high = outlfp.l_uf << (mbits - 32 - msb);
+ mantissa_low = outlfp.l_uf << (mbits - 32);
+ }
+ }
+
+#ifdef LIBDEBUG
+ exponent = msb - 32;
+ characteristic = exponent + bias;
+
+ if (debug > 4)
+ printf("FP: %s\n", fmt_flt(sign, mantissa_high, mantissa_low, characteristic));
+#endif
+ }
+ return IEEE_OK;
+}
+
+
+#if defined(DEBUG) && defined(LIBDEBUG)
+int main(
+ int argc,
+ char **argv
+ )
+{
+ static offsets_t native_off = { 0, 1, 2, 3, 4, 5, 6, 7 };
+ double f = 1.0;
+ double *f_p = &f;
+ l_fp fp;
+
+ if (argc == 2)
+ {
+ if (sscanf(argv[1], "%lf", &f) != 1)
+ {
+ printf("cannot convert %s to a float\n", argv[1]);
+ return 1;
+ }
+ }
+
+ printf("double: %s %s\n", fmt_blong(*(unsigned long *)&f, 32), fmt_blong(*(unsigned long *)((char *)(&f)+4), 32));
+ printf("fetch from %f = %d\n", f, fetch_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off));
+ printf("fp [%s %s] = %s\n", fmt_blong(fp.l_ui, 32), fmt_blong(fp.l_uf, 32), mfptoa(fp.l_ui, fp.l_uf, 15));
+ f_p = &f;
+ put_ieee754((void *)&f_p, IEEE_DOUBLE, &fp, native_off);
+
+ return 0;
+}
+
+#endif
+/*
+ * History:
+ *
+ * ieee754io.c,v
+ * Revision 4.12 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.11 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.8 1999/02/21 12:17:36 kardel
+ * 4.91f reconcilation
+ *
+ * Revision 4.7 1999/02/21 11:26:03 kardel
+ * renamed index to fieldindex to avoid index() name clash
+ *
+ * Revision 4.6 1998/11/15 20:27:52 kardel
+ * Release 4.0.73e13 reconcilation
+ *
+ * Revision 4.5 1998/08/16 19:01:51 kardel
+ * debug information only compile for LIBDEBUG case
+ *
+ * Revision 4.4 1998/08/09 09:39:28 kardel
+ * Release 4.0.73e2 reconcilation
+ *
+ * Revision 4.3 1998/06/13 11:56:19 kardel
+ * disabled putbute() for the time being
+ *
+ * Revision 4.2 1998/06/12 15:16:58 kardel
+ * ansi2knr compatibility
+ *
+ * Revision 4.1 1998/05/24 07:59:56 kardel
+ * conditional debug support
+ *
+ * Revision 4.0 1998/04/10 19:46:29 kardel
+ * Start 4.0 release version numbering
+ *
+ * Revision 1.1 1998/04/10 19:27:46 kardel
+ * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
+ *
+ * Revision 1.1 1997/10/06 21:05:45 kardel
+ * new parse structure
+ *
+ */
diff --git a/libparse/info_trimble.c b/libparse/info_trimble.c
new file mode 100644
index 0000000..6456e0f
--- /dev/null
+++ b/libparse/info_trimble.c
@@ -0,0 +1,94 @@
+/*
+ * Automatically generated - do not modify
+ */
+
+#include <config.h>
+#include "ntp_types.h"
+#include "ntpd.h"
+#include "trimble.h"
+
+cmd_info_t trimble_scmds[] = {
+ { CMD_CCLROSC, "CMD_CCLROSC", "clear oscillator offset (0x1D)", "", 0 },
+ { CMD_CCLRRST, "CMD_CCLRRST", "clear battery backup and RESET (0x1E)", "", 0 },
+ { CMD_CVERSION, "CMD_CVERSION", "return software version (0x1F)", "", 0 },
+ { CMD_CALMANAC, "CMD_CALMANAC", "almanac (0x20)", "", 0 },
+ { CMD_CCURTIME, "CMD_CCURTIME", "current time (0x21)", "", 0 },
+ { CMD_CMODESEL, "CMD_CMODESEL", "mode select (2-d, 3-D, auto) (0x22)", "", 0 },
+ { CMD_CINITPOS, "CMD_CINITPOS", "initial position (0x23)", "", 0 },
+ { CMD_CRECVPOS, "CMD_CRECVPOS", "receiver position fix mode (0x24)", "", 0 },
+ { CMD_CRESET, "CMD_CRESET", "soft reset & selftest (0x25)", "", 0 },
+ { CMD_CRECVHEALTH, "CMD_CRECVHEALTH", "receiver health (0x26)", "", 0 },
+ { CMD_CSIGNALLV, "CMD_CSIGNALLV", "signal levels (0x27)", "", 0 },
+ { CMD_CMESSAGE, "CMD_CMESSAGE", "GPS system message (0x28)", "", 0 },
+ { CMD_CALMAHEALTH, "CMD_CALMAHEALTH", "almanac healt page (0x29)", "", 0 },
+ { CMD_C2DALTITUDE, "CMD_C2DALTITUDE", "altitude for 2-D mode (0x2A)", "", 0 },
+ { CMD_CINITPOSLLA, "CMD_CINITPOSLLA", "initial position LLA (0x2B)", "", 0 },
+ { CMD_COPERPARAM, "CMD_COPERPARAM", "operating parameters (0x2C)", "", 0 },
+ { CMD_COSCOFFSET, "CMD_COSCOFFSET", "oscillator offset (0x2D)", "", 0 },
+ { CMD_CSETGPSTIME, "CMD_CSETGPSTIME", "set GPS time (0x2E)", "", 0 },
+ { CMD_CUTCPARAM, "CMD_CUTCPARAM", "UTC parameters (0x2F)", "", 0 },
+ { CMD_CACCPOSXYZ, "CMD_CACCPOSXYZ", "accurate initial position (XYZ/ECEF) (0x31)", "", 0 },
+ { CMD_CACCPOS, "CMD_CACCPOS", "accurate initial position (0x32)", "", 0 },
+ { CMD_CANALOGDIG, "CMD_CANALOGDIG", "analog to digital (0x33)", "", 0 },
+ { CMD_CSAT1SAT, "CMD_CSAT1SAT", "satellite for 1-Sat mode (0x34)", "", 0 },
+ { CMD_CIOOPTIONS, "CMD_CIOOPTIONS", "I/O options (0x35)", "", 0 },
+ { CMD_CVELOCAID, "CMD_CVELOCAID", "velocity aiding of acquisition (0x36)", "", 0 },
+ { CMD_CSTATLSTPOS, "CMD_CSTATLSTPOS", "status and values of last pos. and vel. (0x37)", "", 0 },
+ { CMD_CLOADSSATDT, "CMD_CLOADSSATDT", "load satellite system data (0x38)", "", 0 },
+ { CMD_CSATDISABLE, "CMD_CSATDISABLE", "satellite disable (0x39)", "", 0 },
+ { CMD_CLASTRAW, "CMD_CLASTRAW", "last raw measurement (0x3A)", "", 0 },
+ { CMD_CSTATSATEPH, "CMD_CSTATSATEPH", "satellite ephemeris status (0x3B)", "", 0 },
+ { CMD_CSTATTRACK, "CMD_CSTATTRACK", "tracking status (0x3C)", "", 0 },
+ { CMD_CCHANADGPS, "CMD_CCHANADGPS", "configure channel A for differential GPS (0x3D)", "", 0 },
+ { CMD_CADDITFIX, "CMD_CADDITFIX", "additional fix data (0x3E)", "", 0 },
+ { CMD_CDGPSFIXMD, "CMD_CDGPSFIXMD", "set/request differential GPS position fix mode (0x62)", "", 0 },
+ { CMD_CDGPSCORR, "CMD_CDGPSCORR", "differential correction status (0x65)", "", 0 },
+ { CMD_CPOSFILT, "CMD_CPOSFILT", "position filter parameters (0x71)", "", 0 },
+ { CMD_CHEIGHTFILT, "CMD_CHEIGHTFILT", "height filter control (0x73)", "", 0 },
+ { CMD_CHIGH8CNT, "CMD_CHIGH8CNT", "high-8 (best 4) / high-6 (overdetermined) control (0x75)", "", 0 },
+ { CMD_CMAXDGPSCOR, "CMD_CMAXDGPSCOR", "maximum rate of DGPS corrections (0x77)", "", 0 },
+ { CMD_CSUPER, "CMD_CSUPER", "super paket (0x8E)", "", 0 },
+ { 0xFF, "", "" }
+};
+
+
+cmd_info_t trimble_rcmds[] = {
+ { CMD_RDATAA, "CMD_RDATAA", "data channel A configuration (0x3D)", "trimble_channelA", RO },
+ { CMD_RALMANAC, "CMD_RALMANAC", "almanac data for sat (0x40)", "gps_almanac", RO },
+ { CMD_RCURTIME, "CMD_RCURTIME", "GPS time (0x41)", "gps_time", RO },
+ { CMD_RSPOSXYZ, "CMD_RSPOSXYZ", "single precision XYZ position (0x42)", "gps_position(XYZ)", RO|DEF },
+ { CMD_RVELOXYZ, "CMD_RVELOXYZ", "velocity fix (XYZ ECEF) (0x43)", "gps_velocity(XYZ)", RO|DEF },
+ { CMD_RBEST4, "CMD_RBEST4", "best 4 satellite selection (0x44)", "trimble_best4", RO|DEF },
+ { CMD_RVERSION, "CMD_RVERSION", "software version (0x45)", "trimble_version", RO|DEF },
+ { CMD_RRECVHEALTH, "CMD_RRECVHEALTH", "receiver health (0x46)", "trimble_receiver_health", RO|DEF },
+ { CMD_RSIGNALLV, "CMD_RSIGNALLV", "signal levels of all satellites (0x47)", "trimble_signal_levels", RO },
+ { CMD_RMESSAGE, "CMD_RMESSAGE", "GPS system message (0x48)", "gps-message", RO|DEF },
+ { CMD_RALMAHEALTH, "CMD_RALMAHEALTH", "almanac health page for all satellites (0x49)", "gps_almanac_health", RO },
+ { CMD_RSLLAPOS, "CMD_RSLLAPOS", "single LLA position (0x4A)", "gps_position(LLA)", RO|DEF },
+ { CMD_RMACHSTAT, "CMD_RMACHSTAT", "machine code / status (0x4B)", "trimble_status", RO|DEF },
+ { CMD_ROPERPARAM, "CMD_ROPERPARAM", "operating parameters (0x4C)", "trimble_opparam", RO },
+ { CMD_ROSCOFFSET, "CMD_ROSCOFFSET", "oscillator offset (0x4D)", "trimble_oscoffset", RO },
+ { CMD_RSETGPSTIME, "CMD_RSETGPSTIME", "response to set GPS time (0x4E)", "trimble_setgpstime", RO },
+ { CMD_RUTCPARAM, "CMD_RUTCPARAM", "UTC parameters (0x4F)", "gps_utc_correction", RO|DEF },
+ { CMD_RANALOGDIG, "CMD_RANALOGDIG", "analog to digital (0x53)", "trimble_analogdigital", RO },
+ { CMD_RSAT1BIAS, "CMD_RSAT1BIAS", "one-satellite bias & bias rate (0x54)", "trimble_sat1bias", RO },
+ { CMD_RIOOPTIONS, "CMD_RIOOPTIONS", "I/O options (0x55)", "trimble_iooptions", RO },
+ { CMD_RSTATLSTFIX, "CMD_RSTATLSTFIX", "status and values of last pos. and vel. (0x57)", "trimble_status_lastpos", RO },
+ { CMD_RLOADSSATDT, "CMD_RLOADSSATDT", "response to load satellite system data (0x58)", "trimble_loaddata", RO },
+ { CMD_RSATDISABLE, "CMD_RSATDISABLE", "satellite disable (0x59)", "trimble_satdisble", RO },
+ { CMD_RLASTRAW, "CMD_RLASTRAW", "last raw measurement (0x5A)", "trimble_lastraw", RO },
+ { CMD_RSTATSATEPH, "CMD_RSTATSATEPH", "satellite ephemeris status (0x5B)", "trimble_ephstatus", RO },
+ { CMD_RSTATTRACK, "CMD_RSTATTRACK", "tracking status (0x5C)", "trimble_tracking_status", RO|DEF },
+ { CMD_RADDITFIX, "CMD_RADDITFIX", "additional fix data (0x5E)", "trimble_addfix", RO },
+ { CMD_RALLINVIEW, "CMD_RALLINVIEW", "all in view satellite selection (0x6D)", "trimble_satview", RO|DEF },
+ { CMD_RPOSFILT, "CMD_RPOSFILT", "position filter parameters (0x72)", "trimble_posfilt", RO },
+ { CMD_RHEIGHTFILT, "CMD_RHEIGHTFILT", "height filter control (0x74)", "trimble_heightfilt", RO },
+ { CMD_RHIGH8CNT, "CMD_RHIGH8CNT", "high-8 (best 4) / high-6 (overdetermined) control (0x76)", "trimble_high8control", RO },
+ { CMD_RMAXAGE, "CMD_RMAXAGE", "DC MaxAge (0x78)", "trimble_dgpsmaxage", RO },
+ { CMD_RDGPSFIX, "CMD_RDGPSFIX", "differential position fix mode (0x82)", "trimble_dgpsfixmode", RO },
+ { CMD_RDOUBLEXYZ, "CMD_RDOUBLEXYZ", "double precision XYZ (0x83)", "gps_position_ext(XYZ)", RO|DEF },
+ { CMD_RDOUBLELLA, "CMD_RDOUBLELLA", "double precision LLA (0x84)", "gps_position_ext(LLA)", RO|DEF },
+ { CMD_RDGPSSTAT, "CMD_RDGPSSTAT", "differential correction status (0x85)", "trimble_dgpsstatus", RO },
+ { CMD_RSUPER, "CMD_RSUPER", "super paket (0x8F)", "", 0 },
+ { 0xFF, "", "" }
+};
diff --git a/libparse/mfp_mul.c b/libparse/mfp_mul.c
new file mode 100644
index 0000000..43c1e39
--- /dev/null
+++ b/libparse/mfp_mul.c
@@ -0,0 +1,207 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/mfp_mul.c,v 4.9 2005/07/17 20:34:40 kardel RELEASE_20050717_A
+ *
+ * mfp_mul.c,v 4.9 2005/07/17 20:34:40 kardel RELEASE_20050717_A
+ *
+ * $Created: Sat Aug 16 20:35:08 1997 $
+ *
+ * Copyright (c) 1997-2005 by Frank Kardel <kardel <AT> ntp.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#include <config.h>
+#include <stdio.h>
+#include "ntp_stdlib.h"
+#include "ntp_types.h"
+#include "ntp_fp.h"
+
+#define LOW_MASK (u_int32)((1<<(FRACTION_PREC/2))-1)
+#define HIGH_MASK (u_int32)(LOW_MASK << (FRACTION_PREC/2))
+
+/*
+ * for those who worry about overflows (possibly triggered by static analysis tools):
+ *
+ * Largest value of a 2^n bit number is 2^n-1.
+ * Thus the result is: (2^n-1)*(2^n-1) = 2^2n - 2^n - 2^n + 1 < 2^2n
+ * Here overflow can not happen for 2 reasons:
+ * 1) the code actually multiplies the absolute values of two signed
+ * 64bit quantities.thus effectively multiplying 2 63bit quantities.
+ * 2) Carry propagation is from low to high, building principle is
+ * addition, so no storage for the 2^2n term from above is needed.
+ */
+
+void
+mfp_mul(
+ int32 *o_i,
+ u_int32 *o_f,
+ int32 a_i,
+ u_int32 a_f,
+ int32 b_i,
+ u_int32 b_f
+ )
+{
+ int32 i, j;
+ u_int32 f;
+ u_long a[4]; /* operand a */
+ u_long b[4]; /* operand b */
+ u_long c[5]; /* result c - 5 items for performance - see below */
+ u_long carry;
+
+ int neg = 0;
+
+ if (a_i < 0) /* examine sign situation */
+ {
+ neg = 1;
+ M_NEG(a_i, a_f);
+ }
+
+ if (b_i < 0) /* examine sign situation */
+ {
+ neg = !neg;
+ M_NEG(b_i, b_f);
+ }
+
+ a[0] = a_f & LOW_MASK; /* prepare a operand */
+ a[1] = (a_f & HIGH_MASK) >> (FRACTION_PREC/2);
+ a[2] = a_i & LOW_MASK;
+ a[3] = (a_i & HIGH_MASK) >> (FRACTION_PREC/2);
+
+ b[0] = b_f & LOW_MASK; /* prepare b operand */
+ b[1] = (b_f & HIGH_MASK) >> (FRACTION_PREC/2);
+ b[2] = b_i & LOW_MASK;
+ b[3] = (b_i & HIGH_MASK) >> (FRACTION_PREC/2);
+
+ c[0] = c[1] = c[2] = c[3] = c[4] = 0;
+
+ for (i = 0; i < 4; i++) /* we do assume 32 * 32 = 64 bit multiplication */
+ for (j = 0; j < 4; j++)
+ {
+ u_long result_low, result_high;
+ int low_index = (i+j)/2; /* formal [0..3] - index for low long word */
+ int mid_index = 1+low_index; /* formal [1..4]! - index for high long word
+ will generate unecessary add of 0 to c[4]
+ but save 15 'if (result_high) expressions' */
+ int high_index = 1+mid_index; /* formal [2..5]! - index for high word overflow
+ - only assigned on overflow (limits range to 2..3) */
+
+ result_low = (u_long)a[i] * (u_long)b[j]; /* partial product */
+
+ if ((i+j) & 1) /* splits across two result registers */
+ {
+ result_high = result_low >> (FRACTION_PREC/2);
+ result_low <<= FRACTION_PREC/2;
+ carry = (unsigned)1<<(FRACTION_PREC/2);
+ }
+ else
+ { /* stays in a result register - except for overflows */
+ result_high = 0;
+ carry = 1;
+ }
+
+ if (((c[low_index] >> 1) + (result_low >> 1) + ((c[low_index] & result_low & carry) != 0)) &
+ (u_int32)((unsigned)1<<(FRACTION_PREC - 1))) {
+ result_high++; /* propagate overflows */
+ }
+
+ c[low_index] += result_low; /* add up partial products */
+
+ if (((c[mid_index] >> 1) + (result_high >> 1) + ((c[mid_index] & result_high & 1) != 0)) &
+ (u_int32)((unsigned)1<<(FRACTION_PREC - 1))) {
+ c[high_index]++; /* propagate overflows of high word sum */
+ }
+
+ c[mid_index] += result_high; /* will add a 0 to c[4] once but saves 15 if conditions */
+ }
+
+#ifdef DEBUG
+ if (debug > 6)
+ printf("mfp_mul: 0x%04lx%04lx%04lx%04lx * 0x%04lx%04lx%04lx%04lx = 0x%08lx%08lx%08lx%08lx\n",
+ a[3], a[2], a[1], a[0], b[3], b[2], b[1], b[0], c[3], c[2], c[1], c[0]);
+#endif
+
+ if (c[3]) /* overflow */
+ {
+ i = ((unsigned)1 << (FRACTION_PREC-1)) - 1;
+ f = ~(unsigned)0;
+ }
+ else
+ { /* take produkt - discarding extra precision */
+ i = c[2];
+ f = c[1];
+ }
+
+ if (neg) /* recover sign */
+ {
+ M_NEG(i, f);
+ }
+
+ *o_i = i;
+ *o_f = f;
+
+#ifdef DEBUG
+ if (debug > 6)
+ printf("mfp_mul: %s * %s => %s\n",
+ mfptoa((u_long)a_i, a_f, 6),
+ mfptoa((u_long)b_i, b_f, 6),
+ mfptoa((u_long)i, f, 6));
+#endif
+}
+
+/*
+ * History:
+ *
+ * mfp_mul.c,v
+ * Revision 4.9 2005/07/17 20:34:40 kardel
+ * correct carry propagation implementation
+ *
+ * Revision 4.8 2005/07/12 16:17:26 kardel
+ * add explanation why we do not write into c[4]
+ *
+ * Revision 4.7 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.6 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.3 1999/02/21 12:17:37 kardel
+ * 4.91f reconcilation
+ *
+ * Revision 4.2 1998/12/20 23:45:28 kardel
+ * fix types and warnings
+ *
+ * Revision 4.1 1998/05/24 07:59:57 kardel
+ * conditional debug support
+ *
+ * Revision 4.0 1998/04/10 19:46:38 kardel
+ * Start 4.0 release version numbering
+ *
+ * Revision 1.1 1998/04/10 19:27:47 kardel
+ * initial NTP VERSION 4 integration of PARSE with GPS166 binary support
+ *
+ * Revision 1.1 1997/10/06 21:05:46 kardel
+ * new parse structure
+ *
+ */
diff --git a/libparse/mkinfo_rcmd.sed b/libparse/mkinfo_rcmd.sed
new file mode 100644
index 0000000..5238d5c
--- /dev/null
+++ b/libparse/mkinfo_rcmd.sed
@@ -0,0 +1,8 @@
+1i\
+\
+\
+cmd_info_t trimble_rcmds[] = {
+s!^#define[ \ ][ \ ]*\(CMD_R[^ \ ]*\)[ \ ][ \ ]*\([^ \ ]*\)[ \ ][ \ ]*/\*[ \ ][ \ ]*\(.*\)[ \ ]*:\([^:]*\):\([^:]*\)[ \ ][ \ ]*\*/!\ { \1, "\1", "\3 (\2)", "\4", \5 },!p
+$a\
+\ { 0xFF, "", "" }\
+};
diff --git a/libparse/mkinfo_scmd.sed b/libparse/mkinfo_scmd.sed
new file mode 100644
index 0000000..9c17f39
--- /dev/null
+++ b/libparse/mkinfo_scmd.sed
@@ -0,0 +1,15 @@
+1i\
+/*\
+\ * Automatically generated - do not modify\
+\ */\
+\
+#include <config.h>\
+#include "ntp_types.h"\
+#include "ntpd.h"\
+#include "trimble.h"\
+\
+cmd_info_t trimble_scmds[] = {
+s!^#define[ ][ ]*\(CMD_C[^ ]*\)[ ][ ]*\([^ ]*\)[ ][ ]*/\*[ ][ ]*\(.*\)[ ][ ]*\*/! { \1, "\1", "\3 (\2)", "", 0 },!p
+$a\
+\ { 0xFF, "", "" }\
+};
diff --git a/libparse/parse.c b/libparse/parse.c
new file mode 100644
index 0000000..85e5299
--- /dev/null
+++ b/libparse/parse.c
@@ -0,0 +1,945 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A
+ *
+ * parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A
+ *
+ * Parser module for reference clock
+ *
+ * PARSEKERNEL define switches between two personalities of the module
+ * if PARSEKERNEL is defined this module can be used
+ * as kernel module. In this case the time stamps will be
+ * a struct timeval.
+ * when PARSEKERNEL is not defined NTP time stamps will be used.
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE)
+
+#if !(defined(lint) || defined(__GNUC__))
+static char rcsid[] = "parse.c,v 4.20 2005/08/06 17:39:40 kardel RELEASE_20050806_A";
+#endif
+
+#include "ntp_fp.h"
+#include "timevalops.h"
+#include "ntp_calendar.h"
+#include "ntp_stdlib.h"
+#include "ntp_machine.h"
+#include "ntp.h" /* (get Y2KFixes definitions) Y2KFixes */
+
+#include "parse.h"
+
+#ifndef PARSESTREAM
+# include <stdio.h>
+#else
+# include "sys/parsestreams.h"
+#endif
+
+extern clockformat_t *clockformats[];
+extern unsigned short nformats;
+
+static u_long timepacket (parse_t *);
+
+/*
+ * strings support usually not in kernel - duplicated, but what the heck
+ */
+static int
+Strlen(
+ register const char *s
+ )
+{
+ register int c;
+
+ c = 0;
+ if (s)
+ {
+ while (*s++)
+ {
+ c++;
+ }
+ }
+ return c;
+}
+
+static int
+Strcmp(
+ register const char *s,
+ register const char *t
+ )
+{
+ register int c = 0;
+
+ if (!s || !t || (s == t))
+ {
+ return 0;
+ }
+
+ while (!(c = *s++ - *t++) && *s && *t)
+ /* empty loop */;
+
+ return c;
+}
+
+int
+parse_timedout(
+ parse_t *parseio,
+ timestamp_t *tstamp,
+ struct timeval *del
+ )
+{
+ struct timeval delta;
+
+#ifdef PARSEKERNEL
+ delta.tv_sec = tstamp->tv.tv_sec - parseio->parse_lastchar.tv.tv_sec;
+ delta.tv_usec = tstamp->tv.tv_usec - parseio->parse_lastchar.tv.tv_usec;
+ if (delta.tv_usec < 0)
+ {
+ delta.tv_sec -= 1;
+ delta.tv_usec += 1000000;
+ }
+#else
+ l_fp delt;
+
+ delt = tstamp->fp;
+ L_SUB(&delt, &parseio->parse_lastchar.fp);
+ TSTOTV(&delt, &delta);
+#endif
+
+ if (timercmp(&delta, del, >))
+ {
+ parseprintf(DD_PARSE, ("parse: timedout: TRUE\n"));
+ return 1;
+ }
+ else
+ {
+ parseprintf(DD_PARSE, ("parse: timedout: FALSE\n"));
+ return 0;
+ }
+}
+
+/*ARGSUSED*/
+int
+parse_ioinit(
+ register parse_t *parseio
+ )
+{
+ parseprintf(DD_PARSE, ("parse_iostart\n"));
+
+ parseio->parse_plen = 0;
+ parseio->parse_pdata = (void *)0;
+
+ parseio->parse_data = 0;
+ parseio->parse_ldata = 0;
+ parseio->parse_dsize = 0;
+
+ parseio->parse_badformat = 0;
+ parseio->parse_ioflags = PARSE_IO_CS7; /* usual unix default */
+ parseio->parse_index = 0;
+ parseio->parse_ldsize = 0;
+
+ return 1;
+}
+
+/*ARGSUSED*/
+void
+parse_ioend(
+ register parse_t *parseio
+ )
+{
+ parseprintf(DD_PARSE, ("parse_ioend\n"));
+
+ if (parseio->parse_pdata)
+ FREE(parseio->parse_pdata, parseio->parse_plen);
+
+ if (parseio->parse_data)
+ FREE(parseio->parse_data, (unsigned)(parseio->parse_dsize * 2 + 2));
+}
+
+unsigned int
+parse_restart(
+ parse_t *parseio,
+ unsigned int ch
+ )
+{
+ unsigned int updated = PARSE_INP_SKIP;
+
+ /*
+ * re-start packet - timeout - overflow - start symbol
+ */
+
+ if (parseio->parse_index)
+ {
+ /*
+ * filled buffer - thus not end character found
+ * do processing now
+ */
+ parseio->parse_data[parseio->parse_index] = '\0';
+ memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
+ parseio->parse_ldsize = parseio->parse_index;
+ updated = PARSE_INP_TIME;
+ }
+
+ parseio->parse_index = 1;
+ parseio->parse_data[0] = ch;
+ parseprintf(DD_PARSE, ("parse: parse_restart: buffer start (updated = %x)\n", updated));
+ return updated;
+}
+
+unsigned int
+parse_addchar(
+ parse_t *parseio,
+ unsigned int ch
+ )
+{
+ /*
+ * add to buffer
+ */
+ if (parseio->parse_index < parseio->parse_dsize)
+ {
+ /*
+ * collect into buffer
+ */
+ parseprintf(DD_PARSE, ("parse: parse_addchar: buffer[%d] = 0x%x\n", parseio->parse_index, ch));
+ parseio->parse_data[parseio->parse_index++] = (char)ch;
+ return PARSE_INP_SKIP;
+ }
+ else
+ /*
+ * buffer overflow - attempt to make the best of it
+ */
+ return parse_restart(parseio, ch);
+}
+
+unsigned int
+parse_end(
+ parse_t *parseio
+ )
+{
+ /*
+ * message complete processing
+ */
+ parseio->parse_data[parseio->parse_index] = '\0';
+ memcpy(parseio->parse_ldata, parseio->parse_data, (unsigned)(parseio->parse_index+1));
+ parseio->parse_ldsize = parseio->parse_index;
+ parseio->parse_index = 0;
+ parseprintf(DD_PARSE, ("parse: parse_end: buffer end\n"));
+ return PARSE_INP_TIME;
+}
+
+/*ARGSUSED*/
+int
+parse_ioread(
+ register parse_t *parseio,
+ register unsigned int ch,
+ register timestamp_t *tstamp
+ )
+{
+ register unsigned updated = CVT_NONE;
+ /*
+ * within STREAMS CSx (x < 8) chars still have the upper bits set
+ * so we normalize the characters by masking unecessary bits off.
+ */
+ switch (parseio->parse_ioflags & PARSE_IO_CSIZE)
+ {
+ case PARSE_IO_CS5:
+ ch &= 0x1F;
+ break;
+
+ case PARSE_IO_CS6:
+ ch &= 0x3F;
+ break;
+
+ case PARSE_IO_CS7:
+ ch &= 0x7F;
+ break;
+
+ case PARSE_IO_CS8:
+ ch &= 0xFF;
+ break;
+ }
+
+ parseprintf(DD_PARSE, ("parse_ioread(0x%lx, char=0x%x, ..., ...)\n", (unsigned long)parseio, ch & 0xFF));
+
+ if (!clockformats[parseio->parse_lformat]->convert)
+ {
+ parseprintf(DD_PARSE, ("parse_ioread: input dropped.\n"));
+ return CVT_NONE;
+ }
+
+ if (clockformats[parseio->parse_lformat]->input)
+ {
+ unsigned long input_status;
+
+ input_status = clockformats[parseio->parse_lformat]->input(parseio, ch, tstamp);
+
+ if (input_status & PARSE_INP_SYNTH)
+ {
+ updated = CVT_OK;
+ }
+
+ if (input_status & PARSE_INP_TIME) /* time sample is available */
+ {
+ updated = timepacket(parseio);
+ }
+
+ if (input_status & PARSE_INP_DATA) /* got additional data */
+ {
+ updated |= CVT_ADDITIONAL;
+ }
+ }
+
+
+ /*
+ * remember last character time
+ */
+ parseio->parse_lastchar = *tstamp;
+
+#ifdef DEBUG
+ if ((updated & CVT_MASK) != CVT_NONE)
+ {
+ parseprintf(DD_PARSE, ("parse_ioread: time sample accumulated (status=0x%x)\n", updated));
+ }
+#endif
+
+ parseio->parse_dtime.parse_status = updated;
+
+ return (((updated & CVT_MASK) != CVT_NONE) ||
+ ((updated & CVT_ADDITIONAL) != 0));
+}
+
+/*
+ * parse_iopps
+ *
+ * take status line indication and derive synchronisation information
+ * from it.
+ * It can also be used to decode a serial serial data format (such as the
+ * ONE, ZERO, MINUTE sync data stream from DCF77)
+ */
+/*ARGSUSED*/
+int
+parse_iopps(
+ register parse_t *parseio,
+ register int status,
+ register timestamp_t *ptime
+ )
+{
+ register unsigned updated = CVT_NONE;
+
+ /*
+ * PPS pulse information will only be delivered to ONE clock format
+ * this is either the last successful conversion module with a ppssync
+ * routine, or a fixed format with a ppssync routine
+ */
+ parseprintf(DD_PARSE, ("parse_iopps: STATUS %s\n", (status == SYNC_ONE) ? "ONE" : "ZERO"));
+
+ if (clockformats[parseio->parse_lformat]->syncpps)
+ {
+ updated = clockformats[parseio->parse_lformat]->syncpps(parseio, status == SYNC_ONE, ptime);
+ parseprintf(DD_PARSE, ("parse_iopps: updated = 0x%x\n", updated));
+ }
+
+ return (updated & CVT_MASK) != CVT_NONE;
+}
+
+/*
+ * parse_iodone
+ *
+ * clean up internal status for new round
+ */
+/*ARGSUSED*/
+void
+parse_iodone(
+ register parse_t *parseio
+ )
+{
+ /*
+ * we need to clean up certain flags for the next round
+ */
+ parseprintf(DD_PARSE, ("parse_iodone: DONE\n"));
+ parseio->parse_dtime.parse_state = 0; /* no problems with ISRs */
+}
+
+/*---------- conversion implementation --------------------*/
+
+/*
+ * convert a struct clock to UTC since Jan, 1st 1970 0:00 (the UNIX EPOCH)
+ */
+#define days_per_year(x) ((x) % 4 ? 365 : ((x % 400) ? ((x % 100) ? 366 : 365) : 366))
+
+time_t
+parse_to_unixtime(
+ register clocktime_t *clock_time,
+ register u_long *cvtrtc
+ )
+{
+#define SETRTC(_X_) { if (cvtrtc) *cvtrtc = (_X_); }
+ static int days_of_month[] =
+ {
+ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+ register int i;
+ time_t t;
+
+ if (clock_time->utctime)
+ return clock_time->utctime; /* if the conversion routine gets it right away - why not */
+
+ if ( clock_time->year < YEAR_PIVOT ) /* Y2KFixes [ */
+ clock_time->year += 100; /* convert 20xx%100 to 20xx-1900 */
+ if ( clock_time->year < YEAR_BREAK ) /* expand to full four-digits */
+ clock_time->year += 1900;
+
+ if (clock_time->year < 1970 ) /* Y2KFixes ] */
+ {
+ SETRTC(CVT_FAIL|CVT_BADDATE);
+ return -1;
+ }
+
+ /*
+ * sorry, slow section here - but it's not time critical anyway
+ */
+ t = julian0(clock_time->year) - julian0(1970); /* Y2kFixes */
+ /* month */
+ if (clock_time->month <= 0 || clock_time->month > 12)
+ {
+ SETRTC(CVT_FAIL|CVT_BADDATE);
+ return -1; /* bad month */
+ }
+
+#if 0 /* Y2KFixes */
+ /* adjust leap year */
+ if (clock_time->month < 3 && days_per_year(clock_time->year) == 366)
+ t--;
+#else /* Y2KFixes [ */
+ if ( clock_time->month >= 3 && isleap_4(clock_time->year) )
+ t++; /* add one more if within leap year */
+#endif /* Y2KFixes ] */
+
+ for (i = 1; i < clock_time->month; i++)
+ {
+ t += days_of_month[i];
+ }
+ /* day */
+ if (clock_time->day < 1 || ((clock_time->month == 2 && days_per_year(clock_time->year) == 366) ?
+ clock_time->day > 29 : clock_time->day > days_of_month[clock_time->month]))
+ {
+ SETRTC(CVT_FAIL|CVT_BADDATE);
+ return -1; /* bad day */
+ }
+
+ t += clock_time->day - 1;
+ /* hour */
+ if (clock_time->hour < 0 || clock_time->hour >= 24)
+ {
+ SETRTC(CVT_FAIL|CVT_BADTIME);
+ return -1; /* bad hour */
+ }
+
+ t = TIMES24(t) + clock_time->hour;
+
+ /* min */
+ if (clock_time->minute < 0 || clock_time->minute > 59)
+ {
+ SETRTC(CVT_FAIL|CVT_BADTIME);
+ return -1; /* bad min */
+ }
+
+ t = TIMES60(t) + clock_time->minute;
+ /* sec */
+
+ if (clock_time->second < 0 || clock_time->second > 60) /* allow for LEAPs */
+ {
+ SETRTC(CVT_FAIL|CVT_BADTIME);
+ return -1; /* bad sec */
+ }
+
+ t = TIMES60(t) + clock_time->second;
+
+ t += clock_time->utcoffset; /* warp to UTC */
+
+ /* done */
+
+ clock_time->utctime = t; /* documentray only */
+
+ return t;
+}
+
+/*--------------- format conversion -----------------------------------*/
+
+int
+Stoi(
+ const unsigned char *s,
+ long *zp,
+ int cnt
+ )
+{
+ char unsigned const *b = s;
+ int f,z,v;
+ char unsigned c;
+
+ f=z=v=0;
+
+ while(*s == ' ')
+ s++;
+
+ if (*s == '-')
+ {
+ s++;
+ v = 1;
+ }
+ else
+ if (*s == '+')
+ s++;
+
+ for(;;)
+ {
+ c = *s++;
+ if (c == '\0' || c < '0' || c > '9' || (cnt && ((s-b) > cnt)))
+ {
+ if (f == 0)
+ {
+ return(-1);
+ }
+ if (v)
+ z = -z;
+ *zp = z;
+ return(0);
+ }
+ z = (z << 3) + (z << 1) + ( c - '0' );
+ f=1;
+ }
+}
+
+int
+Strok(
+ const unsigned char *s,
+ const unsigned char *m
+ )
+{
+ if (!s || !m)
+ return 0;
+
+ while(*s && *m)
+ {
+ if ((*m == ' ') ? 1 : (*s == *m))
+ {
+ s++;
+ m++;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ return !*m;
+}
+
+u_long
+updatetimeinfo(
+ register parse_t *parseio,
+ register u_long flags
+ )
+{
+#ifdef PARSEKERNEL
+ {
+ int s = splhigh();
+#endif
+
+ parseio->parse_lstate = parseio->parse_dtime.parse_state | flags | PARSEB_TIMECODE;
+
+ parseio->parse_dtime.parse_state = parseio->parse_lstate;
+
+#ifdef PARSEKERNEL
+ (void)splx((unsigned int)s);
+ }
+#endif
+
+
+#ifdef PARSEKERNEL
+ parseprintf(DD_PARSE, ("updatetimeinfo status=0x%x, time=%x\n", parseio->parse_dtime.parse_state,
+ parseio->parse_dtime.parse_time.tv.tv_sec));
+#else
+ parseprintf(DD_PARSE, ("updatetimeinfo status=0x%lx, time=%x\n", (long)parseio->parse_dtime.parse_state,
+ parseio->parse_dtime.parse_time.fp.l_ui));
+#endif
+
+ return CVT_OK; /* everything fine and dandy... */
+}
+
+
+/*
+ * syn_simple
+ *
+ * handle a sync time stamp
+ */
+/*ARGSUSED*/
+void
+syn_simple(
+ register parse_t *parseio,
+ register timestamp_t *ts,
+ register struct format *format,
+ register u_long why
+ )
+{
+ parseio->parse_dtime.parse_stime = *ts;
+}
+
+/*
+ * pps_simple
+ *
+ * handle a pps time stamp
+ */
+/*ARGSUSED*/
+u_long
+pps_simple(
+ register parse_t *parseio,
+ register int status,
+ register timestamp_t *ptime
+ )
+{
+ parseio->parse_dtime.parse_ptime = *ptime;
+ parseio->parse_dtime.parse_state |= PARSEB_PPS|PARSEB_S_PPS;
+
+ return CVT_NONE;
+}
+
+/*
+ * pps_one
+ *
+ * handle a pps time stamp in ONE edge
+ */
+/*ARGSUSED*/
+u_long
+pps_one(
+ register parse_t *parseio,
+ register int status,
+ register timestamp_t *ptime
+ )
+{
+ if (status)
+ return pps_simple(parseio, status, ptime);
+
+ return CVT_NONE;
+}
+
+/*
+ * pps_zero
+ *
+ * handle a pps time stamp in ZERO edge
+ */
+/*ARGSUSED*/
+u_long
+pps_zero(
+ register parse_t *parseio,
+ register int status,
+ register timestamp_t *ptime
+ )
+{
+ if (!status)
+ return pps_simple(parseio, status, ptime);
+
+ return CVT_NONE;
+}
+
+/*
+ * timepacket
+ *
+ * process a data packet
+ */
+static u_long
+timepacket(
+ register parse_t *parseio
+ )
+{
+ register unsigned short format;
+ register time_t t;
+ u_long cvtrtc; /* current conversion result */
+ clocktime_t clock_time;
+
+ memset((char *)&clock_time, 0, sizeof clock_time);
+ format = parseio->parse_lformat;
+
+ if (format == (unsigned short)~0)
+ return CVT_NONE;
+
+ switch ((cvtrtc = clockformats[format]->convert ?
+ clockformats[format]->convert((unsigned char *)parseio->parse_ldata, parseio->parse_ldsize, (struct format *)(clockformats[format]->data), &clock_time, parseio->parse_pdata) :
+ CVT_NONE) & CVT_MASK)
+ {
+ case CVT_FAIL:
+ parseio->parse_badformat++;
+ break;
+
+ case CVT_NONE:
+ /*
+ * too bad - pretend bad format
+ */
+ parseio->parse_badformat++;
+ break;
+
+ case CVT_OK:
+ break;
+
+ case CVT_SKIP:
+ return CVT_NONE;
+
+ default:
+ /* shouldn't happen */
+#ifndef PARSEKERNEL
+ msyslog(LOG_WARNING, "parse: INTERNAL error: bad return code of convert routine \"%s\"", clockformats[format]->name);
+#endif
+ return CVT_FAIL|cvtrtc;
+ }
+
+ if ((t = parse_to_unixtime(&clock_time, &cvtrtc)) == -1)
+ {
+ return CVT_FAIL|cvtrtc;
+ }
+
+ /*
+ * time stamp
+ */
+#ifdef PARSEKERNEL
+ parseio->parse_dtime.parse_time.tv.tv_sec = t;
+ parseio->parse_dtime.parse_time.tv.tv_usec = clock_time.usecond;
+#else
+ parseio->parse_dtime.parse_time.fp.l_ui = t + JAN_1970;
+ TVUTOTSF(clock_time.usecond, parseio->parse_dtime.parse_time.fp.l_uf);
+#endif
+
+ parseio->parse_dtime.parse_format = format;
+
+ return updatetimeinfo(parseio, clock_time.flags);
+}
+
+/*ARGSUSED*/
+int
+parse_timecode(
+ parsectl_t *dct,
+ parse_t *parse
+ )
+{
+ dct->parsegettc.parse_state = parse->parse_lstate;
+ dct->parsegettc.parse_format = parse->parse_lformat;
+ /*
+ * move out current bad packet count
+ * user program is expected to sum these up
+ * this is not a problem, as "parse" module are
+ * exclusive open only
+ */
+ dct->parsegettc.parse_badformat = parse->parse_badformat;
+ parse->parse_badformat = 0;
+
+ if (parse->parse_ldsize <= PARSE_TCMAX)
+ {
+ dct->parsegettc.parse_count = parse->parse_ldsize;
+ memcpy(dct->parsegettc.parse_buffer, parse->parse_ldata, dct->parsegettc.parse_count);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+/*ARGSUSED*/
+int
+parse_setfmt(
+ parsectl_t *dct,
+ parse_t *parse
+ )
+{
+ if (dct->parseformat.parse_count <= PARSE_TCMAX)
+ {
+ if (dct->parseformat.parse_count)
+ {
+ register unsigned short i;
+
+ for (i = 0; i < nformats; i++)
+ {
+ if (!Strcmp(dct->parseformat.parse_buffer, clockformats[i]->name))
+ {
+ if (parse->parse_pdata)
+ FREE(parse->parse_pdata, parse->parse_plen);
+ parse->parse_pdata = 0;
+
+ parse->parse_plen = clockformats[i]->plen;
+
+ if (parse->parse_plen)
+ {
+ parse->parse_pdata = MALLOC(parse->parse_plen);
+ if (!parse->parse_pdata)
+ {
+ parseprintf(DD_PARSE, ("set format failed: malloc for private data area failed\n"));
+ return 0;
+ }
+ memset((char *)parse->parse_pdata, 0, parse->parse_plen);
+ }
+
+ if (parse->parse_data)
+ FREE(parse->parse_data, (unsigned)(parse->parse_dsize * 2 + 2));
+ parse->parse_ldata = parse->parse_data = 0;
+
+ parse->parse_dsize = clockformats[i]->length;
+
+ if (parse->parse_dsize)
+ {
+ parse->parse_data = (char*)MALLOC((unsigned)(parse->parse_dsize * 2 + 2));
+ if (!parse->parse_data)
+ {
+ if (parse->parse_pdata)
+ FREE(parse->parse_pdata, parse->parse_plen);
+ parse->parse_pdata = 0;
+
+ parseprintf(DD_PARSE, ("init failed: malloc for data area failed\n"));
+ return 0;
+ }
+ }
+
+
+ /*
+ * leave room for '\0'
+ */
+ parse->parse_ldata = parse->parse_data + parse->parse_dsize + 1;
+
+ parse->parse_lformat = i;
+
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*ARGSUSED*/
+int
+parse_getfmt(
+ parsectl_t *dct,
+ parse_t *parse
+ )
+{
+ if (dct->parseformat.parse_format < nformats &&
+ Strlen(clockformats[dct->parseformat.parse_format]->name) <= PARSE_TCMAX)
+ {
+ dct->parseformat.parse_count = Strlen(clockformats[dct->parseformat.parse_format]->name)+1;
+ memcpy(dct->parseformat.parse_buffer, clockformats[dct->parseformat.parse_format]->name, dct->parseformat.parse_count);
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/*ARGSUSED*/
+int
+parse_setcs(
+ parsectl_t *dct,
+ parse_t *parse
+ )
+{
+ parse->parse_ioflags &= ~PARSE_IO_CSIZE;
+ parse->parse_ioflags |= dct->parsesetcs.parse_cs & PARSE_IO_CSIZE;
+ return 1;
+}
+
+#else /* not (REFCLOCK && CLOCK_PARSE) */
+int parse_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE) */
+
+/*
+ * History:
+ *
+ * parse.c,v
+ * Revision 4.20 2005/08/06 17:39:40 kardel
+ * cleanup size handling wrt/ to buffer boundaries
+ *
+ * Revision 4.19 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.18 2004/11/14 16:11:05 kardel
+ * update Id tags
+ *
+ * Revision 4.17 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.14 1999/11/28 09:13:52 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.13 1999/02/28 11:50:20 kardel
+ * (timepacket): removed unecessary code
+ *
+ * Revision 4.12 1999/02/21 12:17:44 kardel
+ * 4.91f reconcilation
+ *
+ * Revision 4.11 1999/02/21 11:09:47 kardel
+ * unified debug output
+ *
+ * Revision 4.10 1998/12/20 23:45:30 kardel
+ * fix types and warnings
+ *
+ * Revision 4.9 1998/08/09 22:26:06 kardel
+ * Trimble TSIP support
+ *
+ * Revision 4.8 1998/06/14 21:09:39 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.7 1998/06/13 15:19:13 kardel
+ * fix mem*() to b*() function macro emulation
+ *
+ * Revision 4.6 1998/06/13 13:24:13 kardel
+ * printf fmt
+ *
+ * Revision 4.5 1998/06/13 13:01:10 kardel
+ * printf fmt
+ *
+ * Revision 4.4 1998/06/13 12:12:10 kardel
+ * bcopy/memcpy cleanup
+ * fix SVSV name clash
+ *
+ * Revision 4.3 1998/06/12 15:22:30 kardel
+ * fix prototypes
+ *
+ * Revision 4.2 1998/06/12 09:13:27 kardel
+ * conditional compile macros fixed
+ * printf prototype
+ *
+ * Revision 4.1 1998/05/24 09:39:55 kardel
+ * implementation of the new IO handling model
+ *
+ * Revision 4.0 1998/04/10 19:45:36 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.46 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/parse_conf.c b/libparse/parse_conf.c
new file mode 100644
index 0000000..b7234dd
--- /dev/null
+++ b/libparse/parse_conf.c
@@ -0,0 +1,182 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/parse_conf.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * parse_conf.c,v 4.9 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * Parser configuration module for reference clocks
+ *
+ * STREAM define switches between two personalities of the module
+ * if STREAM is defined this module can be used with dcf77sync.c as
+ * a STREAMS kernel module. In this case the time stamps will be
+ * a struct timeval.
+ * when STREAM is not defined NTP time stamps will be used.
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if defined(REFCLOCK) && defined(CLOCK_PARSE)
+
+#include "ntp_fp.h"
+#include "ntp_unixtime.h"
+#include "ntp_calendar.h"
+
+#include "parse.h"
+
+#ifdef CLOCK_SCHMID
+extern clockformat_t clock_schmid;
+#endif
+
+#ifdef CLOCK_DCF7000
+extern clockformat_t clock_dcf7000;
+#endif
+
+#ifdef CLOCK_MEINBERG
+extern clockformat_t clock_meinberg[];
+#endif
+
+#ifdef CLOCK_RAWDCF
+extern clockformat_t clock_rawdcf;
+#endif
+
+#ifdef CLOCK_TRIMTAIP
+extern clockformat_t clock_trimtaip;
+#endif
+
+#ifdef CLOCK_TRIMTSIP
+extern clockformat_t clock_trimtsip;
+#endif
+
+#ifdef CLOCK_RCC8000
+extern clockformat_t clock_rcc8000;
+#endif
+
+#ifdef CLOCK_HOPF6021
+extern clockformat_t clock_hopf6021;
+#endif
+
+#ifdef CLOCK_COMPUTIME
+extern clockformat_t clock_computime;
+#endif
+
+#ifdef CLOCK_WHARTON_400A
+extern clockformat_t clock_wharton_400a;
+#endif
+
+#ifdef CLOCK_VARITEXT
+extern clockformat_t clock_varitext;
+#endif
+
+#ifdef CLOCK_SEL240X
+extern clockformat_t clock_sel240x;
+#endif
+
+/*
+ * format definitions
+ */
+clockformat_t *clockformats[] =
+{
+#ifdef CLOCK_MEINBERG
+ &clock_meinberg[0],
+ &clock_meinberg[1],
+ &clock_meinberg[2],
+#endif
+#ifdef CLOCK_DCF7000
+ &clock_dcf7000,
+#endif
+#ifdef CLOCK_SCHMID
+ &clock_schmid,
+#endif
+#ifdef CLOCK_RAWDCF
+ &clock_rawdcf,
+#endif
+#ifdef CLOCK_TRIMTAIP
+ &clock_trimtaip,
+#endif
+#ifdef CLOCK_TRIMTSIP
+ &clock_trimtsip,
+#endif
+#ifdef CLOCK_RCC8000
+ &clock_rcc8000,
+#endif
+#ifdef CLOCK_HOPF6021
+ &clock_hopf6021,
+#endif
+#ifdef CLOCK_COMPUTIME
+ &clock_computime,
+#endif
+#ifdef CLOCK_WHARTON_400A
+ &clock_wharton_400a,
+#endif
+#ifdef CLOCK_VARITEXT
+ &clock_varitext,
+#endif
+#ifdef CLOCK_SEL240X
+ &clock_sel240x,
+#endif
+ 0};
+
+unsigned short nformats = sizeof(clockformats) / sizeof(clockformats[0]) - 1;
+
+#else /* not (REFCLOCK && CLOCK_PARSE) */
+int parse_conf_bs;
+#endif /* not (REFCLOCK && CLOCK_PARSE) */
+
+/*
+ * History:
+ *
+ * parse_conf.c,v
+ * Revision 4.9 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.8 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.5 1999/11/28 09:13:53 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.4 1999/02/28 15:27:25 kardel
+ * wharton clock integration
+ *
+ * Revision 4.3 1998/08/16 18:52:15 kardel
+ * (clockformats): Trimble TSIP driver now also
+ * available for kernel operation
+ *
+ * Revision 4.2 1998/06/12 09:13:48 kardel
+ * conditional compile macros fixed
+ *
+ * Revision 4.1 1998/05/24 09:40:49 kardel
+ * adjustments of log messages
+ *
+ *
+ * from V3 3.24 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/parsesolaris.c b/libparse/parsesolaris.c
new file mode 100644
index 0000000..d3756af
--- /dev/null
+++ b/libparse/parsesolaris.c
@@ -0,0 +1,1202 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/parsesolaris.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * parsesolaris.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * STREAMS module for reference clocks
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#define _KERNEL /* it is a _KERNEL module */
+
+#ifndef lint
+static char rcsid[] = "parsesolaris.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A";
+#endif
+
+#include <config.h>
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/termios.h>
+#include <sys/stream.h>
+#include <sys/strtty.h>
+#include <sys/stropts.h>
+#include <sys/modctl.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
+#ifdef __GNUC__ /* makes it compile on Solaris 2.6 - acc doesn't like it -- GREAT! */
+#include <stdarg.h>
+#endif
+
+#include "ntp_fp.h"
+#include "parse.h"
+#include <sys/parsestreams.h>
+
+/*--------------- loadable driver section -----------------------------*/
+
+static struct streamtab parseinfo;
+
+static struct fmodsw fmod_templ =
+{
+ "parse", /* module name */
+ &parseinfo, /* module information */
+ D_NEW|D_MP|D_MTQPAIR, /* exclusive for q pair */
+ /* lock ptr */
+};
+
+extern struct mod_ops mod_strmodops;
+
+static struct modlstrmod modlstrmod =
+{
+ &mod_strmodops, /* a STREAMS module */
+ "PARSE - NTP reference", /* name this baby - keep room for revision number */
+ &fmod_templ
+};
+
+static struct modlinkage modlinkage =
+{
+ MODREV_1,
+ {
+ &modlstrmod,
+ NULL
+ }
+};
+
+/*
+ * module management routines
+ */
+/*ARGSUSED*/
+int
+_init(
+ void
+ )
+{
+ static char revision[] = "4.6";
+ char *s, *S;
+ char *t;
+
+#ifndef lint
+ t = rcsid;
+#endif
+
+ /*
+ * copy RCS revision into Drv_name
+ *
+ * are we forcing RCS here to do things it was not built for ?
+ */
+ s = revision;
+ if (*s == '$')
+ {
+ /*
+ * skip "$Revision: "
+ * if present. - not necessary on a -kv co (cvs export)
+ */
+ while (*s && (*s != ' '))
+ {
+ s++;
+ }
+ if (*s == ' ') s++;
+ }
+
+ t = modlstrmod.strmod_linkinfo;
+ while (*t && (*t != ' '))
+ {
+ t++;
+ }
+ if (*t == ' ') t++;
+
+ S = s;
+ while (*S && (((*S >= '0') && (*S <= '9')) || (*S == '.')))
+ {
+ S++;
+ }
+
+ if (*s && *t && (S > s))
+ {
+ if (strlen(t) >= (S - s))
+ {
+ strlcpy(t, s, (unsigned)(S - s));
+ }
+ }
+ return (mod_install(&modlinkage));
+}
+
+/*ARGSUSED*/
+int
+_info(
+ struct modinfo *modinfop
+ )
+{
+ return (mod_info(&modlinkage, modinfop));
+}
+
+/*ARGSUSED*/
+int
+_fini(
+ void
+ )
+{
+ if (mod_remove(&modlinkage) != DDI_SUCCESS)
+ {
+ return EBUSY;
+ }
+ else
+ return DDI_SUCCESS;
+}
+
+/*--------------- stream module definition ----------------------------*/
+
+static int parseopen (queue_t *, dev_t *, int, int, cred_t *);
+static int parseclose (queue_t *, int);
+static int parsewput (queue_t *, mblk_t *);
+static int parserput (queue_t *, mblk_t *);
+static int parsersvc (queue_t *);
+
+static struct module_info driverinfo =
+{
+ 0, /* module ID number */
+ fmod_templ.f_name, /* module name - why repeated here ? compat ?*/
+ 0, /* minimum accepted packet size */
+ INFPSZ, /* maximum accepted packet size */
+ 1, /* high water mark - flow control */
+ 0 /* low water mark - flow control */
+};
+
+static struct qinit rinit = /* read queue definition */
+{
+ parserput, /* put procedure */
+ parsersvc, /* service procedure */
+ parseopen, /* open procedure */
+ parseclose, /* close procedure */
+ NULL, /* admin procedure - NOT USED FOR NOW */
+ &driverinfo, /* information structure */
+ NULL /* statistics */
+};
+
+static struct qinit winit = /* write queue definition */
+{
+ parsewput, /* put procedure */
+ NULL, /* service procedure */
+ NULL, /* open procedure */
+ NULL, /* close procedure */
+ NULL, /* admin procedure - NOT USED FOR NOW */
+ &driverinfo, /* information structure */
+ NULL /* statistics */
+};
+
+static struct streamtab parseinfo = /* stream info element for parse driver */
+{
+ &rinit, /* read queue */
+ &winit, /* write queue */
+ NULL, /* read mux */
+ NULL /* write mux */
+};
+
+/*--------------- driver data structures ----------------------------*/
+
+/*
+ * we usually have an inverted signal - but you
+ * can change this to suit your needs
+ */
+int cd_invert = 1; /* invert status of CD line - PPS support via CD input */
+
+#ifdef PARSEDEBUG
+int parsedebug = ~0;
+#else
+int parsedebug = 0;
+#endif
+
+/*--------------- module implementation -----------------------------*/
+
+#define TIMEVAL_USADD(_X_, _US_) do {\
+ (_X_)->tv_usec += (_US_);\
+ if ((_X_)->tv_usec >= 1000000)\
+ {\
+ (_X_)->tv_sec++;\
+ (_X_)->tv_usec -= 1000000;\
+ }\
+ } while (0)
+
+static int init_linemon (queue_t *);
+static void close_linemon (queue_t *, queue_t *);
+
+#define M_PARSE 0x0001
+#define M_NOPARSE 0x0002
+
+void
+ntp_memset(
+ char *a,
+ int x,
+ int c
+ )
+{
+ while (c-- > 0)
+ *a++ = x;
+}
+
+static void
+pprintf(
+ int lev,
+ char *form,
+ ...
+ )
+{
+ va_list ap;
+
+ va_start(ap, form);
+
+ if (lev & parsedebug)
+ vcmn_err(CE_CONT, form, ap);
+
+ va_end(ap);
+}
+
+static int
+setup_stream(
+ queue_t *q,
+ int mode
+ )
+{
+ register mblk_t *mp;
+
+ pprintf(DD_OPEN,"parse: SETUP_STREAM - setting up stream for q=%x\n", q);
+
+ mp = allocb(sizeof(struct stroptions), BPRI_MED);
+ if (mp)
+ {
+ struct stroptions *str = (void *)mp->b_wptr;
+
+ str->so_flags = SO_READOPT|SO_HIWAT|SO_LOWAT|SO_ISNTTY;
+ str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM;
+ str->so_hiwat = (mode == M_PARSE) ? sizeof(parsetime_t) : 256;
+ str->so_lowat = 0;
+ mp->b_datap->db_type = M_SETOPTS;
+ mp->b_wptr += sizeof(struct stroptions);
+ if (!q)
+ panic("NULL q - strange");
+ putnext(q, mp);
+ return putctl1(WR(q)->q_next, M_CTL, (mode == M_PARSE) ? MC_SERVICEIMM :
+ MC_SERVICEDEF);
+ }
+ else
+ {
+ pprintf(DD_OPEN, "parse: setup_stream - FAILED - no MEMORY for allocb\n");
+ return 0;
+ }
+}
+
+/*ARGSUSED*/
+static int
+parseopen(
+ queue_t *q,
+ dev_t *dev,
+ int flag,
+ int sflag,
+ cred_t *credp
+ )
+{
+ register parsestream_t *parse;
+ static int notice = 0;
+
+ pprintf(DD_OPEN, "parse: OPEN - q=%x\n", q);
+
+ if (sflag != MODOPEN)
+ { /* open only for modules */
+ pprintf(DD_OPEN, "parse: OPEN - FAILED - not MODOPEN\n");
+ return EIO;
+ }
+
+ if (q->q_ptr != (caddr_t)NULL)
+ {
+ pprintf(DD_OPEN, "parse: OPEN - FAILED - EXCLUSIVE ONLY\n");
+ return EBUSY;
+ }
+
+ q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t), KM_SLEEP);
+ if (q->q_ptr == (caddr_t)0)
+ {
+ return ENOMEM;
+ }
+
+ pprintf(DD_OPEN, "parse: OPEN - parse area q=%x, q->q_ptr=%x\n", q, q->q_ptr);
+ WR(q)->q_ptr = q->q_ptr;
+ pprintf(DD_OPEN, "parse: OPEN - WQ parse area q=%x, q->q_ptr=%x\n", WR(q), WR(q)->q_ptr);
+
+ parse = (parsestream_t *) q->q_ptr;
+ bzero((caddr_t)parse, sizeof(*parse));
+ parse->parse_queue = q;
+ parse->parse_status = PARSE_ENABLE;
+ parse->parse_ppsclockev.tv.tv_sec = 0;
+ parse->parse_ppsclockev.tv.tv_usec = 0;
+ parse->parse_ppsclockev.serial = 0;
+
+ qprocson(q);
+
+ pprintf(DD_OPEN, "parse: OPEN - initializing io subsystem q=%x\n", q);
+
+ if (!parse_ioinit(&parse->parse_io))
+ {
+ /*
+ * ok guys - beat it
+ */
+ qprocsoff(q);
+
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+
+ return EIO;
+ }
+
+ pprintf(DD_OPEN, "parse: OPEN - initializing stream q=%x\n", q);
+
+ if (setup_stream(q, M_PARSE))
+ {
+ (void) init_linemon(q); /* hook up PPS ISR routines if possible */
+ pprintf(DD_OPEN, "parse: OPEN - SUCCEEDED\n");
+
+ /*
+ * I know that you know the delete key, but you didn't write this
+ * code, did you ? - So, keep the message in here.
+ */
+ if (!notice)
+ {
+ cmn_err(CE_CONT, "?%s: Copyright (c) 1993-2005, Frank Kardel\n", modlstrmod.strmod_linkinfo);
+ notice = 1;
+ }
+
+ return 0;
+ }
+ else
+ {
+ qprocsoff(q);
+
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+
+ return EIO;
+ }
+}
+
+/*ARGSUSED*/
+static int
+parseclose(
+ queue_t *q,
+ int flags
+ )
+{
+ register parsestream_t *parse = (parsestream_t *)q->q_ptr;
+ register unsigned long s;
+
+ pprintf(DD_CLOSE, "parse: CLOSE\n");
+
+ qprocsoff(q);
+
+ s = splhigh();
+
+ if (parse->parse_dqueue)
+ close_linemon(parse->parse_dqueue, q);
+ parse->parse_dqueue = (queue_t *)0;
+
+ (void) splx(s);
+
+ parse_ioend(&parse->parse_io);
+
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+
+ q->q_ptr = (caddr_t)NULL;
+ WR(q)->q_ptr = (caddr_t)NULL;
+
+ return 0;
+}
+
+/*
+ * move unrecognized stuff upward
+ */
+static int
+parsersvc(
+ queue_t *q
+ )
+{
+ mblk_t *mp;
+
+ while ((mp = getq(q)))
+ {
+ if (canputnext(q) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ pprintf(DD_RSVC, "parse: RSVC - putnext\n");
+ }
+ else
+ {
+ putbq(q, mp);
+ pprintf(DD_RSVC, "parse: RSVC - flow control wait\n");
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ * do ioctls and
+ * send stuff down - dont care about
+ * flow control
+ */
+static int
+parsewput(
+ queue_t *q,
+ mblk_t *mp
+ )
+{
+ register int ok = 1;
+ register mblk_t *datap;
+ register struct iocblk *iocp;
+ parsestream_t *parse = (parsestream_t *)q->q_ptr;
+
+ pprintf(DD_WPUT, "parse: parsewput\n");
+
+ switch (mp->b_datap->db_type)
+ {
+ default:
+ putnext(q, mp);
+ break;
+
+ case M_IOCTL:
+ iocp = (void *)mp->b_rptr;
+ switch (iocp->ioc_cmd)
+ {
+ default:
+ pprintf(DD_WPUT, "parse: parsewput - forward M_IOCTL\n");
+ putnext(q, mp);
+ break;
+
+ case CIOGETEV:
+ /*
+ * taken from Craig Leres ppsclock module (and modified)
+ */
+ datap = allocb(sizeof(struct ppsclockev), BPRI_MED);
+ if (datap == NULL || mp->b_cont)
+ {
+ mp->b_datap->db_type = M_IOCNAK;
+ iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL;
+ if (datap != NULL)
+ freeb(datap);
+ qreply(q, mp);
+ break;
+ }
+
+ mp->b_cont = datap;
+ /* (void *) quiets cast alignment warning */
+ *(struct ppsclockev *)(void *)datap->b_wptr = parse->parse_ppsclockev;
+ datap->b_wptr +=
+ sizeof(struct ppsclockev) / sizeof(*datap->b_wptr);
+ mp->b_datap->db_type = M_IOCACK;
+ iocp->ioc_count = sizeof(struct ppsclockev);
+ qreply(q, mp);
+ break;
+
+ case PARSEIOC_ENABLE:
+ case PARSEIOC_DISABLE:
+ {
+ parse->parse_status = (parse->parse_status & (unsigned)~PARSE_ENABLE) |
+ (iocp->ioc_cmd == PARSEIOC_ENABLE) ?
+ PARSE_ENABLE : 0;
+ if (!setup_stream(RD(q), (parse->parse_status & PARSE_ENABLE) ?
+ M_PARSE : M_NOPARSE))
+ {
+ mp->b_datap->db_type = M_IOCNAK;
+ }
+ else
+ {
+ mp->b_datap->db_type = M_IOCACK;
+ }
+ qreply(q, mp);
+ break;
+ }
+
+ case PARSEIOC_TIMECODE:
+ case PARSEIOC_SETFMT:
+ case PARSEIOC_GETFMT:
+ case PARSEIOC_SETCS:
+ if (iocp->ioc_count == sizeof(parsectl_t))
+ {
+ parsectl_t *dct = (void *)mp->b_cont->b_rptr;
+
+ switch (iocp->ioc_cmd)
+ {
+ case PARSEIOC_TIMECODE:
+ pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_TIMECODE\n");
+ ok = parse_timecode(dct, &parse->parse_io);
+ break;
+
+ case PARSEIOC_SETFMT:
+ pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_SETFMT\n");
+ ok = parse_setfmt(dct, &parse->parse_io);
+ break;
+
+ case PARSEIOC_GETFMT:
+ pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_GETFMT\n");
+ ok = parse_getfmt(dct, &parse->parse_io);
+ break;
+
+ case PARSEIOC_SETCS:
+ pprintf(DD_WPUT, "parse: parsewput - PARSEIOC_SETCS\n");
+ ok = parse_setcs(dct, &parse->parse_io);
+ break;
+ }
+ mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK;
+ }
+ else
+ {
+ mp->b_datap->db_type = M_IOCNAK;
+ }
+ pprintf(DD_WPUT, "parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK");
+ qreply(q, mp);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ * read characters from streams buffers
+ */
+static unsigned long
+rdchar(
+ mblk_t **mp
+ )
+{
+ while (*mp != (mblk_t *)NULL)
+ {
+ if ((*mp)->b_wptr - (*mp)->b_rptr)
+ {
+ return (unsigned long)(*(unsigned char *)((*mp)->b_rptr++));
+ }
+ else
+ {
+ register mblk_t *mmp = *mp;
+
+ *mp = (*mp)->b_cont;
+ freeb(mmp);
+ }
+ }
+ return (unsigned long)~0;
+}
+
+/*
+ * convert incoming data
+ */
+static int
+parserput(
+ queue_t *q,
+ mblk_t *imp
+ )
+{
+ register unsigned char type;
+ mblk_t *mp = imp;
+
+ switch (type = mp->b_datap->db_type)
+ {
+ default:
+ /*
+ * anything we don't know will be put on queue
+ * the service routine will move it to the next one
+ */
+ pprintf(DD_RPUT, "parse: parserput - forward type 0x%x\n", type);
+
+ if (canputnext(q) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ }
+ else
+ putq(q, mp);
+ break;
+
+ case M_BREAK:
+ case M_DATA:
+ {
+ register parsestream_t * parse = (parsestream_t *)q->q_ptr;
+ register mblk_t *nmp;
+ register unsigned long ch;
+ timestamp_t c_time;
+ timespec_t hres_time;
+
+ /*
+ * get time on packet delivery
+ */
+ gethrestime(&hres_time);
+ c_time.tv.tv_sec = hres_time.tv_sec;
+ c_time.tv.tv_usec = hres_time.tv_nsec / 1000;
+
+ if (!(parse->parse_status & PARSE_ENABLE))
+ {
+ pprintf(DD_RPUT, "parse: parserput - parser disabled - forward type 0x%x\n", type);
+ if (canputnext(q) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ }
+ else
+ putq(q, mp);
+ }
+ else
+ {
+ pprintf(DD_RPUT, "parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK");
+ if (type == M_DATA)
+ {
+ /*
+ * parse packet looking for start an end characters
+ */
+ while (mp != (mblk_t *)NULL)
+ {
+ ch = rdchar(&mp);
+ if (ch != ~0 && parse_ioread(&parse->parse_io, (unsigned int)ch, &c_time))
+ {
+ /*
+ * up up and away (hopefully ...)
+ * don't press it if resources are tight or nobody wants it
+ */
+ nmp = (mblk_t *)NULL;
+ if (canputnext(parse->parse_queue) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
+ {
+ bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
+ nmp->b_wptr += sizeof(parsetime_t);
+ putnext(parse->parse_queue, nmp);
+ }
+ else
+ if (nmp) freemsg(nmp);
+ parse_iodone(&parse->parse_io);
+ }
+ }
+ }
+ else
+ {
+ if (parse_ioread(&parse->parse_io, (unsigned int)0, &c_time))
+ {
+ /*
+ * up up and away (hopefully ...)
+ * don't press it if resources are tight or nobody wants it
+ */
+ nmp = (mblk_t *)NULL;
+ if (canputnext(parse->parse_queue) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
+ {
+ bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
+ nmp->b_wptr += sizeof(parsetime_t);
+ putnext(parse->parse_queue, nmp);
+ }
+ else
+ if (nmp) freemsg(nmp);
+ parse_iodone(&parse->parse_io);
+ }
+ freemsg(mp);
+ }
+ break;
+ }
+ }
+
+ /*
+ * CD PPS support for non direct ISR hack
+ */
+ case M_HANGUP:
+ case M_UNHANGUP:
+ {
+ register parsestream_t * parse = (parsestream_t *)q->q_ptr;
+ timestamp_t c_time;
+ timespec_t hres_time;
+ register mblk_t *nmp;
+ register int status = cd_invert ^ (type == M_UNHANGUP);
+
+ gethrestime(&hres_time);
+ c_time.tv.tv_sec = hres_time.tv_sec;
+ c_time.tv.tv_usec = hres_time.tv_nsec / 1000;
+
+ pprintf(DD_RPUT, "parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN");
+
+ if ((parse->parse_status & PARSE_ENABLE) &&
+ parse_iopps(&parse->parse_io, status ? SYNC_ONE : SYNC_ZERO, &c_time))
+ {
+ nmp = (mblk_t *)NULL;
+ if (canputnext(parse->parse_queue) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
+ {
+ bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
+ nmp->b_wptr += sizeof(parsetime_t);
+ putnext(parse->parse_queue, nmp);
+ }
+ else
+ if (nmp) freemsg(nmp);
+ parse_iodone(&parse->parse_io);
+ freemsg(mp);
+ }
+ else
+ if (canputnext(q) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ }
+ else
+ putq(q, mp);
+
+ if (status)
+ {
+ parse->parse_ppsclockev.tv = c_time.tv;
+ ++(parse->parse_ppsclockev.serial);
+ }
+ }
+ }
+ return 0;
+}
+
+static int init_zs_linemon (queue_t *, queue_t *); /* handle line monitor for "zs" driver */
+static void close_zs_linemon (queue_t *, queue_t *);
+
+/*-------------------- CD isr status monitor ---------------*/
+
+static int
+init_linemon(
+ queue_t *q
+ )
+{
+ register queue_t *dq;
+
+ dq = WR(q);
+ /*
+ * we ARE doing very bad things down here (basically stealing ISR
+ * hooks)
+ *
+ * so we chase down the STREAMS stack searching for the driver
+ * and if this is a known driver we insert our ISR routine for
+ * status changes in to the ExternalStatus handling hook
+ */
+ while (dq->q_next)
+ {
+ dq = dq->q_next; /* skip down to driver */
+ }
+
+ /*
+ * find appropriate driver dependent routine
+ */
+ if (dq->q_qinfo && dq->q_qinfo->qi_minfo)
+ {
+ register char *dname = dq->q_qinfo->qi_minfo->mi_idname;
+
+ pprintf(DD_INSTALL, "init_linemon: driver is \"%s\"\n", dname);
+
+#ifdef sun
+ if (dname && !strcmp(dname, "zs"))
+ {
+ return init_zs_linemon(dq, q);
+ }
+ else
+#endif
+ {
+ pprintf(DD_INSTALL, "init_linemon: driver \"%s\" not suitable for CD monitoring\n", dname);
+ return 0;
+ }
+ }
+ pprintf(DD_INSTALL, "init_linemon: cannot find driver\n");
+ return 0;
+}
+
+static void
+close_linemon(
+ queue_t *q,
+ queue_t *my_q
+ )
+{
+ /*
+ * find appropriate driver dependent routine
+ */
+ if (q->q_qinfo && q->q_qinfo->qi_minfo)
+ {
+ register char *dname = q->q_qinfo->qi_minfo->mi_idname;
+
+#ifdef sun
+ if (dname && !strcmp(dname, "zs"))
+ {
+ close_zs_linemon(q, my_q);
+ return;
+ }
+ pprintf(DD_INSTALL, "close_linemon: cannot find driver close routine for \"%s\"\n", dname);
+#endif
+ }
+ pprintf(DD_INSTALL, "close_linemon: cannot find driver name\n");
+}
+
+#ifdef sun
+#include <sys/tty.h>
+#include <sys/zsdev.h>
+#include <sys/ser_async.h>
+#include <sys/ser_zscc.h>
+
+static void zs_xsisr (struct zscom *); /* zs external status interupt handler */
+
+/*
+ * there should be some docs telling how to get to
+ * sz:zs_usec_delay and zs:initzsops()
+ */
+#define zs_usec_delay 5
+
+struct savedzsops
+{
+ struct zsops zsops;
+ struct zsops *oldzsops;
+};
+
+static struct zsops *emergencyzs;
+
+static int
+init_zs_linemon(
+ queue_t *q,
+ queue_t *my_q
+ )
+{
+ register struct zscom *zs;
+ register struct savedzsops *szs;
+ register parsestream_t *parsestream = (parsestream_t *)my_q->q_ptr;
+ /*
+ * we expect the zsaline pointer in the q_data pointer
+ * from there on we insert our on EXTERNAL/STATUS ISR routine
+ * into the interrupt path, before the standard handler
+ */
+ zs = ((struct asyncline *)q->q_ptr)->za_common;
+ if (!zs)
+ {
+ /*
+ * well - not found on startup - just say no (shouldn't happen though)
+ */
+ return 0;
+ }
+ else
+ {
+ /*
+ * we do a direct replacement, in case others fiddle also
+ * if somebody else grabs our hook and we disconnect
+ * we are in DEEP trouble - panic is likely to be next, sorry
+ */
+ szs = (struct savedzsops *) kmem_alloc(sizeof(struct savedzsops), KM_SLEEP);
+
+ if (szs == (struct savedzsops *)0)
+ {
+ pprintf(DD_INSTALL, "init_zs_linemon: CD monitor NOT installed - no memory\n");
+
+ return 0;
+ }
+ else
+ {
+ parsestream->parse_data = (void *)szs;
+
+ mutex_enter(zs->zs_excl);
+
+ parsestream->parse_dqueue = q; /* remember driver */
+
+ szs->zsops = *zs->zs_ops;
+ szs->zsops.zsop_xsint = (void (*) (struct zscom *))zs_xsisr; /* place our bastard */
+ szs->oldzsops = zs->zs_ops;
+ emergencyzs = zs->zs_ops;
+
+ zs->zs_ops = &szs->zsops; /* hook it up */
+ /*
+ * XXX: this is usually done via zsopinit()
+ * - have yet to find a way to call that routine
+ */
+ zs->zs_xsint = (void (*) (struct zscom *))zs_xsisr;
+
+ mutex_exit(zs->zs_excl);
+
+ pprintf(DD_INSTALL, "init_zs_linemon: CD monitor installed\n");
+
+ return 1;
+ }
+ }
+}
+
+/*
+ * unregister our ISR routine - must call under splhigh() (or
+ * whatever block ZS status interrupts)
+ */
+static void
+close_zs_linemon(
+ queue_t *q,
+ queue_t *my_q
+ )
+{
+ register struct zscom *zs;
+ register parsestream_t *parsestream = (parsestream_t *)my_q->q_ptr;
+
+ zs = ((struct asyncline *)q->q_ptr)->za_common;
+ if (!zs)
+ {
+ /*
+ * well - not found on startup - just say no (shouldn't happen though)
+ */
+ return;
+ }
+ else
+ {
+ register struct savedzsops *szs = (struct savedzsops *)parsestream->parse_data;
+
+ mutex_enter(zs->zs_excl);
+
+ zs->zs_ops = szs->oldzsops; /* reset to previous handler functions */
+ /*
+ * XXX: revert xsint (usually done via zsopinit() - have still to find
+ * a way to call that bugger
+ */
+ zs->zs_xsint = zs->zs_ops->zsop_xsint;
+
+ mutex_exit(zs->zs_excl);
+
+ kmem_free((caddr_t)szs, sizeof (struct savedzsops));
+
+ pprintf(DD_INSTALL, "close_zs_linemon: CD monitor deleted\n");
+ return;
+ }
+}
+
+#define ZSRR0_IGNORE (ZSRR0_CD|ZSRR0_SYNC|ZSRR0_CTS)
+
+#define MAXDEPTH 50 /* maximum allowed stream crawl */
+
+/*
+ * take external status interrupt (only CD interests us)
+ */
+static void
+zs_xsisr(
+ struct zscom *zs
+ )
+{
+ register struct asyncline *za = (void *)zs->zs_priv;
+ register queue_t *q;
+ register unsigned char zsstatus;
+ register int loopcheck;
+ register unsigned char cdstate;
+ register const char *dname = "-UNKNOWN-";
+ timespec_t hres_time;
+
+ /*
+ * pick up current state
+ */
+ zsstatus = SCC_READ0();
+
+ if (za->za_rr0 ^ (cdstate = zsstatus & ZSRR0_CD))
+ {
+ timestamp_t cdevent;
+ register int status;
+
+ /*
+ * time stamp
+ */
+ gethrestime(&hres_time);
+ cdevent.tv.tv_sec = hres_time.tv_sec;
+ cdevent.tv.tv_usec = hres_time.tv_nsec / 1000;
+
+ q = za->za_ttycommon.t_readq;
+
+ /*
+ * logical state
+ */
+ status = cd_invert ? cdstate == 0 : cdstate != 0;
+
+ /*
+ * ok - now the hard part - find ourself
+ */
+ loopcheck = MAXDEPTH;
+
+ while (q)
+ {
+ if (q->q_qinfo && q->q_qinfo->qi_minfo)
+ {
+ dname = q->q_qinfo->qi_minfo->mi_idname;
+
+ if (!strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
+ {
+ /*
+ * back home - phew (hopping along stream queues might
+ * prove dangerous to your health)
+ */
+
+ if ((((parsestream_t *)q->q_ptr)->parse_status & PARSE_ENABLE) &&
+ parse_iopps(&((parsestream_t *)q->q_ptr)->parse_io, status ? SYNC_ONE : SYNC_ZERO, &cdevent))
+ {
+ /*
+ * XXX - currently we do not pass up the message, as
+ * we should.
+ * for a correct behaviour wee need to block out
+ * processing until parse_iodone has been posted via
+ * a softcall-ed routine which does the message pass-up
+ * right now PPS information relies on input being
+ * received
+ */
+ parse_iodone(&((parsestream_t *)q->q_ptr)->parse_io);
+ }
+
+ if (status)
+ {
+ ((parsestream_t *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv;
+ ++(((parsestream_t *)q->q_ptr)->parse_ppsclockev.serial);
+ }
+
+ pprintf(DD_ISR, "zs_xsisr: CD event %s has been posted for \"%s\"\n", status ? "ONE" : "ZERO", dname);
+ break;
+ }
+ }
+
+ q = q->q_next;
+
+ if (!loopcheck--)
+ {
+ panic("zs_xsisr: STREAMS Queue corrupted - CD event");
+ }
+ }
+
+ if (cdstate) /* fake CARRIER status - XXX currently not coordinated */
+ za->za_flags |= ZAS_CARR_ON;
+ else
+ za->za_flags &= ~ZAS_CARR_ON;
+
+ /*
+ * only pretend that CD and ignored transistion (SYNC,CTS)
+ * have been handled
+ */
+ za->za_rr0 = (za->za_rr0 & ~ZSRR0_IGNORE) | (zsstatus & ZSRR0_IGNORE);
+
+ if (((za->za_rr0 ^ zsstatus) & ~ZSRR0_IGNORE) == 0)
+ {
+ /*
+ * all done - kill status indication and return
+ */
+ SCC_WRITE0(ZSWR0_RESET_STATUS); /* might kill other conditions here */
+ return;
+ }
+ }
+
+ pprintf(DD_ISR, "zs_xsisr: non CD event 0x%x for \"%s\"\n",
+ (za->za_rr0 ^ zsstatus) & ~ZSRR0_CD,dname);
+ /*
+ * we are now gathered here to process some unusual external status
+ * interrupts.
+ * any CD events have also been handled and shouldn't be processed
+ * by the original routine (unless we have a VERY busy port pin)
+ * some initializations are done here, which could have been done before for
+ * both code paths but have been avioded for minimum path length to
+ * the uniq_time routine
+ */
+ dname = (char *) 0;
+ q = za->za_ttycommon.t_readq;
+
+ loopcheck = MAXDEPTH;
+
+ /*
+ * the real thing for everything else ...
+ */
+ while (q)
+ {
+ if (q->q_qinfo && q->q_qinfo->qi_minfo)
+ {
+ dname = q->q_qinfo->qi_minfo->mi_idname;
+ if (!strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
+ {
+ register void (*zsisr) (struct zscom *);
+
+ /*
+ * back home - phew (hopping along stream queues might
+ * prove dangerous to your health)
+ */
+ if ((zsisr = ((struct savedzsops *)((parsestream_t *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint))
+ zsisr(zs);
+ else
+ panic("zs_xsisr: unable to locate original ISR");
+
+ pprintf(DD_ISR, "zs_xsisr: non CD event was processed for \"%s\"\n", dname);
+ /*
+ * now back to our program ...
+ */
+ return;
+ }
+ }
+
+ q = q->q_next;
+
+ if (!loopcheck--)
+ {
+ panic("zs_xsisr: STREAMS Queue corrupted - non CD event");
+ }
+ }
+
+ /*
+ * last resort - shouldn't even come here as it indicates
+ * corrupted TTY structures
+ */
+ printf("zs_zsisr: looking for \"%s\" - found \"%s\" - taking EMERGENCY path\n", parseinfo.st_rdinit->qi_minfo->mi_idname, dname ? dname : "-NIL-");
+
+ if (emergencyzs && emergencyzs->zsop_xsint)
+ emergencyzs->zsop_xsint(zs);
+ else
+ panic("zs_xsisr: no emergency ISR handler");
+}
+#endif /* sun */
+
+/*
+ * History:
+ *
+ * parsesolaris.c,v
+ * Revision 4.11 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.10 2004/11/14 16:06:08 kardel
+ * update Id tags
+ *
+ * Revision 4.9 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.6 1998/11/15 21:56:08 kardel
+ * ntp_memset not necessary
+ *
+ * Revision 4.5 1998/11/15 21:23:37 kardel
+ * ntp_memset() replicated in Sun kernel files
+ *
+ * Revision 4.4 1998/06/14 21:09:40 kardel
+ * Sun acc cleanup
+ *
+ * Revision 4.3 1998/06/13 12:14:59 kardel
+ * more prototypes
+ * fix name clashes
+ * allow for ansi2knr
+ *
+ * Revision 4.2 1998/06/12 15:23:08 kardel
+ * fix prototypes
+ * adjust for ansi2knr
+ *
+ * Revision 4.1 1998/05/24 09:38:46 kardel
+ * streams initiated iopps calls (M_xHANGUP) are now consistent with the
+ * respective calls from zs_xsisr()
+ * simulation of CARRIER status to avoid unecessary M_xHANGUP messages
+ *
+ * Revision 4.0 1998/04/10 19:45:38 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.28 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/parsestreams.c b/libparse/parsestreams.c
new file mode 100644
index 0000000..3fb4cc3
--- /dev/null
+++ b/libparse/parsestreams.c
@@ -0,0 +1,1367 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * STREAMS module for reference clocks
+ * (SunOS4.x)
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#define KERNEL /* MUST */
+#define VDDRV /* SHOULD */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifndef lint
+static char rcsid[] = "parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A";
+#endif
+
+#ifndef KERNEL
+#include "Bletch: MUST COMPILE WITH KERNEL DEFINE"
+#endif
+
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/buf.h>
+#include <sys/param.h>
+#include <sys/sysmacros.h>
+#include <sys/time.h>
+#include <sundev/mbvar.h>
+#include <sun/autoconf.h>
+#include <sys/stream.h>
+#include <sys/stropts.h>
+#include <sys/dir.h>
+#include <sys/signal.h>
+#include <sys/termios.h>
+#include <sys/termio.h>
+#include <sys/ttold.h>
+#include <sys/user.h>
+#include <sys/tty.h>
+
+#ifdef VDDRV
+#include <sun/vddrv.h>
+#endif
+
+#include "ntp_stdlib.h"
+#include "ntp_fp.h"
+/*
+ * just make checking compilers more silent
+ */
+extern int printf (const char *, ...);
+extern int putctl1 (queue_t *, int, int);
+extern int canput (queue_t *);
+extern void putbq (queue_t *, mblk_t *);
+extern void freeb (mblk_t *);
+extern void qreply (queue_t *, mblk_t *);
+extern void freemsg (mblk_t *);
+extern void panic (const char *, ...);
+extern void usec_delay (int);
+
+#include "parse.h"
+#include "sys/parsestreams.h"
+
+/*
+ * use microtime instead of uniqtime if advised to
+ */
+#ifdef MICROTIME
+#define uniqtime microtime
+#endif
+
+#ifdef VDDRV
+static unsigned int parsebusy = 0;
+
+/*--------------- loadable driver section -----------------------------*/
+
+extern struct streamtab parseinfo;
+
+
+#ifdef PPS_SYNC
+static char mnam[] = "PARSEPPS "; /* name this baby - keep room for revision number */
+#else
+static char mnam[] = "PARSE "; /* name this baby - keep room for revision number */
+#endif
+struct vdldrv parsesync_vd =
+{
+ VDMAGIC_PSEUDO, /* nothing like a real driver - a STREAMS module */
+ mnam,
+};
+
+/*
+ * strings support usually not in kernel
+ */
+static int
+Strlen(
+ register const char *s
+ )
+{
+ register int c;
+
+ c = 0;
+ if (s)
+ {
+ while (*s++)
+ {
+ c++;
+ }
+ }
+ return c;
+}
+
+static void
+Strncpy(
+ register char *t,
+ register char *s,
+ register int c
+ )
+{
+ if (s && t)
+ {
+ while ((c-- > 0) && (*t++ = *s++))
+ ;
+ }
+}
+
+static int
+Strcmp(
+ register const char *s,
+ register const char *t
+ )
+{
+ register int c = 0;
+
+ if (!s || !t || (s == t))
+ {
+ return 0;
+ }
+
+ while (!(c = *s++ - *t++) && *s && *t)
+ /* empty loop */;
+
+ return c;
+}
+
+static int
+Strncmp(
+ register char *s,
+ register char *t,
+ register int n
+ )
+{
+ register int c = 0;
+
+ if (!s || !t || (s == t))
+ {
+ return 0;
+ }
+
+ while (n-- && !(c = *s++ - *t++) && *s && *t)
+ /* empty loop */;
+
+ return c;
+}
+
+void
+ntp_memset(
+ char *a,
+ int x,
+ int c
+ )
+{
+ while (c-- > 0)
+ *a++ = x;
+}
+
+/*
+ * driver init routine
+ * since no mechanism gets us into and out of the fmodsw, we have to
+ * do it ourselves
+ */
+/*ARGSUSED*/
+int
+xxxinit(
+ unsigned int fc,
+ struct vddrv *vdp,
+ addr_t vdin,
+ struct vdstat *vds
+ )
+{
+ extern struct fmodsw fmodsw[];
+ extern int fmodcnt;
+
+ struct fmodsw *fm = fmodsw;
+ struct fmodsw *fmend = &fmodsw[fmodcnt];
+ struct fmodsw *ifm = (struct fmodsw *)0;
+ char *mname = parseinfo.st_rdinit->qi_minfo->mi_idname;
+
+ switch (fc)
+ {
+ case VDLOAD:
+ vdp->vdd_vdtab = (struct vdlinkage *)&parsesync_vd;
+ /*
+ * now, jog along fmodsw scanning for an empty slot
+ * and deposit our name there
+ */
+ while (fm <= fmend)
+ {
+ if (!Strncmp(fm->f_name, mname, FMNAMESZ))
+ {
+ printf("vddrinit[%s]: STREAMS module already loaded.\n", mname);
+ return(EBUSY);
+ }
+ else
+ if ((ifm == (struct fmodsw *)0) &&
+ (fm->f_name[0] == '\0') &&
+ (fm->f_str == (struct streamtab *)0))
+ {
+ /*
+ * got one - so move in
+ */
+ ifm = fm;
+ break;
+ }
+ fm++;
+ }
+
+ if (ifm == (struct fmodsw *)0)
+ {
+ printf("vddrinit[%s]: no slot free for STREAMS module\n", mname);
+ return (ENOSPC);
+ }
+ else
+ {
+ static char revision[] = "4.7";
+ char *s, *S, *t;
+
+ s = rcsid; /* NOOP - keep compilers happy */
+
+ Strncpy(ifm->f_name, mname, FMNAMESZ);
+ ifm->f_name[FMNAMESZ] = '\0';
+ ifm->f_str = &parseinfo;
+ /*
+ * copy RCS revision into Drv_name
+ *
+ * are we forcing RCS here to do things it was not built for ?
+ */
+ s = revision;
+ if (*s == '$')
+ {
+ /*
+ * skip "$Revision: "
+ * if present. - not necessary on a -kv co (cvs export)
+ */
+ while (*s && (*s != ' '))
+ {
+ s++;
+ }
+ if (*s == ' ') s++;
+ }
+
+ t = parsesync_vd.Drv_name;
+ while (*t && (*t != ' '))
+ {
+ t++;
+ }
+ if (*t == ' ') t++;
+
+ S = s;
+ while (*S && (((*S >= '0') && (*S <= '9')) || (*S == '.')))
+ {
+ S++;
+ }
+
+ if (*s && *t && (S > s))
+ {
+ if (Strlen(t) >= (S - s))
+ {
+ (void) Strncpy(t, s, S - s);
+ }
+ }
+ return (0);
+ }
+ break;
+
+ case VDUNLOAD:
+ if (parsebusy > 0)
+ {
+ printf("vddrinit[%s]: STREAMS module has still %d instances active.\n", mname, parsebusy);
+ return (EBUSY);
+ }
+ else
+ {
+ while (fm <= fmend)
+ {
+ if (!Strncmp(fm->f_name, mname, FMNAMESZ))
+ {
+ /*
+ * got it - kill entry
+ */
+ fm->f_name[0] = '\0';
+ fm->f_str = (struct streamtab *)0;
+ fm++;
+
+ break;
+ }
+ fm++;
+ }
+ if (fm > fmend)
+ {
+ printf("vddrinit[%s]: cannot find entry for STREAMS module\n", mname);
+ return (ENXIO);
+ }
+ else
+ return (0);
+ }
+
+
+ case VDSTAT:
+ return (0);
+
+ default:
+ return (EIO);
+
+ }
+ return EIO;
+}
+
+#endif
+
+/*--------------- stream module definition ----------------------------*/
+
+static int parseopen (queue_t *, dev_t, int, int);
+static int parseclose (queue_t *, int);
+static int parsewput (queue_t *, mblk_t *);
+static int parserput (queue_t *, mblk_t *);
+static int parsersvc (queue_t *);
+
+static char mn[] = "parse";
+
+static struct module_info driverinfo =
+{
+ 0, /* module ID number */
+ mn, /* module name */
+ 0, /* minimum accepted packet size */
+ INFPSZ, /* maximum accepted packet size */
+ 1, /* high water mark - flow control */
+ 0 /* low water mark - flow control */
+};
+
+static struct qinit rinit = /* read queue definition */
+{
+ parserput, /* put procedure */
+ parsersvc, /* service procedure */
+ parseopen, /* open procedure */
+ parseclose, /* close procedure */
+ NULL, /* admin procedure - NOT USED FOR NOW */
+ &driverinfo, /* information structure */
+ NULL /* statistics */
+};
+
+static struct qinit winit = /* write queue definition */
+{
+ parsewput, /* put procedure */
+ NULL, /* service procedure */
+ NULL, /* open procedure */
+ NULL, /* close procedure */
+ NULL, /* admin procedure - NOT USED FOR NOW */
+ &driverinfo, /* information structure */
+ NULL /* statistics */
+};
+
+struct streamtab parseinfo = /* stream info element for dpr driver */
+{
+ &rinit, /* read queue */
+ &winit, /* write queue */
+ NULL, /* read mux */
+ NULL, /* write mux */
+ NULL /* module auto push */
+};
+
+/*--------------- driver data structures ----------------------------*/
+
+/*
+ * we usually have an inverted signal - but you
+ * can change this to suit your needs
+ */
+int cd_invert = 1; /* invert status of CD line - PPS support via CD input */
+
+int parsedebug = ~0;
+
+extern void uniqtime (struct timeval *);
+
+/*--------------- module implementation -----------------------------*/
+
+#define TIMEVAL_USADD(_X_, _US_) {\
+ (_X_)->tv_usec += (_US_);\
+ if ((_X_)->tv_usec >= 1000000)\
+ {\
+ (_X_)->tv_sec++;\
+ (_X_)->tv_usec -= 1000000;\
+ }\
+ } while (0)
+
+static int init_linemon (queue_t *);
+static void close_linemon (queue_t *, queue_t *);
+
+#define M_PARSE 0x0001
+#define M_NOPARSE 0x0002
+
+static int
+setup_stream(
+ queue_t *q,
+ int mode
+ )
+{
+ mblk_t *mp;
+
+ mp = allocb(sizeof(struct stroptions), BPRI_MED);
+ if (mp)
+ {
+ struct stroptions *str = (struct stroptions *)(void *)mp->b_rptr;
+
+ str->so_flags = SO_READOPT|SO_HIWAT|SO_LOWAT;
+ str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM;
+ str->so_hiwat = (mode == M_PARSE) ? sizeof(parsetime_t) : 256;
+ str->so_lowat = 0;
+ mp->b_datap->db_type = M_SETOPTS;
+ mp->b_wptr += sizeof(struct stroptions);
+ putnext(q, mp);
+ return putctl1(WR(q)->q_next, M_CTL, (mode == M_PARSE) ? MC_SERVICEIMM :
+ MC_SERVICEDEF);
+ }
+ else
+ {
+ parseprintf(DD_OPEN,("parse: setup_stream - FAILED - no MEMORY for allocb\n"));
+ return 0;
+ }
+}
+
+/*ARGSUSED*/
+static int
+parseopen(
+ queue_t *q,
+ dev_t dev,
+ int flag,
+ int sflag
+ )
+{
+ register parsestream_t *parse;
+ static int notice = 0;
+
+ parseprintf(DD_OPEN,("parse: OPEN\n"));
+
+ if (sflag != MODOPEN)
+ { /* open only for modules */
+ parseprintf(DD_OPEN,("parse: OPEN - FAILED - not MODOPEN\n"));
+ return OPENFAIL;
+ }
+
+ if (q->q_ptr != (caddr_t)NULL)
+ {
+ u.u_error = EBUSY;
+ parseprintf(DD_OPEN,("parse: OPEN - FAILED - EXCLUSIVE ONLY\n"));
+ return OPENFAIL;
+ }
+
+#ifdef VDDRV
+ parsebusy++;
+#endif
+
+ q->q_ptr = (caddr_t)kmem_alloc(sizeof(parsestream_t));
+ if (q->q_ptr == (caddr_t)0)
+ {
+ parseprintf(DD_OPEN,("parse: OPEN - FAILED - no memory\n"));
+#ifdef VDDRV
+ parsebusy--;
+#endif
+ return OPENFAIL;
+ }
+ WR(q)->q_ptr = q->q_ptr;
+
+ parse = (parsestream_t *)(void *)q->q_ptr;
+ bzero((caddr_t)parse, sizeof(*parse));
+ parse->parse_queue = q;
+ parse->parse_status = PARSE_ENABLE;
+ parse->parse_ppsclockev.tv.tv_sec = 0;
+ parse->parse_ppsclockev.tv.tv_usec = 0;
+ parse->parse_ppsclockev.serial = 0;
+
+ if (!parse_ioinit(&parse->parse_io))
+ {
+ /*
+ * ok guys - beat it
+ */
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+#ifdef VDDRV
+ parsebusy--;
+#endif
+ return OPENFAIL;
+ }
+
+ if (setup_stream(q, M_PARSE))
+ {
+ (void) init_linemon(q); /* hook up PPS ISR routines if possible */
+
+ parseprintf(DD_OPEN,("parse: OPEN - SUCCEEDED\n"));
+
+ /*
+ * I know that you know the delete key, but you didn't write this
+ * code, did you ? - So, keep the message in here.
+ */
+ if (!notice)
+ {
+#ifdef VDDRV
+ printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", parsesync_vd.Drv_name);
+#else
+ printf("%s: Copyright (C) 1991-2005, Frank Kardel\n", "parsestreams.c,v 4.11 2005/04/16 17:32:10 kardel RELEASE_20050508_A");
+#endif
+ notice = 1;
+ }
+
+ return MODOPEN;
+ }
+ else
+ {
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+
+#ifdef VDDRV
+ parsebusy--;
+#endif
+ return OPENFAIL;
+ }
+}
+
+/*ARGSUSED*/
+static int
+parseclose(
+ queue_t *q,
+ int flags
+ )
+{
+ register parsestream_t *parse = (parsestream_t *)(void *)q->q_ptr;
+ register unsigned long s;
+
+ parseprintf(DD_CLOSE,("parse: CLOSE\n"));
+
+ s = splhigh();
+
+ if (parse->parse_dqueue)
+ close_linemon(parse->parse_dqueue, q);
+ parse->parse_dqueue = (queue_t *)0;
+
+ (void) splx(s);
+
+ parse_ioend(&parse->parse_io);
+
+ kmem_free((caddr_t)parse, sizeof(parsestream_t));
+
+ q->q_ptr = (caddr_t)NULL;
+ WR(q)->q_ptr = (caddr_t)NULL;
+
+#ifdef VDDRV
+ parsebusy--;
+#endif
+ return 0;
+}
+
+/*
+ * move unrecognized stuff upward
+ */
+static int
+parsersvc(
+ queue_t *q
+ )
+{
+ mblk_t *mp;
+
+ while ((mp = getq(q)))
+ {
+ if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ parseprintf(DD_RSVC,("parse: RSVC - putnext\n"));
+ }
+ else
+ {
+ putbq(q, mp);
+ parseprintf(DD_RSVC,("parse: RSVC - flow control wait\n"));
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ * do ioctls and
+ * send stuff down - dont care about
+ * flow control
+ */
+static int
+parsewput(
+ queue_t *q,
+ register mblk_t *mp
+ )
+{
+ register int ok = 1;
+ register mblk_t *datap;
+ register struct iocblk *iocp;
+ parsestream_t *parse = (parsestream_t *)(void *)q->q_ptr;
+
+ parseprintf(DD_WPUT,("parse: parsewput\n"));
+
+ switch (mp->b_datap->db_type)
+ {
+ default:
+ putnext(q, mp);
+ break;
+
+ case M_IOCTL:
+ iocp = (struct iocblk *)(void *)mp->b_rptr;
+ switch (iocp->ioc_cmd)
+ {
+ default:
+ parseprintf(DD_WPUT,("parse: parsewput - forward M_IOCTL\n"));
+ putnext(q, mp);
+ break;
+
+ case CIOGETEV:
+ /*
+ * taken from Craig Leres ppsclock module (and modified)
+ */
+ datap = allocb(sizeof(struct ppsclockev), BPRI_MED);
+ if (datap == NULL || mp->b_cont)
+ {
+ mp->b_datap->db_type = M_IOCNAK;
+ iocp->ioc_error = (datap == NULL) ? ENOMEM : EINVAL;
+ if (datap != NULL)
+ freeb(datap);
+ qreply(q, mp);
+ break;
+ }
+
+ mp->b_cont = datap;
+ *(struct ppsclockev *)(void *)datap->b_wptr = parse->parse_ppsclockev;
+ datap->b_wptr +=
+ sizeof(struct ppsclockev) / sizeof(*datap->b_wptr);
+ mp->b_datap->db_type = M_IOCACK;
+ iocp->ioc_count = sizeof(struct ppsclockev);
+ qreply(q, mp);
+ break;
+
+ case PARSEIOC_ENABLE:
+ case PARSEIOC_DISABLE:
+ {
+ parse->parse_status = (parse->parse_status & (unsigned)~PARSE_ENABLE) |
+ (iocp->ioc_cmd == PARSEIOC_ENABLE) ?
+ PARSE_ENABLE : 0;
+ if (!setup_stream(RD(q), (parse->parse_status & PARSE_ENABLE) ?
+ M_PARSE : M_NOPARSE))
+ {
+ mp->b_datap->db_type = M_IOCNAK;
+ }
+ else
+ {
+ mp->b_datap->db_type = M_IOCACK;
+ }
+ qreply(q, mp);
+ break;
+ }
+
+ case PARSEIOC_TIMECODE:
+ case PARSEIOC_SETFMT:
+ case PARSEIOC_GETFMT:
+ case PARSEIOC_SETCS:
+ if (iocp->ioc_count == sizeof(parsectl_t))
+ {
+ parsectl_t *dct = (parsectl_t *)(void *)mp->b_cont->b_rptr;
+
+ switch (iocp->ioc_cmd)
+ {
+ case PARSEIOC_TIMECODE:
+ parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_TIMECODE\n"));
+ ok = parse_timecode(dct, &parse->parse_io);
+ break;
+
+ case PARSEIOC_SETFMT:
+ parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETFMT\n"));
+ ok = parse_setfmt(dct, &parse->parse_io);
+ break;
+
+ case PARSEIOC_GETFMT:
+ parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_GETFMT\n"));
+ ok = parse_getfmt(dct, &parse->parse_io);
+ break;
+
+ case PARSEIOC_SETCS:
+ parseprintf(DD_WPUT,("parse: parsewput - PARSEIOC_SETCS\n"));
+ ok = parse_setcs(dct, &parse->parse_io);
+ break;
+ }
+ mp->b_datap->db_type = ok ? M_IOCACK : M_IOCNAK;
+ }
+ else
+ {
+ mp->b_datap->db_type = M_IOCNAK;
+ }
+ parseprintf(DD_WPUT,("parse: parsewput qreply - %s\n", (mp->b_datap->db_type == M_IOCNAK) ? "M_IOCNAK" : "M_IOCACK"));
+ qreply(q, mp);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+ * read characters from streams buffers
+ */
+static unsigned long
+rdchar(
+ register mblk_t **mp
+ )
+{
+ while (*mp != (mblk_t *)NULL)
+ {
+ if ((*mp)->b_wptr - (*mp)->b_rptr)
+ {
+ return (unsigned long)(*(unsigned char *)((*mp)->b_rptr++));
+ }
+ else
+ {
+ register mblk_t *mmp = *mp;
+
+ *mp = (*mp)->b_cont;
+ freeb(mmp);
+ }
+ }
+ return (unsigned)~0;
+}
+
+/*
+ * convert incoming data
+ */
+static int
+parserput(
+ queue_t *q,
+ mblk_t *mp
+ )
+{
+ unsigned char type;
+
+ switch (type = mp->b_datap->db_type)
+ {
+ default:
+ /*
+ * anything we don't know will be put on queue
+ * the service routine will move it to the next one
+ */
+ parseprintf(DD_RPUT,("parse: parserput - forward type 0x%x\n", type));
+ if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ }
+ else
+ putq(q, mp);
+ break;
+
+ case M_BREAK:
+ case M_DATA:
+ {
+ register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr;
+ register mblk_t *nmp;
+ register unsigned long ch;
+ timestamp_t ctime;
+
+ /*
+ * get time on packet delivery
+ */
+ uniqtime(&ctime.tv);
+
+ if (!(parse->parse_status & PARSE_ENABLE))
+ {
+ parseprintf(DD_RPUT,("parse: parserput - parser disabled - forward type 0x%x\n", type));
+ if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ }
+ else
+ putq(q, mp);
+ }
+ else
+ {
+ parseprintf(DD_RPUT,("parse: parserput - M_%s\n", (type == M_DATA) ? "DATA" : "BREAK"));
+
+ if (type == M_DATA)
+ {
+ /*
+ * parse packet looking for start an end characters
+ */
+ while (mp != (mblk_t *)NULL)
+ {
+ ch = rdchar(&mp);
+ if (ch != ~0 && parse_ioread(&parse->parse_io, (unsigned int)ch, &ctime))
+ {
+ /*
+ * up up and away (hopefully ...)
+ * don't press it if resources are tight or nobody wants it
+ */
+ nmp = (mblk_t *)NULL;
+ if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
+ {
+ bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
+ nmp->b_wptr += sizeof(parsetime_t);
+ putnext(parse->parse_queue, nmp);
+ }
+ else
+ if (nmp) freemsg(nmp);
+ parse_iodone(&parse->parse_io);
+ }
+ }
+ }
+ else
+ {
+ if (parse_ioread(&parse->parse_io, (unsigned int)0, &ctime))
+ {
+ /*
+ * up up and away (hopefully ...)
+ * don't press it if resources are tight or nobody wants it
+ */
+ nmp = (mblk_t *)NULL;
+ if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
+ {
+ bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
+ nmp->b_wptr += sizeof(parsetime_t);
+ putnext(parse->parse_queue, nmp);
+ }
+ else
+ if (nmp) freemsg(nmp);
+ parse_iodone(&parse->parse_io);
+ }
+ freemsg(mp);
+ }
+ break;
+ }
+ }
+
+ /*
+ * CD PPS support for non direct ISR hack
+ */
+ case M_HANGUP:
+ case M_UNHANGUP:
+ {
+ register parsestream_t * parse = (parsestream_t *)(void *)q->q_ptr;
+ timestamp_t ctime;
+ register mblk_t *nmp;
+ register int status = cd_invert ^ (type == M_UNHANGUP);
+
+ uniqtime(&ctime.tv);
+
+ parseprintf(DD_RPUT,("parse: parserput - M_%sHANGUP\n", (type == M_HANGUP) ? "" : "UN"));
+
+ if ((parse->parse_status & PARSE_ENABLE) &&
+ parse_iopps(&parse->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &ctime))
+ {
+ nmp = (mblk_t *)NULL;
+ if (canput(parse->parse_queue->q_next) && (nmp = allocb(sizeof(parsetime_t), BPRI_MED)))
+ {
+ bcopy((caddr_t)&parse->parse_io.parse_dtime, (caddr_t)nmp->b_rptr, sizeof(parsetime_t));
+ nmp->b_wptr += sizeof(parsetime_t);
+ putnext(parse->parse_queue, nmp);
+ }
+ else
+ if (nmp) freemsg(nmp);
+ parse_iodone(&parse->parse_io);
+ freemsg(mp);
+ }
+ else
+ if (canput(q->q_next) || (mp->b_datap->db_type > QPCTL))
+ {
+ putnext(q, mp);
+ }
+ else
+ putq(q, mp);
+
+ if (status)
+ {
+ parse->parse_ppsclockev.tv = ctime.tv;
+ ++(parse->parse_ppsclockev.serial);
+ }
+ }
+ }
+ return 0;
+}
+
+static int init_zs_linemon (queue_t *, queue_t *); /* handle line monitor for "zs" driver */
+static void close_zs_linemon (queue_t *, queue_t *);
+
+/*-------------------- CD isr status monitor ---------------*/
+
+static int
+init_linemon(
+ register queue_t *q
+ )
+{
+ register queue_t *dq;
+
+ dq = WR(q);
+ /*
+ * we ARE doing very bad things down here (basically stealing ISR
+ * hooks)
+ *
+ * so we chase down the STREAMS stack searching for the driver
+ * and if this is a known driver we insert our ISR routine for
+ * status changes in to the ExternalStatus handling hook
+ */
+ while (dq->q_next)
+ {
+ dq = dq->q_next; /* skip down to driver */
+ }
+
+ /*
+ * find appropriate driver dependent routine
+ */
+ if (dq->q_qinfo && dq->q_qinfo->qi_minfo)
+ {
+ register char *dname = dq->q_qinfo->qi_minfo->mi_idname;
+
+ parseprintf(DD_INSTALL, ("init_linemon: driver is \"%s\"\n", dname));
+
+#ifdef sun
+ if (dname && !Strcmp(dname, "zs"))
+ {
+ return init_zs_linemon(dq, q);
+ }
+ else
+#endif
+ {
+ parseprintf(DD_INSTALL, ("init_linemon: driver \"%s\" not suitable for CD monitoring\n", dname));
+ return 0;
+ }
+ }
+ parseprintf(DD_INSTALL, ("init_linemon: cannot find driver\n"));
+ return 0;
+}
+
+static void
+close_linemon(
+ register queue_t *q,
+ register queue_t *my_q
+ )
+{
+ /*
+ * find appropriate driver dependent routine
+ */
+ if (q->q_qinfo && q->q_qinfo->qi_minfo)
+ {
+ register char *dname = q->q_qinfo->qi_minfo->mi_idname;
+
+#ifdef sun
+ if (dname && !Strcmp(dname, "zs"))
+ {
+ close_zs_linemon(q, my_q);
+ return;
+ }
+ parseprintf(DD_INSTALL, ("close_linemon: cannot find driver close routine for \"%s\"\n", dname));
+#endif
+ }
+ parseprintf(DD_INSTALL, ("close_linemon: cannot find driver name\n"));
+}
+
+#ifdef sun
+
+#include <sundev/zsreg.h>
+#include <sundev/zscom.h>
+#include <sundev/zsvar.h>
+
+static unsigned long cdmask = ZSRR0_CD;
+
+struct savedzsops
+{
+ struct zsops zsops;
+ struct zsops *oldzsops;
+};
+
+struct zsops *emergencyzs;
+extern void zsopinit (struct zscom *, struct zsops *);
+static int zs_xsisr (struct zscom *); /* zs external status interupt handler */
+
+static int
+init_zs_linemon(
+ register queue_t *q,
+ register queue_t *my_q
+ )
+{
+ register struct zscom *zs;
+ register struct savedzsops *szs;
+ register parsestream_t *parsestream = (parsestream_t *)(void *)my_q->q_ptr;
+ /*
+ * we expect the zsaline pointer in the q_data pointer
+ * from there on we insert our on EXTERNAL/STATUS ISR routine
+ * into the interrupt path, before the standard handler
+ */
+ zs = ((struct zsaline *)(void *)q->q_ptr)->za_common;
+ if (!zs)
+ {
+ /*
+ * well - not found on startup - just say no (shouldn't happen though)
+ */
+ return 0;
+ }
+ else
+ {
+ unsigned long s;
+
+ /*
+ * we do a direct replacement, in case others fiddle also
+ * if somebody else grabs our hook and we disconnect
+ * we are in DEEP trouble - panic is likely to be next, sorry
+ */
+ szs = (struct savedzsops *)(void *)kmem_alloc(sizeof(struct savedzsops));
+
+ if (szs == (struct savedzsops *)0)
+ {
+ parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor NOT installed - no memory\n"));
+
+ return 0;
+ }
+ else
+ {
+ parsestream->parse_data = (void *)szs;
+
+ s = splhigh();
+
+ parsestream->parse_dqueue = q; /* remember driver */
+
+ szs->zsops = *zs->zs_ops;
+ szs->zsops.zsop_xsint = zs_xsisr; /* place our bastard */
+ szs->oldzsops = zs->zs_ops;
+ emergencyzs = zs->zs_ops;
+
+ zsopinit(zs, &szs->zsops); /* hook it up */
+
+ (void) splx(s);
+
+ parseprintf(DD_INSTALL, ("init_zs_linemon: CD monitor installed\n"));
+
+ return 1;
+ }
+ }
+}
+
+/*
+ * unregister our ISR routine - must call under splhigh()
+ */
+static void
+close_zs_linemon(
+ register queue_t *q,
+ register queue_t *my_q
+ )
+{
+ register struct zscom *zs;
+ register parsestream_t *parsestream = (parsestream_t *)(void *)my_q->q_ptr;
+
+ zs = ((struct zsaline *)(void *)q->q_ptr)->za_common;
+ if (!zs)
+ {
+ /*
+ * well - not found on startup - just say no (shouldn't happen though)
+ */
+ return;
+ }
+ else
+ {
+ register struct savedzsops *szs = (struct savedzsops *)parsestream->parse_data;
+
+ zsopinit(zs, szs->oldzsops); /* reset to previous handler functions */
+
+ kmem_free((caddr_t)szs, sizeof (struct savedzsops));
+
+ parseprintf(DD_INSTALL, ("close_zs_linemon: CD monitor deleted\n"));
+ return;
+ }
+}
+
+#define MAXDEPTH 50 /* maximum allowed stream crawl */
+
+#ifdef PPS_SYNC
+extern void hardpps (struct timeval *, long);
+#ifdef PPS_NEW
+extern struct timeval timestamp;
+#else
+extern struct timeval pps_time;
+#endif
+#endif
+
+/*
+ * take external status interrupt (only CD interests us)
+ */
+static int
+zs_xsisr(
+ struct zscom *zs
+ )
+{
+ register struct zsaline *za = (struct zsaline *)(void *)zs->zs_priv;
+ register struct zscc_device *zsaddr = zs->zs_addr;
+ register queue_t *q;
+ register unsigned char zsstatus;
+ register int loopcheck;
+ register char *dname;
+#ifdef PPS_SYNC
+ register unsigned int s;
+ register long usec;
+#endif
+
+ /*
+ * pick up current state
+ */
+ zsstatus = zsaddr->zscc_control;
+
+ if ((za->za_rr0 ^ zsstatus) & (cdmask))
+ {
+ timestamp_t cdevent;
+ register int status;
+
+ za->za_rr0 = (za->za_rr0 & ~(cdmask)) | (zsstatus & (cdmask));
+
+#ifdef PPS_SYNC
+ s = splclock();
+#ifdef PPS_NEW
+ usec = timestamp.tv_usec;
+#else
+ usec = pps_time.tv_usec;
+#endif
+#endif
+ /*
+ * time stamp
+ */
+ uniqtime(&cdevent.tv);
+
+#ifdef PPS_SYNC
+ (void)splx(s);
+#endif
+
+ /*
+ * logical state
+ */
+ status = cd_invert ? (zsstatus & cdmask) == 0 : (zsstatus & cdmask) != 0;
+
+#ifdef PPS_SYNC
+ if (status)
+ {
+ usec = cdevent.tv.tv_usec - usec;
+ if (usec < 0)
+ usec += 1000000;
+
+ hardpps(&cdevent.tv, usec);
+ }
+#endif
+
+ q = za->za_ttycommon.t_readq;
+
+ /*
+ * ok - now the hard part - find ourself
+ */
+ loopcheck = MAXDEPTH;
+
+ while (q)
+ {
+ if (q->q_qinfo && q->q_qinfo->qi_minfo)
+ {
+ dname = q->q_qinfo->qi_minfo->mi_idname;
+
+ if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
+ {
+ /*
+ * back home - phew (hopping along stream queues might
+ * prove dangerous to your health)
+ */
+
+ if ((((parsestream_t *)(void *)q->q_ptr)->parse_status & PARSE_ENABLE) &&
+ parse_iopps(&((parsestream_t *)(void *)q->q_ptr)->parse_io, (int)(status ? SYNC_ONE : SYNC_ZERO), &cdevent))
+ {
+ /*
+ * XXX - currently we do not pass up the message, as
+ * we should.
+ * for a correct behaviour wee need to block out
+ * processing until parse_iodone has been posted via
+ * a softcall-ed routine which does the message pass-up
+ * right now PPS information relies on input being
+ * received
+ */
+ parse_iodone(&((parsestream_t *)(void *)q->q_ptr)->parse_io);
+ }
+
+ if (status)
+ {
+ ((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.tv = cdevent.tv;
+ ++(((parsestream_t *)(void *)q->q_ptr)->parse_ppsclockev.serial);
+ }
+
+ parseprintf(DD_ISR, ("zs_xsisr: CD event %s has been posted for \"%s\"\n", status ? "ONE" : "ZERO", dname));
+ break;
+ }
+ }
+
+ q = q->q_next;
+
+ if (!loopcheck--)
+ {
+ panic("zs_xsisr: STREAMS Queue corrupted - CD event");
+ }
+ }
+
+ /*
+ * only pretend that CD has been handled
+ */
+ ZSDELAY(2);
+
+ if (!((za->za_rr0 ^ zsstatus) & ~(cdmask)))
+ {
+ /*
+ * all done - kill status indication and return
+ */
+ zsaddr->zscc_control = ZSWR0_RESET_STATUS; /* might kill other conditions here */
+ return 0;
+ }
+ }
+
+ if (zsstatus & cdmask) /* fake CARRIER status */
+ za->za_flags |= ZAS_CARR_ON;
+ else
+ za->za_flags &= ~ZAS_CARR_ON;
+
+ /*
+ * we are now gathered here to process some unusual external status
+ * interrupts.
+ * any CD events have also been handled and shouldn't be processed
+ * by the original routine (unless we have a VERY busy port pin)
+ * some initializations are done here, which could have been done before for
+ * both code paths but have been avoided for minimum path length to
+ * the uniq_time routine
+ */
+ dname = (char *) 0;
+ q = za->za_ttycommon.t_readq;
+
+ loopcheck = MAXDEPTH;
+
+ /*
+ * the real thing for everything else ...
+ */
+ while (q)
+ {
+ if (q->q_qinfo && q->q_qinfo->qi_minfo)
+ {
+ dname = q->q_qinfo->qi_minfo->mi_idname;
+ if (!Strcmp(dname, parseinfo.st_rdinit->qi_minfo->mi_idname))
+ {
+ register int (*zsisr) (struct zscom *);
+
+ /*
+ * back home - phew (hopping along stream queues might
+ * prove dangerous to your health)
+ */
+ if ((zsisr = ((struct savedzsops *)((parsestream_t *)(void *)q->q_ptr)->parse_data)->oldzsops->zsop_xsint))
+ return zsisr(zs);
+ else
+ panic("zs_xsisr: unable to locate original ISR");
+
+ parseprintf(DD_ISR, ("zs_xsisr: non CD event was processed for \"%s\"\n", dname));
+ /*
+ * now back to our program ...
+ */
+ return 0;
+ }
+ }
+
+ q = q->q_next;
+
+ if (!loopcheck--)
+ {
+ panic("zs_xsisr: STREAMS Queue corrupted - non CD event");
+ }
+ }
+
+ /*
+ * last resort - shouldn't even come here as it indicates
+ * corrupted TTY structures
+ */
+ printf("zs_zsisr: looking for \"%s\" - found \"%s\" - taking EMERGENCY path\n", parseinfo.st_rdinit->qi_minfo->mi_idname, dname ? dname : "-NIL-");
+
+ if (emergencyzs && emergencyzs->zsop_xsint)
+ emergencyzs->zsop_xsint(zs);
+ else
+ panic("zs_xsisr: no emergency ISR handler");
+ return 0;
+}
+#endif /* sun */
+
+/*
+ * History:
+ *
+ * parsestreams.c,v
+ * Revision 4.11 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.10 2004/11/14 16:06:08 kardel
+ * update Id tags
+ *
+ * Revision 4.9 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.7 1999/11/28 09:13:53 kardel
+ * RECON_4_0_98F
+ *
+ * Revision 4.6 1998/12/20 23:45:31 kardel
+ * fix types and warnings
+ *
+ * Revision 4.5 1998/11/15 21:23:38 kardel
+ * ntp_memset() replicated in Sun kernel files
+ *
+ * Revision 4.4 1998/06/13 12:15:59 kardel
+ * superfluous variable removed
+ *
+ * Revision 4.3 1998/06/12 15:23:08 kardel
+ * fix prototypes
+ * adjust for ansi2knr
+ *
+ * Revision 4.2 1998/05/24 18:16:22 kardel
+ * moved copy of shadow status to the beginning
+ *
+ * Revision 4.1 1998/05/24 09:38:47 kardel
+ * streams initiated iopps calls (M_xHANGUP) are now consistent with the
+ * respective calls from zs_xsisr()
+ * simulation of CARRIER status to avoid unecessary M_xHANGUP messages
+ *
+ * Revision 4.0 1998/04/10 19:45:38 kardel
+ * Start 4.0 release version numbering
+ *
+ * from V3 3.37 log info deleted 1998/04/11 kardel
+ */
diff --git a/libparse/trim_info.c b/libparse/trim_info.c
new file mode 100644
index 0000000..619e238
--- /dev/null
+++ b/libparse/trim_info.c
@@ -0,0 +1,70 @@
+/*
+ * /src/NTP/ntp4-dev/libparse/trim_info.c,v 4.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * trim_info.c,v 4.5 2005/04/16 17:32:10 kardel RELEASE_20050508_A
+ *
+ * $Created: Sun Aug 2 20:20:34 1998 $
+ *
+ * Copyright (c) 1995-2005 by Frank Kardel <kardel <AT> ntp.org>
+ * Copyright (c) 1989-1994 by Frank Kardel, Friedrich-Alexander Universität Erlangen-Nürnberg, Germany
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+#include <config.h>
+#include "ntp_types.h"
+#include "trimble.h"
+
+cmd_info_t *
+trimble_convert(
+ unsigned int cmd,
+ cmd_info_t *tbl
+ )
+{
+ int i;
+
+ for (i = 0; tbl[i].cmd != 0xFF; i++)
+ {
+ if (tbl[i].cmd == cmd)
+ return &tbl[i];
+ }
+ return 0;
+}
+
+/*
+ * trim_info.c,v
+ * Revision 4.5 2005/04/16 17:32:10 kardel
+ * update copyright
+ *
+ * Revision 4.4 2004/11/14 15:29:41 kardel
+ * support PPSAPI, upgrade Copyright to Berkeley style
+ *
+ * Revision 4.2 1998/12/20 23:45:31 kardel
+ * fix types and warnings
+ *
+ * Revision 4.1 1998/08/09 22:27:48 kardel
+ * Trimble TSIP support
+ *
+ */