diff --git a/libs/spandsp/Makefile.am b/libs/spandsp/Makefile.am index 193c108c6b..ccc9240240 100644 --- a/libs/spandsp/Makefile.am +++ b/libs/spandsp/Makefile.am @@ -16,6 +16,8 @@ ## License along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +ACLOCAL_AMFLAGS = -I m4 + AM_CFLAGS = $(COMP_VENDOR_CFLAGS) AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS) diff --git a/libs/spandsp/configure.ac b/libs/spandsp/configure.ac index 7914885d79..9783f0a685 100644 --- a/libs/spandsp/configure.ac +++ b/libs/spandsp/configure.ac @@ -18,34 +18,25 @@ # @start 1 -AC_INIT - -m4_include(config/ax_compiler_vendor.m4) -m4_include(config/ax_check_real_file.m4) -m4_include(config/ax_fixed_point_machine.m4) -m4_include(config/ax_misaligned_access_fails.m4) -m4_include(config/ax_c99_features.m4) -m4_include(config/ax_check_export_capability.m4) - -SPANDSP_MAJOR_VERSION=0 -SPANDSP_MINOR_VERSION=0 -SPANDSP_MICRO_VERSION=6 +AC_PREREQ([2.59]) +AC_INIT([spandsp], [0.0.6]) SPANDSP_LT_CURRENT=2 SPANDSP_LT_REVISION=0 SPANDSP_LT_AGE=0 -VERSION=$SPANDSP_MAJOR_VERSION.$SPANDSP_MINOR_VERSION.$SPANDSP_MICRO_VERSION -PACKAGE=spandsp - -AC_SUBST(SPANDSP_LT_CURRENT) -AC_SUBST(SPANDSP_LT_REVISION) -AC_SUBST(SPANDSP_LT_AGE) +m4_include(m4/ax_compiler_vendor.m4) +m4_include(m4/ax_check_real_file.m4) +m4_include(m4/ax_fixed_point_machine.m4) +m4_include(m4/ax_misaligned_access_fails.m4) +m4_include(m4/ax_c99_features.m4) +m4_include(m4/ax_check_export_capability.m4) AC_CONFIG_SRCDIR([src/tone_generate.c]) -AC_CONFIG_AUX_DIR(config) +AC_CONFIG_AUX_DIR([config]) +AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([src/config.h:config-h.in]) -AM_INIT_AUTOMAKE($PACKAGE, $VERSION) +AM_INIT_AUTOMAKE([1.9.5]) AC_CANONICAL_HOST #AC_CANONICAL_BUILD @@ -59,51 +50,51 @@ AX_COMPILER_VENDOR if test "${build}" != "${host}" then - # If we are doing a Canadian Cross, in which the host and build systems - # are not the same, we set reasonable default values for the tools. + # If we are doing a Canadian Cross, in which the host and build systems + # are not the same, we set reasonable default values for the tools. - CC_FOR_BUILD=${CC_FOR_BUILD-gcc} - CPPFLAGS_FOR_BUILD="\$(CPPFLAGS)" - CC=${CC-${host_alias}-gcc} - CFLAGS=${CFLAGS-"-g -O2"} - CXX=${CXX-${host_alias}-c++} - CXXFLAGS=${CXXFLAGS-"-g -O2"} + CC_FOR_BUILD=${CC_FOR_BUILD-gcc} + CPPFLAGS_FOR_BUILD="\$(CPPFLAGS)" + CC=${CC-${host_alias}-gcc} + CFLAGS=${CFLAGS-"-g -O2"} + CXX=${CXX-${host_alias}-c++} + CXXFLAGS=${CXXFLAGS-"-g -O2"} else - # Set reasonable default values for some tools even if not Canadian. - # Of course, these are different reasonable default values, originally - # specified directly in the Makefile. - # We don't export, so that autoconf can do its job. - # Note that all these settings are above the fragment inclusion point - # in Makefile.in, so can still be overridden by fragments. - # This is all going to change when we autoconfiscate... - CC_FOR_BUILD="\$(CC)" - CPPFLAGS_FOR_BUILD="\$(CPPFLAGS)" - AC_PROG_CC + # Set reasonable default values for some tools even if not Canadian. + # Of course, these are different reasonable default values, originally + # specified directly in the Makefile. + # We don't export, so that autoconf can do its job. + # Note that all these settings are above the fragment inclusion point + # in Makefile.in, so can still be overridden by fragments. + # This is all going to change when we autoconfiscate... + CC_FOR_BUILD="\$(CC)" + CPPFLAGS_FOR_BUILD="\$(CPPFLAGS)" + AC_PROG_CC - # We must set the default linker to the linker used by gcc for the correct - # operation of libtool. If LD is not defined and we are using gcc, try to - # set the LD default to the ld used by gcc. - if test -z "$LD" - then - if test "$GCC" = yes + # We must set the default linker to the linker used by gcc for the correct + # operation of libtool. If LD is not defined and we are using gcc, try to + # set the LD default to the ld used by gcc. + if test -z "$LD" then - case $build in - *-*-mingw*) - gcc_prog_ld=`$CC -print-prog-name=ld 2>&1 | tr -d '\015'` ;; - *) - gcc_prog_ld=`$CC -print-prog-name=ld 2>&1` ;; - esac - case $gcc_prog_ld in - # Accept absolute paths. - [[\\/]* | [A-Za-z]:[\\/]*)] - LD="$gcc_prog_ld" ;; - esac + if test "$GCC" = yes + then + case $build in + *-*-mingw*) + gcc_prog_ld=`$CC -print-prog-name=ld 2>&1 | tr -d '\015'` ;; + *) + gcc_prog_ld=`$CC -print-prog-name=ld 2>&1` ;; + esac + case $gcc_prog_ld in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + LD="$gcc_prog_ld" ;; + esac + fi fi - fi - CXX=${CXX-"c++"} - CFLAGS=${CFLAGS-"-g -O2"} - CXXFLAGS=${CXXFLAGS-"-g -O2"} + CXX=${CXX-"c++"} + CFLAGS=${CFLAGS-"-g -O2"} + CXXFLAGS=${CXXFLAGS-"-g -O2"} fi AC_DEFUN([REMOVE_FROM_VAR],[ @@ -143,6 +134,7 @@ AC_ARG_ENABLE(sse4_1, [ --enable-sse4-1 Enable SSE4.1 support]) AC_ARG_ENABLE(sse4_2, [ --enable-sse4-2 Enable SSE4.2 support]) AC_ARG_ENABLE(sse4a, [ --enable-sse4a Enable SSE4A support]) AC_ARG_ENABLE(sse5, [ --enable-sse5 Enable SSE5 support]) +AC_ARG_ENABLE(avx, [ --enable-avx Enable AVX support]) AC_ARG_ENABLE(fixed_point, [ --enable-fixed-point Enable fixed point support]) # The following is for MSVC, where we may be using a local copy of libtiff, built alongside spandsp AC_ARG_ENABLE(builtin_tiff, @@ -207,9 +199,9 @@ AC_CHECK_HEADERS([fenv.h]) AC_CHECK_HEADERS([fftw3.h], , [AC_CHECK_HEADERS([fftw.h])]) AC_CHECK_HEADERS([pcap.h]) AC_CHECK_HEADERS([pthread.h]) -if test "${build}" = "${host}" +if test "${build}" == "${host}" then - AC_CHECK_HEADERS([X11/X.h]) + AC_CHECK_HEADERS([X11/X.h]) fi # Determine XML2 include path @@ -253,12 +245,12 @@ AC_CHECK_HEADERS([FL/Fl_Audio_Meter.H], [], [], [],[[#include <FL/Fl.H> AC_LANG([C]) -if test "${build}" = "${host}" +if test "${build}" == "${host}" then case "${host}" in x86_64-*) # X86_64 Linux machines may have both 64 bit and 32 bit libraries. We need to choose the right set - AX_CHECK_REAL_FILE([${prefix}/lib64], libdir='$(exec_prefix)/lib64') + AX_CHECK_REAL_FILE([${prefix}/lib64], libdir='${exec_prefix}/lib64') AX_CHECK_REAL_FILE([/usr/X11R6/lib64], [TESTLIBS="$TESTLIBS -L/usr/X11R6/lib64"], AC_CHECK_FILE([/usr/X11R6/lib], [TESTLIBS="$TESTLIBS -L/usr/X11R6/lib"])) # The very oldest AMD 64 bit chips support SSE2, SSE and MMX enable_sse2="yes" @@ -266,6 +258,10 @@ then esac fi +#AC_DEFINE([SPANDSP_SUPPORT_T42], [1], [Support T.42 JPEG compression]) +SPANDSP_SUPPORT_T42="#undef SPANDSP_SUPPORT_T42" +#AC_DEFINE([SPANDSP_SUPPORT_T43], [1], [Support T.43 JBIG gray and colour compression]) +SPANDSP_SUPPORT_T43="#undef SPANDSP_SUPPORT_T43" #AC_DEFINE([SPANDSP_SUPPORT_T85], [1], [Support T.85 JBIG compression]) SPANDSP_SUPPORT_T85="#undef SPANDSP_SUPPORT_T85" #AC_DEFINE([SPANDSP_SUPPORT_V34], [1], [Support the V.34 FAX modem]) @@ -287,14 +283,27 @@ AC_SEARCH_LIBS([expf], [m], AC_DEFINE([HAVE_EXPF], [1], [Define to 1 if you have AC_SEARCH_LIBS([logf], [m], AC_DEFINE([HAVE_LOGF], [1], [Define to 1 if you have the logf() function.])) AC_SEARCH_LIBS([log10f], [m], AC_DEFINE([HAVE_LOG10F], [1], [Define to 1 if you have the log10f() function.])) -# Checks for libraries. -AC_CHECK_LIB([xml2], [xmlParseFile], [AC_DEFINE([HAVE_LIBXML2], [1], [Define to 1 if you have the 'libxml2' library (-lxml2).]) SIMLIBS="$SIMLIBS -lxml2"]) +AC_SEARCH_LIBS([open_memstream], [m], AC_DEFINE([HAVE_OPEN_MEMSTREAM], [1], [Define to 1 if you have the open_memstream() function.])) if test -n "$enable_tests" ; then + AC_CHECK_PROG([HAVE_SOX], [sox], yes) + if test "x$HAVE_SOX" != "xyes" ; then + AC_MSG_ERROR("Cannot make tests without sox installed") + fi + AC_CHECK_PROG([HAVE_PBMTOG3], [pbmtog3], yes) + if test "x$HAVE_PBMTOG3" != "xyes" ; then + AC_MSG_ERROR("Cannot make tests without pbmtog3 installed (does your system require a netpbm-progs package?)") + fi + AC_CHECK_PROG([HAVE_FAX2TIFF], [fax2tiff], yes) + if test "x$HAVE_FAX2TIFF" != "xyes" ; then + AC_MSG_ERROR("Cannot make tests without fax2tiff installed (does your system require a libtiff-tools package?)") + fi AC_LANG([C]) - AC_CHECK_LIB([sndfile], [sf_open], SIMLIBS="$SIMLIBS -lsndfile", AC_MSG_ERROR("Can't make tests without libsndfile (does your system require a libsndfile-devel package?)")) - AC_CHECK_LIB([fftw3], [fftw_plan_dft_1d], SIMLIBS="$SIMLIBS -lfftw3", [AC_CHECK_LIB([fftw], [fftw_create_plan], SIMLIBS="$SIMLIBS -lfftw", AC_MSG_ERROR("Can't make tests without FFTW 2 or 3 (does your system require an fftw?-devel package?)"))]) - AC_CHECK_LIB([pcap], [pcap_open_offline], TESTLIBS="$TESTLIBS -lpcap", AC_MSG_ERROR("Can't make tests without libpcap (does your system require a libpcap-devel package?)")) + # Checks for libraries. + AC_CHECK_LIB([sndfile], [sf_open], SIMLIBS="$SIMLIBS -lsndfile", AC_MSG_ERROR("Cannot make tests without libsndfile (does your system require a libsndfile-devel package?)")) + AC_CHECK_LIB([fftw3], [fftw_plan_dft_1d], SIMLIBS="$SIMLIBS -lfftw3", [AC_CHECK_LIB([fftw], [fftw_create_plan], SIMLIBS="$SIMLIBS -lfftw", AC_MSG_ERROR("Cannot make tests without FFTW 2 or 3 (does your system require an fftw?-devel package?)"))]) + AC_CHECK_LIB([xml2], [xmlParseFile], TESTLIBS="$TESTLIBS -lxml2", AC_MSG_ERROR("Cannot make tests without libxml2 (does your system require a libxml2-devel package?)")) + AC_CHECK_LIB([pcap], [pcap_open_offline], TESTLIBS="$TESTLIBS -lpcap", [AC_CHECK_LIB([wpcap], [pcap_open_offline], TESTLIBS="$TESTLIBS -lwpcap", AC_MSG_ERROR("Cannot make tests without libpcap (does your system require an libpcap-devel package?)"))]) AC_CHECK_LIB([pthread], [pthread_attr_init], TESTLIBS="$TESTLIBS -lpthread") AC_CHECK_LIB([dl], [dlopen], TESTLIBS="$TESTLIBS -ldl") AC_CHECK_LIB([Xft], [XftFontOpen], TESTLIBS="$TESTLIBS -lXft",, $TESTLIBS) @@ -314,7 +323,10 @@ AX_CHECK_EXPORT_CAPABILITY([$host], case "${ax_cv_c_compiler_vendor}" in gnu) - COMP_VENDOR_CFLAGS="-std=gnu99 -ffast-math -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS" + COMP_VENDOR_CFLAGS="-std=gnu99 -ffast-math -Wall -Wunused-variable -Wunused-but-set-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS" + if test "$enable_avx" = "yes" ; then + COMP_VENDOR_CFLAGS="-mavx $COMP_VENDOR_CFLAGS" + fi if test "$enable_sse5" = "yes" ; then COMP_VENDOR_CFLAGS="-msse5 $COMP_VENDOR_CFLAGS" fi @@ -343,9 +355,12 @@ gnu) COMP_VENDOR_CFLAGS="-mmmx $COMP_VENDOR_CFLAGS" fi case $host_os in - mingw* | cygwin*) + cygwin*) COMP_VENDOR_LDFLAGS="-no-undefined" ;; + mingw*) + COMP_VENDOR_LDFLAGS="-no-undefined -lws2_32" + ;; *) COMP_VENDOR_LDFLAGS= ;; @@ -369,7 +384,10 @@ sun) REMOVE_FROM_VAR(CFLAGS, -Xc) ;; intel) - COMP_VENDOR_CFLAGS="-std=c99 -D_POSIX_C_SOURCE=2 -D_GNU_SOURCE=1 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS" + COMP_VENDOR_CFLAGS="-std=c99 -D_POSIX_C_SOURCE=2 -D_GNU_SOURCE=1 -Wall -Wunused-variable -Wunused-but-set-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS" + if test "$enable_avx" = "yes" ; then + COMP_VENDOR_CFLAGS="-mavx $COMP_VENDOR_CFLAGS" + fi if test "$enable_sse5" = "yes" ; then COMP_VENDOR_CFLAGS="-msse5 $COMP_VENDOR_CFLAGS" fi @@ -400,25 +418,13 @@ intel) COMP_VENDOR_LDFLAGS= ;; *) - COMP_VENDOR_CFLAGS="-std=c99 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS" + COMP_VENDOR_CFLAGS="-std=c99 -Wall -Wunused-variable -Wunused-but-set-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS" COMP_VENDOR_LDFLAGS= ;; esac COMP_VENDOR_CFLAGS="-DNDEBUG $COMP_VENDOR_CFLAGS" -AM_CONDITIONAL([COND_DOC], [test "$enable_doc" = yes]) -AM_CONDITIONAL([COND_TESTS], [test "$enable_tests" = yes]) -AM_CONDITIONAL([COND_TESTDATA], [test "$enable_test_data" = yes]) -AM_CONDITIONAL([COND_MMX], [test "$enable_mmx" = yes]) -AM_CONDITIONAL([COND_SSE], [test "$enable_sse" = yes]) -AM_CONDITIONAL([COND_SSE2], [test "$enable_sse2" = yes]) -AM_CONDITIONAL([COND_SSE3], [test "$enable_sse3" = yes]) -AM_CONDITIONAL([COND_SSSE3], [test "$enable_ssse3" = yes]) -AM_CONDITIONAL([COND_SSE4_1], [test "$enable_sse4_1" = yes]) -AM_CONDITIONAL([COND_SSE4_2], [test "$enable_sse4_2" = yes]) -AM_CONDITIONAL([COND_SSE4A], [test "$enable_sse4a" = yes]) -AM_CONDITIONAL([COND_SSE5], [test "$enable_sse5" = yes]) if test "$enable_fixed_point" = "yes" ; then AC_DEFINE([SPANDSP_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point]) SPANDSP_USE_FIXED_POINT="#define SPANDSP_USE_FIXED_POINT 1" @@ -433,6 +439,10 @@ AX_MISALIGNED_ACCESS_FAILS([$host], SPANDSP_MISALIGNED_ACCESS_FAILS="#define SPANDSP_MISALIGNED_ACCESS_FAILS 1"], [SPANDSP_MISALIGNED_ACCESS_FAILS="#undef SPANDSP_MISALIGNED_ACCESS_FAILS"]) +if test "$enable_avx" = "yes" ; then + AC_DEFINE([SPANDSP_USE_AVX], [1], [Use the AVX instruction set (i386 and x86_64 only).]) + enable_sse5"yes" +fi if test "$enable_sse5" = "yes" ; then AC_DEFINE([SPANDSP_USE_SSE5], [1], [Use the SSE5 instruction set (i386 and x86_64 only).]) enable_sse4a="yes" @@ -469,23 +479,42 @@ if test "$enable_mmx" = "yes" ; then AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) fi +AM_CONDITIONAL([COND_DOC], [test "$enable_doc" = yes]) +AM_CONDITIONAL([COND_TESTS], [test "$enable_tests" = yes]) +AM_CONDITIONAL([COND_TESTDATA], [test "$enable_test_data" = yes]) +AM_CONDITIONAL([COND_MMX], [test "$enable_mmx" = yes]) +AM_CONDITIONAL([COND_SSE], [test "$enable_sse" = yes]) +AM_CONDITIONAL([COND_SSE2], [test "$enable_sse2" = yes]) +AM_CONDITIONAL([COND_SSE3], [test "$enable_sse3" = yes]) +AM_CONDITIONAL([COND_SSSE3], [test "$enable_ssse3" = yes]) +AM_CONDITIONAL([COND_SSE4_1], [test "$enable_sse4_1" = yes]) +AM_CONDITIONAL([COND_SSE4_2], [test "$enable_sse4_2" = yes]) +AM_CONDITIONAL([COND_SSE4A], [test "$enable_sse4a" = yes]) +AM_CONDITIONAL([COND_SSE5], [test "$enable_sse5" = yes]) +AM_CONDITIONAL([COND_AVX], [test "$enable_avx" = yes]) + if test "$enable_builtin_tiff" = "yes" ; then - abs_tiffdir="`cd $srcdir/../tiff-3.8.2/ && pwd`" - save_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS -I$abs_tiffdir/libtiff" - AC_CHECK_HEADERS([tiffio.h]) - CFLAGS="$save_CFLAGS" - COMP_VENDOR_CFLAGS="-I$abs_tiffdir/libtiff $COMP_VENDOR_CFLAGS" - COMP_VENDOR_LDFLAGS="-L$abs_tiffdir/libtiff $COMP_VENDOR_LDFLAGS" - LIBS="$LIBS $abs_tiffdir/libtiff/libtiff.la" - AC_DEFINE([HAVE_LIBTIFF], [1], [Define to 1 if you have the `tiff' library (-ltiff).]) + abs_tiffdir="`cd $srcdir/../tiff-3.8.2/ && pwd`" + save_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -I$abs_tiffdir/libtiff" + AC_CHECK_HEADERS([tiffio.h]) + CFLAGS="$save_CFLAGS" + COMP_VENDOR_CFLAGS="-I$abs_tiffdir/libtiff $COMP_VENDOR_CFLAGS" + COMP_VENDOR_LDFLAGS="-L$abs_tiffdir/libtiff $COMP_VENDOR_LDFLAGS" + LIBS="$LIBS $abs_tiffdir/libtiff/libtiff.la" + AC_DEFINE([HAVE_LIBTIFF], [1], [Define to 1 if you have the `tiff' library (-ltiff).]) else - AC_CHECK_HEADERS([tiffio.h]) - AC_CHECK_LIB([tiff], [TIFFOpen], , AC_MSG_ERROR("Can't build without libtiff (does your system require a libtiff-devel package?)"), -lm) + AC_CHECK_HEADERS([tiffio.h]) + AC_CHECK_LIB([tiff], [TIFFOpen], , AC_MSG_ERROR("Cannot build without libtiff (does your system require a libtiff-devel package?)"), -lm) fi +AC_CHECK_HEADERS([jpeglib.h]) +AC_CHECK_LIB([jpeg], [jpeg_start_compress]) TESTLIBS="$SIMLIBS $TESTLIBS" +AC_SUBST(SPANDSP_LT_CURRENT) +AC_SUBST(SPANDSP_LT_REVISION) +AC_SUBST(SPANDSP_LT_AGE) AC_SUBST(CC_FOR_BUILD) AC_SUBST(CPPFLAGS_FOR_BUILD) AC_SUBST(COMP_VENDOR_CFLAGS) @@ -495,6 +524,8 @@ AC_SUBST(TESTLIBS) AC_SUBST(SPANDSP_USE_FIXED_POINT) AC_SUBST(SPANDSP_MISALIGNED_ACCESS_FAILS) AC_SUBST(SPANDSP_USE_EXPORT_CAPABILITY) +AC_SUBST(SPANDSP_SUPPORT_T42) +AC_SUBST(SPANDSP_SUPPORT_T43) AC_SUBST(SPANDSP_SUPPORT_T85) AC_SUBST(SPANDSP_SUPPORT_V34) AC_SUBST(INSERT_INTTYPES_HEADER) diff --git a/libs/spandsp/doc/doxygen.in b/libs/spandsp/doc/doxygen.in index 87c3c34572..38af500c1a 100644 --- a/libs/spandsp/doc/doxygen.in +++ b/libs/spandsp/doc/doxygen.in @@ -357,12 +357,6 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is YES. - -SHOW_DIRECTORIES = YES - # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via @@ -635,12 +629,6 @@ HTML_FOOTER = HTML_STYLESHEET = css.css -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) @@ -1123,7 +1111,7 @@ CALL_GRAPH = NO GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. diff --git a/libs/spandsp/config/ax_c99_features.m4 b/libs/spandsp/m4/ax_c99_features.m4 similarity index 100% rename from libs/spandsp/config/ax_c99_features.m4 rename to libs/spandsp/m4/ax_c99_features.m4 diff --git a/libs/spandsp/config/ax_check_export_capability.m4 b/libs/spandsp/m4/ax_check_export_capability.m4 similarity index 100% rename from libs/spandsp/config/ax_check_export_capability.m4 rename to libs/spandsp/m4/ax_check_export_capability.m4 diff --git a/libs/spandsp/config/ax_check_real_file.m4 b/libs/spandsp/m4/ax_check_real_file.m4 similarity index 100% rename from libs/spandsp/config/ax_check_real_file.m4 rename to libs/spandsp/m4/ax_check_real_file.m4 diff --git a/libs/spandsp/config/ax_compiler_vendor.m4 b/libs/spandsp/m4/ax_compiler_vendor.m4 similarity index 100% rename from libs/spandsp/config/ax_compiler_vendor.m4 rename to libs/spandsp/m4/ax_compiler_vendor.m4 diff --git a/libs/spandsp/config/ax_fixed_point_machine.m4 b/libs/spandsp/m4/ax_fixed_point_machine.m4 similarity index 100% rename from libs/spandsp/config/ax_fixed_point_machine.m4 rename to libs/spandsp/m4/ax_fixed_point_machine.m4 diff --git a/libs/spandsp/config/ax_misaligned_access_fails.m4 b/libs/spandsp/m4/ax_misaligned_access_fails.m4 similarity index 100% rename from libs/spandsp/config/ax_misaligned_access_fails.m4 rename to libs/spandsp/m4/ax_misaligned_access_fails.m4 diff --git a/libs/spandsp/spandsp.pc.in b/libs/spandsp/spandsp.pc.in index 1a91ba04e1..19fb1d501a 100644 --- a/libs/spandsp/spandsp.pc.in +++ b/libs/spandsp/spandsp.pc.in @@ -1,5 +1,5 @@ prefix=@prefix@ -exec_prefix=@prefix@ +exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ @@ -7,5 +7,6 @@ Name: spandsp Description: A DSP library for telephony. Requires: Version: @VERSION@ -Libs: -L${libdir} -lspandsp -ltiff -lm +Libs: -L${libdir} -lspandsp +Libs.private: -ltiff -lm Cflags: -I${includedir} diff --git a/libs/spandsp/spandsp.spec b/libs/spandsp/spandsp.spec index 5ba3f2cc8d..bf4fcb13da 100644 --- a/libs/spandsp/spandsp.spec +++ b/libs/spandsp/spandsp.spec @@ -1,19 +1,22 @@ -Summary: A DSP library for telephony. -Name: spandsp -Version: 0.0.6 -Release: 1 -License: LGPL -Group: System Environment/Libraries -URL: http://www.soft-switch.org/spandsp -BuildRoot: %{_tmppath}/%{name}-%{version}-root -Source: http://www.soft-switch.org/downloads/spandsp/spandsp-0.0.6.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +%global pre 21 -BuildRequires: libtiff-devel -BuildRequires: audiofile-devel +Summary: A DSP library for telephony. +Name: spandsp +Version: 0.0.6 +Release: 1 +License: LGPLv2 and GPLv2 +Group: System Environment/Libraries +URL: http://www.soft-switch.org/spandsp +Source: http://www.soft-switch.org/downloads/spandsp/spandsp-0.0.6.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +BuildRequires: libtiff-devel%{?_isa} +BuildRequires: libjpeg-turbo-devel%{?_isa} +BuildRequires: libxml2-devel%{?_isa} +BuildRequires: libsndfile-devel%{?_isa} BuildRequires: doxygen -# for xsltproc: BuildRequires: libxslt +BuildRequires: docbook-style-xsl %description SpanDSP is a library of DSP functions for telephony, in the 8000 @@ -26,49 +29,66 @@ relevant patents have expired. See the file DueDiligence for important information about these intellectual property issues. %package devel -Summary: SpanDSP development files -Group: Development/Libraries -Requires: spandsp = %{version} -Requires: libtiff-devel -PreReq: /sbin/install-info +Summary: SpanDSP development files +Group: Development/Libraries +Requires: spandsp%{?_isa} = %{version}-%{release} +Requires: libtiff-devel%{?_isa} +Requires: libjpeg-turbo-devel%{?_isa} %description devel SpanDSP development files. +%package apidoc +Summary: SpanDSP API documentation +Group: Development/Libraries + +%description apidoc +SpanDSP API documentation. + %prep %setup -q %build %configure --enable-doc --disable-static --disable-rpath make +find doc/api -type f | xargs touch -r configure %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} rm %{buildroot}%{_libdir}/libspandsp.la +mkdir -p %{buildroot}%{_datadir}/spandsp %clean rm -rf %{buildroot} %files %defattr(-,root,root,-) -%doc DueDiligence ChangeLog AUTHORS COPYING NEWS README +%doc DueDiligence ChangeLog AUTHORS COPYING NEWS README %{_libdir}/libspandsp.so.* +%{_datadir}/spandsp + %files devel %defattr(-,root,root,-) -%doc doc/api %{_includedir}/spandsp.h %{_includedir}/spandsp %{_libdir}/libspandsp.so %{_libdir}/pkgconfig/spandsp.pc +%files apidoc +%defattr(-,root,root,-) +%doc doc/api/html/* + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %changelog +* Mon Oct 03 2011 Steve Underwood <steveu@coppice.org> 0.0.6-1 +- Converge with what Fedora do + * Wed Sep 24 2008 Tzafrir Cohen <tzafrir.cohen@xorcom.com> 0.0.5-1 - Preparing for 0.0.5pre4 release - License: LGPL diff --git a/libs/spandsp/spandsp.spec.in b/libs/spandsp/spandsp.spec.in index 7b8406fa7c..759dd17c07 100644 --- a/libs/spandsp/spandsp.spec.in +++ b/libs/spandsp/spandsp.spec.in @@ -1,19 +1,22 @@ -Summary: A DSP library for telephony. -Name: @PACKAGE@ -Version: @VERSION@ -Release: 1 -License: LGPL -Group: System Environment/Libraries -URL: http://www.soft-switch.org/spandsp -BuildRoot: %{_tmppath}/%{name}-%{version}-root -Source: http://www.soft-switch.org/downloads/spandsp/@PACKAGE@-@VERSION@.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +%global pre 21 -BuildRequires: libtiff-devel -BuildRequires: audiofile-devel +Summary: A DSP library for telephony. +Name: @PACKAGE@ +Version: @VERSION@ +Release: 1 +License: LGPLv2 and GPLv2 +Group: System Environment/Libraries +URL: http://www.soft-switch.org/spandsp +Source: http://www.soft-switch.org/downloads/spandsp/@PACKAGE@-@VERSION@.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +BuildRequires: libtiff-devel%{?_isa} +BuildRequires: libjpeg-turbo-devel%{?_isa} +BuildRequires: libxml2-devel%{?_isa} +BuildRequires: libsndfile-devel%{?_isa} BuildRequires: doxygen -# for xsltproc: BuildRequires: libxslt +BuildRequires: docbook-style-xsl %description SpanDSP is a library of DSP functions for telephony, in the 8000 @@ -26,49 +29,66 @@ relevant patents have expired. See the file DueDiligence for important information about these intellectual property issues. %package devel -Summary: SpanDSP development files -Group: Development/Libraries -Requires: spandsp = %{version} -Requires: libtiff-devel -PreReq: /sbin/install-info +Summary: SpanDSP development files +Group: Development/Libraries +Requires: spandsp%{?_isa} = %{version}-%{release} +Requires: libtiff-devel%{?_isa} +Requires: libjpeg-turbo-devel%{?_isa} %description devel SpanDSP development files. +%package apidoc +Summary: SpanDSP API documentation +Group: Development/Libraries + +%description apidoc +SpanDSP API documentation. + %prep %setup -q %build %configure --enable-doc --disable-static --disable-rpath make +find doc/api -type f | xargs touch -r configure %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} rm %{buildroot}%{_libdir}/libspandsp.la +mkdir -p %{buildroot}%{_datadir}/spandsp %clean rm -rf %{buildroot} %files %defattr(-,root,root,-) -%doc DueDiligence ChangeLog AUTHORS COPYING NEWS README +%doc DueDiligence ChangeLog AUTHORS COPYING NEWS README %{_libdir}/libspandsp.so.* +%{_datadir}/spandsp + %files devel %defattr(-,root,root,-) -%doc doc/api %{_includedir}/spandsp.h %{_includedir}/spandsp %{_libdir}/libspandsp.so %{_libdir}/pkgconfig/spandsp.pc +%files apidoc +%defattr(-,root,root,-) +%doc doc/api/html/* + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %changelog +* Mon Oct 03 2011 Steve Underwood <steveu@coppice.org> 0.0.6-1 +- Converge with what Fedora do + * Wed Sep 24 2008 Tzafrir Cohen <tzafrir.cohen@xorcom.com> 0.0.5-1 - Preparing for 0.0.5pre4 release - License: LGPL diff --git a/libs/spandsp/src/Makefile.am b/libs/spandsp/src/Makefile.am index 96924bfe4c..ce4f5bad4c 100644 --- a/libs/spandsp/src/Makefile.am +++ b/libs/spandsp/src/Makefile.am @@ -87,7 +87,8 @@ INCLUDES = -I$(top_builddir) lib_LTLIBRARIES = libspandsp.la -libspandsp_la_SOURCES = adsi.c \ +libspandsp_la_SOURCES = ademco_contactid.c \ + adsi.c \ async.c \ at_interpreter.c \ awgn.c \ @@ -173,7 +174,8 @@ libspandsp_la_SOURCES = adsi.c \ libspandsp_la_LDFLAGS = -version-info @SPANDSP_LT_CURRENT@:@SPANDSP_LT_REVISION@:@SPANDSP_LT_AGE@ $(COMP_VENDOR_LDFLAGS) -nobase_include_HEADERS = spandsp/adsi.h \ +nobase_include_HEADERS = spandsp/ademco_contactid.h \ + spandsp/adsi.h \ spandsp/async.h \ spandsp/arctan2.h \ spandsp/at_interpreter.h \ @@ -257,6 +259,7 @@ nobase_include_HEADERS = spandsp/adsi.h \ spandsp/vector_float.h \ spandsp/vector_int.h \ spandsp/version.h \ + spandsp/private/ademco_contactid.h \ spandsp/private/adsi.h \ spandsp/private/async.h \ spandsp/private/at_interpreter.h \ diff --git a/libs/spandsp/src/ademco_contactid.c b/libs/spandsp/src/ademco_contactid.c new file mode 100644 index 0000000000..1ba11f4763 --- /dev/null +++ b/libs/spandsp/src/ademco_contactid.c @@ -0,0 +1,1062 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * ademco_contactid.c - Ademco ContactID alarm protocol + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2012 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \file */ + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <inttypes.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#if defined(HAVE_TGMATH_H) +#include <tgmath.h> +#endif +#if defined(HAVE_MATH_H) +#include <math.h> +#endif +#include "floating_fudge.h" +#include <memory.h> +#include <string.h> +#include <limits.h> +#include <assert.h> + +#include "spandsp/telephony.h" +#include "spandsp/fast_convert.h" +#include "spandsp/logging.h" +#include "spandsp/queue.h" +#include "spandsp/complex.h" +#include "spandsp/dds.h" +#include "spandsp/power_meter.h" +#include "spandsp/async.h" +#include "spandsp/vector_float.h" +#include "spandsp/complex_vector_float.h" +#include "spandsp/vector_int.h" +#include "spandsp/complex_vector_int.h" +#include "spandsp/tone_detect.h" +#include "spandsp/tone_generate.h" +#include "spandsp/super_tone_rx.h" +#include "spandsp/dtmf.h" +#include "spandsp/ademco_contactid.h" + +#include "spandsp/private/logging.h" +#include "spandsp/private/queue.h" +#include "spandsp/private/tone_detect.h" +#include "spandsp/private/tone_generate.h" +#include "spandsp/private/dtmf.h" +#include "spandsp/private/ademco_contactid.h" + +/* +Ademco ContactID Protocol + +Answer +Wait 0.5s to 2s for the line to settle +Send 1400Hz for 100ms +Send silence for 100ms +Send 2300Hz for 100ms +Receiver now waits + +(both timing and frequency errors specified as 3%, but sender side should accept these tones with 5% frequency error.) + +Sender waits 250-300ms after end of 2300Hz tone + +Send ACCT MT QXYZ GG CCC + +ACCT = 4 digit account code (0-9, B-F) +MT = 2 digit message type (18 preferred, 98 optional) +Q = 1 digit event qualifier. 1 = New event or opening. 3 = New restore or closing. 6 = Previous condition still present +XYZ = 3 digit event code (0-9, B-F) +GG = 2 digit group or partition number (0-9, B-F). 00=no specific group +CCC = 3 digit zone number (event reports) or user number (open/close reports). 000=no specific zone or user information +S = 1 digit hex checksum (sum all message digits + S) mod 15 == 0 + +DTMF tones are 50-60ms on 50-60ms off + +0 10 (counted as 10 in checksum calculations) +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 +B (*) 11 +C (#) 12 +D (A) 13 +E (B) 14 +F (C) 15 + +DTMF D is not used + +Wait 1.25s for a kiss-off tone +Detect at least 400ms of kissoff to be valid, then wait for end of tone + +Wait 250-300ms before sending the next DTMF message + +If kissoff doesn't start within 1.25s of the end of the DTMF, repeat the DTMF message + +Receiver sends 750-1000ms of 1400Hz as the kissoff tone + +Sender shall make 4 attempts before giving up. One successful kissoff resets the attempt counter +*/ + +struct ademco_code_s +{ + int code; + const char *name; + int data_type; +}; + +static const struct ademco_code_s ademco_codes[] = +{ + {0x100, "Medical", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x101, "Personal emergency", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x102, "Fail to report in", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x110, "Fire", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x111, "Smoke", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x112, "Combustion", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x113, "Water flow", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x114, "Heat", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x115, "Pull station", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x116, "Duct", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x117, "Flame", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x118, "Near alarm", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x120, "Panic", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x121, "Duress", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x122, "Silent", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x123, "Audible", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x124, "Duress - Access granted", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x125, "Duress - Egress granted", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x130, "Burglary", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x131, "Perimeter", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x132, "Interior", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x133, "24 hour (safe)", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x134, "Entry/Exit", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x135, "Day/Night", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x136, "Outdoor", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x137, "Tamper", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x138, "Near alarm", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x139, "Intrusion verifier", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x140, "General alarm", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x141, "Polling loop open", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x142, "Polling loop short", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x143, "Expansion module failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x144, "Sensor tamper", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x145, "Expansion module tamper", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x146, "Silent burglary", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x147, "Sensor supervision failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x150, "24 hour non-burglary", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x151, "Gas detected", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x152, "Refrigeration", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x153, "Loss of heat", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x154, "Water leakage", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x155, "Foil break", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x156, "Day trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x157, "Low bottled gas level", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x158, "High temp", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x159, "Low temp", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x161, "Loss of air flow", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x162, "Carbon monoxide detected", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x163, "Tank level", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x200, "Fire supervisory", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x201, "Low water pressure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x202, "Low CO2", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x203, "Gate valve sensor", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x204, "Low water level", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x205, "Pump activated", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x206, "Pump failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x300, "System trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x301, "AC loss", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x302, "Low system battery", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x303, "RAM checksum bad", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x304, "ROM checksum bad", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x305, "System reset", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x306, "Panel programming changed", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x307, "Self-test failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x308, "System shutdown", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x309, "Battery test failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x310, "Ground fault", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x311, "Battery missing/dead", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x312, "Power supply overcurrent", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x313, "Engineer reset", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x320, "Sounder/relay", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x321, "Bell 1", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x322, "Bell 2", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x323, "Alarm relay", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x324, "Trouble relay", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x325, "Reversing relay", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x326, "Notification appliance ckt. #3", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x327, "Notification appliance ckt. #4", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x330, "System peripheral trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x331, "Polling loop open", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x332, "Polling loop short", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x333, "Expansion module failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x334, "Repeater failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x335, "Local printer out of paper", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x336, "Local printer failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x337, "Exp. module DC loss", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x338, "Exp. module low battery", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x339, "Exp. module reset", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x341, "Exp. module tamper", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x342, "Exp. module AC loss", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x343, "Exp. module self-test fail", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x344, "RF receiver jam detect", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x350, "Communication trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x351, "Telco 1 fault", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x352, "Telco 2 fault", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x353, "Long range radio transmitter fault", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x354, "Failure to communicate event", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x355, "Loss of radio supervision", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x356, "Loss of central polling", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x357, "Long range radio VSWR problem", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x370, "Protection loop", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x371, "Protection loop open", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x372, "Protection loop short", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x373, "Fire trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x374, "Exit error alarm (zone)", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x375, "Panic zone trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x376, "Hold-up zone trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x377, "Swinger trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x378, "Cross-zone trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x380, "Sensor trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x381, "Loss of supervision - RF", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x382, "Loss of supervision - RPM", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x383, "Sensor tamper", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x384, "RF low battery", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x385, "Smoke detector high sensitivity", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x386, "Smoke detector low sensitivity", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x387, "Intrusion detector high sensitivity", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x388, "Intrusion detector low sensitivity", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x389, "Sensor self-test failure", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x391, "Sensor Watch trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x392, "Drift compensation error", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x393, "Maintenance alert", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x400, "Open/Close", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x401, "O/C by user", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x402, "Group O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x403, "Automatic O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x404, "Late to O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x405, "Deferred O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x406, "Cancel", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x407, "Remote arm/disarm", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x408, "Quick arm", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x409, "Keyswitch O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x441, "Armed STAY", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x442, "Keyswitch Armed STAY", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x450, "Exception O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x451, "Early O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x452, "Late O/C", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x453, "Failed to open", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x454, "Failed to close", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x455, "Auto-arm failed", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x456, "Partial arm", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x457, "Exit error (user)", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x458, "User on Premises", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x459, "Recent close", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x461, "Wrong code entry", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x462, "Legal code entry", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x463, "Re-arm after alarm", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x464, "Auto-arm time extended", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x465, "Panic alarm reset", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x466, "Service on/off premises", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x411, "Callback request made", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x412, "Successful download/access", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x413, "Unsuccessful access", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x414, "System shutdown command received", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x415, "Dialer shutdown command received", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x416, "Successful Upload", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x421, "Access denied", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x422, "Access report by user", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x423, "Forced Access", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x424, "Egress Denied", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x425, "Egress Granted", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x426, "Access Door propped open", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x427, "Access point door status monitor trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x428, "Access point request to exit trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x429, "Access program mode entry", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x430, "Access program mode exit", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x431, "Access threat level change", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x432, "Access relay/trigger fail", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x433, "Access RTE shunt", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x434, "Access DSM shunt", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x501, "Access reader disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x520, "Sounder/Relay disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x521, "Bell 1 disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x522, "Bell 2 disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x523, "Alarm relay disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x524, "Trouble relay disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x525, "Reversing relay disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x526, "Notification appliance ckt. #3 disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x527, "Notification appliance ckt. #4 disable", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x531, "Module added", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x532, "Module removed", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x551, "Dialer disabled", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x552, "Radio transmitter disabled", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x553, "Remote upload/download disabled", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x570, "Zone/Sensor bypass", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x571, "Fire bypass", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x572, "24 hour zone bypass", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x573, "Burg. bypass", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x574, "Group bypass", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x575, "Swinger bypass", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x576, "Access zone shunt", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x577, "Access point bypass", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x601, "Manual trigger test report", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x602, "Periodic test report", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x603, "Periodic RF transmission", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x604, "Fire test", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x605, "Status report to follow", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x606, "Listen-in to follow", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x607, "Walk test mode", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x608, "Periodic test - system trouble present", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x609, "Video transmitter active", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x611, "Point tested OK", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x612, "Point not tested", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x613, "Intrusion zone walk tested", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x614, "Fire zone walk tested", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x615, "Panic zone walk tested", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x616, "Service request", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x621, "Event log reset", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x622, "Event log 50% full", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x623, "Event log 90% full", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x624, "Event log overflow", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x625, "Time/Date reset", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x626, "Time/Date inaccurate", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x627, "Program mode entry", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x628, "Program mode exit", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x629, "32 hour event log marker", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x630, "Schedule change", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x631, "Exception schedule change", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x632, "Access schedule change", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x641, "Senior watch trouble", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x642, "Latch-key supervision", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x651, "Reserved for Ademco use", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x652, "Reserved for Ademco use", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x653, "Reserved for Ademco use", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x654, "System inactivity", ADEMCO_CONTACTID_DATA_IS_ZONE}, + {0x900, "Download abort", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x901, "Download start/end", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x902, "Download interrupted", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x910, "Auto-close with bypass", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x911, "Bypass closing", ADEMCO_CONTACTID_DATA_IS_USER}, + {0x999, "32 hour no read of event log", ADEMCO_CONTACTID_DATA_IS_USER}, + {-1, "???"} +}; + +#if defined(SPANDSP_USE_FIXED_POINT) +#define GOERTZEL_SAMPLES_PER_BLOCK 55 /* We need to detect over a +-5% range */ +#define DETECTION_THRESHOLD 16439 /* -42dBm0 [((GOERTZEL_SAMPLES_PER_BLOCK*GOERTZEL_SAMPLES_PER_BLOCK*32768.0/(1.4142*128.0))*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */ +#define TONE_TWIST 4 /* 6dB */ +#define TONE_TO_TOTAL_ENERGY 64 /* -3dB */ +#else +#define GOERTZEL_SAMPLES_PER_BLOCK 55 /* We need to detect over a +-5% range */ +#define DETECTION_THRESHOLD 2104205.6f /* -42dBm0 [((GOERTZEL_SAMPLES_PER_BLOCK*GOERTZEL_SAMPLES_PER_BLOCK*32768.0/1.4142)*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */ +#define TONE_TWIST 3.981f /* 6dB */ +#define TONE_TO_TOTAL_ENERGY 1.995f /* 3dB */ +#endif + +static goertzel_descriptor_t tone_1400_desc; +static goertzel_descriptor_t tone_2300_desc; + +SPAN_DECLARE(int) encode_msg(char buf[], const ademco_contactid_report_t *report) +{ + char *s; + int sum; + int x; + static const char remap[] = {'D', '*', '#', 'A', 'B', 'C'}; + + sprintf(buf, "%04X%02X%1X%03X%02X%03X", report->acct, report->mt, report->q, report->xyz, report->gg, report->ccc); + for (sum = 0, s = buf; *s; s++) + { + if (*s == 'A') + return -1; + if (*s > '9') + { + x = *s - ('A' - 10); + /* Remap the Ademco B-F digits to normal DTMF *#ABC digits */ + *s = remap[x - 10]; + } + else + { + x = *s - '0'; + if (x == 0) + x = 10; + } + sum += x; + } + sum = ((sum + 15)/15)*15 - sum; + if (sum == 0) + sum = 'C'; + else if (sum <= 9) + sum += '0'; + else + sum = remap[sum - 10]; + *s++ = sum; + *s = '\0'; + return s - buf; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) decode_msg(ademco_contactid_report_t *report, const char buf[]) +{ + const char *s; + char *t; + int sum; + int x; + char buf2[20]; + + /* We need to remap normal DTMF (0-0, *, #, A-D) to Ademco's psuedo-hex (0-0, B-F, nothing for A) + and calculate the checksum */ + for (sum = 0, s = buf, t = buf2; *s; s++, t++) + { + x = *s; + switch (x) + { + case '*': + x = 'B'; + break; + case '#': + x = 'C'; + break; + case 'A': + x = 'D'; + break; + case 'B': + x = 'E'; + break; + case 'C': + x = 'F'; + break; + case 'D': + /* This should not happen in the Ademco protocol */ + x = 'A'; + break; + default: + x = *s; + break; + } + *t = x; + if (x > '9') + { + x -= ('B' - 11); + } + else + { + if (x == '0') + x = 10; + else + x -= '0'; + } + sum += x; + } + *t = '\0'; + if (sum%15 != 0) + return -1; + if (sscanf(buf2, "%04x%02x%1x%03x%02x%03x", &report->acct, &report->mt, &report->q, &report->xyz, &report->gg, &report->ccc) != 6) + return -1; + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(const char *) ademco_contactid_msg_qualifier_to_str(int q) +{ + switch (q) + { + case ADEMCO_CONTACTID_QUALIFIER_NEW_EVENT: + return "New event"; + case ADEMCO_CONTACTID_QUALIFIER_NEW_RESTORE: + return "New restore"; + case ADEMCO_CONTACTID_QUALIFIER_STATUS_REPORT: + return "Status report"; + } + return "???"; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(const char *) ademco_contactid_event_to_str(int xyz) +{ + int entry; + + for (entry = 0; ademco_codes[entry].code >= 0; entry++) + { + if (xyz == ademco_codes[entry].code) + return ademco_codes[entry].name; + } + return "???"; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_receiver_log_msg(ademco_contactid_receiver_state_t *s, const ademco_contactid_report_t *report) +{ + const char *t; + + span_log(&s->logging, SPAN_LOG_FLOW, "Ademco Contact ID message:\n"); + span_log(&s->logging, SPAN_LOG_FLOW, " Account %X\n", report->acct); + switch (report->mt) + { + case ADEMCO_CONTACTID_MESSAGE_TYPE_18: + case ADEMCO_CONTACTID_MESSAGE_TYPE_98: + t = "Contact ID"; + break; + default: + t = "???"; + break; + } + span_log(&s->logging, SPAN_LOG_FLOW, " Message type %s (%X)\n", t, report->mt); + t = ademco_contactid_msg_qualifier_to_str(report->q); + span_log(&s->logging, SPAN_LOG_FLOW, " Qualifier %s (%X)\n", t, report->q); + t = ademco_contactid_event_to_str(report->xyz); + span_log(&s->logging, SPAN_LOG_FLOW, " Event %s (%X)\n", t, report->xyz); + span_log(&s->logging, SPAN_LOG_FLOW, " Group/partition %X\n", report->gg); + span_log(&s->logging, SPAN_LOG_FLOW, " User/Zone information %X\n", report->ccc); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_receiver_tx(ademco_contactid_receiver_state_t *s, int16_t amp[], int max_samples) +{ + int i; + int samples; + + switch (s->step) + { + case 0: + samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; + vec_zeroi16(amp, samples); + s->remaining_samples -= samples; + if (s->remaining_samples > 0) + return samples; + span_log(&s->logging, SPAN_LOG_FLOW, "Initial silence finished\n"); + s->step++; + s->tone_phase_rate = dds_phase_rate(1400.0); + s->tone_level = dds_scaling_dbm0(-11); + s->tone_phase = 0; + s->remaining_samples = ms_to_samples(100); + return samples; + case 1: + samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; + for (i = 0; i < samples; i++) + amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->tone_level, 0); + s->remaining_samples -= samples; + if (s->remaining_samples > 0) + return samples; + span_log(&s->logging, SPAN_LOG_FLOW, "1400Hz tone finished\n"); + s->step++; + s->remaining_samples = ms_to_samples(100); + return samples; + case 2: + samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; + vec_zeroi16(amp, samples); + s->remaining_samples -= samples; + if (s->remaining_samples > 0) + return samples; + span_log(&s->logging, SPAN_LOG_FLOW, "Second silence finished\n"); + s->step++; + s->tone_phase_rate = dds_phase_rate(2300.0); + s->tone_level = dds_scaling_dbm0(-11); + s->tone_phase = 0; + s->remaining_samples = ms_to_samples(100); + return samples; + case 3: + samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; + for (i = 0; i < samples; i++) + amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->tone_level, 0); + s->remaining_samples -= samples; + if (s->remaining_samples > 0) + return samples; + span_log(&s->logging, SPAN_LOG_FLOW, "2300Hz tone finished\n"); + s->step++; + s->remaining_samples = ms_to_samples(100); + return samples; + case 4: + /* Idle here, waiting for a response */ + return 0; + case 5: + samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; + vec_zeroi16(amp, samples); + s->remaining_samples -= samples; + if (s->remaining_samples > 0) + return samples; + span_log(&s->logging, SPAN_LOG_FLOW, "Sending kissoff\n"); + s->step++; + s->tone_phase_rate = dds_phase_rate(1400.0); + s->tone_level = dds_scaling_dbm0(-11); + s->tone_phase = 0; + s->remaining_samples = ms_to_samples(850); + return samples; + case 6: + samples = (s->remaining_samples > max_samples) ? max_samples : s->remaining_samples; + for (i = 0; i < samples; i++) + amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->tone_level, 0); + s->remaining_samples -= samples; + if (s->remaining_samples > 0) + return samples; + span_log(&s->logging, SPAN_LOG_FLOW, "1400Hz tone finished\n"); + s->step = 4; + s->remaining_samples = ms_to_samples(100); + return samples; + } + return max_samples; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_receiver_rx(ademco_contactid_receiver_state_t *s, const int16_t amp[], int samples) +{ + return dtmf_rx(&s->dtmf, amp, samples); +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_receiver_fillin(ademco_contactid_receiver_state_t *s, int samples) +{ + return dtmf_rx_fillin(&s->dtmf, samples); +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(logging_state_t *) ademco_contactid_receiver_get_logging_state(ademco_contactid_receiver_state_t *s) +{ + return &s->logging; +} +/*- End of function --------------------------------------------------------*/ + +static void dtmf_digit_delivery(void *user_data, const char *digits, int len) +{ + ademco_contactid_receiver_state_t *s; + ademco_contactid_report_t report; + + s = (ademco_contactid_receiver_state_t *) user_data; + memcpy(&s->rx_digits[s->rx_digits_len], digits, len); + s->rx_digits_len += len; + if (s->rx_digits_len == 16) + { + s->rx_digits[16] = '\0'; + if (decode_msg(&report, s->rx_digits) == 0) + { + ademco_contactid_receiver_log_msg(s, &report); + if (s->callback) + s->callback(s->callback_user_data, &report); + s->step++; + } + s->rx_digits_len = 0; + } +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(void) ademco_contactid_receiver_set_realtime_callback(ademco_contactid_receiver_state_t *s, + ademco_contactid_report_func_t callback, + void *user_data) +{ + s->callback = callback; + s->callback_user_data = user_data; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(ademco_contactid_receiver_state_t *) ademco_contactid_receiver_init(ademco_contactid_receiver_state_t *s, + ademco_contactid_report_func_t callback, + void *user_data) +{ + if (s == NULL) + { + if ((s = (ademco_contactid_receiver_state_t *) malloc(sizeof (*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + span_log_init(&s->logging, SPAN_LOG_NONE, NULL); + span_log_set_protocol(&s->logging, "Ademco"); + + dtmf_rx_init(&s->dtmf, dtmf_digit_delivery, (void *) s); + s->rx_digits_len = 0; + + s->callback = callback; + s->callback_user_data = user_data; + + s->step = 0; + s->remaining_samples = ms_to_samples(500); + return s; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_receiver_release(ademco_contactid_receiver_state_t *s) +{ + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_receiver_free(ademco_contactid_receiver_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_sender_tx(ademco_contactid_sender_state_t *s, int16_t amp[], int max_samples) +{ + int sample; + int samples; + + for (sample = 0; sample < max_samples; sample += samples) + { + switch (s->step) + { + case 0: + if (!s->clear_to_send) + return 0; + s->clear_to_send = FALSE; + s->step++; + s->remaining_samples = ms_to_samples(250); + /* Fall through */ + case 1: + samples = (s->remaining_samples > (max_samples - sample)) ? (max_samples - sample) : s->remaining_samples; + vec_zeroi16(&[sample], samples); + s->remaining_samples -= samples; + if (s->remaining_samples > 0) + return samples; + span_log(&s->logging, SPAN_LOG_FLOW, "Pre-send silence finished\n"); + s->step++; + break; + case 2: + samples = dtmf_tx(&s->dtmf, &[sample], max_samples - sample); + if (samples == 0) + { + s->clear_to_send = FALSE; + s->step = 0; + return sample; + } + break; + default: + return sample; + } + } + return sample; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_sender_rx(ademco_contactid_sender_state_t *s, const int16_t amp[], int samples) +{ +#if defined(SPANDSP_USE_FIXED_POINT) + int32_t energy_1400; + int32_t energy_2300; + int16_t xamp; +#else + float energy_1400; + float energy_2300; + float xamp; +#endif + int sample; + int limit; + int hit; + int j; + + for (sample = 0; sample < samples; sample = limit) + { + if ((samples - sample) >= (GOERTZEL_SAMPLES_PER_BLOCK - s->current_sample)) + limit = sample + (GOERTZEL_SAMPLES_PER_BLOCK - s->current_sample); + else + limit = samples; + for (j = sample; j < limit; j++) + { + xamp = amp[j]; + xamp = goertzel_preadjust_amp(xamp); +#if defined(SPANDSP_USE_FIXED_POINT) + s->energy += ((int32_t) xamp*xamp); +#else + s->energy += xamp*xamp; +#endif + goertzel_samplex(&s->tone_1400, xamp); + goertzel_samplex(&s->tone_2300, xamp); + } + s->current_sample += (limit - sample); + if (s->current_sample < GOERTZEL_SAMPLES_PER_BLOCK) + continue; + + energy_1400 = goertzel_result(&s->tone_1400); + energy_2300 = goertzel_result(&s->tone_2300); + hit = 0; + if (energy_1400 > DETECTION_THRESHOLD || energy_2300 > DETECTION_THRESHOLD) + { + if (energy_1400 > energy_2300) + { + if (energy_1400 > TONE_TO_TOTAL_ENERGY*s->energy) + hit = 1; + } + else + { + if (energy_2300 > TONE_TO_TOTAL_ENERGY*s->energy) + hit = 2; + } + } + if (hit != s->in_tone && hit == s->last_hit) + { + /* We have two successive indications that something has changed to a + specific new state. */ + switch (s->tone_state) + { + case 0: + if (hit == 1) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Receiving initial 1400Hz\n"); + s->in_tone = hit; + s->tone_state = 1; + s->duration = 0; + } + break; + case 1: + /* We are looking for a burst of 1400Hz which is 100ms +- 5% long */ + if (hit == 0) + { + if (s->duration < ms_to_samples(70) || s->duration > ms_to_samples(130)) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Bad initial 1400Hz tone duration\n"); + s->tone_state = 0; + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Received 1400Hz tone\n"); + s->tone_state = 2; + } + s->in_tone = hit; + s->duration = 0; + } + break; + case 2: + /* We are looking for 100ms +-5% of silence after the 1400Hz tone */ + if (s->duration < ms_to_samples(70) || s->duration > ms_to_samples(130)) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Bad silence length\n"); + s->tone_state = 0; + s->in_tone = hit; + } + else if (hit == 2) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Received silence\n"); + s->tone_state = 3; + s->in_tone = hit; + } + else + { + s->tone_state = 0; + s->in_tone = 0; + } + s->duration = 0; + break; + case 3: + /* We are looking for a burst of 2300Hz which is 100ms +- 5% long */ + if (hit == 0) + { + if (s->duration < ms_to_samples(70) || s->duration > ms_to_samples(130)) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Bad initial 2300Hz tone duration\n"); + s->tone_state = 0; + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Received 2300Hz\n"); + if (s->callback) + s->callback(s->callback_user_data, -1, 0, 0); + s->tone_state = 4; + /* Release the transmit side, and it will time the 250ms post tone delay */ + s->clear_to_send = TRUE; + s->tries = 0; + if (s->tx_digits_len) + s->timer = ms_to_samples(3000); + } + s->in_tone = hit; + s->duration = 0; + } + break; + case 4: + if (hit == 1) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Receiving kissoff\n"); + s->tone_state = 5; + s->in_tone = hit; + s->duration = 0; + } + break; + case 5: + if (hit == 0) + { + s->busy = FALSE; + if (s->duration < ms_to_samples(400) || s->duration > ms_to_samples(1500)) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Bad kissoff duration %d\n", s->duration); + if (++s->tries < 4) + { + dtmf_tx_put(&s->dtmf, s->tx_digits, s->tx_digits_len); + s->timer = ms_to_samples(3000); + s->tone_state = 4; + } + else + { + s->timer = 0; + if (s->callback) + s->callback(s->callback_user_data, FALSE, 0, 0); + } + } + else + { + span_log(&s->logging, SPAN_LOG_FLOW, "Received good kissoff\n"); + s->clear_to_send = TRUE; + s->tx_digits_len = 0; + if (s->callback) + s->callback(s->callback_user_data, TRUE, 0, 0); + s->tone_state = 4; + s->clear_to_send = TRUE; + s->tries = 0; + if (s->tx_digits_len) + s->timer = ms_to_samples(3000); + } + s->in_tone = hit; + s->duration = 0; + } + break; + } + } + s->last_hit = hit; + s->duration += GOERTZEL_SAMPLES_PER_BLOCK; + if (s->timer > 0) + { + s->timer -= GOERTZEL_SAMPLES_PER_BLOCK; + if (s->timer <= 0) + { + span_log(&s->logging, SPAN_LOG_FLOW, "Timer expired\n"); + if (s->tone_state == 4 && s->tx_digits_len) + { + if (++s->tries < 4) + { + dtmf_tx_put(&s->dtmf, s->tx_digits, s->tx_digits_len); + s->timer = ms_to_samples(3000); + } + else + { + s->timer = 0; + if (s->callback) + s->callback(s->callback_user_data, FALSE, 0, 0); + } + } + } + } + s->energy = 0; + s->current_sample = 0; + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_sender_fillin(ademco_contactid_sender_state_t *s, int samples) +{ + /* Restart any Goertzel and energy gathering operation we might be in the middle of. */ + goertzel_reset(&s->tone_1400); + goertzel_reset(&s->tone_2300); +#if defined(SPANDSP_USE_FIXED_POINT) + s->energy = 0; +#else + s->energy = 0.0f; +#endif + s->current_sample = 0; + /* Don't update the hit detection. Pretend it never happened. */ + /* TODO: Surely we can be cleverer than this. */ + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_sender_put(ademco_contactid_sender_state_t *s, const ademco_contactid_report_t *report) +{ + if (s->busy) + return -1; + if ((s->tx_digits_len = encode_msg(s->tx_digits, report)) < 0) + return -1; + s->busy = TRUE; + return dtmf_tx_put(&s->dtmf, s->tx_digits, s->tx_digits_len); +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(logging_state_t *) ademco_contactid_sender_get_logging_state(ademco_contactid_sender_state_t *s) +{ + return &s->logging; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(void) ademco_contactid_sender_set_realtime_callback(ademco_contactid_sender_state_t *s, + tone_report_func_t callback, + void *user_data) +{ + s->callback = callback; + s->callback_user_data = user_data; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(ademco_contactid_sender_state_t *) ademco_contactid_sender_init(ademco_contactid_sender_state_t *s, + tone_report_func_t callback, + void *user_data) +{ + static int initialised = FALSE; + + if (s == NULL) + { + if ((s = (ademco_contactid_sender_state_t *) malloc(sizeof (*s))) == NULL) + return NULL; + } + memset(s, 0, sizeof(*s)); + span_log_init(&s->logging, SPAN_LOG_NONE, NULL); + span_log_set_protocol(&s->logging, "Ademco"); + + if (!initialised) + { + make_goertzel_descriptor(&tone_1400_desc, 1400.0f, GOERTZEL_SAMPLES_PER_BLOCK); + make_goertzel_descriptor(&tone_2300_desc, 2300.0f, GOERTZEL_SAMPLES_PER_BLOCK); + } + goertzel_init(&s->tone_1400, &tone_1400_desc); + goertzel_init(&s->tone_2300, &tone_2300_desc); + s->current_sample = 0; + + s->callback = callback; + s->callback_user_data = user_data; + + s->step = 0; + s->remaining_samples = ms_to_samples(100); + dtmf_tx_init(&s->dtmf); + /* The specified timing is 50-60ms on, 50-60ms off */ + dtmf_tx_set_timing(&s->dtmf, 55, 55); + return s; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_sender_release(ademco_contactid_sender_state_t *s) +{ + return 0; +} +/*- End of function --------------------------------------------------------*/ + +SPAN_DECLARE(int) ademco_contactid_sender_free(ademco_contactid_sender_state_t *s) +{ + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/libspandsp.2010.vcxproj b/libs/spandsp/src/libspandsp.2010.vcxproj index bb2ae97878..393a1b6d45 100644 --- a/libs/spandsp/src/libspandsp.2010.vcxproj +++ b/libs/spandsp/src/libspandsp.2010.vcxproj @@ -155,6 +155,7 @@ </Link> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="ademco_contactid.c" /> <ClCompile Include="adsi.c" /> <ClCompile Include="async.c" /> <ClCompile Include="at_interpreter.c" /> @@ -239,6 +240,7 @@ <ClCompile Include="msvc\gettimeofday.c" /> </ItemGroup> <ItemGroup> + <ClInclude Include="spandsp\ademco_contactid.h" /> <ClInclude Include="spandsp\adsi.h" /> <ClInclude Include="spandsp\async.h" /> <ClInclude Include="spandsp\arctan2.h" /> @@ -279,6 +281,7 @@ <ClInclude Include="spandsp\playout.h" /> <ClInclude Include="spandsp\plc.h" /> <ClInclude Include="spandsp\power_meter.h" /> + <ClInclude Include="spandsp\private\ademco_contactid.h" /> <ClInclude Include="spandsp\queue.h" /> <ClInclude Include="spandsp\saturated.h" /> <ClInclude Include="spandsp\schedule.h" /> diff --git a/libs/spandsp/src/libspandsp.2010.vcxproj.filters b/libs/spandsp/src/libspandsp.2010.vcxproj.filters index 2a6d60a9d4..c75936a851 100644 --- a/libs/spandsp/src/libspandsp.2010.vcxproj.filters +++ b/libs/spandsp/src/libspandsp.2010.vcxproj.filters @@ -253,6 +253,12 @@ <ClCompile Include="msvc\gettimeofday.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="timezone.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ademco_contactid.c"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="spandsp\adsi.h"> @@ -660,6 +666,14 @@ <ClInclude Include="spandsp.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="spandsp\t4_t6_decode.h" /> + <ClInclude Include="spandsp\t4_t6_encode.h" /> + <ClInclude Include="spandsp\ademco_contactid.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="spandsp\private\ademco_contactid.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <CustomBuild Include="msvc\spandsp.h" /> diff --git a/libs/spandsp/src/msvc/spandsp.h b/libs/spandsp/src/msvc/spandsp.h index 95ee8bf11b..ba0bc280d6 100644 --- a/libs/spandsp/src/msvc/spandsp.h +++ b/libs/spandsp/src/msvc/spandsp.h @@ -118,6 +118,7 @@ #include <spandsp/t38_terminal.h> #include <spandsp/t31.h> #include <spandsp/adsi.h> +#include <spandsp/ademco_contactid.h> #include <spandsp/oki_adpcm.h> #include <spandsp/ima_adpcm.h> #include <spandsp/g722.h> diff --git a/libs/spandsp/src/sig_tone.c b/libs/spandsp/src/sig_tone.c index 6aaecdb211..369218438c 100644 --- a/libs/spandsp/src/sig_tone.c +++ b/libs/spandsp/src/sig_tone.c @@ -647,9 +647,9 @@ SPAN_DECLARE(sig_tone_rx_state_t *) sig_tone_rx_init(sig_tone_rx_state_t *s, int } memset(s, 0, sizeof(*s)); #if !defined(SPANDSP_USE_FIXED_POINT) - for (j = 0; j < 2; j++) + for (j = 0; j < 3; j++) { - for (i = 0; i < 3; i++) + for (i = 0; i < 2; i++) { s->tone[j].notch_z1[i] = 0.0f; s->tone[j].notch_z2[i] = 0.0f; diff --git a/libs/spandsp/src/spandsp.h.in b/libs/spandsp/src/spandsp.h.in index acb8a18ed5..e3c0d4f477 100644 --- a/libs/spandsp/src/spandsp.h.in +++ b/libs/spandsp/src/spandsp.h.in @@ -33,15 +33,19 @@ @SPANDSP_USE_EXPORT_CAPABILITY@ +@SPANDSP_SUPPORT_T42@ +@SPANDSP_SUPPORT_T43@ +@SPANDSP_SUPPORT_T85@ +@SPANDSP_SUPPORT_V34@ + #include <stdlib.h> @INSERT_INTTYPES_HEADER@ #include <string.h> #include <limits.h> #include <time.h> @INSERT_MATH_HEADER@ -#if !defined(SPANDSP_NO_TIFF) #include <tiffio.h> -#endif + #include <spandsp/telephony.h> #include <spandsp/fast_convert.h> #include <spandsp/logging.h> @@ -106,6 +110,8 @@ #include <spandsp/t4_t6_encode.h> /*#include <spandsp/t81_t82_arith_coding.h>*/ /*#include <spandsp/t85.h>*/ +/*#include <spandsp/t42.h>*/ +/*#include <spandsp/t43.h>*/ #include <spandsp/t30.h> #include <spandsp/t30_api.h> #include <spandsp/t30_fcf.h> @@ -120,6 +126,7 @@ #include <spandsp/t38_terminal.h> #include <spandsp/t31.h> #include <spandsp/adsi.h> +#include <spandsp/ademco_contactid.h> #include <spandsp/oki_adpcm.h> #include <spandsp/ima_adpcm.h> #include <spandsp/g722.h> diff --git a/libs/spandsp/src/spandsp/ademco_contactid.h b/libs/spandsp/src/spandsp/ademco_contactid.h new file mode 100644 index 0000000000..8e42d70256 --- /dev/null +++ b/libs/spandsp/src/spandsp/ademco_contactid.h @@ -0,0 +1,365 @@ +/* + * SpanDSP a series of DSP components for telephony + * + * ademco_contactid.h Ademco ContactID alarm protocol + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2012 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \file */ + +#if !defined(_SPANDSP_ADEMCO_CONTACTID_H_) +#define _SPANDSP_ADEMCO_CONTACTID_H_ + +enum +{ + ADEMCO_CONTACTID_MESSAGE_TYPE_18 = 0x18, + ADEMCO_CONTACTID_MESSAGE_TYPE_98 = 0x98 +}; + +enum +{ + ADEMCO_CONTACTID_QUALIFIER_NEW_EVENT = 1, + ADEMCO_CONTACTID_QUALIFIER_NEW_RESTORE = 3, + ADEMCO_CONTACTID_QUALIFIER_STATUS_REPORT = 6 +}; + +enum +{ + ADEMCO_CONTACTID_DATA_IS_ZONE = 0, + ADEMCO_CONTACTID_DATA_IS_USER = 1 +}; + +enum +{ + ADEMCO_CONTACTID_MEDICAL = 0x100, + ADEMCO_CONTACTID_PERSONAL_EMERGENCY = 0x101, + ADEMCO_CONTACTID_FAIL_TO_REPORT_IN = 0x102, + ADEMCO_CONTACTID_FIRE = 0x110, + ADEMCO_CONTACTID_SMOKE = 0x111, + ADEMCO_CONTACTID_COMBUSTION = 0x112, + ADEMCO_CONTACTID_WATER_FLOW = 0x113, + ADEMCO_CONTACTID_HEAT = 0x114, + ADEMCO_CONTACTID_PULL_STATION = 0x115, + ADEMCO_CONTACTID_DUCT = 0x116, + ADEMCO_CONTACTID_FLAME = 0x117, + ADEMCO_CONTACTID_NEAR_ALARM_A = 0x118, + ADEMCO_CONTACTID_PANIC = 0x120, + ADEMCO_CONTACTID_DURESS = 0x121, + ADEMCO_CONTACTID_SILENT = 0x122, + ADEMCO_CONTACTID_AUDIBLE = 0x123, + ADEMCO_CONTACTID_DURESS_ACCESS_GRANTED = 0x124, + ADEMCO_CONTACTID_DURESS_EGRESS_GRANTED = 0x125, + ADEMCO_CONTACTID_BURGLARY = 0x130, + ADEMCO_CONTACTID_PERIMETER = 0x131, + ADEMCO_CONTACTID_INTERIOR = 0x132, + ADEMCO_CONTACTID_24_HOUR_SAFE = 0x133, + ADEMCO_CONTACTID_ENTRY_EXIT = 0x134, + ADEMCO_CONTACTID_DAY_NIGHT = 0x135, + ADEMCO_CONTACTID_OUTDOOR = 0x136, + ADEMCO_CONTACTID_TAMPER = 0x137, + ADEMCO_CONTACTID_NEAR_ALARM_B = 0x138, + ADEMCO_CONTACTID_INTRUSION_VERIFIER = 0x139, + ADEMCO_CONTACTID_GENERAL_ALARM = 0x140, + ADEMCO_CONTACTID_POLLING_LOOP_OPEN_A = 0x141, + ADEMCO_CONTACTID_POLLING_LOOP_SHORT_A = 0x142, + ADEMCO_CONTACTID_EXPANSION_MODULE_FAILURE_A = 0x143, + ADEMCO_CONTACTID_SENSOR_TAMPER_A = 0x144, + ADEMCO_CONTACTID_EXPANSION_MODULE_TAMPER = 0x145, + ADEMCO_CONTACTID_SILENT_BURGLARY = 0x146, + ADEMCO_CONTACTID_SENSOR_SUPERVISION_FAILURE = 0x147, + ADEMCO_CONTACTID_24_HOUR_NONBURGLARY = 0x150, + ADEMCO_CONTACTID_GAS_DETECTED = 0x151, + ADEMCO_CONTACTID_REFRIGERATION = 0x152, + ADEMCO_CONTACTID_LOSS_OF_HEAT = 0x153, + ADEMCO_CONTACTID_WATER_LEAKAGE = 0x154, + ADEMCO_CONTACTID_FOIL_BREAK = 0x155, + ADEMCO_CONTACTID_DAY_TROUBLE = 0x156, + ADEMCO_CONTACTID_LOW_BOTTLED_GAS_LEVEL = 0x157, + ADEMCO_CONTACTID_HIGH_TEMP = 0x158, + ADEMCO_CONTACTID_LOW_TEMP = 0x159, + ADEMCO_CONTACTID_LOSS_OF_AIR_FLOW = 0x161, + ADEMCO_CONTACTID_CARBON_MONOXIDE_DETECTED = 0x162, + ADEMCO_CONTACTID_TANK_LEVEL = 0x163, + ADEMCO_CONTACTID_FIRE_SUPERVISORY = 0x200, + ADEMCO_CONTACTID_LOW_WATER_PRESSURE = 0x201, + ADEMCO_CONTACTID_LOW_CO2 = 0x202, + ADEMCO_CONTACTID_GATE_VALVE_SENSOR = 0x203, + ADEMCO_CONTACTID_LOW_WATER_LEVEL = 0x204, + ADEMCO_CONTACTID_PUMP_ACTIVATED = 0x205, + ADEMCO_CONTACTID_PUMP_FAILURE = 0x206, + ADEMCO_CONTACTID_SYSTEM_TROUBLE = 0x300, + ADEMCO_CONTACTID_AC_LOSS = 0x301, + ADEMCO_CONTACTID_LOW_SYSTEM_BATTERY = 0x302, + ADEMCO_CONTACTID_RAM_CHECKSUM_BAD = 0x303, + ADEMCO_CONTACTID_ROM_CHECKSUM_BAD = 0x304, + ADEMCO_CONTACTID_SYSTEM_RESET = 0x305, + ADEMCO_CONTACTID_PANEL_PROGRAMMING_CHANGED = 0x306, + ADEMCO_CONTACTID_SELFTEST_FAILURE = 0x307, + ADEMCO_CONTACTID_SYSTEM_SHUTDOWN = 0x308, + ADEMCO_CONTACTID_BATTERY_TEST_FAILURE = 0x309, + ADEMCO_CONTACTID_GROUND_FAULT = 0x310, + ADEMCO_CONTACTID_BATTERY_MISSING_DEAD = 0x311, + ADEMCO_CONTACTID_POWER_SUPPLY_OVERCURRENT = 0x312, + ADEMCO_CONTACTID_ENGINEER_RESET = 0x313, + ADEMCO_CONTACTID_SOUNDER_RELAY = 0x320, + ADEMCO_CONTACTID_BELL_1 = 0x321, + ADEMCO_CONTACTID_BELL_2 = 0x322, + ADEMCO_CONTACTID_ALARM_RELAY = 0x323, + ADEMCO_CONTACTID_TROUBLE_RELAY = 0x324, + ADEMCO_CONTACTID_REVERSING_RELAY = 0x325, + ADEMCO_CONTACTID_NOTIFICATION_APPLIANCE_CKT_3 = 0x326, + ADEMCO_CONTACTID_NOTIFICATION_APPLIANCE_CKT_4 = 0x327, + ADEMCO_CONTACTID_SYSTEM_PERIPHERAL_TROUBLE = 0x330, + ADEMCO_CONTACTID_POLLING_LOOP_OPEN_B = 0x331, + ADEMCO_CONTACTID_POLLING_LOOP_SHORT_B = 0x332, + ADEMCO_CONTACTID_EXPANSION_MODULE_FAILURE_B = 0x333, + ADEMCO_CONTACTID_REPEATER_FAILURE = 0x334, + ADEMCO_CONTACTID_LOCAL_PRINTER_OUT_OF_PAPER = 0x335, + ADEMCO_CONTACTID_LOCAL_PRINTER_FAILURE = 0x336, + ADEMCO_CONTACTID_EXP_MODULE_DC_LOSS = 0x337, + ADEMCO_CONTACTID_EXP_MODULE_LOW_BATTERY = 0x338, + ADEMCO_CONTACTID_EXP_MODULE_RESET = 0x339, + ADEMCO_CONTACTID_EXP_MODULE_TAMPER = 0x341, + ADEMCO_CONTACTID_EXP_MODULE_AC_LOSS = 0x342, + ADEMCO_CONTACTID_EXP_MODULE_SELFTEST_FAIL = 0x343, + ADEMCO_CONTACTID_RF_RECEIVER_JAM_DETECT = 0x344, + ADEMCO_CONTACTID_COMMUNICATION_TROUBLE = 0x350, + ADEMCO_CONTACTID_TELCO_1_FAULT = 0x351, + ADEMCO_CONTACTID_TELCO_2_FAULT = 0x352, + ADEMCO_CONTACTID_LONG_RANGE_RADIO_TRANSMITTER_FAULT = 0x353, + ADEMCO_CONTACTID_FAILURE_TO_COMMUNICATE_EVENT = 0x354, + ADEMCO_CONTACTID_LOSS_OF_RADIO_SUPERVISION = 0x355, + ADEMCO_CONTACTID_LOSS_OF_CENTRAL_POLLING = 0x356, + ADEMCO_CONTACTID_LONG_RANGE_RADIO_VSWR_PROBLEM = 0x357, + ADEMCO_CONTACTID_PROTECTION_LOOP = 0x370, + ADEMCO_CONTACTID_PROTECTION_LOOP_OPEN = 0x371, + ADEMCO_CONTACTID_PROTECTION_LOOP_SHORT = 0x372, + ADEMCO_CONTACTID_FIRE_TROUBLE = 0x373, + ADEMCO_CONTACTID_EXIT_ERROR_ALARM_ZONE = 0x374, + ADEMCO_CONTACTID_PANIC_ZONE_TROUBLE = 0x375, + ADEMCO_CONTACTID_HOLDUP_ZONE_TROUBLE = 0x376, + ADEMCO_CONTACTID_SWINGER_TROUBLE = 0x377, + ADEMCO_CONTACTID_CROSSZONE_TROUBLE = 0x378, + ADEMCO_CONTACTID_SENSOR_TROUBLE = 0x380, + ADEMCO_CONTACTID_LOSS_OF_SUPERVISION__RF = 0x381, + ADEMCO_CONTACTID_LOSS_OF_SUPERVISION__RPM = 0x382, + ADEMCO_CONTACTID_SENSOR_TAMPER_B = 0x383, + ADEMCO_CONTACTID_RF_LOW_BATTERY = 0x384, + ADEMCO_CONTACTID_SMOKE_DETECTOR_HIGH_SENSITIVITY = 0x385, + ADEMCO_CONTACTID_SMOKE_DETECTOR_LOW_SENSITIVITY = 0x386, + ADEMCO_CONTACTID_INTRUSION_DETECTOR_HIGH_SENSITIVITY = 0x387, + ADEMCO_CONTACTID_INTRUSION_DETECTOR_LOW_SENSITIVITY = 0x388, + ADEMCO_CONTACTID_SENSOR_SELFTEST_FAILURE = 0x389, + ADEMCO_CONTACTID_SENSOR_WATCH_TROUBLE = 0x391, + ADEMCO_CONTACTID_DRIFT_COMPENSATION_ERROR = 0x392, + ADEMCO_CONTACTID_MAINTENANCE_ALERT = 0x393, + ADEMCO_CONTACTID_OPEN_CLOSE = 0x400, + ADEMCO_CONTACTID_OC_BY_USER = 0x401, + ADEMCO_CONTACTID_GROUP_OC = 0x402, + ADEMCO_CONTACTID_AUTOMATIC_OC = 0x403, + ADEMCO_CONTACTID_LATE_TO_OC = 0x404, + ADEMCO_CONTACTID_DEFERRED_OC = 0x405, + ADEMCO_CONTACTID_CANCEL = 0x406, + ADEMCO_CONTACTID_REMOTE_ARM_DISARM = 0x407, + ADEMCO_CONTACTID_QUICK_ARM = 0x408, + ADEMCO_CONTACTID_KEYSWITCH_OC = 0x409, + ADEMCO_CONTACTID_ARMED_STAY = 0x441, + ADEMCO_CONTACTID_KEYSWITCH_ARMED_STAY = 0x442, + ADEMCO_CONTACTID_EXCEPTION_OC = 0x450, + ADEMCO_CONTACTID_EARLY_OC = 0x451, + ADEMCO_CONTACTID_LATE_OC = 0x452, + ADEMCO_CONTACTID_FAILED_TO_OPEN = 0x453, + ADEMCO_CONTACTID_FAILED_TO_CLOSE = 0x454, + ADEMCO_CONTACTID_AUTOARM_FAILED = 0x455, + ADEMCO_CONTACTID_PARTIAL_ARM = 0x456, + ADEMCO_CONTACTID_EXIT_ERROR_USER = 0x457, + ADEMCO_CONTACTID_USER_ON_PREMISES = 0x458, + ADEMCO_CONTACTID_RECENT_CLOSE = 0x459, + ADEMCO_CONTACTID_WRONG_CODE_ENTRY = 0x461, + ADEMCO_CONTACTID_LEGAL_CODE_ENTRY = 0x462, + ADEMCO_CONTACTID_REARM_AFTER_ALARM = 0x463, + ADEMCO_CONTACTID_AUTOARM_TIME_EXTENDED = 0x464, + ADEMCO_CONTACTID_PANIC_ALARM_RESET = 0x465, + ADEMCO_CONTACTID_SERVICE_ON_OFF_PREMISES = 0x466, + ADEMCO_CONTACTID_CALLBACK_REQUEST_MADE = 0x411, + ADEMCO_CONTACTID_SUCCESSFUL_DOWNLOAD_ACCESS = 0x412, + ADEMCO_CONTACTID_UNSUCCESSFUL_ACCESS = 0x413, + ADEMCO_CONTACTID_SYSTEM_SHUTDOWN_COMMAND_RECEIVED = 0x414, + ADEMCO_CONTACTID_DIALER_SHUTDOWN_COMMAND_RECEIVED = 0x415, + ADEMCO_CONTACTID_SUCCESSFUL_UPLOAD = 0x416, + ADEMCO_CONTACTID_ACCESS_DENIED = 0x421, + ADEMCO_CONTACTID_ACCESS_REPORT_BY_USER = 0x422, + ADEMCO_CONTACTID_FORCED_ACCESS = 0x423, + ADEMCO_CONTACTID_EGRESS_DENIED = 0x424, + ADEMCO_CONTACTID_EGRESS_GRANTED = 0x425, + ADEMCO_CONTACTID_ACCESS_DOOR_PROPPED_OPEN = 0x426, + ADEMCO_CONTACTID_ACCESS_POINT_DOOR_STATUS_MONITOR_TROUBLE = 0x427, + ADEMCO_CONTACTID_ACCESS_POINT_REQUEST_TO_EXIT_TROUBLE = 0x428, + ADEMCO_CONTACTID_ACCESS_PROGRAM_MODE_ENTRY = 0x429, + ADEMCO_CONTACTID_ACCESS_PROGRAM_MODE_EXIT = 0x430, + ADEMCO_CONTACTID_ACCESS_THREAT_LEVEL_CHANGE = 0x431, + ADEMCO_CONTACTID_ACCESS_RELAY_TRIGGER_FAIL = 0x432, + ADEMCO_CONTACTID_ACCESS_RTE_SHUNT = 0x433, + ADEMCO_CONTACTID_ACCESS_DSM_SHUNT = 0x434, + ADEMCO_CONTACTID_ACCESS_READER_DISABLE = 0x501, + ADEMCO_CONTACTID_SOUNDER_RELAY_DISABLE = 0x520, + ADEMCO_CONTACTID_BELL_1_DISABLE = 0x521, + ADEMCO_CONTACTID_BELL_2_DISABLE = 0x522, + ADEMCO_CONTACTID_ALARM_RELAY_DISABLE = 0x523, + ADEMCO_CONTACTID_TROUBLE_RELAY_DISABLE = 0x524, + ADEMCO_CONTACTID_REVERSING_RELAY_DISABLE = 0x525, + ADEMCO_CONTACTID_NOTIFICATION_APPLIANCE_CKT_3_DISABLE = 0x526, + ADEMCO_CONTACTID_NOTIFICATION_APPLIANCE_CKT_4_DISABLE = 0x527, + ADEMCO_CONTACTID_MODULE_ADDED = 0x531, + ADEMCO_CONTACTID_MODULE_REMOVED = 0x532, + ADEMCO_CONTACTID_DIALER_DISABLED = 0x551, + ADEMCO_CONTACTID_RADIO_TRANSMITTER_DISABLED = 0x552, + ADEMCO_CONTACTID_REMOTE_UPLOAD_DOWNLOAD_DISABLED = 0x553, + ADEMCO_CONTACTID_ZONE_SENSOR_BYPASS = 0x570, + ADEMCO_CONTACTID_FIRE_BYPASS = 0x571, + ADEMCO_CONTACTID_24_HOUR_ZONE_BYPASS = 0x572, + ADEMCO_CONTACTID_BURG_BYPASS = 0x573, + ADEMCO_CONTACTID_GROUP_BYPASS = 0x574, + ADEMCO_CONTACTID_SWINGER_BYPASS = 0x575, + ADEMCO_CONTACTID_ACCESS_ZONE_SHUNT = 0x576, + ADEMCO_CONTACTID_ACCESS_POINT_BYPASS = 0x577, + ADEMCO_CONTACTID_MANUAL_TRIGGER_TEST_REPORT = 0x601, + ADEMCO_CONTACTID_PERIODIC_TEST_REPORT = 0x602, + ADEMCO_CONTACTID_PERIODIC_RF_TRANSMISSION = 0x603, + ADEMCO_CONTACTID_FIRE_TEST = 0x604, + ADEMCO_CONTACTID_STATUS_REPORT_TO_FOLLOW = 0x605, + ADEMCO_CONTACTID_LISTENIN_TO_FOLLOW = 0x606, + ADEMCO_CONTACTID_WALK_TEST_MODE = 0x607, + ADEMCO_CONTACTID_PERIODIC_TEST__SYSTEM_TROUBLE_PRESENT = 0x608, + ADEMCO_CONTACTID_VIDEO_TRANSMITTER_ACTIVE = 0x609, + ADEMCO_CONTACTID_POINT_TESTED_OK = 0x611, + ADEMCO_CONTACTID_POINT_NOT_TESTED = 0x612, + ADEMCO_CONTACTID_INTRUSION_ZONE_WALK_TESTED = 0x613, + ADEMCO_CONTACTID_FIRE_ZONE_WALK_TESTED = 0x614, + ADEMCO_CONTACTID_PANIC_ZONE_WALK_TESTED = 0x615, + ADEMCO_CONTACTID_SERVICE_REQUEST = 0x616, + ADEMCO_CONTACTID_EVENT_LOG_RESET = 0x621, + ADEMCO_CONTACTID_EVENT_LOG_50PC_FULL = 0x622, + ADEMCO_CONTACTID_EVENT_LOG_90PC_FULL = 0x623, + ADEMCO_CONTACTID_EVENT_LOG_OVERFLOW = 0x624, + ADEMCO_CONTACTID_TIME_DATE_RESET = 0x625, + ADEMCO_CONTACTID_TIME_DATE_INACCURATE = 0x626, + ADEMCO_CONTACTID_PROGRAM_MODE_ENTRY = 0x627, + ADEMCO_CONTACTID_PROGRAM_MODE_EXIT = 0x628, + ADEMCO_CONTACTID_32_HOUR_EVENT_LOG_MARKER = 0x629, + ADEMCO_CONTACTID_SCHEDULE_CHANGE = 0x630, + ADEMCO_CONTACTID_EXCEPTION_SCHEDULE_CHANGE = 0x631, + ADEMCO_CONTACTID_ACCESS_SCHEDULE_CHANGE = 0x632, + ADEMCO_CONTACTID_SENIOR_WATCH_TROUBLE = 0x641, + ADEMCO_CONTACTID_LATCHKEY_SUPERVISION = 0x642, + ADEMCO_CONTACTID_RESERVED_FOR_ADEMCO_USE_1 = 0x651, + ADEMCO_CONTACTID_RESERVED_FOR_ADEMCO_USE_2 = 0x652, + ADEMCO_CONTACTID_RESERVED_FOR_ADEMCO_USE_3 = 0x653, + ADEMCO_CONTACTID_SYSTEM_INACTIVITY = 0x654, + ADEMCO_CONTACTID_DOWNLOAD_ABORT = 0x900, + ADEMCO_CONTACTID_DOWNLOAD_START_END = 0x901, + ADEMCO_CONTACTID_DOWNLOAD_INTERRUPTED = 0x902, + ADEMCO_CONTACTID_AUTOCLOSE_WITH_BYPASS = 0x910, + ADEMCO_CONTACTID_BYPASS_CLOSING = 0x911, + ADEMCO_CONTACTID_32_HOUR_NO_READ_OF_EVENT_LOG = 0x999 +}; + +typedef struct ademco_contactid_sender_state_s ademco_contactid_sender_state_t; + +typedef struct ademco_contactid_receiver_state_s ademco_contactid_receiver_state_t; + +typedef struct +{ + int acct; + int mt; + int q; + int xyz; + int gg; + int ccc; +} ademco_contactid_report_t; + +typedef void (*ademco_contactid_report_func_t)(void *user_data, const ademco_contactid_report_t *report); + +#if defined(__cplusplus) +extern "C" +{ +#endif + +SPAN_DECLARE(const char *) ademco_contactid_msg_qualifier_to_str(int q); + +SPAN_DECLARE(const char *) ademco_contactid_event_to_str(int xyz); + +SPAN_DECLARE(int) encode_msg(char buf[], const ademco_contactid_report_t *report); + +SPAN_DECLARE(int) decode_msg(ademco_contactid_report_t *report, const char buf[]); + +SPAN_DECLARE(int) ademco_contactid_receiver_log_msg(ademco_contactid_receiver_state_t *s, const ademco_contactid_report_t *report); + +SPAN_DECLARE(int) ademco_contactid_receiver_tx(ademco_contactid_receiver_state_t *s, int16_t amp[], int max_samples); + +SPAN_DECLARE(int) ademco_contactid_receiver_rx(ademco_contactid_receiver_state_t *s, const int16_t amp[], int samples); + +SPAN_DECLARE(int) ademco_contactid_receiver_fillin(ademco_contactid_receiver_state_t *s, int samples); + +SPAN_DECLARE(logging_state_t *) ademco_contactid_receiver_get_logging_state(ademco_contactid_receiver_state_t *s); + +SPAN_DECLARE(void) ademco_contactid_receiver_set_realtime_callback(ademco_contactid_receiver_state_t *s, + ademco_contactid_report_func_t callback, + void *user_data); + +SPAN_DECLARE(ademco_contactid_receiver_state_t *) ademco_contactid_receiver_init(ademco_contactid_receiver_state_t *s, + ademco_contactid_report_func_t callback, + void *user_data); + +SPAN_DECLARE(int) ademco_contactid_receiver_release(ademco_contactid_receiver_state_t *s); + +SPAN_DECLARE(int) ademco_contactid_receiver_free(ademco_contactid_receiver_state_t *s); + + + +SPAN_DECLARE(int) ademco_contactid_sender_tx(ademco_contactid_sender_state_t *s, int16_t amp[], int max_samples); + +SPAN_DECLARE(int) ademco_contactid_sender_rx(ademco_contactid_sender_state_t *s, const int16_t amp[], int samples); + +SPAN_DECLARE(int) ademco_contactid_sender_fillin(ademco_contactid_sender_state_t *s, int samples); + +SPAN_DECLARE(int) ademco_contactid_sender_put(ademco_contactid_sender_state_t *s, const ademco_contactid_report_t *report); + +SPAN_DECLARE(logging_state_t *) ademco_contactid_sender_get_logging_state(ademco_contactid_sender_state_t *s); + +SPAN_DECLARE(void) ademco_contactid_sender_set_realtime_callback(ademco_contactid_sender_state_t *s, + tone_report_func_t callback, + void *user_data); + +SPAN_DECLARE(ademco_contactid_sender_state_t *) ademco_contactid_sender_init(ademco_contactid_sender_state_t *s, + tone_report_func_t callback, + void *user_data); + +SPAN_DECLARE(int) ademco_contactid_sender_release(ademco_contactid_sender_state_t *s); + +SPAN_DECLARE(int) ademco_contactid_sender_free(ademco_contactid_sender_state_t *s); + +#if defined(__cplusplus) +} +#endif + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/spandsp/expose.h b/libs/spandsp/src/spandsp/expose.h index ac10084535..75c16f2405 100644 --- a/libs/spandsp/src/spandsp/expose.h +++ b/libs/spandsp/src/spandsp/expose.h @@ -93,6 +93,7 @@ #include <spandsp/private/t31.h> #include <spandsp/private/v18.h> #include <spandsp/private/adsi.h> +#include <spandsp/private/ademco_contactid.h> #endif /*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/spandsp/private/ademco_contactid.h b/libs/spandsp/src/spandsp/private/ademco_contactid.h new file mode 100644 index 0000000000..bada9193a1 --- /dev/null +++ b/libs/spandsp/src/spandsp/private/ademco_contactid.h @@ -0,0 +1,95 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * private/ademco_contactid.h - Ademco ContactID alarm protocol + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2012 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \file */ + +#if !defined(_SPANDSP_PRIVATE_ADEMCO_CONTACTID_H_) +#define _SPANDSP_PRIVATE_ADEMCO_CONTACTID_H_ + +struct ademco_contactid_receiver_state_s +{ + ademco_contactid_report_func_t callback; + void *callback_user_data; + + int step; + int remaining_samples; + uint32_t tone_phase; + int32_t tone_phase_rate; + int16_t tone_level; + dtmf_rx_state_t dtmf; + + char rx_digits[16 + 1]; + int rx_digits_len; + + /*! \brief Error and flow logging control */ + logging_state_t logging; +}; + +struct ademco_contactid_sender_state_s +{ + tone_report_func_t callback; + void *callback_user_data; + + int step; + int remaining_samples; + + dtmf_tx_state_t dtmf; +#if defined(SPANDSP_USE_FIXED_POINT) + /*! Minimum acceptable tone level for detection. */ + int32_t threshold; + /*! The accumlating total energy on the same period over which the Goertzels work. */ + int32_t energy; +#else + /*! Minimum acceptable tone level for detection. */ + float threshold; + /*! The accumlating total energy on the same period over which the Goertzels work. */ + float energy; +#endif + goertzel_state_t tone_1400; + goertzel_state_t tone_2300; + /*! The current sample number within a processing block. */ + int current_sample; + + /*! \brief A buffer to save the sent message, in case we need to retry. */ + char tx_digits[16 + 1]; + int tx_digits_len; + /*! \brief The number of consecutive retries. */ + int tries; + + int tone_state; + int duration; + int last_hit; + int in_tone; + int clear_to_send; + int timer; + + int busy; + + /*! \brief Error and flow logging control */ + logging_state_t logging; +}; + +#endif +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 68a5c901c3..92564fcb0e 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -2534,7 +2534,7 @@ static int process_rx_pps(t30_state_t *s, const uint8_t *msg, int len) we sent - which would have been a T30_MCF - If the block is for the previous page, or the previous block of the current page, we can assume we have hit this condition. */ - if (((s->rx_page_number & 0xFF) == page && (s->ecm_block & 0xFF) == block) + if (((s->rx_page_number & 0xFF) == page && ((s->ecm_block - 1) & 0xFF) == block) || (((s->rx_page_number - 1) & 0xFF) == page && s->ecm_block == 0)) { @@ -2568,7 +2568,6 @@ static int process_rx_pps(t30_state_t *s, const uint8_t *msg, int len) for (j = 0; j < 8; j++) { frame_no = (i << 3) + j; -#if defined(VET_ALL_FCD_FRAMES) if (s->ecm_len[frame_no] >= 0) { /* The correct pattern of frame lengths is they will all be 64 or 256 octets long, except the @@ -2598,7 +2597,6 @@ static int process_rx_pps(t30_state_t *s, const uint8_t *msg, int len) } } } -#endif if (s->ecm_len[frame_no] < 0) { s->ecm_frame_map[i + 3] |= (1 << j); diff --git a/libs/spandsp/src/t38_gateway.c b/libs/spandsp/src/t38_gateway.c index 03552efc41..85022b8d54 100644 --- a/libs/spandsp/src/t38_gateway.c +++ b/libs/spandsp/src/t38_gateway.c @@ -383,7 +383,6 @@ static void hdlc_underflow_handler(void *user_data) { t38_gateway_state_t *s; t38_gateway_hdlc_state_t *t; - int old_data_type; s = (t38_gateway_state_t *) user_data; t = &s->core.hdlc_to_modem; @@ -392,7 +391,6 @@ static void hdlc_underflow_handler(void *user_data) underflow must be an end of preamble condition. */ if ((t->buf[t->out].flags & HDLC_FLAG_PROCEED_WITH_OUTPUT)) { - old_data_type = t->buf[t->out].contents; t->buf[t->out].len = 0; t->buf[t->out].flags = 0; t->buf[t->out].contents = 0; @@ -2117,6 +2115,7 @@ static void t38_hdlc_rx_put_bit(hdlc_rx_state_t *t, int new_bit) static int restart_rx_modem(t38_gateway_state_t *s) { + fax_modems_state_t *t; put_bit_func_t put_bit_func; void *put_bit_user_data; @@ -2138,19 +2137,20 @@ static int restart_rx_modem(t38_gateway_state_t *s) s->core.short_train, s->core.ecm_mode); - hdlc_rx_init(&(s->audio.modems.hdlc_rx), FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, NULL, s); - s->audio.modems.rx_signal_present = FALSE; - s->audio.modems.rx_trained = FALSE; + t = &s->audio.modems; + hdlc_rx_init(&t->hdlc_rx, FALSE, TRUE, HDLC_FRAMING_OK_THRESHOLD, NULL, s); + t->rx_signal_present = FALSE; + t->rx_trained = FALSE; /* Default to the transmit data being V.21, unless a faster modem pops up trained. */ s->t38x.current_tx_data_type = T38_DATA_V21; - fsk_rx_init(&(s->audio.modems.v21_rx), &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) t38_hdlc_rx_put_bit, &(s->audio.modems.hdlc_rx)); + fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], FSK_FRAME_MODE_SYNC, (put_bit_func_t) t38_hdlc_rx_put_bit, &t->hdlc_rx); #if 0 - fsk_rx_signal_cutoff(&(s->audio.modems.v21_rx), -45.5f); + fsk_rx_signal_cutoff(&t->v21_rx, -45.5f); #endif if (s->core.image_data_mode && s->core.ecm_mode) { put_bit_func = (put_bit_func_t) t38_hdlc_rx_put_bit; - put_bit_user_data = (void *) &(s->audio.modems.hdlc_rx); + put_bit_user_data = (void *) &t->hdlc_rx; } else { @@ -2166,26 +2166,26 @@ static int restart_rx_modem(t38_gateway_state_t *s) s->core.to_t38.octets_per_data_packet = 1; switch (s->core.fast_rx_modem) { - case FAX_MODEM_V17_RX: - v17_rx_restart(&s->audio.modems.fast_modems.v17_rx, s->core.fast_bit_rate, s->core.short_train); - v17_rx_set_put_bit(&s->audio.modems.fast_modems.v17_rx, put_bit_func, put_bit_user_data); - set_rx_handler(s, &v17_v21_rx, &v17_v21_rx_fillin, s); - s->core.fast_rx_active = FAX_MODEM_V17_RX; - break; case FAX_MODEM_V27TER_RX: - v27ter_rx_restart(&s->audio.modems.fast_modems.v27ter_rx, s->core.fast_bit_rate, FALSE); - v27ter_rx_set_put_bit(&s->audio.modems.fast_modems.v27ter_rx, put_bit_func, put_bit_user_data); + v27ter_rx_restart(&t->fast_modems.v27ter_rx, s->core.fast_bit_rate, FALSE); + v27ter_rx_set_put_bit(&t->fast_modems.v27ter_rx, put_bit_func, put_bit_user_data); set_rx_handler(s, &v27ter_v21_rx, &v27ter_v21_rx_fillin, s); s->core.fast_rx_active = FAX_MODEM_V27TER_RX; break; case FAX_MODEM_V29_RX: - v29_rx_restart(&s->audio.modems.fast_modems.v29_rx, s->core.fast_bit_rate, FALSE); - v29_rx_set_put_bit(&s->audio.modems.fast_modems.v29_rx, put_bit_func, put_bit_user_data); + v29_rx_restart(&t->fast_modems.v29_rx, s->core.fast_bit_rate, FALSE); + v29_rx_set_put_bit(&t->fast_modems.v29_rx, put_bit_func, put_bit_user_data); set_rx_handler(s, &v29_v21_rx, &v29_v21_rx_fillin, s); s->core.fast_rx_active = FAX_MODEM_V29_RX; break; + case FAX_MODEM_V17_RX: + v17_rx_restart(&t->fast_modems.v17_rx, s->core.fast_bit_rate, s->core.short_train); + v17_rx_set_put_bit(&t->fast_modems.v17_rx, put_bit_func, put_bit_user_data); + set_rx_handler(s, &v17_v21_rx, &v17_v21_rx_fillin, s); + s->core.fast_rx_active = FAX_MODEM_V17_RX; + break; default: - set_rx_handler(s, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &(s->audio.modems.v21_rx)); + set_rx_handler(s, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &t->v21_rx); s->core.fast_rx_active = FAX_MODEM_NONE; break; } diff --git a/libs/spandsp/src/t38_terminal.c b/libs/spandsp/src/t38_terminal.c index 1a2c3eca2e..1efa1b09d6 100644 --- a/libs/spandsp/src/t38_terminal.c +++ b/libs/spandsp/src/t38_terminal.c @@ -152,9 +152,12 @@ enum T38_TIMED_STEP_NO_SIGNAL = 0x60 }; -static __inline__ void front_end_status(t38_terminal_state_t *s, int status) +static __inline__ int front_end_status(t38_terminal_state_t *s, int status) { t30_front_end_status(&s->t30, status); + if (s->t38_fe.timed_step == T38_TIMED_STEP_NONE) + return -1; + return 0; } /*- End of function --------------------------------------------------------*/ @@ -749,6 +752,9 @@ static int stream_non_ecm(t38_terminal_state_t *s) contain data. Hopefully, following the current spec will not cause compatibility issues. */ len = t30_non_ecm_get_chunk(&s->t30, buf, fe->octets_per_data_packet); + if (len < 0) + return -1; + /*endif*/ if (len > 0) bit_reverse(buf, buf, len); /*endif*/ @@ -776,7 +782,8 @@ static int stream_non_ecm(t38_terminal_state_t *s) return res; /*endif*/ fe->timed_step = T38_TIMED_STEP_NON_ECM_MODEM_5; - front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE); + if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) + return -1; break; } /*endif*/ @@ -806,7 +813,8 @@ static int stream_non_ecm(t38_terminal_state_t *s) if (fe->us_per_tx_chunk) delay = bits_to_us(s, 8*len) + 60000; /*endif*/ - front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE); + if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) + return -1; break; } /*endif*/ @@ -910,7 +918,8 @@ static int stream_hdlc(t38_terminal_state_t *s) previous = fe->current_tx_data_type; fe->hdlc_tx.ptr = 0; fe->hdlc_tx.len = 0; - front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE); + if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) + return -1; /* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */ if (fe->hdlc_tx.len >= 0) { @@ -940,7 +949,8 @@ static int stream_hdlc(t38_terminal_state_t *s) if (fe->us_per_tx_chunk) delay += 100000; /*endif*/ - front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE); + if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) + return -1; } /*endif*/ break; @@ -969,7 +979,8 @@ static int stream_hdlc(t38_terminal_state_t *s) previous = fe->current_tx_data_type; fe->hdlc_tx.ptr = 0; fe->hdlc_tx.len = 0; - front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE); + if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) + return -1; /* The above step should have got the next HDLC step ready - either another frame, or an instruction to stop transmission. */ if (fe->hdlc_tx.len >= 0) { @@ -1003,7 +1014,8 @@ static int stream_hdlc(t38_terminal_state_t *s) if (fe->us_per_tx_chunk) delay += 100000; /*endif*/ - front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE); + if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) + return -1; } /*endif*/ break; @@ -1059,7 +1071,8 @@ static int stream_ced(t38_terminal_state_t *s) case T38_TIMED_STEP_CED_3: /* End of CED */ fe->timed_step = fe->queued_timed_step; - front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE); + if (front_end_status(s, T30_FRONT_END_SEND_STEP_COMPLETE) < 0) + return -1; return 0; } /*endswitch*/ diff --git a/libs/spandsp/src/timezone.c b/libs/spandsp/src/timezone.c index 04dfa51daf..79966f1d4c 100644 --- a/libs/spandsp/src/timezone.c +++ b/libs/spandsp/src/timezone.c @@ -112,9 +112,11 @@ static const int year_lengths[2] = DAYS_PER_LEAP_YEAR }; -static int increment_overflow(int *number, int delta) +static int add_with_overflow_detection(int *number, int delta) { - int last_number; + /* This needs to be considered volatile, or clever optimisation destroys + the effect of the the rollover detection logic */ + volatile int last_number; last_number = *number; *number += delta; @@ -209,7 +211,7 @@ static struct tm *time_sub(const time_t * const timep, const long int offset, co if (idelta == 0) idelta = (tdays < 0) ? -1 : 1; newy = y; - if (increment_overflow(&newy, idelta)) + if (add_with_overflow_detection(&newy, idelta)) return NULL; leapdays = leaps_thru_end_of(newy - 1) - leaps_thru_end_of(y - 1); tdays -= ((time_t) newy - y)*DAYS_PER_NON_LEAP_YEAR; @@ -234,18 +236,18 @@ static struct tm *time_sub(const time_t * const timep, const long int offset, co } while (idays < 0) { - if (increment_overflow(&y, -1)) + if (add_with_overflow_detection(&y, -1)) return NULL; idays += year_lengths[isleap(y)]; } while (idays >= year_lengths[isleap(y)]) { idays -= year_lengths[isleap(y)]; - if (increment_overflow(&y, 1)) + if (add_with_overflow_detection(&y, 1)) return NULL; } tmp->tm_year = y; - if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) + if (add_with_overflow_detection(&tmp->tm_year, -TM_YEAR_BASE)) return NULL; tmp->tm_yday = idays; /* The "extra" mods below avoid overflow problems. */ diff --git a/libs/spandsp/src/v18.c b/libs/spandsp/src/v18.c index bb26644b62..b35d5fa4e9 100644 --- a/libs/spandsp/src/v18.c +++ b/libs/spandsp/src/v18.c @@ -567,9 +567,11 @@ SPAN_DECLARE(uint8_t) v18_decode_baudot(v18_state_t *s, uint8_t ch) static void v18_rx_dtmf(void *user_data, const char digits[], int len) { +#if 0 v18_state_t *s; s = (v18_state_t *) user_data; +#endif } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/src/v8.c b/libs/spandsp/src/v8.c index 78f2904bac..906f96ba95 100644 --- a/libs/spandsp/src/v8.c +++ b/libs/spandsp/src/v8.c @@ -124,7 +124,7 @@ SPAN_DECLARE(const char *) v8_call_function_to_str(int call_function) case V8_CALL_FUNCTION_EXTENSION: return "Call function is in extension octet"; } - return "???"; + return "Unknown call function"; } /*- End of function --------------------------------------------------------*/ @@ -199,7 +199,7 @@ SPAN_DECLARE(const char *) v8_pstn_access_to_str(int pstn_access) case V8_PSTN_ACCESS_DCE_ON_DIGITAL | V8_PSTN_ACCESS_ANSWER_DCE_CELLULAR | V8_PSTN_ACCESS_CALL_DCE_CELLULAR: return "DCE on digital, and answering and calling modems on cellular"; } - return "???"; + return "PSTN access unknown"; } /*- End of function --------------------------------------------------------*/ @@ -235,7 +235,7 @@ SPAN_DECLARE(const char *) v8_pcm_modem_availability_to_str(int pcm_modem_availa case V8_PSTN_PCM_MODEM_V91 | V8_PSTN_PCM_MODEM_V90_V92_DIGITAL | V8_PSTN_PCM_MODEM_V90_V92_ANALOGUE: return "V.91 and V.90/V.92 digital/analogue available"; } - return "???"; + return "PCM availability unknown"; } /*- End of function --------------------------------------------------------*/ @@ -374,6 +374,7 @@ static const uint8_t *process_pstn_access(v8_state_t *s, const uint8_t *p) static const uint8_t *process_non_standard_facilities(v8_state_t *s, const uint8_t *p) { + /* TODO: This is wrong */ s->result.nsf = (*p >> 5) & 0x07; span_log(&s->logging, SPAN_LOG_FLOW, "%s\n", v8_nsf_to_str(s->result.nsf)); return p; diff --git a/libs/spandsp/tests/Makefile.am b/libs/spandsp/tests/Makefile.am index 401e8f41e6..c370f20a46 100644 --- a/libs/spandsp/tests/Makefile.am +++ b/libs/spandsp/tests/Makefile.am @@ -50,7 +50,8 @@ INCLUDES = -I$(top_builddir)/src -I$(top_builddir)/spandsp-sim -DDATADIR="\"$(pk LIBDIR = -L$(top_builddir)/src -noinst_PROGRAMS = adsi_tests \ +noinst_PROGRAMS = ademco_contactid_tests \ + adsi_tests \ async_tests \ at_interpreter_tests \ awgn_tests \ @@ -134,6 +135,9 @@ noinst_HEADERS = echo_monitor.h \ pcap_parse.h \ udptl.h +ademco_contactid_tests_SOURCES = ademco_contactid_tests.c +ademco_contactid_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp + adsi_tests_SOURCES = adsi_tests.c adsi_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp diff --git a/libs/spandsp/tests/ademco_contactid_tests.c b/libs/spandsp/tests/ademco_contactid_tests.c new file mode 100644 index 0000000000..c8e87f1fb8 --- /dev/null +++ b/libs/spandsp/tests/ademco_contactid_tests.c @@ -0,0 +1,391 @@ +/* + * SpanDSP - a series of DSP components for telephony + * + * ademco_contactid.c - Ademco ContactID alarm protocol + * + * Written by Steve Underwood <steveu@coppice.org> + * + * Copyright (C) 2012 Steve Underwood + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1, + * as published by the Free Software Foundation. + * + * 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. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/*! \page ademco_contactid_tests_page Ademco ContactID tests +\section ademco_contactid_tests_page_sec_1 What does it do? + +\section ademco_contactid_tests_page_sec_2 How does it work? +*/ + +/* Enable the following definition to enable direct probing into the FAX structures */ +//#define WITH_SPANDSP_INTERNALS + +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <sndfile.h> + +//#if defined(WITH_SPANDSP_INTERNALS) +//#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES +//#endif + +#include "spandsp.h" +#include "spandsp-sim.h" + +#define SAMPLES_PER_CHUNK 160 + +#define OUTPUT_FILE_NAME "ademco_contactid.wav" + +#define MITEL_DIR "../test-data/mitel/" +#define BELLCORE_DIR "../test-data/bellcore/" + +const char *bellcore_files[] = +{ + MITEL_DIR "mitel-cm7291-talkoff.wav", + BELLCORE_DIR "tr-tsy-00763-1.wav", + BELLCORE_DIR "tr-tsy-00763-2.wav", + BELLCORE_DIR "tr-tsy-00763-3.wav", + BELLCORE_DIR "tr-tsy-00763-4.wav", + BELLCORE_DIR "tr-tsy-00763-5.wav", + BELLCORE_DIR "tr-tsy-00763-6.wav", + "" +}; + +static const ademco_contactid_report_t reports[] = +{ + {0x1234, 0x18, 0x1, 0x131, 0x1, 0x15}, + {0x1234, 0x18, 0x3, 0x131, 0x1, 0x15}, + {0x1234, 0x18, 0x1, 0x401, 0x2, 0x3}, + {0x1234, 0x18, 0x3, 0x401, 0x3, 0x5}, + {0x1234, 0x56, 0x7, 0x890, 0xBC, 0xDEF}, + {0x1234, 0x56, 0x7, 0x89A, 0xBC, 0xDEF} /* This one is bad, as it contains a hex 'A' */ +}; +static int reports_entry = 0; + +static int16_t amp[1000000]; + +int tx_callback_reported = FALSE; +int rx_callback_reported = FALSE; + +int sending_complete = FALSE; + +SNDFILE *outhandle; + +static void talkoff_tx_callback(void *user_data, int tone, int level, int duration) +{ + printf("Ademco sender report %d\n", tone); + tx_callback_reported = TRUE; +} + +static int mitel_cm7291_side_2_and_bellcore_tests(void) +{ + int j; + SNDFILE *inhandle; + int frames; + ademco_contactid_sender_state_t *sender; + logging_state_t *logging; + + if ((sender = ademco_contactid_sender_init(NULL, talkoff_tx_callback, NULL)) == NULL) + return -1; + logging = ademco_contactid_sender_get_logging_state(sender); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "Ademco-tx"); + + tx_callback_reported = FALSE; + + /* The remainder of the Mitel tape is the talk-off test */ + /* Here we use the Bellcore test tapes (much tougher), in six + files - 1 from each side of the original 3 cassette tapes */ + /* Bellcore say you should get no more than 470 false detections with + a good receiver. Dialogic claim 20. Of course, we can do better than + that, eh? */ + printf("Talk-off test\n"); + for (j = 0; bellcore_files[j][0]; j++) + { + if ((inhandle = sf_open_telephony_read(bellcore_files[j], 1)) == NULL) + { + printf(" Cannot open speech file '%s'\n", bellcore_files[j]); + return -1; + } + while ((frames = sf_readf_short(inhandle, amp, SAMPLE_RATE))) + { + ademco_contactid_sender_rx(sender, amp, frames); + } + if (sf_close_telephony(inhandle)) + { + printf(" Cannot close speech file '%s'\n", bellcore_files[j]); + return -1; + } + printf(" File %d gave %d false hits.\n", j + 1, 0); + } + if (tx_callback_reported) + { + printf(" Failed\n"); + return -1; + } + printf(" Passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static void rx_callback(void *user_data, const ademco_contactid_report_t *report) +{ + printf("Ademco Contact ID message:\n"); + printf(" Account %X\n", report->acct); + printf(" Message type %X\n", report->mt); + printf(" Qualifier %X\n", report->q); + printf(" Event %X\n", report->xyz); + printf(" Group/partition %X\n", report->gg); + printf(" User/Zone information %X\n", report->ccc); + if (memcmp(&reports[reports_entry], report, sizeof (*report))) + { + printf("Report mismatch\n"); + exit(2); + } + rx_callback_reported = TRUE; +} +/*- End of function --------------------------------------------------------*/ + +static void tx_callback(void *user_data, int tone, int level, int duration) +{ + ademco_contactid_sender_state_t *sender; + + sender = (ademco_contactid_sender_state_t *) user_data; + printf("Ademco sender report %d\n", tone); + switch (tone) + { + case -1: + /* We are connected and ready to send */ + ademco_contactid_sender_put(sender, &reports[reports_entry]); + break; + case 1: + /* We have succeeded in sending, and are ready to send another message. */ + if (++reports_entry < 5) + ademco_contactid_sender_put(sender, &reports[reports_entry]); + else + sending_complete = TRUE; + break; + case 0: + /* Sending failed after retries */ + sending_complete = TRUE; + break; + } +} +/*- End of function --------------------------------------------------------*/ + +static int end_to_end_tests(void) +{ + ademco_contactid_receiver_state_t *receiver; + ademco_contactid_sender_state_t *sender; + logging_state_t *logging; + codec_munge_state_t *munge; + awgn_state_t noise_source; + int16_t amp[SAMPLES_PER_CHUNK]; + int16_t sndfile_buf[2*SAMPLES_PER_CHUNK]; + int samples; + int i; + int j; + + printf("End to end tests\n"); + + if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 2)) == NULL) + { + fprintf(stderr, " Cannot open audio file '%s'\n", OUTPUT_FILE_NAME); + exit(2); + } + + if ((receiver = ademco_contactid_receiver_init(NULL, rx_callback, NULL)) == NULL) + return -1; + ademco_contactid_receiver_set_realtime_callback(receiver, rx_callback, receiver); + + logging = ademco_contactid_receiver_get_logging_state(receiver); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "Ademco-rx"); + + if ((sender = ademco_contactid_sender_init(NULL, tx_callback, NULL)) == NULL) + return -1; + ademco_contactid_sender_set_realtime_callback(sender, tx_callback, sender); + logging = ademco_contactid_sender_get_logging_state(sender); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "Ademco-tx"); + + awgn_init_dbm0(&noise_source, 1234567, -50); + munge = codec_munge_init(MUNGE_CODEC_ALAW, 0); + + sending_complete = FALSE; + rx_callback_reported = FALSE; + + for (i = 0; i < 1000; i++) + { + samples = ademco_contactid_sender_tx(sender, amp, SAMPLES_PER_CHUNK); + for (j = samples; j < SAMPLES_PER_CHUNK; j++) + amp[j] = 0; + for (j = 0; j < SAMPLES_PER_CHUNK; j++) + sndfile_buf[2*j] = amp[j]; + /* There is no point in impairing this signal. It is just DTMF tones, which + will work as wel as the DTMF detector beign used. */ + ademco_contactid_receiver_rx(receiver, amp, SAMPLES_PER_CHUNK); + + samples = ademco_contactid_receiver_tx(receiver, amp, SAMPLES_PER_CHUNK); + for (j = samples; j < SAMPLES_PER_CHUNK; j++) + amp[j] = 0; + + /* We add AWGN and codec impairments to the signal, to stress the tone detector. */ + codec_munge(munge, amp, SAMPLES_PER_CHUNK); + for (j = 0; j < SAMPLES_PER_CHUNK; j++) + { + sndfile_buf[2*j + 1] = amp[j]; + /* Add noise to the tones */ + amp[j] += awgn(&noise_source); + } + codec_munge(munge, amp, SAMPLES_PER_CHUNK); + ademco_contactid_sender_rx(sender, amp, SAMPLES_PER_CHUNK); + + sf_writef_short(outhandle, sndfile_buf, SAMPLES_PER_CHUNK); + } + if (!rx_callback_reported) + { + fprintf(stderr, " Report not received\n"); + return -1; + } + + if (sf_close_telephony(outhandle)) + { + fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME); + return -1; + } + printf(" Passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static int encode_decode_tests(void) +{ + char buf[100]; + ademco_contactid_receiver_state_t *receiver; + ademco_contactid_sender_state_t *sender; + logging_state_t *logging; + ademco_contactid_report_t result; + int i; + + printf("Encode and decode tests\n"); + + if ((receiver = ademco_contactid_receiver_init(NULL, NULL, NULL)) == NULL) + return 2; + logging = ademco_contactid_receiver_get_logging_state(receiver); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "Ademco-rx"); + + if ((sender = ademco_contactid_sender_init(NULL, NULL, NULL)) == NULL) + return 2; + logging = ademco_contactid_sender_get_logging_state(sender); + span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW); + span_log_set_tag(logging, "Ademco-tx"); + + for (i = 0; i < 5; i++) + { + if (encode_msg(buf, &reports[i]) < 0) + { + printf("Bad encode message\n"); + return -1; + } + printf("'%s'\n", buf); + if (decode_msg(&result, buf)) + { + printf("Bad decode message\n"); + return -1; + } + ademco_contactid_receiver_log_msg(receiver, &result); + printf("\n"); + if (memcmp(&reports[i], &result, sizeof(result))) + { + printf("Received message does not match the one sent\n"); + return -1; + } + } + + if (encode_msg(buf, &reports[5]) >= 0) + { + printf("Incorrectly good message\n"); + return -1; + } + printf("'%s'\n", buf); + printf("\n"); + printf(" Passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static void decode_file(const char *file) +{ + //SPAN_DECLARE(int) decode_msg(ademco_contactid_report_t *report, const char buf[]) +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + int opt; + const char *decode_test_file; + + decode_test_file = NULL; + while ((opt = getopt(argc, argv, "d:")) != -1) + { + switch (opt) + { + case 'd': + decode_test_file = optarg; + break; + default: + //usage(); + exit(2); + break; + } + } + + if (decode_test_file) + { + decode_file(decode_test_file); + return 0; + } + + if (encode_decode_tests()) + { + printf("Tests failed\n"); + return 2; + } + + if (mitel_cm7291_side_2_and_bellcore_tests()) + { + printf("Tests failed\n"); + return 2; + } + + if (end_to_end_tests()) + { + printf("Tests failed\n"); + return 2; + } + + printf("Tests passed\n"); + return 0; +} +/*- End of function --------------------------------------------------------*/ +/*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/tests/echo_tests.c b/libs/spandsp/tests/echo_tests.c index 86b6cda961..2bf0d68799 100644 --- a/libs/spandsp/tests/echo_tests.c +++ b/libs/spandsp/tests/echo_tests.c @@ -633,20 +633,20 @@ static int perform_test_sanity(void) int16_t tx; int16_t clean; int far_tx; - int16_t far_sound[SAMPLE_RATE]; + //int16_t far_sound[SAMPLE_RATE]; int16_t result_sound[64000]; int result_cur; int outframes; - int local_cur; - int far_cur; + //int local_cur; + //int far_cur; //int32_t coeffs[200][128]; //int coeff_index; print_test_title("Performing basic sanity test\n"); ctx = echo_can_init(TEST_EC_TAPS, 0); - local_cur = 0; - far_cur = 0; + //local_cur = 0; + //far_cur = 0; result_cur = 0; echo_can_flush(ctx); @@ -684,7 +684,7 @@ static int perform_test_sanity(void) far_tx = 0; } #else - far_sound[0] = 0; + //far_sound[0] = 0; far_tx = 0; #endif rx = channel_model(&chan_model, tx, far_tx); diff --git a/libs/spandsp/tests/fax_decode.c b/libs/spandsp/tests/fax_decode.c index dd60fe9280..e175a6168b 100644 --- a/libs/spandsp/tests/fax_decode.c +++ b/libs/spandsp/tests/fax_decode.c @@ -89,7 +89,7 @@ int decode_test = FALSE; int rx_bits = 0; t30_state_t t30_dummy; -t4_state_t t4_state; +t4_state_t t4_rx_state; int t4_up = FALSE; hdlc_rx_state_t hdlcrx; @@ -291,12 +291,12 @@ static void t4_begin(void) int i; //printf("Begin T.4 - %d %d %d %d\n", line_encoding, x_resolution, y_resolution, image_width); - t4_rx_set_rx_encoding(&t4_state, line_encoding); - t4_rx_set_x_resolution(&t4_state, x_resolution); - t4_rx_set_y_resolution(&t4_state, y_resolution); - t4_rx_set_image_width(&t4_state, image_width); + t4_rx_set_rx_encoding(&t4_rx_state, line_encoding); + t4_rx_set_x_resolution(&t4_rx_state, x_resolution); + t4_rx_set_y_resolution(&t4_rx_state, y_resolution); + t4_rx_set_image_width(&t4_rx_state, image_width); - t4_rx_start_page(&t4_state); + t4_rx_start_page(&t4_rx_state); t4_up = TRUE; for (i = 0; i < 256; i++) @@ -316,13 +316,13 @@ static void t4_end(void) for (i = 0; i < 256; i++) { if (ecm_len[i] > 0) - t4_rx_put_chunk(&t4_state, ecm_data[i], ecm_len[i]); + t4_rx_put_chunk(&t4_rx_state, ecm_data[i], ecm_len[i]); fprintf(stderr, "%d", (ecm_len[i] <= 0) ? 0 : 1); } fprintf(stderr, "\n"); } - t4_rx_end_page(&t4_state); - t4_rx_get_transfer_statistics(&t4_state, &stats); + t4_rx_end_page(&t4_rx_state); + t4_rx_get_transfer_statistics(&t4_rx_state, &stats); fprintf(stderr, "Pages = %d\n", stats.pages_transferred); fprintf(stderr, "Image size = %dx%d\n", stats.width, stats.length); fprintf(stderr, "Image resolution = %dx%d\n", stats.x_resolution, stats.y_resolution); @@ -378,7 +378,7 @@ static void v17_put_bit(void *user_data, int bit) } else { - if (t4_rx_put_bit(&t4_state, bit)) + if (t4_rx_put_bit(&t4_rx_state, bit)) { t4_end(); fprintf(stderr, "End of page detected\n"); @@ -414,7 +414,7 @@ static void v29_put_bit(void *user_data, int bit) } else { - if (t4_rx_put_bit(&t4_state, bit)) + if (t4_rx_put_bit(&t4_rx_state, bit)) { t4_end(); fprintf(stderr, "End of page detected\n"); @@ -450,7 +450,7 @@ static void v27ter_put_bit(void *user_data, int bit) } else { - if (t4_rx_put_bit(&t4_state, bit)) + if (t4_rx_put_bit(&t4_rx_state, bit)) { t4_end(); fprintf(stderr, "End of page detected\n"); @@ -527,7 +527,7 @@ int main(int argc, char *argv[]) span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW); #endif - if (t4_rx_init(&t4_state, "fax_decode.tif", T4_COMPRESSION_ITU_T4_2D) == NULL) + if (t4_rx_init(&t4_rx_state, "fax_decode.tif", T4_COMPRESSION_ITU_T4_2D) == NULL) { fprintf(stderr, "Failed to init\n"); exit(0); @@ -543,7 +543,7 @@ int main(int argc, char *argv[]) v29_rx(v29, amp, len); //v27ter_rx(v27ter, amp, len); } - t4_rx_release(&t4_state); + t4_rx_release(&t4_rx_state); if (sf_close(inhandle)) { diff --git a/libs/spandsp/tests/fax_tester.c b/libs/spandsp/tests/fax_tester.c index 79e8a09ae8..20af011981 100644 --- a/libs/spandsp/tests/fax_tester.c +++ b/libs/spandsp/tests/fax_tester.c @@ -271,14 +271,11 @@ static void non_ecm_rx_status(void *user_data, int status) static void non_ecm_put_bit(void *user_data, int bit) { - faxtester_state_t *s; - if (bit < 0) { non_ecm_rx_status(user_data, bit); return; } - s = (faxtester_state_t *) user_data; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/tests/fax_tests.sh b/libs/spandsp/tests/fax_tests.sh index bd29f3bf34..3c78fe51a2 100755 --- a/libs/spandsp/tests/fax_tests.sh +++ b/libs/spandsp/tests/fax_tests.sh @@ -18,7 +18,7 @@ run_fax_test() { rm -f fax_tests_1.tif - echo -i ${FILE} ${OPTS} -i ${FILE} + echo ./fax_tests -i ${FILE} ${OPTS} -i ${FILE} ./fax_tests ${OPTS} -i ${FILE} >xyzzy 2>xyzzy2 RETVAL=$? if [ $RETVAL != 0 ] @@ -28,7 +28,7 @@ run_fax_test() fi # Now use tiffcmp to check the results. It will return non-zero if any page images differ. The -t # option means the normal differences in tags will be ignored. - tiffcmp -t ${FILE} fax_tests.tif #>/dev/null + tiffcmp -t ${FILE} fax_tests.tif >/dev/null RETVAL=$? if [ $RETVAL != 0 ] then diff --git a/libs/spandsp/tests/g722_tests.c b/libs/spandsp/tests/g722_tests.c index c33d9e67b6..863ea3e63d 100644 --- a/libs/spandsp/tests/g722_tests.c +++ b/libs/spandsp/tests/g722_tests.c @@ -307,7 +307,7 @@ static void itu_compliance_tests(void) /* Get the upper reference output data */ len_comp_upper = get_test_vector(decode_test_files[file + 4], itu_ref_upper, MAX_TEST_VECTOR_LEN); - if (len_data != len_comp_lower || len_data != len_comp_lower) + if (len_data != len_comp_lower || len_data != len_comp_upper) { printf("Test data length mismatch\n"); exit(2); diff --git a/libs/spandsp/tests/regression_tests.sh b/libs/spandsp/tests/regression_tests.sh index 4f32ebbc32..fe1e1a8ad9 100755 --- a/libs/spandsp/tests/regression_tests.sh +++ b/libs/spandsp/tests/regression_tests.sh @@ -634,7 +634,7 @@ do done echo v27ter_tests completed OK -for OPTS in "-b 9600 -s -42 -n -62" "-b 7200 -s -42 -n -58" "-b 4800 -s -42 -n -55" +for OPTS in "-b 9600 -s -42 -n -62" "-b 7200 -s -42 -n -59" "-b 4800 -s -42 -n -55" do ./v29_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST RETVAL=$? diff --git a/libs/spandsp/tests/schedule_tests.c b/libs/spandsp/tests/schedule_tests.c index 81c467c927..a9fa466199 100644 --- a/libs/spandsp/tests/schedule_tests.c +++ b/libs/spandsp/tests/schedule_tests.c @@ -86,7 +86,7 @@ int main(int argc, char *argv[]) int i; span_sched_state_t sched; uint64_t when; - + span_schedule_init(&sched); span_schedule_event(&sched, 500000, callback1, NULL); diff --git a/libs/spandsp/tests/super_tone_rx_tests.c b/libs/spandsp/tests/super_tone_rx_tests.c index 717768d0c5..b9b673855d 100644 --- a/libs/spandsp/tests/super_tone_rx_tests.c +++ b/libs/spandsp/tests/super_tone_rx_tests.c @@ -410,7 +410,6 @@ static int detection_range_tests(super_tone_rx_state_t *super) int16_t amp[SAMPLES_PER_CHUNK]; int i; int j; - int x; uint32_t phase; int32_t phase_inc; int scale; @@ -427,7 +426,7 @@ static int detection_range_tests(super_tone_rx_state_t *super) { for (i = 0; i < SAMPLES_PER_CHUNK; i++) amp[i] = (dds(&phase, phase_inc)*scale) >> 15; - x = super_tone_rx(super, amp, SAMPLES_PER_CHUNK); + super_tone_rx(super, amp, SAMPLES_PER_CHUNK); } } return 0; diff --git a/libs/spandsp/tests/tsb85_tests.c b/libs/spandsp/tests/tsb85_tests.c index aa78e5dfba..74587fbb90 100644 --- a/libs/spandsp/tests/tsb85_tests.c +++ b/libs/spandsp/tests/tsb85_tests.c @@ -80,6 +80,8 @@ int test_local_interrupt = FALSE; const char *output_tiff_file_name; +int log_audio = FALSE; + fax_state_t *fax; faxtester_state_t state; @@ -1058,10 +1060,8 @@ static void exchange(faxtester_state_t *s) int len; int i; int total_audio_time; - int log_audio; logging_state_t *logging; - log_audio = TRUE; output_tiff_file_name = OUTPUT_TIFF_FILE_NAME; if (log_audio) @@ -1295,10 +1295,14 @@ int main(int argc, char *argv[]) xml_file_name = "../spandsp/tsb85.xml"; test_name = "MRGN01"; - while ((opt = getopt(argc, argv, "x:")) != -1) + log_audio = FALSE; + while ((opt = getopt(argc, argv, "lx:")) != -1) { switch (opt) { + case 'l': + log_audio = TRUE; + break; case 'x': xml_file_name = optarg; break; diff --git a/src/include/switch_event.h b/src/include/switch_event.h index 5909c0e0c0..d0474a6929 100644 --- a/src/include/switch_event.h +++ b/src/include/switch_event.h @@ -403,6 +403,7 @@ SWITCH_DECLARE(void) switch_event_deliver(switch_event_t **event); SWITCH_DECLARE(char *) switch_event_build_param_string(switch_event_t *event, const char *prefix, switch_hash_t *vars_map); SWITCH_DECLARE(int) switch_event_check_permission_list(switch_event_t *list, const char *name); SWITCH_DECLARE(void) switch_event_add_presence_data_cols(switch_channel_t *channel, switch_event_t *event, const char *prefix); +SWITCH_DECLARE(void) switch_event_launch_dispatch_threads(uint32_t max); ///\} diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index c98db6a04b..344544f705 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2869,6 +2869,10 @@ SWITCH_STANDARD_APP(audio_bridge_function) moh = switch_channel_get_variable(caller_channel, "campon_hold_music"); } + if (!zstr(moh) && !strcasecmp(moh, "silence")) { + moh = NULL; + } + do { fail = 0; diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index b08d7efc17..68763cd452 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -5764,6 +5764,8 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, "sip_full_to")); } else { + int break_rfc = switch_true(switch_channel_get_variable(channel, "sip_recovery_break_rfc")); + tech_pvt->redirected = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_contact_uri")); if (zstr(rr)) { @@ -5776,11 +5778,11 @@ static int recover_callback(void *pArg, int argc, char **argv, char **columnName tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_from_uri")); if (!switch_channel_get_variable_dup(channel, "sip_handle_full_from", SWITCH_FALSE, -1)) { - switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, "sip_full_to")); + switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, break_rfc ? "sip_full_from" : "sip_full_to")); } if (!switch_channel_get_variable_dup(channel, "sip_handle_full_to", SWITCH_FALSE, -1)) { - switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, "sip_full_from")); + switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, break_rfc ? "sip_full_to" : "sip_full_from")); } } diff --git a/src/switch_core.c b/src/switch_core.c index d706563f83..2a4cae408f 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1538,7 +1538,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc switch_log_init(runtime.memory_pool, runtime.colorize_console); if (flags & SCF_MINIMAL) return SWITCH_STATUS_SUCCESS; - + runtime.tipping_point = 0; runtime.timer_affinity = -1; runtime.microseconds_per_tick = 20000; @@ -1813,6 +1813,23 @@ static void switch_load_core_config(const char *file) switch_core_min_idle_cpu(atof(val)); } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) { runtime.tipping_point = atoi(val); + } else if (!strcasecmp(var, "initial-event-threads") && !zstr(val)) { + int tmp = atoi(val); + + + if (tmp > runtime.cpu_count / 2) { + tmp = runtime.cpu_count / 2; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be higher than %d so setting it to that value\n", + runtime.cpu_count / 2); + } + + if (tmp < 1) { + tmp = 1; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "This value cannot be lower than 1 so setting it to that level\n"); + } + + switch_event_launch_dispatch_threads(tmp); + } else if (!strcasecmp(var, "1ms-timer") && switch_true(val)) { runtime.microseconds_per_tick = 1000; } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) { diff --git a/src/switch_event.c b/src/switch_event.c index defae3586c..0f08b496c0 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -34,6 +34,7 @@ #include <switch.h> #include <switch_event.h> + //#define SWITCH_EVENT_RECYCLE #define DISPATCH_QUEUE_LEN 100 //#define DEBUG_DISPATCH_QUEUES @@ -87,7 +88,6 @@ static uint64_t EVENT_SEQUENCE_NR = 0; static switch_queue_t *EVENT_RECYCLE_QUEUE = NULL; static switch_queue_t *EVENT_HEADER_RECYCLE_QUEUE = NULL; #endif -static void launch_dispatch_threads(uint32_t max, switch_memory_pool_t *pool); static char *my_dup(const char *s) { @@ -305,7 +305,7 @@ static switch_status_t switch_event_queue_dispatch_event(switch_event_t **eventp if (launch) { if (SOFT_MAX_DISPATCH + 1 < MAX_DISPATCH) { - launch_dispatch_threads(SOFT_MAX_DISPATCH + 1, RUNTIME_POOL); + switch_event_launch_dispatch_threads(SOFT_MAX_DISPATCH + 1); } } @@ -515,13 +515,15 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) return SWITCH_STATUS_SUCCESS; } -static void launch_dispatch_threads(uint32_t max, switch_memory_pool_t *pool) +SWITCH_DECLARE(void) switch_event_launch_dispatch_threads(uint32_t max) { switch_threadattr_t *thd_attr; uint32_t index = 0; int launched = 0; uint32_t sanity = 200; + switch_memory_pool_t *pool = RUNTIME_POOL; + if (max > MAX_DISPATCH) { return; } @@ -532,6 +534,7 @@ static void launch_dispatch_threads(uint32_t max, switch_memory_pool_t *pool) for (index = SOFT_MAX_DISPATCH; index < max && index < MAX_DISPATCH; index++) { if (EVENT_DISPATCH_QUEUE_THREADS[index]) { + printf("Index exists continue\n"); continue; } @@ -540,13 +543,13 @@ static void launch_dispatch_threads(uint32_t max, switch_memory_pool_t *pool) switch_threadattr_priority_increase(thd_attr); switch_thread_create(&EVENT_DISPATCH_QUEUE_THREADS[index], thd_attr, switch_event_dispatch_thread, EVENT_DISPATCH_QUEUE, pool); while(--sanity && !EVENT_DISPATCH_QUEUE_RUNNING[index]) switch_yield(10000); + if (index == 1) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Create event dispatch thread %d\n", index); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Create event dispatch thread %d\n", index); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Create additional event dispatch thread %d\n", index); } launched++; - break; } SOFT_MAX_DISPATCH = index; @@ -598,7 +601,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) //switch_threadattr_priority_increase(thd_attr); switch_queue_create(&EVENT_DISPATCH_QUEUE, DISPATCH_QUEUE_LEN * MAX_DISPATCH, pool); - launch_dispatch_threads(1, RUNTIME_POOL); + switch_event_launch_dispatch_threads(1); //switch_thread_create(&EVENT_QUEUE_THREADS[0], thd_attr, switch_event_thread, EVENT_QUEUE[0], RUNTIME_POOL); //switch_thread_create(&EVENT_QUEUE_THREADS[1], thd_attr, switch_event_thread, EVENT_QUEUE[1], RUNTIME_POOL); diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 8f50fe1257..cac064b544 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1734,7 +1734,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_transfer(switch_core_session_ (long) switch_epoch_time_now(NULL), new_profile->uuid_str, extension, use_context, use_dialplan); switch_channel_add_variable_var_check(channel, SWITCH_TRANSFER_HISTORY_VARIABLE, new_profile->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH); - switch_channel_set_variable(channel, SWITCH_TRANSFER_SOURCE_VARIABLE, new_profile->transfer_source); + switch_channel_set_variable_var_check(channel, SWITCH_TRANSFER_SOURCE_VARIABLE, new_profile->transfer_source, SWITCH_FALSE); return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 72d0ab0393..6d3ad966ec 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2331,7 +2331,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess q = !q; } - if (end && p < end && *p == ',') { + if (end && p < end && *p == ',' && *(p-1) != '\\') { if (q || alt) { *p = QUOTED_ESC_COMMA; diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 8738071cb4..c15da6fb03 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1879,6 +1879,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, switch_status_t status = SWITCH_STATUS_SUCCESS; size_t len = 0; char tb[2] = ""; + int term_required = 0; + + + if (valid_terminators && *valid_terminators == '=') { + term_required = 1; + } switch_assert(session); @@ -1945,6 +1951,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session, } } } + } else if (term_required) { + status = SWITCH_STATUS_TOO_SMALL; } len = strlen(digit_buffer); diff --git a/src/switch_log.c b/src/switch_log.c index 1bd931a44e..9799a3698f 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -296,6 +296,7 @@ static void *SWITCH_THREAD_FUNC log_thread(switch_thread_t *t, void *obj) } if (!pop) { + THREAD_RUNNING = -1; break; } @@ -558,7 +559,7 @@ SWITCH_DECLARE(switch_status_t) switch_log_shutdown(void) { switch_status_t st; - THREAD_RUNNING = -1; + switch_queue_push(LOG_QUEUE, NULL); while (THREAD_RUNNING) { switch_cond_next(); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 33be911b2c..c8e6ff94cb 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2883,7 +2883,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t #endif #ifdef ENABLE_SRTP - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_RECV) && rtp_session->rtcp_recv_msg.header.version == 2) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_RECV)) { int sbytes = (int) *bytes; err_status_t stat = 0; @@ -3002,7 +3002,7 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t } #ifdef ENABLE_SRTP - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_RECV) && rtp_session->rtcp_recv_msg.header.version == 2) { + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_RECV)) { int sbytes = (int) *bytes; err_status_t stat = 0;